go語言緩沖區(qū)溢出 golang 棧溢出

什么是C語言緩沖區(qū)溢出漏洞?怎么利用?誰可以提供詳細(xì)的資料

緩沖區(qū)溢出漏洞入門介紹

成都創(chuàng)新互聯(lián)公司是一家專注于成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè)與策劃設(shè)計,名山網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)公司做網(wǎng)站,專注于網(wǎng)站建設(shè)10多年,網(wǎng)設(shè)計領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:名山等地區(qū)。名山做網(wǎng)站價格咨詢:18982081108

文/hokersome

一、引言

不管你是否相信,幾十年來,緩沖區(qū)溢出一直引起許多嚴(yán)重的安全性問題。甚至毫不夸張的說,當(dāng)前網(wǎng)絡(luò)種種安全問題至少有50%源自緩沖區(qū)溢出的問題。遠(yuǎn)的不說,一個沖擊波病毒已經(jīng)令人談溢出色變了。而作為一名黑客,了解緩沖區(qū)溢出漏洞則是一門必修課。網(wǎng)上關(guān)于溢出的漏洞的文章有很多,但是大多太深或者集中在一個主題,不適合初學(xué)者做一般性了解。為此,我寫了這篇文章,主要是針對初學(xué)者,對緩沖區(qū)溢出漏洞進(jìn)行一般性的介紹。

緩沖區(qū)溢出漏洞是之所以這么多,是在于它的產(chǎn)生是如此的簡單。只要C/C++程序員稍微放松警惕,他的代碼里面可能就出現(xiàn)了一個緩沖區(qū)溢出漏洞,甚至即使經(jīng)過仔細(xì)檢查的代碼,也會存在緩沖區(qū)溢出漏洞。

二、溢出

聽我說了這些廢話,你一定很想知道究竟什么緩沖區(qū)溢出漏洞,溢出究竟是怎么發(fā)生的。好,現(xiàn)在我們來先弄清楚什么是溢出。以下的我將假設(shè)你對C語言編程有一點(diǎn)了解,一點(diǎn)點(diǎn)就夠了,當(dāng)然,越多越好。

盡管緩沖區(qū)溢出也會發(fā)生在非C/C++語言上,但考慮到各種語言的運(yùn)用程度,我們可以在某種程度上說,緩沖區(qū)溢出是C/C++的專利。相信我,如果你在一個用VB寫的程序里面找溢出漏洞,你將會很出名?;氐秸fC/C++,在這兩種使用非常廣泛的語言里面,并沒有邊界來檢查數(shù)組和指針的引用,這樣做的目的是為了提高效率,而不幸的是,這也留下了嚴(yán)重的安全問題。先看下面一段簡單的代碼:

#includestdio.h

void main()

{

char buf[8];

gets(buf);

}

程序運(yùn)行的時候,如果你輸入“Hello”,或者“Kitty”,那么一切正常,但是如果輸入“Today is a good day”,那么我得通知你,程序發(fā)生溢出了。很顯然,buf這個數(shù)組只申請到8個字節(jié)的內(nèi)存空間,而輸入的字符卻超過了這個數(shù)目,于是,多余的字符將會占領(lǐng)程序中不屬于自己的內(nèi)存。因?yàn)镃/C++語言并不檢查邊界,于是,程序?qū)⒖此普@^續(xù)運(yùn)行。如果被溢出部分占領(lǐng)的內(nèi)存并不重要,或者是一塊沒有使用的內(nèi)存,那么,程序?qū)^續(xù)看似正常的運(yùn)行到結(jié)束。但是,如果溢出部分占領(lǐng)的正好的是存放了程序重要數(shù)據(jù)的內(nèi)存,那么一切將會不堪設(shè)想。

實(shí)際上,緩沖區(qū)溢出通常有兩種,堆溢出和堆棧溢出。盡管兩者實(shí)質(zhì)都是一樣,但由于利用的方式不同,我將在下面分開介紹。不過在介紹之前,還是來做一些必要的知識預(yù)備。

三、知識預(yù)備

要理解大多數(shù)緩沖區(qū)溢出的本質(zhì),首先需要理解當(dāng)程序運(yùn)行時機(jī)器中的內(nèi)存是如何分配的。在許多系統(tǒng)上,每個進(jìn)程都有其自己的虛擬地址空間,它們以某種方式映射到實(shí)際內(nèi)存。我們不必關(guān)心描述用來將虛擬地址空間映射成基本體系結(jié)構(gòu)的確切機(jī)制,而只關(guān)心理論上允許尋址大塊連續(xù)內(nèi)存的進(jìn)程。

程序運(yùn)行時,其內(nèi)存里面一般都包含這些部分:1)程序參數(shù)和程序環(huán)境;2)程序堆棧,它通常在程序執(zhí)行時增長,一般情況下,它向下朝堆增長。3)堆,它也在程序執(zhí)行時增長,相反,它向上朝堆棧增長;4)BSS 段,它包含未初始化的全局可用的數(shù)據(jù)(例如,全局變量); 5)數(shù)據(jù)段,它包含初始化的全局可用的數(shù)據(jù)(通常是全局變量);6)文本段,它包含只讀程序代碼。BSS、數(shù)據(jù)和文本段組成靜態(tài)內(nèi)存:在程序運(yùn)行之前這些段的大小已經(jīng)固定。程序運(yùn)行時雖然可以更改個別變量,但不能將數(shù)據(jù)分配到這些段中。下面以一個簡單的例子來說明以上的看起來讓人頭暈的東西:

