免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 843 | 回复: 0
打印 上一主题 下一主题

[C++] Playing with ptrace例子freespaceinject.c无法得到期望的结果 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2015-12-23 16:32 |只看该作者 |倒序浏览
本帖最后由 luozhaotian 于 2015-12-23 16:31 编辑

运行Playing with ptrace中的最后一个例子freespaceinject.c,没有得到期望的结果。(让被调试程序dummy2打印字符串“Hello World\n”。)

操作系统是Ubuntn 12.04 32位,是运行在VirtualBox里面的虚拟机。

freespaceinject.c的处理过程如下:
(1)使用ptrace附加到被调试程序
(2)将打印代码注入(注入前先备份)到程序的自由空间
(3)修改EIP,指向打印代码
(4)被调试程序执行打印代码,打印字符串并执行int3指令
(5)freespaceinject恢复数据和寄存器、EIP
(6)被调试程序继续进行。

操作时,先运行被调试程序dummy2,然后启动freespaceinject。
具体的操作过程如下:
【ptrace scope设置】
hx@hx-VirtualBox:~/dev/ptrace$ su
root@hx-VirtualBox:/home/hx/dev/ptrace# echo 0 > /proc/sys/kernel/yama/ptrace_scope
root@hx-VirtualBox:/home/hx/dev/ptrace# exit
exit
hx@hx-VirtualBox:~/dev/ptrace$

【被调试程序dummy2.c】
hx@hx-VirtualBox:~/dev/ptrace/tmp3$ cat dummy2.c

  1. #include <stdio.h>

  2. int main()
  3. {   int i;
  4.     for(i = 0;i < 10; ++i) {
  5.         printf("My counter: %d \n", i);
  6.         sleep(2);
  7.     }
  8.     return 0;
  9. }
复制代码
hx@hx-VirtualBox:~/dev/ptrace/tmp3$ gcc -zexecstack dummy2.c -o dummy2
hx@hx-VirtualBox:~/dev/ptrace/tmp3$ ./dummy2
My counter: 0
My counter: 1
My counter: 2
My counter: 3
My counter: 4
My counter: 5
My counter: 6
My counter: 7
My counter: 8
My counter: 9

hx@hx-VirtualBox:~/dev/ptrace/tmp3$ cat /proc/`pgrep dummy2`/maps
08048000-08049000 r-xp 00000000 08:01 54069      /home/hx/dev/ptrace/tmp3/dummy2
08049000-0804a000 r-xp 00000000 08:01 54069      /home/hx/dev/ptrace/tmp3/dummy2
0804a000-0804b000 rwxp 00001000 08:01 54069      /home/hx/dev/ptrace/tmp3/dummy2
b7e20000-b7e21000 rwxp 00000000 00:00 0
b7e21000-b7fc4000 r-xp 00000000 08:01 130959     /lib/i386-linux-gnu/libc-2.15.so
b7fc4000-b7fc6000 r-xp 001a3000 08:01 130959     /lib/i386-linux-gnu/libc-2.15.so
b7fc6000-b7fc7000 rwxp 001a5000 08:01 130959     /lib/i386-linux-gnu/libc-2.15.so
b7fc7000-b7fca000 rwxp 00000000 00:00 0
b7fda000-b7fdd000 rwxp 00000000 00:00 0
b7fdd000-b7fde000 r-xp 00000000 00:00 0          [vdso]
b7fde000-b7ffe000 r-xp 00000000 08:01 130939     /lib/i386-linux-gnu/ld-2.15.so
b7ffe000-b7fff000 r-xp 0001f000 08:01 130939     /lib/i386-linux-gnu/ld-2.15.so
b7fff000-b8000000 rwxp 00020000 08:01 130939     /lib/i386-linux-gnu/ld-2.15.so
bffdf000-c0000000 rwxp 00000000 00:00 0          [stack]

