2012-06-17 274 views
6

我正在玩一個堆棧溢出的例子。此示例如下所示:Dillema與緩衝區溢出

void return_input (void){ 
    char array[30];  
    gets (array); 
    printf("%s\n", array); 

} 

main() { 
    return_input();  
    return 0;  
} 

所有此代碼位於名爲overflow.c的文件中。我們有脆弱的函數叫做return_input,特別是它是30字節的char數組。我編譯它,並在GDB打開漏洞的功能,得到了以下的輸出:

(gdb) disas return_input 
0x08048464 <+0>: push %ebp 
0x08048465 <+1>: mov %esp,%ebp 
0x08048467 <+3>: sub $0x48,%esp 
0x0804846a <+6>: mov %gs:0x14,%eax 
0x08048470 <+12>: mov %eax,-0xc(%ebp) 
0x08048473 <+15>: xor %eax,%eax 
0x08048475 <+17>: lea -0x2a(%ebp),%eax 
0x08048478 <+20>: mov %eax,(%esp) 
0x0804847b <+23>: call 0x8048360 <[email protected]> 
0x08048480 <+28>: lea -0x2a(%ebp),%eax 
0x08048483 <+31>: mov %eax,(%esp) 
0x08048486 <+34>: call 0x8048380 <[email protected]> 
0x0804848b <+39>: mov -0xc(%ebp),%eax 
0x0804848e <+42>: xor %gs:0x14,%eax 
0x08048495 <+49>: je  0x804849c <return_input+56> 
0x08048497 <+51>: call 0x8048370 <[email protected]> 
0x0804849c <+56>: leave 
0x0804849d <+57>: ret  
End of assembler dump. 

正如你從函數序言我們保留hex48(DEC 72)查看堆棧局部變量的字節。首先,我試圖找到我們易受攻擊的數組在棧上開始的地址。我認爲它是-0x2a(%ebp),對嗎? Hex2a是十進制42。據我所知,這意味着我們可以安全地寫入42個字節,然後我們開始覆蓋保存在堆棧上的EBP。但是,當我運行這個例子足以權只有37個字節得到分段錯誤:

[email protected]:~/temp/ELF_reader$ ./overflow 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 
Segmentation fault (core dumped) 

如何37個字節,足以溢出緩衝區?如果我們的本地字符數組是-42字節從保存的EBP

+0

無關,但[此問題](http://stackoverflow.com/questions/9249315/what-is-gs-in-assembly)*非常相似。 – huon

+0

在C中,向一個30字節數組寫入31個字節足以使該數組溢出(並導致未定義行爲)。 – pmg

回答

6

很難說,沒有看到整個功能的反彙編。

但是,我的猜測是存儲在-0xc(%ebp)的%gs:0x14可能是您的stack canary,如果檢測到堆棧coruption,則會導致乾淨退出。 所以這個值存儲在-0xc(%ebp),這意味着你的緩衝區實際上只有30個字節很大,接下來是什麼。

+0

感謝兄弟,沒有gcc堆棧保護重新編譯,彙編代碼正確提供所有值。 –