#includestdio.h

char buf[3]="abc";

int i;

void main()

{

i=1

return;

}

其中,i屬于BBS段,而buf屬于數(shù)據(jù)段。兩者都屬于靜態(tài)內(nèi)存,因?yàn)樗麄冊诔绦蛑须m然可以改變值,但是其分配的內(nèi)存大小是固定的,如buf的數(shù)據(jù)大于三個字符,將會覆蓋其他數(shù)據(jù)。

與靜態(tài)內(nèi)存形成對比,堆和堆棧是動態(tài)的,可以在程序運(yùn)行的時候改變大小。堆的程序員接口因語言而異。在C語言中,堆是經(jīng)由 malloc() 和其它相關(guān)函數(shù)來訪問的,而C++中的new運(yùn)算符則是堆的程序員接口。堆棧則比較特殊,主要是在調(diào)用函數(shù)時來保存現(xiàn)場,以便函數(shù)返回之后能繼續(xù)運(yùn)行。

四、堆溢出

堆溢出的思路很簡單,覆蓋重要的變量以達(dá)到自己的目的。而在實(shí)際操作的時候,這顯得比較困難,尤其是源代碼不可見的時候。第一,你必須確定哪個變量是重要的變量;第二,你必須找到一個內(nèi)存地址比目標(biāo)變量低的溢出點(diǎn);第三,在特定目的下,你還必須讓在為了覆蓋目標(biāo)變量而在中途覆蓋了其他變量之后,程序依然能運(yùn)行下去。下面以一個源代碼看見的程序來舉例演示一次簡單的堆溢出是如何發(fā)生的:

#include "malloc.h"

#include "string.h"

#include "stdio.h"

void main()

{

char *large_str = (char *)malloc(sizeof(char)*1024);

char *important = (char *)malloc(sizeof(char)*6);

char *str = (char *)malloc(sizeof(char)*4);

strcpy(important,"abcdef");//給important賦初值

//下面兩行代碼是為了看str和important的地址

printf("%d/n",str);

printf("%d/n",important);

gets(large_str);//輸入一個字符串

strcpy(str, large_str);//代碼本意是將輸入的字符串拷貝到str

printf("%s/n",important);

}

在實(shí)際應(yīng)用中,這樣的代碼當(dāng)然是不存在的,這只是一個最簡單的實(shí)驗(yàn)程序?,F(xiàn)在我們的目標(biāo)是important這個字符串變成"hacker"。str和important的地址在不同的環(huán)境中并不是一定的,我這里是7868032和7868080。很好,important的地址比str大,這就為溢出創(chuàng)造了可能。計算一下可以知道,兩者中間隔了48個字節(jié),因此在輸入溢出字符串時候,可以先輸入48個任意字符,然后再輸入hakcer回車,哈哈,出來了,important成了"hacker"。

五、堆棧溢出

堆溢出的一個關(guān)鍵問題是很難找到所謂的重要變量,而堆棧溢出則不存在這個問題,因?yàn)樗鼘⒏采w一個非常重要的東西----函數(shù)的返回地址。在進(jìn)行函數(shù)調(diào)用的時候,斷點(diǎn)或者說返回地址將保存到堆棧里面,以便函數(shù)結(jié)束之后繼續(xù)運(yùn)行。而堆棧溢出的思路就是在函數(shù)里面找到一個溢出點(diǎn),把堆棧里面的返回地址覆蓋,替換成一個自己指定的地方,而在那個地方,我們將把一些精心設(shè)計了的攻擊代碼。由于攻擊代碼的編寫需要一些匯編知識,這里我將不打算涉及。我們這里的目標(biāo)是寫出一個通過覆蓋堆棧返回地址而讓程序執(zhí)行到另一個函數(shù)的堆棧溢出演示程序。

因?yàn)槎褩J峭略黾拥?,因此,先進(jìn)入堆棧的地址反而要大,這為在函數(shù)中找到溢出點(diǎn)提供了可能。試想,而堆棧是往上增加的,我們將永遠(yuǎn)無法在函數(shù)里面找到一個溢出點(diǎn)去覆蓋返回地址。還是先從一個最簡單的例子開始:

void test(int i)

{

char buf[12];

}

void main()

{

test(1);

}

test 函數(shù)具有一個局部參數(shù)和一個靜態(tài)分配的緩沖區(qū)。為了查看這兩個變量所在的內(nèi)存地址(彼此相對的地址),我們將對代碼略作修改:

void test(int i)

{

char buf[12];

printf("i = %d/n", i);

printf("buf[0] = %d/n", buf);

}

void main()

{

test(1);

}

