C 字串拷貝與緩衝區溢位

2021-06-30 16:41:12 字數 1858 閱讀 2861

對於常用的字串拷貝函式,常用的有:

ansi版本如下:

strcpy, strncpy, strcpy_s, strncpy_s, stringcbcopy

unicode版本為:

wcscpy,wcsncpy,wcsncpy_s,wcsncpy_s,stringcbcopyw

其中最後乙個為windows的api,其餘為c執行時函式。

這些函式完成的功能是一樣的,然而本質上卻有極大區別。

現在我們來看看這些函式分別如何工作。

為簡化測試,我們只測試ansi版本的函式。unicde版本功能與之如出一轍。

測試**如下(vs2005,多位元組編碼):

[cpp]view plain

copy

char

buff1[2] = ;  

char

buff2[2] = ;  

strcpy(buff1, "1111111111111111"

);  

strncpy(buff2, "abcdefghijklmnopqratuvwxyz"

, 2);  

stringcbcopy(buff2, 2, "abcdefghijklmnopqratuvwxyz"

);  

strcpy_s(buff2, 2, "abcdefghijklmnopqratuvwxyz"

);  

buff2的位址為0x22fe0c,記憶體分布如下圖:

可以看到buff1和buff2之間被填充了0xcc,這是vs為了檢測緩衝區執行時整的。

另外注意棧記憶體分配上的特點,後分配的buff2的位址在先分配的buff1位址之前。

現在執行strcpy,看記憶體變化:

strcpy強行把16位元組寫入了buff1為首的記憶體。然而系統沒有任何反映,似乎一切正常。

然而,正式這種僥倖的正常,才會導致日後不可避免的緩衝區溢位導致的崩潰---誰知道buff1+2之後的14個位元組是什麼內容。

繼續執行,看看strncpy的表現會不會好一點:

strncpy的第三個引數接收緩衝區大小,如果待拷貝字串長度超過緩衝區,則截斷超出的字元不拷貝。

這麼做似乎很安全。然而致命的問題是這個「截斷「太過劣質。

因為buff2失去了'/0'結束符,buff2字串是從buff2開始直到之後記憶體中找到的第乙個'/0'

在這裡,由於buff2記憶體之後是buff1,buff2已經不再是2個位元組的字串了。緩衝區受到了破壞。

這個例子裡,我們看到buff2的內容是形如"ab燙燙燙燙燙燙燙燙1111111111111111"這樣的亂碼

誠然,這樣的操作也是極不安全的。

我們繼續執行,看看stringcbcopy表現如何。

呼呼,我們終於看到乙個表現堪稱「不錯」的字串拷貝函式了。

她總算是「優美」的截斷了過長的字串,保證了緩衝區的安全性。

然而,這樣的截斷後的字串是你需要的嗎?比如乙個路徑名字串被截斷了,你還能用他來開啟檔案嗎?

strcpy_s的第2個引數接收緩衝區大小。我們看看他執行結果如何:

餓...出現了assert錯誤。

不過這樣對程式設計師來說應該是最好的,你很快能知道是**出了問題。

一般而言,凡是函式後面帶有_s的字串系列函式,都是微軟整的「安全」字串函式。

他會進行傳入指標不為null、緩衝區足夠大等等安全檢查。

因此,我們在整字串的時候,應該使用這些安全字串。

最後請注意:上面所有函式都不進行記憶體重疊檢查!請自己進行必要的記憶體重疊檢查。

字串緩衝區

在學習string類時,api中說字串緩衝區支援可變的字串,什麼是字串緩衝區呢?接下來我們來研究下字串緩衝區。查閱stringbuffer的api,執行緒安全的可變字串行。乙個類似於 string 的字串緩衝區,但不能修改。雖然在任意時間點上它都包含某種特定的字串行,但通過某些方法呼叫可以改變該序列...

StringBuffer字串緩衝區

構造乙個其中不帶字元的字串緩衝區,初始容量為 16 個字元。特點 1 可以對字串內容進行修改。2 是乙個容器。3 是可變長度的。4 緩衝區中可以儲存任意型別的資料。5 最終需要變成字串。容器通常具備一些固定的方法 1,新增。stringbuffer insert index,data 在指定位置插入...

什麼是緩衝區溢位 C

緩衝區定義 緩衝區是程式執行的時候機器記憶體中的乙個連續塊,它儲存了給定型別的資料。緩衝區溢位定義 溢位原因 由於大多數程式都會假設資料長度總是與所分配的儲存資料相當,進而存在緩衝區溢位安全隱患,最好的情況是程式不允許輸入超過緩衝區長度的字元並檢查資料長度。攻擊方式 人為的緩衝區溢位一般是由於攻擊者...