为什么这个程序会导致segfault



我目前正在写关于堆栈溢出的文章,并创建了以下程序(作为参考,我使用的是32位linux机器):

#include <stdio.h>
#include <string.h>
int main () {
char foo[16];
strcpy(foo, "AAAAAAAAAAAAAAAABBBBC");
}

这个程序是用编译的

gcc stack_buffer_2.c -g -o stack_buffer_2 -fno-stack-protector

这个程序的作用是:

  • 用"A"字符填充所有"foo"数组
  • 用"B"字符填充保存的EBP
  • 将"C"字符(加上null字符)写入已保存的ESP

我在GDB中验证了这个程序的行为,下面是我得到的:

(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0xb7e30043 in ?? () from /lib/i386-linux-gnu/libc.so.6

在这种情况下,程序试图跳转到0xb7e30043(溢出值,带有0x43和null终止符),而不是原始值0xb7e31637,它是__libc_start_main的返回点。

对我来说,这就是事情变得棘手的地方。在进行"info-proc映射"时,我发现0xb7e30043似乎就像"有效"内存(在/lib/i386-linux-gnu/libc.so.6中)

我知道segfault可能是由我不"拥有"的内存或未映射的段触发的。但在这种情况下,既然它在我的应用程序的内存空间中,并且libc被映射到它,为什么我会得到一个segfault?

我怀疑这是由于某种错位造成的,因为在溢出后EIP指向libc内的随机指令。如果是,我该如何调整?它背后的制约因素是什么?谁来执行它?内核,MMU?

问题是0xb7e30043处的指令无效。

这是当前的指令:

0xb7e30043: add    %cl,(%eax)

我查了一下eax值,结果是零。从那里开始,事情变得更容易了。进程尝试访问0x0处的内存,但由于segfault而失败。

相关内容

  • 没有找到相关文章