需要說明的是,由于個人習(xí)慣的原因,我把地址結(jié)果輸出成10進(jìn)制形式,但愿這并不影響文章的敘述。在我這里,產(chǎn)生下列輸出:i = 6684072 buf[0] = 6684052。這里我補(bǔ)充一下,當(dāng)調(diào)用一個函數(shù)的時候,首先是參數(shù)入棧,然后是返回地址。并且,這些數(shù)據(jù)都是倒著表示的,因?yàn)榉祷氐刂肥?個字節(jié),所以可以知道,返回地址應(yīng)該是保存在從6684068到6684071。因?yàn)閿?shù)據(jù)是倒著表示的,所以實(shí)際上返回地址就是:buf[19]*256*256*256+buf[18]*256*256+buf[17]*256+buf[16]。

我們的目標(biāo)還沒有達(dá)到,下面我們繼續(xù)。在上面程序的基礎(chǔ),修改成:

#include stdio.h

void main()

{

void test(int i);

test(1);

}

void test(int i)

{

void come();

char buf[12];//用于發(fā)生溢出的數(shù)組

int addr[4];

int k=(int)i-(int)buf;//計算參數(shù)到溢出數(shù)組之間的距離

int go=(int)come;

//由于EIP地址是倒著表示的,所以首先把come()函數(shù)的地址分離成字節(jié)

addr[0]=(go 24)24;

addr[1]=(go 16)24;

addr[2]=(go 8)24;

addr[3]=go24;

//用come()函數(shù)的地址覆蓋EIP

for(int j=0;j4;j++)

{

buf[k-j-1]=addr[3-j];

}

}

void come()

{

printf("Success!");

}

一切搞定!運(yùn)行之后,"Success!"成功打印出來!不過,由于這個程序破壞了堆棧,所以系統(tǒng)會提示程序遇到問題需要關(guān)閉。但這并不要緊,因?yàn)橹辽傥覀円呀?jīng)邁出了萬里長征的第一步。

錯誤提示

我來解釋下.

運(yùn)行某些程序的時候,有時會出現(xiàn)內(nèi)存錯誤的提示,然后該程序就關(guān)閉。

“0x????????”指令引用的“0x????????”內(nèi)存。該內(nèi)存不能為“read”。

“0x????????”指令引用的“0x????????”內(nèi)存,該內(nèi)存不能為“written”。

以上的情況相信大家都應(yīng)該見到過,甚至說一些網(wǎng)友因?yàn)椴凰谶@個經(jīng)常出現(xiàn)的錯誤提示而屢次重裝系統(tǒng)。相信普通用戶應(yīng)該不會理解那些復(fù)雜的十六進(jìn)制代碼。

出現(xiàn)這個現(xiàn)象有方面的,一是硬件,即內(nèi)存方面有問題,二是軟件,這就有多方面的問題了。

一:先說說硬件:

一般來說,電腦硬件是很不容易壞的。內(nèi)存出現(xiàn)問題的可能性并不大(除非你的內(nèi)存真的是雜牌的一塌徒地),主要方面是:1。內(nèi)存條壞了(二手內(nèi)存情況居多)、2。使用了有質(zhì)量問題的內(nèi)存,3。內(nèi)存插在主板上的金手指部分灰塵太多。4。使用不同品牌不同容量的內(nèi)存,從而出現(xiàn)不兼容的情況。5。超頻帶來的散熱問題。你可以使用MemTest 這個軟件來檢測一下內(nèi)存,它可以徹底的檢測出內(nèi)存的穩(wěn)定度。

二、如果都沒有,那就從軟件方面排除故障了。

先說原理:內(nèi)存有個存放數(shù)據(jù)的地方叫緩沖區(qū),當(dāng)程序把數(shù)據(jù)放在緩沖區(qū),需要操作系統(tǒng)提供的“功能函數(shù)”來申請,如果內(nèi)存分配成功,函數(shù)就會將所新開辟的內(nèi)存區(qū)地址返回給應(yīng)用程序,應(yīng)用程序就可以通過這個地址使用這塊內(nèi)存。這就是“動態(tài)內(nèi)存分配”,內(nèi)存地址也就是編程中的“光標(biāo)”。內(nèi)存不是永遠(yuǎn)都招之即來、用之不盡的,有時候內(nèi)存分配也會失敗。當(dāng)分配失敗時系統(tǒng)函數(shù)會返回一個0值,這時返回值“0”已不表示新啟用的光標(biāo),而是系統(tǒng)向應(yīng)用程序發(fā)出的一個通知,告知出現(xiàn)了錯誤。

作為應(yīng)用程序,在每一次申請內(nèi)存后都應(yīng)該檢查返回值是否為0,如果是,則意味著出現(xiàn)了故障,應(yīng)該采取一些措施挽救,這就增強(qiáng)了程序的“健壯性”。若應(yīng)用程序沒有檢查這個錯誤,它就會按照“思維慣性”認(rèn)為這個值是給它分配的可用光標(biāo),繼續(xù)在之后的執(zhí)行中使用這塊內(nèi)存。真正的0地址內(nèi)存區(qū)儲存的是計算機(jī)系統(tǒng)中最重要的“中斷描述符表”,絕對不允許應(yīng)用程序使用。在沒有保護(hù)機(jī)制的操作系統(tǒng)下(如DOS),寫數(shù)據(jù)到這個地址會導(dǎo)致立即當(dāng)機(jī),而在健壯的操作系統(tǒng)中,如Windows等,這個操作會馬上被系統(tǒng)的保護(hù)機(jī)制捕獲,其結(jié)果就是由操作系統(tǒng)強(qiáng)行關(guān)閉出錯的應(yīng)用程序,以防止其錯誤擴(kuò)大。這時候,就會出現(xiàn)上述的內(nèi)存不能為“read”錯誤,并指出被引用的內(nèi)存地址為“0x00000000“。

