2015-10-30 2 views
1

Я работаю над назначением, в котором я должен реализовать strace как функциональность, используя ptrace. До сих пор, я узнал, как извлечь номер системного вызова и возвращаемого значения, как это:Извлечение системного имени и аргументов с использованием ptrace

//In parent process 
struct user_regs_struct regs; 
ptrace(PTRACE_GETREGS, child_pid, 0, &regs); 
//child_pid is the pid of child process executing the required program 
//or system call passed as command line arguments 
syscall_num = regs.orig_rax; 
syscall_retval = regs.rax; 

Но я не смог найти, как извлечь имя системного вызова и аргументы. Может ли кто-нибудь предложить способ?

+1

вы должны пройти код 'strace()', вы получите некоторую идею. Кроме того, показывая вам, что вы попросили здесь, на самом деле нужен очень большой ответ. – Haris

+0

Хорошо, я пишу вам ответ, вкладывая все, что знаю. Надеюсь, это поможет. – Haris

ответ

2

Чтобы получить аргументы системного вызова, вы должны прочитать регистры один за другим. Для этого вам нужно знать, какие регистры будут хранить, какие параметры системного вызова. Несколько месяцев назад я написал одну такую ​​программу сам.

regs.rdi - Сохраняет первый аргумент

regs.rsi - магазины второй аргумент

regs.rdx - магазины третий аргумент

regs.r10 - Сохраняет четвертый аргумент

regs.r8 - Магазины пятый аргумент

regs.r9 - Хранит Sixt h аргумент

Теперь вы должны пройти документацию по каждому системному вызову, чтобы понимать и кодировать их отдельно. Существуют разные способы чтения различных аргументов.


Позволяет принимать read() системный вызов, чтобы продемонстрировать это.

Мы увидим различные аргументы и посмотрим, как получить к ним доступ.

первый аргумент (интермедиат FD)

Поскольку это число будет сохранено непосредственно в реестре regs.rdi.

В моем коде мне нужно было получить файл, на который указывал fd, поэтому я использовал следующий код.

sprintf(fdpath,"/proc/%u/fd/%llu",proc,regs.rdi); 
size = readlink(fdpath, filepath, 256); //this gives the filepath for a particular fd 
filepath[size] = '\0'; 
printf("File-%s-\n", filepath); 

второй аргумент (недействительными * ЬиЕ) PTR для входного буфера

Для чтения этого вам нужно будет использовать POKEDATA запрос (первый аргумент ptrace() для чтения байтов. Поскольку ptrace() читает и возвращает только 8 байт за раз, вам нужно сделать это итеративно, используя переменную long. Должно быть другое char *, указывающее в начале памяти, которое будет использоваться позже, чтобы прочитать строку.

Код, который я использовал, следующий.

char message[1000]; 
char* temp_char2 = message; 
int j = 0; 
long temp_long; 

while(j < (regs.rdx/8)) //regs.rdx stores the size of the input buffer 
{ 
    temp_long = ptrace(PTRACE_PEEKDATA, proc, regs.rsi + (j*8) , NULL); 
    memcpy(temp_char2, &temp_long, 8); 
    temp_char2 += sizeof(long); 
    ++j; 
} 
message[regs.rdx] = '\0'; 
printf("Message-%s-\n\n", message); 

Это все что я могу сказать. Думаю, вы можете прочитать почти все параметры большинства системных вызовов таким образом.

Что касается имени системного вызова. Я сопоставил OS и сделал руководство switch case, чтобы получить имя системного вызова.


Надеюсь, что это поможет. :)

Смежные вопросы