談談C語言的溢位

2021-05-25 03:09:54 字數 2078 閱讀 2780

溢位是c語言中最常見的漏洞。最常見的溢位包括

陣列溢位

、數溢位

、緩衝區溢位

、指標溢位

以及棧溢位

,下面筆者就對這些溢位做乙個總結歸納。

1 陣列溢位

陣列溢位是最常見的一種溢位。因為在c語言中,含n個元素的陣列下標是從0開始,到n-1結束,而且c語言沒有提供陣列越界檢查的機制。 

請看如下**:

上面的迴圈判定應該改為: for (int i = 0; i < 5; ++i) 

也就是說,乙個含有n個元素的陣列,其遍歷元素的方式為: for (int i = 0; i < n - 1; ++i) 

再看下面這個程式:

上面的迴圈判斷應該改為: for (int i = 0; i < n - 1; ++i) 

從上面的例子看出,c語言中尤其要注意陣列的溢位錯誤。一旦發生了陣列的溢位,就會造成記憶體的非法訪問。可能會導致程式崩潰,也可能什麼都沒發生。

2數溢位

數的溢位是指數的值超過了他的型別的表示範圍。c++標準規定了每個算術型別的最小儲存空間,但它並不阻止編譯器使用更大的儲存空間。 

請看如下**:

當ch == uchar_max時,執行++ch的時候就會發生unsigned char型別的上溢,導致ch重新為0,此時程式會陷入死迴圈。 

請看如下**,查詢記憶體中特定的字元位置 : 

當無符號整型size_t(unsigned int)變數size == 0時,--size將會發生下溢,變為4294967295,導致死迴圈。 

請看如下**: 

在上面的**中,如果i == -2147483648時,對它求反將是2147483648,而這個值已經超過了int型別表示的最大值,即發生了上溢。應該用assert()巨集來規定i的有效範圍。

3緩衝區溢位

程式在執行過程中,為了臨時訪問資料的需要,一般都要分配一些記憶體空間,通常稱這些空間為緩衝區。如果向緩衝區寫入超過其本身長度的資料,以致於緩衝區無法容納,就會造成緩衝區以外的儲存單元被改寫,這種現象就被稱為緩衝區溢位。 

請看如下**:

執行結果:  

最重要的一點是把peip的位址及呼叫函式做成一串字串,就會導致緩衝區溢位。 

字串處理操作是緩衝區溢位的常見根源,大部分是由於c/c++語言執行時庫提供的標準字串處理函式(strcat、strcpy、sprintf等)不會阻止超出緩衝區結尾的寫入操作。所以需要使用更加安全的字串函式來消除程式中許多潛在的緩衝區溢位。比如可以使用strncat、strncpy、snprintf等函式,來控制字串操作的實際字元數,避免溢位的問題。而在最新的微軟字串操作庫中,已經提供了一些安全的字串操作函式,如strcpy_s、strcat_s等。

4棧溢位

系統的核心棧大小為乙個可以設定的定值。一般核心棧的大小為4kb或8kb。因此由於程式的區域性變數都分配在棧上,在寫程式時模組的區域性變數大小之和不應該超過這個棧的大小,否則就會發生棧溢位,而導致系統崩潰,例如下面的程式在linux系統執行就會造成核心棧溢位:

buf[10000]分配在棧上,但10000的空間超過了棧的預設大小8kb,所以發生溢位。

不僅系統棧會有溢位的問題,應用程式也可能會造成棧溢位。最常見的溢位可能就是當用遞迴演算法寫程式時,當遞迴巢狀過深,就會造成棧的溢位。因為遞迴呼叫的中間結果將儲存在堆疊中。要防止遞迴造成的棧的溢位,可以跟蹤遞迴的深度,當其大於某個深度就返回。也可以將遞迴演算法改為非遞迴演算法。

5指標溢位

指標的溢位可以理解為指標的錯誤運算,而指向了不該指向的位址。這個位址可能是null空間,可能是核心空間,也可能是無效的記憶體空間。例如:

上面的**用於查詢記憶體中特定的字元位置。對於其中的while()迴圈,平時執行似乎都沒有任何問題。但是考慮一種特別情況,即pv所指的記憶體位置為末尾若干個位元組,那麼因為pchend = pch + size,所以pchend指向最後乙個字元的下乙個位元組,那麼因為pchend所指的位置已經不存在,所以會發生指標溢位,因此在程式中應注意記憶體結尾的計算方式。 

正確**如下:

(完)

C語言 關於溢位

對於變數的值超出其定義的資料型別的表示範圍,這種情況稱為溢位。書上以shot型變數為例畫出了溢位的二進位制原理,如圖1。color blue 圖1 color img 圖中變數a換算成十進位制為32767,變數b換算成十進位制為3,本意想得到32770,不過由於溢位,得到的結果變數c換算成十進位制為...

的c語言 C語言的歷史,個人談談c語言

c語言的設計目標就是提供一種簡單的方式,編譯處理低階儲存器,產生少量的機器碼,來完成程式設計。20世紀80年代,美國國家標準局為了避免各國產生的差異,於是給c語言制定了一套完整的國際標準語言,它的名稱是ansic,2011年12月8日,國際標準化組織發布ce標準,也就是c語言的新標準。20世紀60年...

C語言中的整數溢位

對於初學者來說,c語言的整數溢位可能一開始可能會不好理解。對於乙個位元組的 unsignde char型別和signed char 型別。賦值乙個超出其儲存範圍的數值時,其真實儲存的數值並不等於我們賦值的資料。要弄清整數溢位問題,首先必須清晰計算機中數值都是以補碼形式儲存的,要會原碼 反碼和補碼的轉...