內(nèi)存分配失敗故障的原因很多,內(nèi)存不夠、系統(tǒng)函數(shù)的版本不匹配等都可能有影響。因此,這種分配失敗多見于操作系統(tǒng)使用很長時間后,安裝了多種應(yīng)用程序(包括無意中“安裝”的病毒程序),更改了大量的系統(tǒng)參數(shù)和系統(tǒng)檔案之后。

在使用動態(tài)分配的應(yīng)用程序中,有時會有這樣的情況出現(xiàn):程序試圖讀寫一塊“應(yīng)該可用”的內(nèi)存,但不知為什么,這個預(yù)料中可用的光標(biāo)已經(jīng)失效了。有可能是“忘記了”向操作系統(tǒng)要求分配,也可能是程序自己在某個時候已經(jīng)注銷了這塊內(nèi)存而“沒有留意”等等。注銷了的內(nèi)存被系統(tǒng)回收,其訪問權(quán)已經(jīng)不屬于該應(yīng)用程序,因此讀寫操作也同樣會觸發(fā)系統(tǒng)的保護(hù)機(jī)制,企圖“違法”的程序唯一的下場就是被操作終止執(zhí)行,回收全部資源。計算機(jī)世界的法律還是要比人類有效和嚴(yán)厲得多??!像這樣的情況都屬于程序自身的BUG,你往往可在特定的操作順序下重現(xiàn)錯誤。無效光標(biāo)不一定總是0,因此錯誤提示中的內(nèi)存地址也不一定為“0x00000000”,而是其它隨機(jī)數(shù)字。

首先建議:

1、 檢查系統(tǒng)中是否有木馬或病毒。這類程序?yàn)榱丝刂葡到y(tǒng)往往不負(fù)責(zé)任地修改系統(tǒng),從而導(dǎo)致操作系統(tǒng)異常。平常應(yīng)加強(qiáng)信息安全意識,對來源不明的可執(zhí)行程序絕不好奇。

2、 更新操作系統(tǒng),讓操作系統(tǒng)的安裝程序重新拷貝正確版本的系統(tǒng)檔案、修正系統(tǒng)參數(shù)。有時候操作系統(tǒng)本身也會有BUG,要注意安裝官方發(fā)行的升級程序。

3、 盡量使用最新正式版本的應(yīng)用程序、Beta版、試用版都會有BUG。

4、 刪除然后重新創(chuàng)建 Winnt\System32\Wbem\Repository 文件夾中的文件:在桌面上右擊我的電腦,然后單擊管理。 在"服務(wù)和應(yīng)用程序"下,單擊服務(wù),然后關(guān)閉并停止 Windows Management Instrumentation 服務(wù)。 刪除 Winnt\System32\Wbem\Repository 文件夾中的所有文件。(在刪除前請創(chuàng)建這些文件的備份副本。) 打開"服務(wù)和應(yīng)用程序",單擊服務(wù),然后打開并啟動 Windows Management Instrumentation 服務(wù)。當(dāng)服務(wù)重新啟動時,將基于以下注冊表項(xiàng)中所提供的信息重新創(chuàng)建這些文件: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WBEM\CIMOM\Autorecover MOFs

內(nèi)存錯誤不能讀寫完全解決方案

運(yùn)行某些程序的時候,有時會出現(xiàn)內(nèi)存錯誤的提示,然后該程序就關(guān)閉。 “0x????????”指令引用的“0x????????”內(nèi)存。該內(nèi)存不能為“read”。

“0x????????”指令引用的“0x????????”內(nèi)存,該內(nèi)存不能為“written”。

不知你出現(xiàn)過類似這樣的故障嗎?(0x后面內(nèi)容有可能不一樣。)

一般出現(xiàn)這個現(xiàn)象有方面的,一是硬件,即內(nèi)存方面有問題,二是軟件,這就有多方面的問題了。

下面先說說硬件:

一般來說,內(nèi)存出現(xiàn)問題的可能性并不大,主要方面是:內(nèi)存條壞了、內(nèi)存質(zhì)量有問題,還有就是2個不同牌子不同容量的內(nèi)存混插,也比較容易出現(xiàn)不兼容的情況,同時還要注意散熱問題,特別是超頻后。你可以使用MemTest 這個軟件來檢測一下內(nèi)存,它可以徹底的檢測出內(nèi)存的穩(wěn)定度。

假如你是雙內(nèi)存,而且是不同品牌的內(nèi)存條混插或者買了二手內(nèi)存時,出現(xiàn)這個問題,這時,你就要檢查是不是內(nèi)存出問題了或者和其它硬件不兼容。

