为什么这个程序会导致段错误?
Why does this program causes a 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' 个字符(加上空字符)到保存的 ESP
我在 GDB 中验证了这个程序的行为,这是我得到的:
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0xb7e30043 in ?? () from /lib/i386-linux-gnu/libc.so.6
程序试图跳转到 0xb7e30043(溢出值,带有 0x43 和空终止符)而不是原始值 0xb7e31637,在此上下文中,它是 __libc_start_main 的 return 点。
这就是让我感到棘手的地方。做一个 "info proc mappings",我看到 0xb7e30043 似乎是 "valid" 内存(在 /lib/i386-linux-gnu/libc.so.6 内)
我知道段错误可以由我不 "own" 的内存或未映射的段触发。但在这种情况下,因为它在我的应用程序的内存 space 中,并且 libc 映射到它,为什么我会遇到段错误?
我怀疑这是由于某种错位造成的,因为溢出后 EIP 指向 libc 中的随机指令。如果是,我该如何调整它?它背后的约束是什么,谁来执行它?内核,MMU?
问题是 0xb7e30043 处的指令无效。
这是当前指令:
0xb7e30043: add %cl,(%eax)
我查看了 eax 值,它是零。从那里开始,事情变得更容易了。该进程试图访问 0x0 处的内存,但因段错误而失败。
我目前正在撰写有关堆栈溢出的文章,并在下面创建了以下程序(供参考,我使用的是 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' 个字符(加上空字符)到保存的 ESP
我在 GDB 中验证了这个程序的行为,这是我得到的:
(gdb) run
Program received signal SIGSEGV, Segmentation fault.
0xb7e30043 in ?? () from /lib/i386-linux-gnu/libc.so.6
程序试图跳转到 0xb7e30043(溢出值,带有 0x43 和空终止符)而不是原始值 0xb7e31637,在此上下文中,它是 __libc_start_main 的 return 点。
这就是让我感到棘手的地方。做一个 "info proc mappings",我看到 0xb7e30043 似乎是 "valid" 内存(在 /lib/i386-linux-gnu/libc.so.6 内)
我知道段错误可以由我不 "own" 的内存或未映射的段触发。但在这种情况下,因为它在我的应用程序的内存 space 中,并且 libc 映射到它,为什么我会遇到段错误?
我怀疑这是由于某种错位造成的,因为溢出后 EIP 指向 libc 中的随机指令。如果是,我该如何调整它?它背后的约束是什么,谁来执行它?内核,MMU?
问题是 0xb7e30043 处的指令无效。
这是当前指令:
0xb7e30043: add %cl,(%eax)
我查看了 eax 值,它是零。从那里开始,事情变得更容易了。该进程试图访问 0x0 处的内存,但因段错误而失败。