2012-03-18 99 views
0

我有下面的代碼:Ptracing系統調用

void 
attach_to_pid (int pid, char *username, int pts) 
{ 
    int sys_call_nr = 0; 
    struct user_regs_struct regs; 
    ptrace (PTRACE_ATTACH, pid, 0, 0); 
    waitpid (pid, 0, WCONTINUED); 
    ptrace (PTRACE_SETOPTIONS, pid, 0, 
      PTRACE_O_TRACESYSGOOD | PTRACE_O_TRACEEXIT); 
    while (true) 
    { 
     ptrace (PTRACE_SYSCALL, pid, 0, 0); 
     int status; 
     waitpid (pid, &status, WCONTINUED); 
     if (status == (SIGTRAP | PTRACE_EVENT_EXIT << 8)) 
     break; 
     ptrace (PTRACE_GETREGS, pid, 0, &regs); 
#ifdef __i386__ 
     sys_call_nr = regs.eax; 
#elif __x86_64__ 
     sys_call_nr = regs.rax; 
#else 
#error "Unsupported architecture." 
#endif 
     if (sys_call_nr == __NR_write) 
     { 
      printf ("read!"); 
     } 
     ptrace (PTRACE_SYSCALL, pid, 0, 0); 
     waitpid (pid, &status, WCONTINUED); 
ptrace(PTRACE_GETREGS,pid,0,&regs); 
printf("%d = %d\n",sys_call_nr,regs.eax); 
//ptrace(PTRACE_CONT, pid, 0 , 0); 
    } 
    ptrace (PTRACE_DETACH, pid, 0, 0); 
} 

我得到了奇怪的結果,具體如下:

-514 = -38 
-514 = -38 
1 = -38 
0 = -38 
... 

通常情況下,與strace stracing一個sshd會話時,我總是得到電話在寫入shell時讀寫系統調用。但有了這個功能,我沒有獲得(假的我猜)系統調用,只有(如你所見):1,0,等等......

任何人都可以幫助我嗎?謝謝。

+0

我猜,Linux Kernel在退出時陷入了sys調用,而不是在輸入和退出時。 – user1189104 2012-03-19 09:55:00

+0

你期望在eax/rax寄存器中看到什麼?你在找功能名稱嗎? – 2012-03-19 15:52:21

回答

1

即使我在同一個問題上掙扎。而你的問題是一個確切的重複this 答案有更精美的解釋。這是我的版本:
您的程序需要區分系統調用入口和系統調用出口。
爲此維護一個變量。看看這個code。這裏的變量in_syscall也是一樣的。
希望這可以幫助你。
下次在發佈問題前,進行基礎研究(重新搜索)。節省您的時間了很多TOO)N也是我們的:d

+0

@ user1189104:小心檢查您發佈的問題的答案? :P – 2012-03-22 03:41:15

+0

非常感謝您的回答,我以不同的方式解決了我的問題,我會在完成另一個不按我希望的方式工作的問題時發佈解決的代碼。非常感謝。 P.D:下次我將在該論壇上進行搜索,不用擔心。謝謝! – user1189104 2012-03-26 21:42:03

+0

你看,它已經很久以前通過了,因爲我問了這個。最後,我可以解決這個問題,但是做一些古怪的技巧。由於在ptrace手冊中不支持所有命名的選項,所以沒有一個簡單的方法來做到這一點。我不記得我必須做什麼,但肯定不是一個正常的 - 手工編寫的程序。而且沒有辦法知道是否捕獲了一個syscall_entry或一個syscall_exit,所以......但是萬分感謝。現在Ptrace仍然不是很強大。 – user1189104 2012-09-01 22:01:07

1

這裏是我的解決方案:

struct user_regs_struct regs /*_on_entry, regs_on_exit*/ ; 
    ptrace (PTRACE_ATTACH, pid, 0, 0); 
    waitpid (pid, 0, WCONTINUED); 
    while (true) 
    { 
     ptrace (PTRACE_SYSCALL, pid, 0, 0); 
     int status; 
     wait (&status); 
#ifdef __i386__ 
     int eax = ptrace (PTRACE_PEEKUSER, pid, ORIG_EAX * 4, 0); 
     ptrace (PTRACE_GETREGS, pid, 0, &regs); 
     ptrace (PTRACE_SYSCALL, pid, 0, 0); 
     waitpid (pid, &status, WCONTINUED); 
     if (eax == __NR_read && regs.ebx == 10) 
     { 
      int *buffer = (int *) malloc (regs.eax + 3); 
      int i = 0; 
      for (int j = 0; i < regs.eax; i += 4, j++) 
      { 
       buffer[j] = ptrace (PTRACE_PEEKTEXT, pid, regs.ecx + i, 0); 
      } 
      if (regs.edx % 4)  // rest of chunk. 
      { 
       buffer[i] = 
       ptrace (PTRACE_PEEKUSER, pid, regs.ecx + 2 * i - regs.eax, 0); 
      } 
      write (1, buffer, regs.eax); 
      free (buffer); 
     } 
#elif __x86_64__ 
#else 
#error "Unsupported architecture." 
#endif 
    } 

感謝您的答覆!

+0

我很想看看你的代碼是幹什麼的。而且你的解決方法也是不同的。如果你不介意你能與我們分享代碼嗎?你可以粘貼你的代碼[這裏](http://pastie.org/) – 2012-03-28 03:49:46

+0

看看:http://pastie.org/3690528;) – user1189104 2012-03-29 08:51:36

+0

這是一個sshd監視器。而且它還沒有完成,因爲我試圖爲這個目標打補丁。感謝您的關注。希望這可以幫助。 – user1189104 2012-03-29 09:12:01