2012-03-18 100 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