簡體   English   中英

為什么粉碎后不會立即出現“堆棧粉碎檢測”?

[英]Why does “stack smashing detected” not appear immediately after smashing?

我理解“堆棧粉碎檢測”是什么意思。 關於這一點,這里已經有很多問題了。 但我沒有找到以下問題的答案。 拿C代碼

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

當我在Ubuntu 13.10 ./buffer 123456789 gcc 4.8.1編譯時./buffer 123456789引發了stack smashing detected的預期錯誤stack smashing detected 但為什么./buffer 12345678沒有引發錯誤? 我希望每個超過5個字符的字符串都會引發錯誤。

理論上你是對的,這就是它應該如何表現。 程序使用超過5個字節的那一刻,這可能會導致未定義的行為。 但是由於各種性能原因,堆棧指針通常與某些邊界對齊 對齊因架構而異。 因此,對於大於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   

編譯器實現了不同的堆棧粉碎保護,但通常是為了防止堆棧溢出利用,在保存的幀指針和返回地址之前放置金絲雀。 金絲雀在這里是為了保護覆蓋保存的幀指針和返回地址。 這里基本上在編譯器在緩沖區的末尾和幀指針/返回地址之間插入了一些填充。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM