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
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:
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