C堆栈缓冲区溢出

时间:2018-01-17 04:39:03

标签: c stack-overflow 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之前没有任何反应,此时我收到“非法指令”错误。 14导致“分段错误”。

问题

  1. 为什么我在5 As时没有出现分段错误?
  2. 非法指令和分段错误有什么区别?
  3. 可视化堆栈的好工具(gdb除外)是什么?
  4. 我看过Trouble replicating a stack buffer overflow exploit,但我无法理解答案。

    这是我的汇编转储:

    (gdb) disassemble main
    Dump of assembler code for function main:
       0x0804844d <+0>: push   %ebp
       0x0804844e <+1>: mov    %esp,%ebp
       0x08048450 <+3>: and    $0xfffffff0,%esp
       0x08048453 <+6>: sub    $0x20,%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 个答案:

答案 0 :(得分:1)

  1. 在执行主函数之后(第3行),堆栈是16字节对齐的。所以你不能只计算保存的返回地址的确切地址,你可以尝试从5个字节到21个字节。
  2. 非法指令是这样的字节,与任何已定义的指令都不匹配。每个指令都用机器代码表示(例如:push ebp是0x55等),但是例如,0xff 0xff与x86机器中的任何指令都不匹配。但是当任何内存访问无效时都会发生分段错误。