every call
in asm, causes that instruction push
es 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