一、 超越整數範圍的溢位
當執行演算法以計算緩衝區大小,真正的安全性漏洞會隨同這些缺陷一起出現。請看下面的示例:
void func(char *b1, int c1, char *b2, int c2)
上面的**看起來沒有問題,但如果將 c1 和 c2 相加,結果超過 232-1,您就會意識到有問題了。例如,0xfffffff0 和 0x40 相加的結果為 0x30(十進位制為 48)。當這些值用於 c1 和 c2 時,加起來的和可以通過大小檢查,然後**會將大約 4gb 複製到 48 個位元組的緩衝區。這樣就會出現緩衝區溢位!類似於這樣的許多錯誤都可以被利用,使攻擊者將**注入您的程序中。
那像這種問題如何解決呢?
可以在可能發生溢位的地方,加上條件判斷,比如解決上面的問題, 可以寫為:
if( c1 < 0 || c2 < 0 || c1 + c2 > max ) return;
二、 型別轉換時的溢位
在乙個複雜的應用程式中,乙個表示式中包含了各種型別的變數,這時在運算過程中就包括了各種的預設型別轉換。這個預設型別轉換都是按你想的過程進行的嗎? 先看如下的例子
, 首先, 自己猜測一下結果:
#include
int main()
輸出的結果是:
-34 > 7
-34 < 3
-84 < 3
7 + -34 = -27
7 + -34 = 4294967269
7 + -34 > 0
以上的程式在
gcc2.9 上編譯,liunx7.3上執行的結果。
從輸出的結果來看,和你預期的輸出結果一樣嗎?
也許從下面的輸出結果,你能了解到問題出在那裡了嗎?
7 + -34 = -27
7 + -34 = 4294967269
7 + -34 > 0
是的,從中我們就可以看出, 型別轉換的作用。
現在來解釋一下如下表示式:
7 + -34 > 0
因為 ulongc1 是無符號數,
longc1是有符號數 ,所以longc1轉換為無符號相加,產生如下結果:
ulongc1 + longc1 = 4294967269
這時,自然
ulongc1 + longc1 > 0
對於longc1 > uintb 以及
intb1 > uintb 的比較過程中, 預設的轉換中,都將雙位元組short型別(不管是有無符號)先轉換為有符號四位元組型別int , 再進行比較,所以才比較出正確的結果。
在 c語言中,在進行表示式計算時,如果其中有多種型別時,一般先進行型別轉換,再進行計算。預設的型別轉換是從位元組少向位元組多的轉換,有符號的向無符號型別轉換。因些,如果算術運算子的乙個運算元是有符號整數,另乙個是無符號整數,那麼有符號整數會被轉換為無符號整數,計算結果自然也是無符號數。
發現其中也有不完善的地方, 因為低於四位元組的型別,如char , unsigned char , short, unsigned shourt 都是先轉換為int 型別,再進行計算, 資料沒有丟失及溢位,因此不存在判斷錯誤。所以要注意的就是int 以及 unsigned int混合,此時何正確進行判斷呢?
只要先有符號數的範圍檢查:
if ((longc1 > 0)
&& (longc1 > ulongc1))
C 整數翻轉中的溢位問題
當輸入1234567899時會顯示,溢位錯誤提醒。在32位的程式設計環境中的int 型數字範圍是 231 231 1 231 2147483648,231 1 2147483647 而當翻轉後的數字在此範圍之外的時候,就會發生溢位。if x 10 it x 10 it int max else x ...
C語言中的整數溢位
對於初學者來說,c語言的整數溢位可能一開始可能會不好理解。對於乙個位元組的 unsignde char型別和signed char 型別。賦值乙個超出其儲存範圍的數值時,其真實儲存的數值並不等於我們賦值的資料。要弄清整數溢位問題,首先必須清晰計算機中數值都是以補碼形式儲存的,要會原碼 反碼和補碼的轉...
c語言中整數溢位的概念
在編寫程式時,如果整數的值太大,超出了所定義的整數型別的範圍會怎麼樣?下面分別將有符號型別好無符號型別整數設定為最大允許值加略大一些的值,看一看結果是是什麼。printf函式使用 u說明符顯示unsigned int型別的值 程式段上面所設定的整形和無符號整形均為系統所允許的最大值,下面即是執行的結...