如果都沒有,那就從軟件方面排除故障了。

先簡單說說原理:內(nèi)存有個存放數(shù)據(jù)的地方叫緩沖區(qū),當(dāng)程序把數(shù)據(jù)放在其一位置時,因?yàn)闆]有足夠空間,就會發(fā)生溢出現(xiàn)象。舉個例子:一個桶子只能將一斤的水,當(dāng)你放入兩斤的水進(jìn)入時,就會溢出來。而系統(tǒng)則是在屏幕上表現(xiàn)出來。這個問題,經(jīng)常出現(xiàn)在windows2000和XP系統(tǒng)上,Windows 2000/XP對硬件的要求是很苛刻的,一旦遇到資源死鎖、溢出或者類似Windows 98里的非法操作,系統(tǒng)為保持穩(wěn)定,就會出現(xiàn)上述情況。另外也可能是硬件設(shè)備之間的兼容性不好造成的。

下面我從幾個例子給大家分析:

例一:打開IE瀏覽器或者沒過幾分鐘就會出現(xiàn)\"0x70dcf39f\"指令引用的\"0x00000000\"內(nèi)存。該內(nèi)存不能為“read”。要終止程序,請單擊“確定”的信息框,單擊“確定”后,又出現(xiàn)“發(fā)生內(nèi)部錯誤,您正在使用的其中一個窗口即將關(guān)閉”的信息框,關(guān)閉該提示信息后,IE瀏覽器也被關(guān)閉。 解決方法:修復(fù)或升級IE瀏覽器,同時打上補(bǔ)丁。看過其中一個修復(fù)方法是,Win2000自升級,也就是Win2000升級到Win2000,其實(shí)這種方法也就是把系統(tǒng)還原到系統(tǒng)初始的狀態(tài)下。比如你的IE升級到了6.0,自升級后,會被IE5.0代替。

例二:在windows xp下雙擊光盤里面的“AutoRun.exe”文件,顯示“0x77f745cc”指令引用的“0x00000078”內(nèi)存。該內(nèi)存不能為“written”,要終止程序,請單擊“確定”,而在Windows 98里運(yùn)行卻正常。 解決方法:這可能是系統(tǒng)的兼容性問題,winXP的系統(tǒng),右鍵“AutoRun.exe”文件,屬性,兼容性,把“用兼容模式運(yùn)行這個程序”項(xiàng)選擇上,并選擇“Windows 98/Me”。win2000如果打了SP的補(bǔ)丁后,只要開始,運(yùn)行,輸入:regsvr32 c:\\winnt\\apppatch\\slayerui.dll。右鍵,屬性,也會出現(xiàn)兼容性的選項(xiàng)。

例三:RealOne Gold關(guān)閉時出現(xiàn)錯誤,以前一直使用正常,最近卻在每次關(guān)閉時出現(xiàn)“0xffffffff”指令引用的“0xffffffff”內(nèi)存。該內(nèi)存不能為“read” 的提示。 解決方法:當(dāng)使用的輸入法為微軟拼音輸入法2003,并且隱藏語言欄時(不隱藏時沒問題)關(guān)閉RealOne就會出現(xiàn)這個問題,因此在關(guān)閉RealOne之前可以顯示語言欄或者將任意其他輸入法作為當(dāng)前輸入法來解決這個問題。

例四:我的豪杰超級解霸自從上網(wǎng)后就不能播放了,每次都提示“Ox060692f6”(每次變化)指令引用的“Oxff000011”內(nèi)存不能為“read”,終止程序請按確定。 解決方法:試試重裝豪杰超級解霸,如果重裝后還會,到官方網(wǎng)站下載相應(yīng)版本的補(bǔ)丁試試。還不行,只好換就用別的播放器試試了。

例五:雙擊一個游戲的快捷方式,“Ox77f5cdO”指令引用“Oxffffffff”內(nèi) 存,該內(nèi)存不能為“read” ,并且提示Client.dat程序錯誤。 解決方法:重裝顯卡的最新驅(qū)動程序,然后下載并且安裝DirectX9.0。

例六:一個朋友發(fā)信息過來,我的電腦便出現(xiàn)了錯誤信息:“0*772b548f”指令引用的“0*00303033”內(nèi)存,該內(nèi)存不能為“written”,然后QQ自動下線,而再打開QQ,發(fā)現(xiàn)了他發(fā)過來的十幾條的信息。 解決方法:這是對方利用QQ的BUG,發(fā)送特殊的代碼,做QQ出錯,只要打上補(bǔ)丁或升級到最新版本,就沒事了。

如果將計算機(jī)上分頁文件Pagefile.sys的大小設(shè)置為小于系統(tǒng)推薦的大小加上物理內(nèi)存的總和,這時系統(tǒng)可能創(chuàng)建一個臨時分頁文件Temppf.sys。如果臨時分頁文件Temppf.sys要使用大量的硬盤可用空間,而剩余的可用硬盤空間小于在“控制面板”中配置的分頁文件設(shè)置的初始大小,就可能出現(xiàn)此問題。解決的方法:

