Rustam Issabekov
Rustam Issabekov

Reputation: 3497

EIP value incorrect during buffer overflow

I am working on ubuntu 12.04 and 64 bit machine. I was reading a good book on buffer overflows and while playing with one example found one strange moment.

I have this really simple C code:

 void getInput (void){ 
    char array[8];    
    gets (array); 
    printf("%s\n", array); 

 }   
 main() { 
    getInput();    
    return 0;    
 }

in the file overflow.c

I compile it with 32 bit flag cause all example in the book assumed 32 bit machine, I do it like this

 gcc -fno-stack-protector -g -m32 -o ./overflow ./overflow.c

In the code char array was only 8 bytes but looking at disassembly I found that that array starts 16 bytes away from saved EBP on the stack, so I executed this line:

 printf "aaaaaaaaaaaaaaaaaaaa\x10\x10\x10\x20" | ./overflow

And got:

 aaaaaaaaaaaaaaaaaaaa 
 Segmentation fault (core dumped)

Then I opened core file:

 gdb ./overflow core
 #0  0x20101010 in ?? ()
 (gdb) info registers
 eax            0x19    25
 ecx            0xffffffff  -1
 edx            0xf77118b8  -143583048
 ebx            0xf770fff4  -143589388
 esp            0xffef6370  0xffef6370
 ebp            0x61616161  0x61616161
 esi            0x0 0
 edi            0x0 0
 eip            0x20101010  0x20101010

As you see EIP in fact got new value, which I wanted. BUT when I want to put some useful values like this 0x08048410

 printf "aaaaaaaaaaaaaaaaaaaa\x10\x84\x04\x08" | ./overflow

Program crashes as usual but than something strange happens when I'm trying to observe the value in EIP register:

 #0  0xf765be1f in ?? () from /lib/i386-linux-gnu/libc.so.6
 (gdb) info registers
 eax            0x61616151  1633771857
 ecx            0xf77828c4  -143120188
 edx            0x1 1
 ebx            0xf7780ff4  -143126540
 esp            0xff92dffc  0xff92dffc
 ebp            0x61616161  0x61616161
 esi            0x0 0
 edi            0x0 0
 eip            0xf765be1f  0xf765be1f

Suddenly EIP start to look like this 0xf765be1f, it doesn't look like 0x08048410. In fact I noticed that it's enough to put any hexadecimal value starting from 0 to get this crumbled EIP value. Do you know why this might happen? Is it because I'm on 64 bit machine?

UPD

Well guys in comments asked for more information, here is the disassembly of getInput function:

 (gdb) disas getInput
 Dump of assembler code for function getInput:
    0x08048404 <+0>:    push   %ebp
    0x08048405 <+1>:    mov    %esp,%ebp
    0x08048407 <+3>:    sub    $0x28,%esp
    0x0804840a <+6>:    lea    -0x10(%ebp),%eax
    0x0804840d <+9>:    mov    %eax,(%esp)
    0x08048410 <+12>:   call   0x8048310 <gets@plt>
    0x08048415 <+17>:   lea    -0x10(%ebp),%eax
    0x08048418 <+20>:   mov    %eax,(%esp)
    0x0804841b <+23>:   call   0x8048320 <puts@plt>
    0x08048420 <+28>:   leave  
    0x08048421 <+29>:   ret 

Upvotes: 4

Views: 3476

Answers (3)

ugoren
ugoren

Reputation: 16441

Perhaps code at 0x08048410 was executed, and jumped to the area of 0xf765be1f.

What's in this address? I guess it's a function (libC?), so you can examine its assembly code and see what it would do.

Also note that in the successful run, you managed to overrun EBP, not EIP. EBP contains 0x61616161, which is aaaa, and EIP contains 0x20101010, which is \n\n\n. It seems like the corrupt EBP indirectly got EIP corrupt.
Try to make the overrun 4 bytes longer, and then it should overrun the return address too.

Upvotes: 3

BЈовић
BЈовић

Reputation: 64253

Buffer overflow is invoking undefined behavior, therefore anything can happen. Theorizing what might happen is futile.

Upvotes: 0

m0skit0
m0skit0

Reputation: 25873

This is probably due to the fact that modern OS (Linux does at least, I don't know about Windows) and modern libc have mechanisms that do not allow code found in stack to be executed.

Upvotes: 1

Related Questions