every call in asm, causes that instruction pushes return value, so once ret is called, the program knows where to continue. So I would like to examine the address upon which ret is called:
having this:
#include <stdio.h>
int main()
{
printf("a=%d; b=%d; c=%d", 1, 2, 3);
return 0;
}
I use gdb:
(gdb) b printf
+b printf
Breakpoint 1 at 0x1030
(gdb) run
+run
Breakpoint 1, __printf (format=0x555555556004 "a=%d; b=%d; c=%d")
at printf.c:28
28 printf.c: No such file or directory.
(gdb) x/10x $rsp
+x/10x $rsp
0x7fffffffdc28: 0x55555159 0x00005555 0x55555160 0x00005555
0x7fffffffdc38: 0xf7e1c09b 0x00007fff 0x00000000 0x00000000
0x7fffffffdc48: 0xffffdd18 0x00007fff
(gdb) x/i 0x55555159
+x/i 0x55555159
0x55555159: Cannot access memory at address 0x55555159
(gdb)
Here I am trying to read instruction from return address, but somehow cannot access that address. Why, when it should be valid address for ret?
As Eric Postpischil commented, you are only examining half of the return address, which 64-bit on x86_64.
Using your program:
(gdb) b printf
Breakpoint 1 at 0x1030
(gdb) run
Starting program: /tmp/a.out
Breakpoint 1, __printf (format=0x555555556004 "a=%d; b=%d; c=%d") at printf.c:28
28 printf.c: No such file or directory.
(gdb) bt
#0 __printf (format=0x555555556004 "a=%d; b=%d; c=%d") at printf.c:28
#1 0x0000555555555159 in main () at t.c:4
This shows that the return address we expect to find on the stack is 0x0000555555555159. Indeed, that is exactly the address @$rsp:
(gdb) x/gx $rsp
0x7fffffffdbd8: 0x0000555555555159
To see the instruction at that address:
(gdb) x/i 0x0000555555555159
0x555555555159 <main+36>: mov $0x0,%eax
You can also disassemble the whole main to see where you are and where you are going to return:
(gdb) disas main
Dump of assembler code for function main:
0x0000555555555135 <+0>: push %rbp
0x0000555555555136 <+1>: mov %rsp,%rbp
0x0000555555555139 <+4>: mov $0x3,%ecx
0x000055555555513e <+9>: mov $0x2,%edx
0x0000555555555143 <+14>: mov $0x1,%esi
0x0000555555555148 <+19>: lea 0xeb5(%rip),%rdi # 0x555555556004
0x000055555555514f <+26>: mov $0x0,%eax
0x0000555555555154 <+31>: callq 0x555555555030 <printf@plt>
0x0000555555555159 <+36>: mov $0x0,%eax
0x000055555555515e <+41>: pop %rbp
0x000055555555515f <+42>: retq
End of assembler dump.
As you can see, the instruction that printf will return to is indeed at address 0x0000555555555159.
User contributions licensed under CC BY-SA 3.0