1.清理系統(tǒng)分區(qū)的垃圾文件,給臨時分頁文件騰出足夠的空間,以適應(yīng)臨時分頁文件的大小。

2.用Win+Break組合鍵打開“系統(tǒng)屬性”,在“高級”選項(xiàng)卡中單擊“性能”欄中的“設(shè)置”按鈕,在彈出窗口的“高級”選項(xiàng)卡中點(diǎn)擊“虛擬內(nèi)存”欄中的“更改”按鈕,將分頁文件的“初始大小”和“最大大小”的值均設(shè)置為0,然后重新啟動計算機(jī)。

3.根據(jù)上面的步驟將“初始大小”和“最大大小”值重置為Windows 2000的推薦(默認(rèn))值,再次重新啟動計算機(jī)。這樣為分頁文件配置了適當(dāng)?shù)拇笮『?,臨時分頁文件將被刪除,虛擬內(nèi)存錯誤將不再發(fā)生。

不明白的話去我的網(wǎng)頁吧:

力扣(LeetCode)70爬樓梯Go語言實(shí)現(xiàn)報錯為啥?

應(yīng)該是遞歸層次太多,導(dǎo)致溢出了,考慮這個轉(zhuǎn)變成循環(huán)吧,不然70級斐波那契遞歸層次太多了

我為什么要選擇Rust

你好,很高興為你解答。

專訪資深程序員莊曉立:我為什么要選擇Rust?

Rust是由Mozilla開發(fā)的注重安全、性能和并發(fā)性的編程語言。這門語言自推出以來就得到了國內(nèi)外程序員的大力推崇。Rust聲稱解決了傳統(tǒng)C語言和C++語言幾十年來飽受責(zé)難的內(nèi)存安全問題,同時還保持了極高的運(yùn)行效率、極深的底層控制、極廣的應(yīng)用范圍。但在國內(nèi)有關(guān)Rust的學(xué)習(xí)文檔并不多見,不久前,筆者聯(lián)系上了Rust1.0版本代碼貢獻(xiàn)者莊曉立(精彩博文:為什么我說Rust是靠譜的編程語言),請他分享Rust語言特性以及學(xué)習(xí)經(jīng)驗(yàn)。

CSDN:你是從什么時候開始接觸Rust語言的?是什么地方吸引了你?

莊曉立:我大概從2013年后半年開始深入接觸Rust語言。它居然聲稱解決了傳統(tǒng)C語言和C++語言幾十年來飽受責(zé)難的內(nèi)存安全問題,同時還保持了極高的運(yùn)行效率、極深的底層控制、極廣的應(yīng)用范圍。

其ownership機(jī)制令人眼前一亮,無虛擬機(jī)(VM)、無垃圾收集器(GC)、無運(yùn)行時(Runtime)、無空指針/野指針/內(nèi)存越界/緩沖區(qū)溢出/段錯誤、無數(shù)據(jù)競爭(Data Race)……所有這些,都深深地吸引了我——這個十多年以來深受C語言折磨的痛并快樂著的程序員。

CSDN:在你看來,Rust是怎樣的一門語言?它適合開發(fā)什么類型的項(xiàng)目?為何你會說Rust不懼怕任何競爭對手,它既能取代C語言地位;又可挑戰(zhàn)C++市場,還可向Java、Python分一杯羹?與這些語言相比,Rust有哪些優(yōu)越的特性?

莊曉立:Rust是一門系統(tǒng)編程語言,特別適合開發(fā)對CPU和內(nèi)存占用十分敏感的系統(tǒng)軟件,例如虛擬機(jī)(VM)、容器(Container)、數(shù)據(jù)庫/游戲/網(wǎng)絡(luò)服務(wù)器、瀏覽器引擎、模擬器等,而這些向來主要都是C/C++的傳統(tǒng)領(lǐng)地。

此外,Rust在系統(tǒng)底層開發(fā)領(lǐng)域,如裸金屬(bare metal)、操作系統(tǒng)(OS)、內(nèi)核(kernel)、內(nèi)核模塊(mod)等,也有強(qiáng)勁的實(shí)力,足以挑戰(zhàn)此領(lǐng)域的傳統(tǒng)老大C語言。Rust豐富的語言特性、先進(jìn)的設(shè)計理念、便捷的項(xiàng)目管理,令它在上層應(yīng)用開發(fā)中也能大展拳腳,至少在運(yùn)行性能上比帶VM和GC的語言要更勝一籌。無GC實(shí)現(xiàn)內(nèi)存安全機(jī)制、無數(shù)據(jù)競爭的并發(fā)機(jī)制、無運(yùn)行時開銷的抽象機(jī)制,是Rust獨(dú)特的優(yōu)越特性。

其他語言很難同時實(shí)現(xiàn)這些目標(biāo),例如傳統(tǒng)C/C++無法保證內(nèi)存安全,Java/Python等無法消除運(yùn)行時開銷。但Rust畢竟還是很年輕的項(xiàng)目,它釋放影響力需要時間,被世人廣泛接受需要時間;它的潛力能否爆發(fā)出來,需要時間去檢驗(yàn)。我們只需耐心等待。

CSDN:Rust在國內(nèi)有沒有具體的實(shí)際使用案例?

