2016-09-04 6 views
0

Я отслеживаю системные вызовы, такие как чтение, запись, открытие и т. Д. С помощью ptrace. Если есть системный вызов для открытия, аргументы, переданные этому системному вызову, могут быть получены из user_regs_struct. Первый аргумент сохраняется в регистре rdi. Содержание rdi - это unsigned long long int. Как получить из него имя строкового файла, например. foo.txt, который был передан открытому системному вызову?Как получить аргументы, переданные системному вызову linux в C?

+0

Это указатель на то, где эта строка находится в памяти процесса. –

+0

Да, но я не могу читать то же самое. Есть ли какой-либо особый способ прочитать адресное пространство процесса? Я либо получаю пустую строку, либо <ошибка: не могу получить доступ ..>. – Sagar

+0

Да, используя 'ptrace'. Посмотрите 'PTRACE_PEEKTEXT' и' PTRACE_PEEKDATA'. –

ответ

0

Аргументы, переданные в open (и любой другой случай, когда системный вызов получает строку), являются указателями на расположение строки в памяти.

К сожалению, для вас эти указатели предназначены для адресного пространства debugee и не могут быть напрямую связаны с адресным пространством отладчика.

В документации ptrace вы повторно вызываете ptrace(PTRACE_PEEKDATA...), чтобы получить строку, 4 (или 8, в зависимости от платформы) байтов за раз. Вы можете увидеть пример того, как это сделать в старом fakeroot-ng code. Обратите внимание, что этот код находится под GPL, поэтому не копируйте дословно, если вы не пишете код совместимой лицензии.

К счастью, есть способ получить данные, которые являются более простыми и быстрее. Он менее портативен, но если вы пишете код ptrace, вам обычно все равно.

Начертательная нить может открыть файл /proc/pid/mem (где pid - это, конечно, численный pid дебюта). Обратите внимание, что только файл ptracer pid может открыть этот файл.

После того, как этот файл открыт, вы можете pread (2) от него на смещение адреса, который вы хотите, и получить данные непосредственно из адресного пространства debugee. Поскольку интерфейс read не ограничивается четырьмя байтами, вы можете угадать длину строки, прочитать, что много байтов в, а затем найти завершающий NULL и знать точную строку.

Поскольку вы вызываете меньше системных вызовов, этот метод не только упрощен, но и намного быстрее.