【发布时间】:2013-02-28 14:54:20
【问题描述】:
我正在尝试控制堆栈溢出。首先,这是我在 x32 VM 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);
}
然后是调试器(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 函数位于地址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 个字节?我的错在哪里?
【问题讨论】:
标签: c assembly gdb reverse-engineering