【freespaceinject】
hx@hx-VirtualBox:~/dev/ptrace/tmp3$ cat freespaceinject.c

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

  9. const int long_size = sizeof(long);

  10. void getdata(pid_t child, long addr, char *str, int len)
  11. {   char *laddr;
  12.     int i, j;
  13.     union u {
  14.             long val;
  15.             char chars[long_size];
  16.     }data;
  17.    
  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. }

  28. void putdata(pid_t child, long addr, char *str, int len)
  29. {   char *laddr;
  30.     int i, j;
  31.     union u {
  32.             long val;
  33.             char chars[long_size];
  34.     }data;
  35.    
  36.     i = 0;
  37.     j = len / long_size;
  38.     laddr = str;
  39.     while(i < j) {
  40.         memcpy(data.chars, laddr, long_size);
  41.         ptrace(PTRACE_POKEDATA, child, addr + i * 4, data.val);
  42.         ++i;
  43.         laddr += long_size;
  44.     }
  45. }

  46. long freespaceaddr(pid_t pid)
  47. {
  48.     FILE *fp;
  49.     char filename[30];
  50.     char line[85];
  51.     long addr;
  52.     char str[20];

  53.     sprintf(filename, "/proc/%d/maps", pid);
  54.     fp = fopen(filename, "r");
  55.     if(fp == NULL)
  56.         exit(1);
  57.     while(fgets(line, 85, fp) != NULL) {
  58.         sscanf(line, "%lx-%*lx %*s %*s %s", &addr, str, str, str, str);
  59.         if(strcmp(str, "00:00") == 0){
  60.             break;
  61.         }
  62.     }
  63.     fclose(fp);
  64.     return addr;
  65. }

  66. int main(int argc, char *argv[])
  67. {   pid_t traced_process;
  68.     struct user_regs_struct oldregs, regs;
  69.     long ins;
  70.     int len = 44;
  71.     char insertcode[] = "\xeb\x15\x5e\xb8\x04\x00\x00\x00\xbb\x02\x00\x00\x00\x89\xf1\xba\x0c\x00\x00\x00\xcd\x80\xcc\xe8\xe6\xff\xff\xff\x48\x65\x6c\x6c\x6f\x20\x57\x6f\x72\x6c\x64\x0a\x00\x00\x00\x00";
  72.     char backup[len];
  73.     long addr;

  74.     if(argc != 2) {
  75.         printf("Usage: %s <pid to be traced>\n", argv[0], argv[1]);
  76.         exit(1);
  77.     }

  78.     traced_process = atoi(argv[1]);

  79.     ptrace(PTRACE_ATTACH, traced_process, NULL, NULL);
  80.     wait(NULL);

  81.     ptrace(PTRACE_GETREGS, traced_process, NULL, &regs);
  82.     addr = freespaceaddr(traced_process);
  83.     getdata(traced_process, addr, backup, len);
  84.     putdata(traced_process, addr, insertcode, len);
  85.     memcpy(&oldregs, &regs, sizeof(regs));
  86.     regs.eip = addr;
  87.     ptrace(PTRACE_SETREGS, traced_process, NULL, &regs);
  88.     ptrace(PTRACE_CONT, traced_process, NULL, NULL);
  89.    
  90.     wait(NULL);
  91.     printf("The process stopped, Putting back the original instructions\n");
  92.     putdata(traced_process, addr, backup, len);
  93.     ptrace(PTRACE_SETREGS, traced_process, NULL, &oldregs);
  94.     printf("Letting it continue with original flow\n");
  95.     ptrace(PTRACE_DETACH, traced_process, NULL, NULL);
  96.    
  97.     return 0;
  98. }
复制代码
hx@hx-VirtualBox:~/dev/ptrace/tmp3$ ./freespaceinject `pgrep dummy2`
free addr: b7e20000
The process stopped, Putting back the original instructions
Letting it continue with original flow

【注入代码hello.c】
freespaceinject.c中的insertcode来自hello.c编译后的结果

hx@hx-VirtualBox:~/dev/ptrace$ cat hello.c

  1. void main()
  2. {
  3. __asm__ (
  4.          "jmp forward\n\t"
  5. "backward:\n\t"
  6.          "popl   %esi          # Get the address of\n\t"
  7.                               "# hello world string\n\t"
  8.          "movl   $4, %eax      # Do write system call\n\t"
  9.          "movl   $2, %ebx\n\t"
  10.          "movl   %esi, %ecx\n\t"
  11.          "movl   $12, %edx\n\t"
  12.          "int    $0x80\n\t"
  13.          "int3                 # Breakpoint. Here the\n\t"
  14.                               "# program will stop and\n\t"
  15.                               "# give control back to\n\t"
  16.                               "# the parent\n\t"
  17. "forward:\n\t"
  18.         "call   backward\n\t"
  19.         ".string \"Hello World\\n\"\n\t"
  20.        );
  21. }
复制代码
hx@hx-VirtualBox:~/dev/ptrace$ gcc hello.c -o hello
hx@hx-VirtualBox:~/dev/ptrace$ gdb ./hello
(gdb) disass /r main
Dump of assembler code for function main:
   0x080483b4 <+0>:        55        push   %ebp
   0x080483b5 <+1>:        89 e5        mov    %esp,%ebp
   0x080483b7 <+3>:        eb 15        jmp    0x80483ce <forward>             //insertcode的开始
   0x080483b9 <+5>:        5e        pop    %esi
   0x080483ba <+6>:        b8 04 00 00 00        mov    $0x4,%eax
   0x080483bf <+11>:        bb 02 00 00 00        mov    $0x2,%ebx
   0x080483c4 <+16>:        89 f1        mov    %esi,%ecx
   0x080483c6 <+18>:        ba 0c 00 00 00        mov    $0xc,%edx
   0x080483cb <+23>:        cd 80        int    $0x80
   0x080483cd <+25>:        cc        int3   
   0x080483ce <+0>:        e8 e6 ff ff ff        call   0x80483b9 <main+5>
   0x080483d3 <+5>:        48        dec    %eax
   0x080483d4 <+6>:        65        gs
   0x080483d5 <+7>:        6c        insb   (%dx),%es%edi)
   0x080483d6 <+8>:        6c        insb   (%dx),%es%edi)
   0x080483d7 <+9>:        6f        outsl  %ds%esi),(%dx)
   0x080483d8 <+10>:        20 57 6f        and    %dl,0x6f(%edi)
   0x080483db <+13>:        72 6c        jb     0x8048449 <__libc_csu_init+89>
   0x080483dd <+15>:        64 0a 00        or     %fs%eax),%al        //insertcode的结束
   0x080483e0 <+18>:        5d        pop    %ebp
   0x080483e1 <+19>:        c3        ret   
End of assembler dump.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP