2011-07-09 38 views
2

我玩弄緩衝區溢出,但我在Mac OS上運行以下簡單的C程序時發現我所困惑的。期待它沒有得到一個分段錯誤

#include <stdio.h> 

int main(void) { 

     char buf[2]; 

     scanf("%s", buf); 

     printf("%s\n", buf); 

} 

通過BUF的長度設置爲2個字節,我希望輸入字符串「CCC」時,導致段錯誤,但這並沒有發生。只有輸入長度爲24個字符的字符串時,纔會產生分段錯誤。

發生了什麼事?這與字符編碼有關嗎?

謝謝。

回答

5

只要溢出緩衝區,程序的行爲就不確定。任何事情都可能發生。你無法預測它。

你的緩衝區後面可能有或沒有一些填充字節,這對你的代碼執行來說並不重要。你不能依靠那個。一個不同的編譯器,以32位和64位編譯,調試設置......所有這些都可能會在溢出之後改變你的代碼執行。

+0

我明白了。我認爲便士已經下降。一個惡意的攻擊者會試圖溢出堆棧的其餘部分,並因此覆蓋寄存器?但是,他們如何預測剩餘的籌碼?操作系統每次都會分配固定數量的內存嗎? –

+0

查看裝配輸出和試錯法是確定「剩餘堆疊」的最佳選擇。這是可能的,但不能保證,在_same environment_中執行_same binary_時,這將保持不變。緩衝區溢出不會覆蓋寄存器。他們覆蓋堆棧或堆。 – Mat

+0

@Martin典型的想法是溢出堆棧中的緩衝區,以便覆蓋堆棧上的一些數據,指示CPU從函數返回後將返回的位置。有關更多詳細信息,請嘗試使用Google搜索「粉碎堆棧」。 –

1

猜想它與內存佈局有關。如果你的進程可以訪問你的進程(映射爲writable的頁面),那麼操作系統就沒有機會看到你正在做一些「錯誤的事情」。

事實上,當做這樣的事情時,從C程序員的眼中看來「這是完全錯誤的!」。但在操作系統的眼中,「好吧,他正在寫東西到某個頁面,頁面是否具有足夠的權限映射?如果是,OKAY」。

1

不能保證你會得到分段錯誤。 char buf[2]覆蓋後有更多的數據可能會或可能不會導致分段錯誤。

1

buf被分配到堆棧上,你只是覆蓋了一個未被使用的區域,很有可能沒有人會抱怨它。在某些平臺上,您的代碼將接受整個段落。

2

因爲buf在堆棧上。當你開始覆蓋它時,你將開始覆蓋屬於OS不會捕獲的程序的堆棧,這取決於在那裏分配了哪些內容(例如編譯器創建的寄存器的溢出插槽)。只有當您跨越分配的堆棧邊界時,操作系統纔有機會引發段錯誤。

相關問題