Search code examples
clinuxubuntu64-bitptrace

Use ptrace to obtain machine instructions


I wrote a simple program to get instructions of a process using ptrace. You can find the code here

http://pastebin.com/yHbkc0Je

I compiled and ran it in under Ubuntu 64bit.

What I got is something like this:

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
...
...

When I used gdb, I only can see those instruction under EIP: 400dab... I can't find those under 7f... so I guess It was wrong...

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

Can anyone explain why my code is wrong and how to print only the correct EIP and instructions ?


Solution

  • Sorry I'm too lazy to actually test your code, but your experiment seemed very interesting to me.

    On my Debian x86_64, I did cat /proc/self/maps to obtain the following result:

    $ 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]
    

    So I suppose 7f... are for libc or ld-linux.so and your output is completely valid. Also try

    $ gdb ./a.out -ex start
    (gdb) disp/4i $pc
    (gdb) nexti
    (gdb) (hit enter to repeat nexti ...)