Why cannot gdb access memory of ret instruction?

0

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?

c
debugging
gdb
asked on Stack Overflow Jun 10, 2020 by autistic456

1 Answer

0

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.

answered on Stack Overflow Jun 11, 2020 by Employed Russian

User contributions licensed under CC BY-SA 3.0