Dark Eagle
Dark Eagle

Reputation: 107

Can not find return address in gdb

I wrote that program in C (just for debugging purposes):

void return_input(void)
{
    char array[10];

    gets(array);
    printf("%s\n", array);
}

main()
{
    return_input();

    return 0;

}

I have been experimenting with stack overflows, and since I am working with a 64 bit machine I compiled it with

gcc -m32 -mpreferred-stack-boundary=2 -ggdb overflow.c -o overflow

I then debugged the program with gdb, and disassembled the return_input function, I got:

   0x0804841b <+0>: push   %ebp
   0x0804841c <+1>: mov    %esp,%ebp
   0x0804841e <+3>: sub    $0xc,%esp
   0x08048421 <+6>: lea    -0xa(%ebp),%eax
   0x08048424 <+9>: push   %eax
   0x08048425 <+10>:    call   0x80482e0 <gets@plt>
   0x0804842a <+15>:    add    $0x4,%esp
   0x0804842d <+18>:    lea    -0xa(%ebp),%eax
   0x08048430 <+21>:    push   %eax
   0x08048431 <+22>:    call   0x80482f0 <puts@plt>
   0x08048436 <+27>:    add    $0x4,%esp
   0x08048439 <+30>:    nop
   0x0804843a <+31>:    leave  
   0x0804843b <+32>:    ret

This marks that the return address should be 0x0804843b (or is it not?) However, when examining the esp (remember this is a 32bit compiled program on a 64bit machine) with x/20x $esp (after setting a breakpoint at the gets function and the ret), I can't find the return address:

    0xffffd400: 0xffffd406  0x080481ec  0x08048459  0x00000000
    0xffffd410: 0xffffd418  0x08048444  0x00000000  0xf7e195f7
    0xffffd420: 0x00000001  0xffffd4b4  0xffffd4bc  0x00000000
    0xffffd430: 0x00000000  0x00000000  0xf7fb0000  0xf7ffdc04
    0xffffd440: 0xf7ffd000  0x00000000  0xf7fb0000  0xf7fb0000

Why can't I see the return address? Sorry for the long question. Thanks in advance

Upvotes: 0

Views: 6676

Answers (1)

user4822941
user4822941

Reputation:

0x0804843b is 'ret'. It seems you confused that with 'return address'. The return address is the address of the next instruction to execute in the calling function. In particular for this code:

   0x08048425 <+10>:    call   0x80482e0 <gets@plt>
   0x0804842a <+15>:    add    $0x4,%esp

The return address is 0x0804842a.

Now, it is unclear what exactly did you do. Compiling as you specified, doing 'break gets' + 'run' works just fine for me. Are you sure you are dumping regs from "within" gets?

(gdb) disassemble return_input
Dump of assembler code for function return_input:
   0x0804843b <+0>: push   %ebp
   0x0804843c <+1>: mov    %esp,%ebp
   0x0804843e <+3>: sub    $0xc,%esp
   0x08048441 <+6>: lea    -0xa(%ebp),%eax
   0x08048444 <+9>: push   %eax
   0x08048445 <+10>:    call   0x8048300 <gets@plt>
   0x0804844a <+15>:    add    $0x4,%esp

That's the instruction gets should return to.

   0x0804844d <+18>:    lea    -0xa(%ebp),%eax
   0x08048450 <+21>:    push   %eax
   0x08048451 <+22>:    call   0x8048310 <puts@plt>
   0x08048456 <+27>:    add    $0x4,%esp
   0x08048459 <+30>:    nop
   0x0804845a <+31>:    leave  
   0x0804845b <+32>:    ret    
End of assembler dump.

(gdb) break gets
Breakpoint 1 at 0x8048300
(gdb) run
[..]
Breakpoint 1, 0xf7e3a005 in gets () from /lib/libc.so.6
(gdb) x/20x $esp
0xffffd160: 0x00000001  0xf7fa3000  0xffffd180  0x0804844a

And here it is on the 4th spot.

0xffffd170: 0xffffd176  0x0804820c  0x08048479  0x00000000
0xffffd180: 0xffffd188  0x08048464  0x00000000  0xf7df15a6
0xffffd190: 0x00000001  0xffffd224  0xffffd22c  0x00000000
0xffffd1a0: 0x00000000  0x00000000  0xf7fa3000  0xf7ffdbe4
(gdb) 

Upvotes: 2

Related Questions