C 堆栈缓冲区溢出
C Stack Buffer Overflow
我正在尝试复制堆栈缓冲区溢出。这是我的代码
#include <stdio.h>
int main(int argc, char *argv[]) {
char x[1];
gets(x);
printf("%s\n", x);
}
我是在 32 位机器上编译的,这意味着每个内存地址都是 4 个字节长。由于每个字符都是 1 个字节(使用 sizeof 验证),所以当我输入 "AAAAA" 作为输入(比 x 可以容纳的多 1 个字节)时,我预计会发生堆栈缓冲区溢出。但是,在我输入 13 As 之前没有任何反应,此时我收到 "Illegal Instruction" 错误。 14 结果为 "Segmentation fault"。
问题
- 为什么我在 5 As 时没有出现分段错误?
- 非法指令和段错误有什么区别?
- 什么是可视化堆栈的好工具(除了 gdb)?
我看过 ,但我无法理解答案。
这是我的程序集转储:
(gdb) disassemble main
Dump of assembler code for function main:
0x0804844d <+0>: push %ebp
0x0804844e <+1>: mov %esp,%ebp
0x08048450 <+3>: and [=11=]xfffffff0,%esp
0x08048453 <+6>: sub [=11=]x20,%esp
0x08048456 <+9>: lea 0x1f(%esp),%eax
0x0804845a <+13>: mov %eax,(%esp)
0x0804845d <+16>: call 0x8048310 <gets@plt>
=> 0x08048462 <+21>: lea 0x1f(%esp),%eax
0x08048466 <+25>: mov %eax,(%esp)
0x08048469 <+28>: call 0x8048320 <puts@plt>
0x0804846e <+33>: leave
0x0804846f <+34>: ret
End of assembler dump.
- 在 main 函数执行后(第 3 行)堆栈是 16 字节对齐的。所以你不能只计算保存的 return 地址的确切地址,你可以尝试从 5 个字节到 21 个字节。
- 非法指令是指与任何定义的指令都不匹配的字节。每条指令都用机器代码表示(例如:push ebp 是 0x55 等),但例如,0xff 0xff 与 x86 机器中的任何指令都不匹配。但是当任何内存访问无效时就会发生段错误。
我正在尝试复制堆栈缓冲区溢出。这是我的代码
#include <stdio.h>
int main(int argc, char *argv[]) {
char x[1];
gets(x);
printf("%s\n", x);
}
我是在 32 位机器上编译的,这意味着每个内存地址都是 4 个字节长。由于每个字符都是 1 个字节(使用 sizeof 验证),所以当我输入 "AAAAA" 作为输入(比 x 可以容纳的多 1 个字节)时,我预计会发生堆栈缓冲区溢出。但是,在我输入 13 As 之前没有任何反应,此时我收到 "Illegal Instruction" 错误。 14 结果为 "Segmentation fault"。
问题
- 为什么我在 5 As 时没有出现分段错误?
- 非法指令和段错误有什么区别?
- 什么是可视化堆栈的好工具(除了 gdb)?
我看过
这是我的程序集转储:
(gdb) disassemble main
Dump of assembler code for function main:
0x0804844d <+0>: push %ebp
0x0804844e <+1>: mov %esp,%ebp
0x08048450 <+3>: and [=11=]xfffffff0,%esp
0x08048453 <+6>: sub [=11=]x20,%esp
0x08048456 <+9>: lea 0x1f(%esp),%eax
0x0804845a <+13>: mov %eax,(%esp)
0x0804845d <+16>: call 0x8048310 <gets@plt>
=> 0x08048462 <+21>: lea 0x1f(%esp),%eax
0x08048466 <+25>: mov %eax,(%esp)
0x08048469 <+28>: call 0x8048320 <puts@plt>
0x0804846e <+33>: leave
0x0804846f <+34>: ret
End of assembler dump.
- 在 main 函数执行后(第 3 行)堆栈是 16 字节对齐的。所以你不能只计算保存的 return 地址的确切地址,你可以尝试从 5 个字节到 21 个字节。
- 非法指令是指与任何定义的指令都不匹配的字节。每条指令都用机器代码表示(例如:push ebp 是 0x55 等),但例如,0xff 0xff 与 x86 机器中的任何指令都不匹配。但是当任何内存访问无效时就会发生段错误。