c - 为什么 "stack smashing detected"不是刷完马上出现?

标签 c linux-kernel buffer-overflow stack-smash

我明白“检测到堆栈崩溃”是什么意思。这里已经有很多关于此的问题。但是我没有找到以下问题的答案。拿C代码

int main(int argc, char **args) {
   char puffer[5];
   strcpy(puffer, *++args);
   printf("%s\n",puffer);
   return EXIT_SUCCESS;
}

当我在 Ubuntu 13.10 中使用 gcc 4.8.1 编译时 ./buffer 123456789 引发了预期的错误 stack smashing detected。但为什么 ./buffer 12345678 没有引发错误?我希望每个超过 5 个字符的字符串都应该引发错误。

最佳答案

理论上你是对的,这就是它应该表现的方式。当您的程序使用超过 5 个字节时,这可能会导致未定义的行为。但堆栈指针通常是 aligned to certain boundaries由于各种性能原因。对齐因架构而异。因此,对于大于 5 的每个输入,您都不会看到此问题。

程序的反汇编显示如下。查看 sub $0x20,%rsp 指令,该指令在堆栈上为此函数分配了 16 字节的内存。

(gdb) disassemble main
Dump of assembler code for function main(int, char**):
   0x00000000004008b0 <+0>: push   %rbp
   0x00000000004008b1 <+1>: mov    %rsp,%rbp
=> 0x00000000004008b4 <+4>: sub    $0x20,%rsp
   0x00000000004008b8 <+8>: mov    %edi,-0x14(%rbp)
   0x00000000004008bb <+11>:    mov    %rsi,-0x20(%rbp) 
  0x00000000004008bf <+15>: mov    %fs:0x28,%rax
   0x00000000004008c8 <+24>:    mov    %rax,-0x8(%rbp)
   0x00000000004008cc <+28>:    xor    %eax,%eax
   0x00000000004008ce <+30>:    addq   $0x8,-0x20(%rbp)
   0x00000000004008d3 <+35>:    mov    -0x20(%rbp),%rax
   0x00000000004008d7 <+39>:    mov    (%rax),%rdx
   0x00000000004008da <+42>:    lea    -0x10(%rbp),%rax
   0x00000000004008de <+46>:    mov    %rdx,%rsi
   0x00000000004008e1 <+49>:    mov    %rax,%rdi
   0x00000000004008e4 <+52>:    callq  0x400770 <strcpy@plt>
   0x00000000004008e9 <+57>:    lea    -0x10(%rbp),%rax
   0x00000000004008ed <+61>:    mov    %rax,%rdi
   0x00000000004008f0 <+64>:    callq  0x400710 <puts@plt>
   0x00000000004008f5 <+69>:    mov    $0x0,%eax
   0x00000000004008fa <+74>:    mov    -0x8(%rbp),%rcx
   0x00000000004008fe <+78>:    xor    %fs:0x28,%rcx
   0x0000000000400907 <+87>:    je     0x400918 <main(int, char**)+104>
   0x0000000000400909 <+89>:    jmp    0x400913 <main(int, char**)+99>
   0x000000000040090b <+91>:    mov    %rax,%rdi
   0x000000000040090e <+94>:    callq  0x400790 <_Unwind_Resume@plt>
   0x0000000000400913 <+99>:    callq  0x400760 <__stack_chk_fail@plt>
   0x0000000000400918 <+104>:   leaveq 
   0x0000000000400919 <+105>:   retq   

关于c - 为什么 "stack smashing detected"不是刷完马上出现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22698118/

相关文章:

c - 两个数相加

android - i2c 设备驱动程序 init 未被调用

data-structures - Linux内核中的哈希表

linux-kernel - 如何确定 Linux 内核 'uImage' 的构建/版本?

python - 为什么我的堆栈缓冲区溢出漏洞利用不起作用?

C 缓冲区溢出导致段错误

C & bash 重定向进程通信

c - 从文件读取值并存储到C中的不同结构

c - 位图字体渲染问题

c++ - memcpy改变指针?