0

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

7
  • How long was the string you had gets fetch? Overwriting the return address is exactly how a buffer overflow can be used to run malicious code... Commented Jan 19, 2017 at 13:36
  • @StoryTeller as I have already mentioned in the question. I set a break at gets, and hence didn't still input anything. The problem is I don't see the return address Commented Jan 19, 2017 at 13:38
  • @StoryTeller I never heard about a stack growing downward. Can you elaborate on that point? Commented Jan 19, 2017 at 13:52
  • I'm not sure that's what the return address should be. Try placing a trace-point in the line that calls gets. Have the trace point print eip to know for sure. Commented Jan 19, 2017 at 13:52
  • It is growing downward. As in the stack pointer is holding addresses with lower values whenever a frame is pushed onto the stack. But then looking 20 machine words forward should reveal the stack pointer. I asked without considering your CPU (as indicated by the set of registers). Naturally it grows downwards.. silly question. Commented Jan 19, 2017 at 13:54

1 Answer 1

2

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) 
Sign up to request clarification or add additional context in comments.

2 Comments

I have three questions here: 1) If the return address is not the address of the next instruction to be executed after returning from a function, what is it then? 2) what address shall I overflow to get a segmentation fault? 3) why can't I find the ret address in the x/20x $esp command?
1. what stack state are you dumping in the first place? 2. you need to overwrite the location where the return address is saved, what else. 3. why are you looking for the address of 'ret' and where did you bt. In general, I can only recommend you read the classic on the subject: phrack.org/issues/49/14.html

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.