莊曉立:因?yàn)镽ust1.0正式版剛剛發(fā)布不足一月,在國內(nèi)影響力還不大,我們不能苛求它在國內(nèi)有實(shí)際應(yīng)用案例。但是在國外,一兩年前就已經(jīng)有OpenDNS和Skylight把Rust應(yīng)用在生產(chǎn)環(huán)境。還有瀏覽器引擎Servo、Rust編譯器和標(biāo)準(zhǔn)庫、項(xiàng)目管理器Cargo等“兩個半大型應(yīng)用案例”。這些足夠說明Rust語言的成熟和實(shí)用。

CSDN:你參與了Rust1.0版本代碼貢獻(xiàn),目前該版本正式版已經(jīng)發(fā)布,對此你感覺如何?這門語言是否已經(jīng)達(dá)到比較成熟的階段?

莊曉立:我積極參與了Rust語言開源項(xiàng)目,多次貢獻(xiàn)源代碼,曾連續(xù)三次出現(xiàn)在Rust官方博客公布的Rust 1.0 alpha、Rust 1.0 beta和Rust 1.0正式版的貢獻(xiàn)者名單中。在Rust 1.0正式版出臺的過程中及此前的很長一段時間,開發(fā)者付出了極大的努力,確保Rust 1.0正式版在Semver 2.0規(guī)范下,務(wù)必保持向后兼容性,除非遇到重大Bug不得不修復(fù)。

我認(rèn)為,在1.0正式發(fā)布之后,Rust就已經(jīng)進(jìn)入了比較成熟的階段。而且,Rust還在快速迭代發(fā)展過程中,1.0發(fā)布6周后將發(fā)布1.1,再6周后將發(fā)布1.2,必然會一步一個臺階,越來越成熟穩(wěn)定。

CSDN:除了功能優(yōu)先級以外,在你看來,Rust正在朝什么方向發(fā)展?未來的Rust可以期待什么樣的特性?

莊曉立:Rust一定會沿著“確保內(nèi)存安全、無運(yùn)行開銷、高效實(shí)用”的既定方向持續(xù)發(fā)展。在短期內(nèi)值得期待的語言特性有:動態(tài)Drop、偏特化、繼承、改進(jìn)borrow checker、改進(jìn)宏和語法擴(kuò)展。短期內(nèi)值得期待的其他特性有:增強(qiáng)文件系統(tǒng)API、提供內(nèi)存申請釋放API、更好地支持Windows和ARM、更快的編譯速度、更方便的二進(jìn)制分發(fā)機(jī)制(MUSL)、更實(shí)用的工具等等。

CSDN:據(jù)我了解,你之前也比較推崇Go語言,為何想到放棄Go轉(zhuǎn)向Rust?

莊曉立:推崇Go語言還談不上,不過我曾經(jīng)嘗試努力接受Go語言,2011底年開始我曾經(jīng)花費(fèi)將近半年時間深度關(guān)注Go開發(fā)進(jìn)程,提了很多具體的改進(jìn)意見和建議,也曾經(jīng)多次嘗試貢獻(xiàn)源代碼。后來考慮到Go語言的設(shè)計理念跟我偏差太大,其社區(qū)也不太友好,慢慢地疏遠(yuǎn)了它。我曾經(jīng)寫過一篇博客《我為什么放棄Go語言》,談到了很多具體的原因。

CSDN:國內(nèi),參與Rust代碼貢獻(xiàn)的開發(fā)者多嗎?有核心的人員嗎?有哪些社區(qū)在維護(hù)Rust?

莊曉立:國內(nèi)參與Rust代碼貢獻(xiàn)的開發(fā)者并不多,但也不少,官方的貢獻(xiàn)者名單中也偶見幾個貌似國人的名字。Rust的核心開發(fā)人員基本上都是Mozilla公司的員工,他們專職負(fù)責(zé)開發(fā)維護(hù)Rust語言和相關(guān)的項(xiàng)目,Rust社區(qū)也主要是他們參與組織和管理的。社區(qū)人員討論主要集中在GitHub項(xiàng)目主頁RFC/PR/Issue官方、Discuss論壇/IRC、Reddit、HN、StackOverflow等。

GO語言(十六):模糊測試入門(上)

本教程介紹了 Go 中模糊測試的基礎(chǔ)知識。通過模糊測試,隨機(jī)數(shù)據(jù)會針對您的測試運(yùn)行,以嘗試找出漏洞或?qū)е卤罎⒌妮斎???梢酝ㄟ^模糊測試發(fā)現(xiàn)的一些漏洞示例包括 SQL 注入、緩沖區(qū)溢出、拒絕服務(wù)和跨站點(diǎn)腳本攻擊。

在本教程中,您將為一個簡單的函數(shù)編寫一個模糊測試,運(yùn)行 go 命令,并調(diào)試和修復(fù)代碼中的問題。

首先,為您要編寫的代碼創(chuàng)建一個文件夾。

1、打開命令提示符并切換到您的主目錄。

在 Linux 或 Mac 上:

在 Windows 上:

2、在命令提示符下,為您的代碼創(chuàng)建一個名為 fuzz 的目錄。

