免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3007 | 回复: 4

请问关于ptrace调用的一个问题 [复制链接]

论坛徽章:
0
发表于 2010-05-07 21:51 |显示全部楼层
学习《玩转ptrace》这篇教程中一段代码的疑惑,最下面附上代码,谢谢各位高手指点

我理解trace的基本流程是

1,子进程 ptrace(PTRACE_TRACEME, 0, NULL, NULL); 表示接受trace
2,循环处理, 父进程 wait(&status); 表示 当子进程有事件(系统调用)的时候暂停他,拿到控制权
3, orig_eax=ptrace(PTRACE_PEEKUSER,。。) 表示窥探子进程系统调用数据
4,  在这个循环中可以通过orig_eax得知系统调用号码, 并作自己需要的处理
5, ptrace(PTRACE_SYSCALL, child, NULL, NULL);

    就是这个我不明白,如果说这个是表示需要让子进程停在系统调用上,那么wait(&status)不是已经让子进程停在系统调用了么
                     如果说这个是表示继续,那么我把它换成 ptrace(PTRACE_CONT,)程序不工作。。。

请问高手这个到底怎么个意思呢?

            




int main()
  {
    pid_t child;
    child = fork();
     if(child == 0) {
       ptrace(PTRACE_TRACEME, 0, NULL, NULL);
       execl("/bin/ls", "ls", NULL);
    }
     else {
       long orig_eax;
       long params[3];
       int status;
       char *str, *laddr;
       int toggle = 0;
        while(1) {
          wait(&status);
          if(WIFEXITED(status))
              break;
          orig_eax = ptrace(PTRACE_PEEKUSER,
                            child, 4 * ORIG_EAX,
                            NULL);
           if(orig_eax == SYS_write) {
              if(toggle == 0) {
                toggle = 1;
                params[0] = ptrace(PTRACE_PEEKUSER,
                                   child, 4 * EBX,
                                   NULL);
                params[1] = ptrace(PTRACE_PEEKUSER,
                                   child, 4 * ECX,
                                   NULL);
                params[2] = ptrace(PTRACE_PEEKUSER,
                                   child, 4 * EDX,
                                   NULL);
                str = (char *)calloc((params[2]+1)
                                  * sizeof(char));
                getdata(child, params[1], str,
                        params[2]);
                reverse(str);
                putdata(child, params[1], str,
                        params[2]);
             }
              else {
                toggle = 0;
             }
          }
       ptrace(PTRACE_SYSCALL, child, NULL, NULL);
       }
    }
    return 0;
}

论坛徽章:
0
发表于 2010-05-07 22:48 |显示全部楼层
看帮助,
PTRACE_SYSCALL, PTRACE_SINGLESTEP
Restarts the stopped child as for PTRACE_CONT, but arranges for the child to be stopped at the next entry to or exit from a system call, or after execution of a single instruction, respectively. (The child will also, as usual, be stopped upon receipt of a signal.) From the parent's perspective, the child will appear to have been stopped by receipt of a SIGTRAP. So, for PTRACE_SYSCALL, for example, the idea is to inspect the arguments to the system call at the first stop, then do another PTRACE_SYSCALL and inspect the return value of the system call at the second stop. (addr is ignored.)
PTRACE_SYSCALL和PTRACE_CONT的处理很相似,子进程继续执行,区别在于PTRACE_SYSCALL设置了进程标志PF_TRACESYS。这样可以使进程在下一次系统调用开始或结束时中止运行。

论坛徽章:
0
发表于 2010-05-07 22:56 |显示全部楼层
还是看原文好些  

原文

论坛徽章:
0
发表于 2010-05-08 08:56 |显示全部楼层
看帮助,
PTRACE_SYSCALL, PTRACE_SINGLESTEP
Restarts the stopped child as for PTRACE_CONT, but arra ...
xiexiecn 发表于 2010-05-07 22:48



多谢,基本明白了,但是还是有个问题,就是这个程序第一次停止在系统调用之前并没有调用ptrace(PTRACE_SYSCALL)啊,ptrace(PTRACE_SYSCALL)是在第一轮处理之后才调用的,那么第一次是怎么停止的呢?

论坛徽章:
0
发表于 2010-05-08 11:08 |显示全部楼层
你说的第一次应该是说子进程第一次的系统调用怎么停止的吧。换个角度考虑问题,如果让你使用上面那些接口,会怎么写这个内核代码呢?要是我子进程调用了PTRACE_TRACEME之后,就表示已经开始让父进程跟踪自己了,这样子进程就停止在第一个系统调用上(我的理解ptrace应该不算第一个,而是execve)。之后父进程的wait被唤醒,然后父进程使用PTRACE_SYSCALL来让子进程继续运行。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP