我尝试使用 PTRACE_PEEKDATA 从内存中读取值。要查找我正在使用 objdump 的特定行的内存地址 -
objdump --dwarf=decodedline ./exe_filename
并得到输出:
test: file format elf64-x86-64
Contents of the .debug_line section:
test.c:
File name Line number Starting address View Stmt
test.c 23 0x1369 x
test.c 23 0x1385 x
test.c 28 0x1394 x
test.c 29 0x139d x
test.c 30 0x13c5 x
test.c 35 0x13cf x
test.c 36 0x13da x
test.c 37 0x13e3 x
test.c 38 0x13f2 x
test.c 42 0x13fc x
test.c 44 0x1405 x
test.c 44 0x1423 x
test.c 45 0x1429 x
test.c 46 0x1438 x
test.c 50 0x1442 x
test.c 50 0x144d x
test.c 50 0x1458 x
test.c 51 0x1466 x
test.c 52 0x1475 x
test.c 57 0x147f x
test.c 57 0x149b x
test.c 58 0x14a0 x
test.c 59 0x14af x
test.c 63 0x14b9 x
test.c 64 0x14df x
test.c 73 0x14fa x
test.c 73 0x1505 x
test.c 73 0x1508 x
test.c 73 0x1513 x
test.c 74 0x1528 x
test.c 75 0x1548 x
test.c 76 0x1556 x
test.c 77 0x1581 x
test.c 78 0x15a3 x
test.c 79 0x15ae x
test.c 79 0x15b2 x
test.c 79 0x15bc x
test.c 79 0x15db x
test.c 80 0x15e2 x
test.c 81 0x15ec x
test.c 82 0x15fb x
test.c 84 0x1605 x
test.c 84 0x1609 x
test.c 87 0x1635 x
test.c 87 0x163e x
test.c 88 0x1647 x
test.c 88 0x164e x
test.c 88 0x1652 x
test.c 88 0x165c x
test.c 91 0x167c x
test.c 91 0x169f x
test.c 92 0x16a6 x
test.c 97 0x16cb x
test.c 97 0x16ec x
test.c 98 0x16f2 x
test.c 99 0x1701 x
test.c 103 0x170b x
test.c 104 0x171a x
test.c 104 0x1723 x
test.c 105 0x1728 x
test.c 105 0x1731 x
test.c 108 0x1754 x
test.c 112 0x1763 x
test.c 113 0x1789 x
test.c 120 0x17a4 x
test.c 121 0x17c9 x
test.c 122 0x17d5 x
test.c 125 0x17fb x
test.c 127 0x181c x
test.c 128 0x182b x
test.c 128 0x1834 x
test.c 129 0x1838 x
test.c 132 0x1849 x
test.c 137 0x1858 x
现在,我使用:
unsigned long long int addr = 0x13cf;
unsigned long long int orig_data = ptrace(PTRACE_PEEKTEXT, child_pid, (void *)addr, 0);
if (orig_data == -1) {
perror("ptrace2");
exit(EXIT_FAILURE);
}
并得到错误:ptrace2: Input/output error
我想也许objdump 返回偏移量,所以我搜索基地址以使用公式:
base address + offset = virtual address
我用过轻松检测并发现基地址为0。所以,我不知道为什么它现在起作用了。
我也尝试从中获取内存地址gdb调试器运行时:
Breakpoint 1, main (argc=3, argv=0x7fffffffe038) at /home/vboxuser/Documents/CreateDebugger/test.c:35
35 child_pid = fork();
(gdb) disas main
Dump of assembler code for function main:
0x0000555555555369 <+0>: endbr64
0x000055555555536d <+4>: push %rbp
0x000055555555536e <+5>: mov %rsp,%rbp
0x0000555555555371 <+8>: sub $0x130,%rsp
0x0000555555555378 <+15>: mov %edi,-0x124(%rbp)
0x000055555555537e <+21>: mov %rsi,-0x130(%rbp)
0x0000555555555385 <+28>: mov %fs:0x28,%rax
0x000055555555538e <+37>: mov %rax,-0x8(%rbp)
0x0000555555555392 <+41>: xor %eax,%eax
0x0000555555555394 <+43>: cmpl $0x3,-0x124(%rbp)
0x000055555555539b <+50>: je 0x5555555553cf <main+102>
0x000055555555539d <+52>: mov -0x130(%rbp),%rax
0x00005555555553a4 <+59>: mov (%rax),%rdx
0x00005555555553a7 <+62>: mov 0x2c72(%rip),%rax # 0x555555558020 <stderr@GLIBC_2.2.5>
0x00005555555553ae <+69>: lea 0xc53(%rip),%rcx # 0x555555556008
0x00005555555553b5 <+76>: mov %rcx,%rsi
0x00005555555553b8 <+79>: mov %rax,%rdi
0x00005555555553bb <+82>: mov $0x0,%eax
0x00005555555553c0 <+87>: call 0x5555555551d0 <fprintf@plt>
0x00005555555553c5 <+92>: mov $0x1,%eax
0x00005555555553ca <+97>: jmp 0x55555555583e <main+1237>
=> 0x00005555555553cf <+102>: call 0x555555555270 <fork@plt>
0x00005555555553d4 <+107>: mov %eax,-0x11c(%rbp)
0x00005555555553da <+113>: cmpl $0xffffffff,-0x11c(%rbp)
0x00005555555553e1 <+120>: jne 0x5555555553fc <main+147>
0x00005555555553e3 <+122>: lea 0xc45(%rip),%rax # 0x55555555602f
0x00005555555553ea <+129>: mov %rax,%rdi
0x00005555555553ed <+132>: call 0x555555555230 <perror@plt>
0x00005555555553f2 <+137>: mov $0x1,%eax
0x00005555555553f7 <+142>: jmp 0x55555555583e <main+1237>
0x00005555555553fc <+147>: cmpl $0x0,-0x11c(%rbp)
0x0000555555555403 <+154>: jne 0x55555555547f <main+278>
0x0000555555555405 <+156>: mov $0x0,%ecx
--Type <RET> for more, q to quit, c to continue without paging--
地址 0x00005555555553cf 和 0x7fffffffe038 也不起作用。
在PTRACE_PEEKTEXT中,我需要放置源代码中的行虚拟地址?怎么找到他? ASLR 会影响地址内存还是固定的?或者问题可能出在 child_pid 中?
请帮忙,我在这个问题上花了很多时间。感谢您的帮助!
顺便说一句,我在虚拟机 Ubuntu 22.04 中使用。