3、創(chuàng)建一個模塊來保存您的代碼。

運(yùn)行g(shù)o mod init命令,為其提供新代碼的模塊路徑。

接下來,您將添加一些簡單的代碼來反轉(zhuǎn)字符串,稍后我們將對其進(jìn)行模糊測試。

在此步驟中,您將添加一個函數(shù)來反轉(zhuǎn)字符串。

a.使用您的文本編輯器,在 fuzz 目錄中創(chuàng)建一個名為 main.go 的文件。

獨(dú)立程序(與庫相反)始終位于 package 中main。

此函數(shù)將接受string,使用byte進(jìn)行循環(huán) ,并在最后返回反轉(zhuǎn)的字符串。

此函數(shù)將運(yùn)行一些Reverse操作,然后將輸出打印到命令行。這有助于查看運(yùn)行中的代碼,并可能有助于調(diào)試。

e.該main函數(shù)使用 fmt 包,因此您需要導(dǎo)入它。

第一行代碼應(yīng)如下所示:

從包含 main.go 的目錄中的命令行,運(yùn)行代碼。

可以看到原來的字符串,反轉(zhuǎn)它的結(jié)果,然后再反轉(zhuǎn)它的結(jié)果,就相當(dāng)于原來的了。

現(xiàn)在代碼正在運(yùn)行,是時候測試它了。

在這一步中,您將為Reverse函數(shù)編寫一個基本的單元測試。

a.使用您的文本編輯器,在 fuzz 目錄中創(chuàng)建一個名為 reverse_test.go 的文件。

b.將以下代碼粘貼到 reverse_test.go 中。

這個簡單的測試將斷言列出的輸入字符串將被正確反轉(zhuǎn)。

使用運(yùn)行單元測試go test

接下來,您將單元測試更改為模糊測試。

單元測試有局限性,即每個輸入都必須由開發(fā)人員添加到測試中。模糊測試的一個好處是它可以為您的代碼提供輸入,并且可以識別您提出的測試用例沒有達(dá)到的邊緣用例。

在本節(jié)中,您將單元測試轉(zhuǎn)換為模糊測試,這樣您就可以用更少的工作生成更多的輸入!

請注意,您可以將單元測試、基準(zhǔn)測試和模糊測試保存在同一個 *_test.go 文件中,但對于本示例,您將單元測試轉(zhuǎn)換為模糊測試。

在您的文本編輯器中,將 reverse_test.go 中的單元測試替換為以下模糊測試。

Fuzzing 也有一些限制。在您的單元測試中,您可以預(yù)測Reverse函數(shù)的預(yù)期輸出,并驗(yàn)證實(shí)際輸出是否滿足這些預(yù)期。

例如,在測試用例Reverse("Hello, world")中,單元測試將返回指定為"dlrow ,olleH".

模糊測試時,您無法預(yù)測預(yù)期輸出,因?yàn)槟鸁o法控制輸入。

但是,Reverse您可以在模糊測試中驗(yàn)證函數(shù)的一些屬性。在這個模糊測試中檢查的兩個屬性是:

(1)將字符串反轉(zhuǎn)兩次保留原始值

(2)反轉(zhuǎn)的字符串將其狀態(tài)保留為有效的 UTF-8。

注意單元測試和模糊測試之間的語法差異:

(3)確保新包unicode/utf8已導(dǎo)入。

隨著單元測試轉(zhuǎn)換為模糊測試,是時候再次運(yùn)行測試了。

a.在不進(jìn)行模糊測試的情況下運(yùn)行模糊測試,以確保種子輸入通過。

如果您在該文件中有其他測試,您也可以運(yùn)行g(shù)o test -run=FuzzReverse,并且您只想運(yùn)行模糊測試。

b.運(yùn)行FuzzReverse模糊測試,查看是否有任何隨機(jī)生成的字符串輸入會導(dǎo)致失敗。這是使用go test新標(biāo)志-fuzz執(zhí)行的。

模糊測試時發(fā)生故障,導(dǎo)致問題的輸入被寫入將在下次運(yùn)行的種子語料庫文件中g(shù)o test,即使沒有-fuzz標(biāo)志也是如此。要查看導(dǎo)致失敗的輸入,請在文本編輯器中打開寫入 testdata/fuzz/FuzzReverse 目錄的語料庫文件。您的種子語料庫文件可能包含不同的字符串,但格式相同。

語料庫文件的第一行表示編碼版本。以下每一行代表構(gòu)成語料庫條目的每種類型的值。由于 fuzz target 只需要 1 個輸入,因此版本之后只有 1 個值。

c.運(yùn)行沒有-fuzz標(biāo)志的go test; 新的失敗種子語料庫條目將被使用:

由于我們的測試失敗,是時候調(diào)試了。

分享題目:go語言緩沖區(qū)溢出 golang 棧溢出
當(dāng)前網(wǎng)址:http://www.muchs.cn/article30/hphgso.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站導(dǎo)航靜態(tài)網(wǎng)站、網(wǎng)站維護(hù)、網(wǎng)站收錄服務(wù)器托管、手機(jī)網(wǎng)站建設(shè)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)