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"。

问题

  1. 为什么我在 5 As 时没有出现分段错误?
  2. 非法指令和段错误有什么区别?
  3. 什么是可视化堆栈的好工具(除了 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.
  1. 在 main 函数执行后(第 3 行)堆栈是 16 字节对齐的。所以你不能只计算保存的 return 地址的确切地址,你可以尝试从 5 个字节到 21 个字节。
  2. 非法指令是指与任何定义的指令都不匹配的字节。每条指令都用机器代码表示(例如:push ebp 是 0x55 等),但例如,0xff 0xff 与 x86 机器中的任何指令都不匹配。但是当任何内存访问无效时就会发生段错误。