簡體   English   中英

緩沖區溢出時程序沒有崩潰

[英]Program didn't crash when buffer overflow

我想從鍵盤上讀取一個字符串並存儲在buf 我設置了一個char buf[6]數組,該數組最多可以存儲5個字符和\\0

然后,我鍵入123 456 789它包含11個字符和一個\\0 ,該程序仍然可以運行,但是如果我鍵入更長的字符串123 456 789 123 456 789 ,它將在運行時崩潰。 這兩個輸入也超出了buf的范圍,但是一個可以運行,另一個崩潰?

這是我的代碼:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void read_str();

int main(){
    read_str();
    system("pause");
    return 0;
}
void read_str(){

    char buf[6] = {};
    scanf("%[^\n]",buf);
    printf("%d\n",strlen(buf));
    printf("%s\n",buf);
}

這只是在分配的內存范圍之外寫入的未定義行為 它可能現在可以工作,但不能依靠它來工作。 附件J.2 未定義行為中C99標准草案說:

即使顯然可以使用給定下標訪問對象,數組下標也超出范圍(如在聲明為int a [4] [5]的左值表達式a [1] [7]中)(6.5.6)。

請注意,第3.4.3未定義行為定義了第2段中的術語( 強調我的 ):

可能的不確定行為范圍從完全忽略具有不可預測結果的情況到在以環境特征的書面方式執行翻譯或程序期間的行為(帶有或不帶有診斷消息的行為)到終止翻譯或執行(帶有發行)診斷消息)。

真正的原因很可能是因為您正在進行函數調用而只是覆蓋了堆棧的內容,並且實際上直到嘗試編寫超出底部的字符后,您才真正擁有了不屬於您的內存它的。 即使它不會崩潰,但這幾乎總是很糟糕,因為您會覆蓋程序出於某種原因放置在其中的值。 畢竟,如果每次改寫緩沖區時總是崩潰,那么緩沖區溢出錯誤就永遠不會發生,我們知道它們確實會發生。

例如,您的堆棧可能會向下增長。 進行函數調用時,您可能會獲得寄存器值,返回地址,參數值以及其他放置在堆棧中的內容。 然后,直到那時,才會分配您用於buf的6個字節。 如果所有其他的東西占去了,說,12個字節,那么你就可以寫18個字符buf ,仍然是不應該只改變觸摸存儲器,但是你的程序擁有。 由於您的進程擁有它,因此您不會獲得非法的內存訪問,也不會崩潰。 超過18個字節后,您很可能進入進程不擁有的內存,並且遇到段錯誤,游戲將啟動。

C的原因是您只是行為未定義,甚至發生了奇怪的事情,甚至您都不應該去理解。

暫無
暫無

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

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