LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1037|回复: 1

会玩ptrace系统调用的人进来帮帮忙

[复制链接]
发表于 2008-11-13 14:18:48 | 显示全部楼层 |阅读模式
第一个程序是用来被跟踪的,第二个程序用来跟踪第一个程序,但是跟踪完后会导致第一个程序报段错误,不知道是什么原因?


  1. #include <stdio.h>

  2. int main(int argc, char **argv) {
  3.         int i = 0;

  4.         while(1) {
  5.                 printf("%d\n",i);
  6.                 i++;
  7.                 sleep(1);
  8.         }
  9. }
复制代码


  1. #include <sys/ptrace.h>
  2. #include <sys/types.h>
  3. #include <sys/wait.h>
  4. #include <sys/syscall.h>
  5. #include <sys/user.h>
  6. #include <unistd.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <stdio.h>

  10. const long long_size = sizeof(long);

  11. void getdata(pid_t child, long addr, char *str, int len) {
  12.   char *laddr;
  13.   int i,j;

  14.   union u {
  15.     long val;
  16.     char chars[long_size];
  17.   } data;

  18.   i = 0;
  19.   j = len / long_size;

  20.   laddr = str;

  21.   while(i < j) {
  22.     data.val = ptrace(PTRACE_PEEKDATA, child, addr + i * 4, NULL);
  23.     memcpy(laddr, data.chars, long_size);
  24.     ++i;
  25.     laddr += long_size;
  26.   }

  27.   j = len % long_size;
  28.   if(j != 0) {
  29.     data.val = ptrace(PTRACE_PEEKDATA, child, addr + i * 4, NULL);
  30.     memcpy(laddr, data.chars, j);
  31.   }
  32. }

  33. void putdata(pid_t child, long addr, char *str, int len) {
  34.   char *laddr;
  35.   int i,j;

  36.   union u {
  37.     long val;
  38.     char chars[long_size];
  39.   } data;

  40.   i = 0;
  41.   j = len /long_size;
  42.   laddr = str;

  43.   while(i < j) {
  44.     memcpy(data.chars, laddr, long_size);
  45.     ptrace(PTRACE_POKEDATA, child, addr + i * 4, data.val);
  46.     ++i;
  47.     laddr += long_size;
  48.   }

  49.   j = len % long_size;
  50.   if(j != 0) {
  51.     memcpy(data.chars, laddr, j);
  52.     ptrace(PTRACE_POKEDATA, child, addr + i * 4, data.val);
  53.   }
  54. }

  55. int main(int argc, char *argv[]) {
  56.   pid_t traced_pid;
  57.   struct user_regs_struct regs;
  58.   long ins;
  59.   char code[] = {0xcd, 0x80, 0xcc};//trap code,让程序挂断
  60.   char backup[3];

  61.   if(argc != 2) {
  62.     printf("usage:%s <pid to be traced>", argv[0], argv[1]);
  63.     exit(1);
  64.   }

  65.   traced_pid = atoi(argv[1]);
  66.   ptrace(PTRACE_ATTACH, traced_pid, NULL, NULL);
  67.   wait(NULL);
  68.   ptrace(PTRACE_GETREGS, traced_pid, NULL, &regs);

  69.   getdata(traced_pid, regs.eip, backup, 3);
  70.   putdata(traced_pid, regs.eip, code, 3);

  71.   ptrace(PTRACE_CONT, traced_pid, NULL, NULL);
  72.   wait(NULL);
  73.   printf("the process stopped, putting back the original instructions\n");
  74.   printf("press <enter> to continue");
  75.   getchar();

  76.   putdata(traced_pid, regs.eip, backup, 3);
  77.   ptrace(PTRACE_SETREGS, traced_pid, NULL, &regs);

  78.   ptrace(PTRACE_DETACH, traced_pid, NULL, NULL);
  79.   return 0;
  80. }
复制代码
发表于 2008-11-27 17:32:24 | 显示全部楼层
看不出错误,可以用coredump调一下。
上面的code[]是什么,int 0x80?要不要push eax,PTRACE_DETACH应该
先做然后_CONT,以前看到的demo好像是这样写的。

int main(int argc, char *argv[]) {
        pid_t traced_pid;
        struct user_regs_struct regs;
        long ins;
        char code[] = {0xcd, 0x80, 0xcc};//trap code,让程序挂断
        char backup[3];

        if(argc != 2) {
                printf("usage:%s <pid to be traced>", argv[0], argv[1]);
                exit(1);
        }

        traced_pid = atoi(argv[1]);
        if(-1 == ptrace(PTRACE_ATTACH, traced_pid, NULL, NULL) || errno) {
                err out;
        }
        waitpid(pid, NULL, WUNTRACED);
        // ptrace(PTRACE_GETREGS, traced_pid, NULL, &regs);

        getdata(traced_pid, regs.eip, backup, 3);
        putdata(traced_pid, regs.eip, code, 3);

        //ptrace(PTRACE_CONT, traced_pid, NULL, NULL);
        //wait(NULL);
        printf("the process stopped, putting back the original instructions\n");
        printf("press <enter> to continue");
        getchar();

        putdata(traced_pid, regs.eip, backup, 3);
        //ptrace(PTRACE_SETREGS, traced_pid, NULL, &regs);

        ptrace(PTRACE_DETACH, traced_pid, NULL, NULL);
        ptrace(PTRACE_CONT, traced_pid, NULL, NULL);                // do continue after detach
        return 0;
}
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表