使用ptrace示例freespaceinject.c无法正常工作
操作系统是Ubuntu 12.04
我正在阅读" Playing with ptrace"。除了最后一个示例freespaceinject.c。
之外,该文章中的所有示例都成功freespaceinject.c的过程如下:
将ptrace与PTRACE_ATTACH
一起使用以附加dummy2。
使用ptrace和PTRACE_PEEKDATA
将指令(包括int3)注入dummy2的可用空间。
Mofify EIP指向注入的说明。
dummy2执行注入的指令以打印" Hello World \ n"。
freespaceinject恢复数据和寄存器。
dummy2继续执行。
Freespaceinject确实附加到dummy2.But注入的指令不起作用(" Hello World \ n"没有打印),为什么? 也许很多年过去了,很多事情都发生了变化。我找到了很多网站,但帮助不大。
我在https://nnc3.com/mags/LJ_1994-2014/LJ/108/6527.html找到了一篇文章。 它说如下:
小心ptrace 在“玩ptrace,第二部分”[LJ,2002年12月]中,Pradeep Padala谈到注入代码 进入一个过程并找到一些“自由空间”来投入。值得注意的是这个空间 提到的并不是真正的“自由”;它通常是用于全局存储的已清除空间 在可执行文件及其共享库或C库的堆存储区域中。 在任何情况下,写入这些数据,而不是在允许执行继续之前恢复它 (一开始似乎合理)可能会导致各种奇怪的行为,包括程序崩溃。
我不知道这是什么原因。
我的操作细节如下:
[ptrace范围设置]
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]
#include <stdio.h>
int main()
{ int i;
for(i = 0;i < 10; ++i) {
printf("My counter: %d \n", i);
sleep(2);
}
return 0;
}
hx@hx-VirtualBox:~/dev/ptrace/tmp3$ gcc -zexecstack dummy2.c -o dummy2
hx@hx-VirtualBox:~/dev/ptrace/tmp3$ ./dummy2
我的柜台:0
我的柜台:1
我的柜台:2
我的柜台:3
我的柜台:4
我的柜台:5
我的柜台:6
我的柜台:7
我的柜台:8
我的柜台: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
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
const int long_size = sizeof(long);
void getdata(pid_t child, long addr, char *str, int len)
{ char *laddr;
int i, j;
union u {
long val;
char chars[long_size];
}data;
i = 0;
j = len / long_size;
laddr = str;
while(i < j) {
data.val = ptrace(PTRACE_PEEKDATA, child, addr + i * 4, NULL);
memcpy(laddr, data.chars, long_size);
++i;
laddr += long_size;
}
}
void putdata(pid_t child, long addr, char *str, int len)
{ char *laddr;
int i, j;
union u {
long val;
char chars[long_size];
}data;
i = 0;
j = len / long_size;
laddr = str;
while(i < j) {
memcpy(data.chars, laddr, long_size);
ptrace(PTRACE_POKEDATA, child, addr + i * 4, data.val);
++i;
laddr += long_size;
}
}
long freespaceaddr(pid_t pid)
{
FILE *fp;
char filename[30];
char line[85];
long addr;
char str[20];
sprintf(filename, "/proc/%d/maps", pid);
fp = fopen(filename, "r");
if(fp == NULL)
exit(1);
while(fgets(line, 85, fp) != NULL) {
sscanf(line, "%lx-%*lx %*s %*s %s", &addr, str, str, str, str);
if(strcmp(str, "00:00") == 0){
break;
}
}
fclose(fp);
return addr;
}
int main(int argc, char *argv[])
{ pid_t traced_process;
struct user_regs_struct oldregs, regs;
long ins;
int len = 44;
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";
char backup[len];
long addr;
if(argc != 2) {
printf("Usage: %s <pid to be traced>\n", argv[0], argv[1]);
exit(1);
}
traced_process = atoi(argv[1]);
ptrace(PTRACE_ATTACH, traced_process, NULL, NULL);
wait(NULL);
ptrace(PTRACE_GETREGS, traced_process, NULL, ®s);
addr = freespaceaddr(traced_process);
getdata(traced_process, addr, backup, len);
putdata(traced_process, addr, insertcode, len);
memcpy(&oldregs, ®s, sizeof(regs));
regs.eip = addr;
ptrace(PTRACE_SETREGS, traced_process, NULL, ®s);
ptrace(PTRACE_CONT, traced_process, NULL, NULL);
wait(NULL);
printf("The process stopped, Putting back the original instructions\n");
putdata(traced_process, addr, backup, len);
ptrace(PTRACE_SETREGS, traced_process, NULL, &oldregs);
printf("Letting it continue with original flow\n");
ptrace(PTRACE_DETACH, traced_process, NULL, NULL);
return 0;
}
hx @hx-VirtualBox:〜/ dev / ptrace / tmp3 $ ./freespaceinject pgrep dummy2
免费地址:b7e20000
该过程停止,放回原始说明
让它继续原始流程
[注入的代码来自hello.c]
hx @hx-VirtualBox:〜/ dev / ptrace $ cat hello.c
void main()
{
__asm__ (
"jmp forward\n\t"
"backward:\n\t"
"popl %esi # Get the address of\n\t"
"# hello world string\n\t"
"movl $4, %eax # Do write system call\n\t"
"movl $2, %ebx\n\t"
"movl %esi, %ecx\n\t"
"movl $12, %edx\n\t"
"int $0x80\n\t"
"int3 # Breakpoint. Here the\n\t"
"# program will stop and\n\t"
"# give control back to\n\t"
"# the parent\n\t"
"forward:\n\t"
"call backward\n\t"
".string \"Hello World\\n\"\n\t"
);
}
hx @hx-VirtualBox:〜/ dev / ptrace $ gcc hello.c -o hello
hx @hx-VirtualBox:〜/ dev / ptrace $ gdb ./hello
(gdb)disass / r main
转储函数main的汇编代码:
0x080483b4&lt; + 0&gt;:55 push%ebp
0x080483b5&lt; + 1&gt;:89 e5 mov%esp,%ebp
0x080483b7&lt; + 3&gt;:eb 15 jmp 0x80483ce //插入代码的开头
0x080483b9&lt; + 5&gt;:5e pop%esi
0x080483ba&lt; + 6&gt;:b8 04 00 00 00 mov $ 0x4,%eax
0x080483bf&lt; + 11&gt;:bb 02 00 00 00 mov $ 0x2,%ebx
0x080483c4&lt; + 16&gt;:89 f1 mov%esi,%ecx
0x080483c6&lt; + 18&gt;:ba 0c 00 00 00 mov $ 0xc,%edx
0x080483cb&lt; + 23&gt;:cd 80 int $ 0x80
0x080483cd&lt; + 25&gt;:cc int3
0x080483ce&lt; + 0&gt;:e8 e6 ff ff ff ff call 0x80483b9
0x080483d3&lt; + 5&gt ;:48 dec%eax
0x080483d4&lt; + 6&gt;:65 gs
0x080483d5&lt; + 7&gt;:6c insb(%dx),%es:(%edi)
0x080483d6&lt; + 8&gt;:6c insb(%dx),%es:(%edi)
0x080483d7&lt; + 9&gt;:6f outsl%ds:(%esi),(%dx)
0x080483d8&lt; + 10&gt;:20 57 6f和%dl,0x6f(%edi)
0x080483db&lt; + 13&gt;:72 6c jb 0x8048449&lt; __ libc_csu_init + 89&gt;
0x080483dd&lt; + 15&gt;:64 0a 00或%fs:(%eax),%al //插入代码的结尾
0x080483e0&lt; + 18&gt;:5d pop%ebp
0x080483e1&lt; + 19&gt;:c3 ret
汇编程序转储结束。