1

我编写了一个简单的程序来获取使用 ptrace 的进程指令。你可以在这里找到代码

http://pastebin.com/yHbkc0Je

我在 Ubuntu 64 位下编译并运行它。

我得到的是这样的:

EIP: 7f7e5edf5c75 Instruction executed: 8824848948f0394c
EIP: 7f7e5edf5c78 Instruction executed: 8824848948
EIP: 7f7e5edf5c80 Instruction executed: 84f6000000da840f
EIP: 7f7e5edf5c86 Instruction executed: 2000000b42484f6
...
...
EIP: 400dab Instruction executed: e8c78948ef458d48
EIP: 400daf Instruction executed: fffffe29e8c78948
EIP: 400db2 Instruction executed: 458d48fffffe29e8
EIP: 400be0 Instruction executed: d680020148225ff
...
...
EIP: 7f7e5ee012f0 Instruction executed: 2404894838ec8348
EIP: 7f7e5ee012f4 Instruction executed: 244c894824048948
...
...

当我使用gdb时,我只能看到EIP下的那些指令:400dab......我找不到那些在7f下......所以我猜它是错误的......

(gdb) x/20xg 0x0000000000400dab
0x400dab <main+135>:    0xe8c78948ef458d48  0xee458d48fffffe29
0x400dbb <main+151>:    0xfffffe4de8c78948  0x10c0834880458b48
0x400dcb <main+167>:    0x48ee558d48088b48  0x8948ce8948c0458d

谁能解释我的代码为什么错误以及如何只打印正确的 EIP 和说明?

4

2 回答 2

1

抱歉,我懒得实际测试您的代码,但您的实验对我来说似乎很有趣。

在我的 Debian x86_64 上,我确实cat /proc/self/maps获得了以下结果:

$ cat /proc/self/maps
00400000-0040c000 r-xp 00000000 08:06 786437                             /bin/cat
0060c000-0060d000 rw-p 0000c000 08:06 786437                             /bin/cat
0121a000-0123b000 rw-p 00000000 00:00 0                                  [heap]
7f3fb1886000-7f3fb1aeb000 r--p 00000000 08:06 274045                     /usr/lib/locale/locale-archive
7f3fb1aeb000-7f3fb1c68000 r-xp 00000000 08:06 136221                     /lib/x86_64-linux-gnu/libc-2.13.so
7f3fb1c68000-7f3fb1e68000 ---p 0017d000 08:06 136221                     /lib/x86_64-linux-gnu/libc-2.13.so
7f3fb1e68000-7f3fb1e6c000 r--p 0017d000 08:06 136221                     /lib/x86_64-linux-gnu/libc-2.13.so
7f3fb1e6c000-7f3fb1e6d000 rw-p 00181000 08:06 136221                     /lib/x86_64-linux-gnu/libc-2.13.so
7f3fb1e6d000-7f3fb1e72000 rw-p 00000000 00:00 0
7f3fb1e72000-7f3fb1e91000 r-xp 00000000 08:06 141623                     /lib/x86_64-linux-gnu/ld-2.13.so
7f3fb206c000-7f3fb206f000 rw-p 00000000 00:00 0
7f3fb208f000-7f3fb2091000 rw-p 00000000 00:00 0
7f3fb2091000-7f3fb2092000 r--p 0001f000 08:06 141623                     /lib/x86_64-linux-gnu/ld-2.13.so
7f3fb2092000-7f3fb2093000 rw-p 00020000 08:06 141623                     /lib/x86_64-linux-gnu/ld-2.13.so
7f3fb2093000-7f3fb2094000 rw-p 00000000 00:00 0
7ffff2e77000-7ffff2e98000 rw-p 00000000 00:00 0                          [stack]
7ffff2fff000-7ffff3000000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

所以我想7f...是针对 libc 或 ld-linux.so 的,你的输出是完全有效的。也试试

$ gdb ./a.out -ex start
(gdb) disp/4i $pc
(gdb) nexti
(gdb) (hit enter to repeat nexti ...)
于 2012-03-05T13:34:01.350 回答
0

您获得的以 7f 开头的地址的输出是针对 libc 和其他系统库的。你可以做的是运行以下命令 -

objdump -d -j.text <your program> | less

这将为您提供整个 objdump。从这里您会看到,在您的代码开始或结束之前,会出现很多序言。出于这个原因,您会看到所有这些 7f 指令。

要回答您的第二个问题,如果您只想从代码中获取指令,您可以解析 /proc//maps 文件并获取代码所在的范围。这可以通过检查 x 标志来获得 -

08048000-08049000 **r-xp** 00000000 fd:5f 33931270                           /fs_user/samirba/myPer/test2
08049000-0804a000 rw-p 00000000 fd:5f 33931270                           /fs_user/samirba/myPer/test2
于 2012-03-05T22:50:58.903 回答