Invalid EIP value for buffer overflow

I am working on ubuntu 12.04 and a 64-bit machine. I read a good book about buffer overflows and, playing with one example, I found one strange moment.

I have this very simple C code:

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

in overflow.c file

I will compile it with a 32-bit flag, because the whole example in the book assumes a 32-bit machine, I do it like

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

There were only 8 bytes in the char array, but looking at disassembly, I found that this array starts with 16 bytes from the stored EBP on the stack, so I ran this line:

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

And received:

  aaaaaaaaaaaaaaaaaaaa Segmentation fault (core dumped) 

Then I opened the kernel 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 can see, EIP actually got the new value that I wanted. BUT when I want to add some useful values ​​like 0x08048410

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

The program crashes, as usual, but something strange happens when I try to observe a value in the 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, the EIP starts to look like 0xf765be1f, it does not look like 0x08048410. In fact, I noticed that it is enough to put a hex value starting with 0 to get this corrupted EIP value. Do you know why this could happen? Is it because I'm on a 64-bit machine?

UPD

Well, the guys in the comments asked for more information, here is the breakdown of the 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 
+4
source share
3 answers

Perhaps the code in 0x08048410 was executed and moved to the area 0xf765be1f .

What is in this address? I assume this is a function (libC?), So you can check its assembly code and see what it will do.

Also note that on successful launch, you managed to block EBP, not EIP. EBP contains 0x61616161 , which is equal to aaaa , and EIP contains 0x20101010 , which is \n\n\n . It seems that corrupt EBP indirectly received EIP damage.
Try to make the excess 4 bytes longer, and then it should also exceed the return address.

+3
source

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

+1
source

Buffer overflows cause undefined behavior, so anything can happen. It is useless to theoreticalize what can happen.

0
source

All Articles