w00d
w00d

Reputation: 5596

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 ?

Upvotes: 2

Views: 1672

Answers (2)

Samir Baid
Samir Baid

Reputation: 1178

The output which you are getting for addresses starting with 7f are for libc and other system libraries. What you can do is run the following command -

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

This will give you the entire objdump. From here you'll see that before your code starts or ends a lot of prologue comes into picture. For this reason you are seeing all those 7f instructions.

To answer your second question, in case you want to get only instructions from your piece of code, either you can parse the /proc//maps file and get the range where your code lies. This can be obtained by checking the x flag -

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

Upvotes: 0

nodakai
nodakai

Reputation: 8011

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

Upvotes: 1

Related Questions