免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
面試官不講武德,居然讓我講講蠕蟲(chóng)和金絲雀!

蠕蟲(chóng)病毒是一種常見(jiàn)的利用Unix系統(tǒng)中的缺點(diǎn)來(lái)進(jìn)行攻擊的病毒。緩沖區(qū)溢出一個(gè)常見(jiàn)的后果是:黑客利用函數(shù)調(diào)用過(guò)程中程序的返回地址,將存放這塊地址的指針精準(zhǔn)指向計(jì)算機(jī)中存放攻擊代碼的位置,造成程序異常中止。為了防止發(fā)生嚴(yán)重的后果,計(jì)算機(jī)會(huì)采用棧隨機(jī)化,利用金絲雀值檢查破壞棧,限制代碼可執(zhí)行區(qū)域等方法來(lái)盡量避免被攻擊。雖然,現(xiàn)代計(jì)算機(jī)已經(jīng)可以“智能”查錯(cuò)了,但是我們還是要養(yǎng)成良好的編程習(xí)慣,盡量避免寫(xiě)出有漏洞的代碼,以節(jié)省寶貴的時(shí)間!

蠕蟲(chóng)病毒簡(jiǎn)介

??蠕蟲(chóng)是一種可以自我復(fù)制的代碼,并且通過(guò)網(wǎng)絡(luò)傳播,通常無(wú)需人為干預(yù)就能傳播。蠕蟲(chóng)病毒入侵并完全控制一臺(tái)計(jì)算機(jī)之后,就會(huì)把這臺(tái)機(jī)器作為宿主,進(jìn)而掃描并感染其他計(jì)算機(jī)。當(dāng)這些新的被蠕蟲(chóng)入侵的計(jì)算機(jī)被控制之后,蠕蟲(chóng)會(huì)以這些計(jì)算機(jī)為宿主繼續(xù)掃描并感染其他計(jì)算機(jī),這種行為會(huì)一直延續(xù)下去。蠕蟲(chóng)使用這種遞歸的方法進(jìn)行傳播,按照指數(shù)增長(zhǎng)的規(guī)律分布自己,進(jìn)而及時(shí)控制越來(lái)越多的計(jì)算機(jī)。

緩沖區(qū)溢出

??緩沖區(qū)溢出是指當(dāng)計(jì)算機(jī)向緩沖區(qū)內(nèi)填充數(shù)據(jù)位數(shù)時(shí)超過(guò)了緩沖區(qū)本身的容量,溢出的數(shù)據(jù)覆蓋在合法數(shù)據(jù)上。理想的情況是:程序會(huì)檢查數(shù)據(jù)長(zhǎng)度,而且并不允許輸入超過(guò)緩沖區(qū)長(zhǎng)度的字符。但是絕大多數(shù)程序都會(huì)假設(shè)數(shù)據(jù)長(zhǎng)度總是與所分配的儲(chǔ)存空間相匹配,這就為緩沖區(qū)溢出埋下隱患。操作系統(tǒng)所使用的緩沖區(qū),又被稱(chēng)為“堆棧”,在各個(gè)操作進(jìn)程之間,指令會(huì)被臨時(shí)儲(chǔ)存在“堆?!碑?dāng)中,“堆?!币矔?huì)出現(xiàn)緩沖區(qū)溢出。

緩沖區(qū)溢出舉例

void echo()
{
  char buf[4];   /*故意設(shè)置很小*/
  gets(buf);
  puts(buf);
}
void call_echo(){
  echo();
}

??反匯編如下:

/*echo*/
000000000040069c <echo>: 
40069c:48 83 ec 18         sub $0x18,%rsp  /*0X18 == 24,分配了24字節(jié)內(nèi)存。計(jì)算機(jī)會(huì)多分配一些給緩沖區(qū)*/
4006a0:48 89 e7            mov %rsp,%rdi   
4006a3:e8 a5 ff ff ff      callq 40064d <gets>
4006a8::48 89 e7           mov %rsp,%rdi
4006ab:e8 50  fe ff ff     callq callq 400500 <puts@plt>
4006b0:48 83 c4 18         add $0x18,%rsp 
4006b4:c3                  retq 
/*call_echo*/
4006b5:48 83  ec 08             sub $0x8,%rsp 
4006b9:b8 00 00 00 00           mov $0x0,%eax
4006be:e8 d9 ff ff ff           callq 40069c <echo>
4006c3:48 83 c4 08              add $0x8,%rsp 
4006c7:c3                       retq

??在這個(gè)例子中,我們故意把buf設(shè)置的很小。運(yùn)行該程序,我們?cè)诿钚兄休斎?12345678901234567890123,程序立馬就會(huì)報(bào)錯(cuò):Segmentation fault。

??要想明白為什么會(huì)報(bào)錯(cuò),我們需要通過(guò)分析反匯編來(lái)了解其在內(nèi)存是如何分布的。具體如下圖所示:

??如下圖所示,此時(shí)計(jì)算機(jī)為buf分配了24字節(jié)空間,其中20字節(jié)還未使用。

??此時(shí),準(zhǔn)備調(diào)用echo函數(shù),將其返回地址壓棧。

??當(dāng)我們輸入“01234567890123456789012"時(shí),緩沖區(qū)已經(jīng)溢出,但是并沒(méi)有破壞程序的運(yùn)行狀態(tài)。

??當(dāng)我們輸入:“012345678901234567890123"。緩沖區(qū)溢出,返回地址被破壞,程序返回 0x0400600。

??這樣程序就跳轉(zhuǎn)到了計(jì)算機(jī)中其他內(nèi)存的位置,很大可能這塊內(nèi)存已經(jīng)被使用。跳轉(zhuǎn)修改了原來(lái)的值,所以程序就會(huì)中止運(yùn)行。

??黑客可以利用這個(gè)漏洞,將程序精準(zhǔn)跳轉(zhuǎn)到其存放木馬的位置,然后就會(huì)執(zhí)行木馬程序,對(duì)我們的計(jì)算機(jī)造成破壞。

緩沖區(qū)溢出的危害

??可以利用它執(zhí)行非授權(quán)指令,甚至可以取得系統(tǒng)特權(quán),進(jìn)而進(jìn)行各種非法操作。緩沖區(qū)溢出攻擊有多種英文名稱(chēng):buffer overflow,buffer overrun,smash the stack,trash the stack,scribble the stack, mangle the stack, memory leak,overrun screw;它們指的都是同一種攻擊手段。第一個(gè)緩沖區(qū)溢出攻擊--Morris蠕蟲(chóng),發(fā)生在二十年前,它曾造成了全世界6000多臺(tái)網(wǎng)絡(luò)服務(wù)器癱瘓。

??在當(dāng)前網(wǎng)絡(luò)與分布式系統(tǒng)安全中,被廣泛利用的50%以上都是緩沖區(qū)溢出,其中最著名的例子是1988年利用fingerd漏洞的蠕蟲(chóng)。而緩沖區(qū)溢出中,最為危險(xiǎn)的是堆棧溢出,因?yàn)槿肭终呖梢岳枚褩R绯?,在函?shù)返回時(shí)改變返回程序的地址,讓其跳轉(zhuǎn)到任意地址,帶來(lái)的危害一種是程序崩潰導(dǎo)致拒絕服務(wù),另外一種就是跳轉(zhuǎn)并且執(zhí)行一段惡意代碼,比如得到shell,然后為所欲為。 (來(lái)源百度百科)

內(nèi)存在計(jì)算機(jī)中的排布方式

??內(nèi)存在計(jì)算機(jī)中的排布方式如下,從上到下依次為共享庫(kù),棧,堆,數(shù)據(jù)段,代碼段。各個(gè)段的作用簡(jiǎn)介如下(更詳細(xì)的內(nèi)容總結(jié)見(jiàn)嵌入式軟件開(kāi)發(fā)知識(shí)點(diǎn)總結(jié).pdf):

??共享庫(kù):共享庫(kù)以.so結(jié)尾.(so==share object)在程序的鏈接時(shí)候并不像靜態(tài)庫(kù)那樣在拷貝使用函數(shù)的代碼,而只是作些標(biāo)記。然后在程序開(kāi)始啟動(dòng)運(yùn)行的時(shí)候,動(dòng)態(tài)地加載所需模塊。所以,應(yīng)用程序在運(yùn)行的時(shí)候仍然需要共享庫(kù)的支持。共享庫(kù)鏈接出來(lái)的文件比靜態(tài)庫(kù)要小得多。

??:棧又稱(chēng)堆棧,是用戶(hù)存放程序臨時(shí)創(chuàng)建的變量,也就是我們函數(shù){}中定義的變量但不包括static聲明的變量,static意味著在數(shù)據(jù)段中存放變量。除此之外,在函數(shù)被調(diào)用時(shí),其參數(shù)也會(huì)被壓入發(fā)起調(diào)用的進(jìn)程棧中,并且待到調(diào)用結(jié)束后,函數(shù)的返回值也會(huì)被存放回棧中,由于棧的先進(jìn)后出特點(diǎn),所以棧特別方便用來(lái)保存、恢復(fù)調(diào)用現(xiàn)場(chǎng)。從這個(gè)意義上講,我們可以把堆??闯梢粋€(gè)寄存,交換臨時(shí)數(shù)據(jù)的內(nèi)存區(qū)。在X86-64 Linux系統(tǒng)中,棧的大小一般為8M(用ulitmit - a命令可以查看)。

??:堆是用來(lái)存放進(jìn)程中被動(dòng)態(tài)分配的內(nèi)存段,它的大小并不固定,可動(dòng)態(tài)擴(kuò)張或縮減。當(dāng)進(jìn)程調(diào)用malloc等函數(shù)分配內(nèi)存時(shí),新分配的內(nèi)存就被動(dòng)態(tài)分配到堆上,當(dāng)利用free等函數(shù)釋放內(nèi)存時(shí),被釋放的內(nèi)存從堆中被剔除。

??堆存放new出來(lái)的對(duì)象、棧里面所有對(duì)象都是在堆里面有指向的、假如棧里指向堆的指針被刪除、堆里的對(duì)象也要釋放(C++需要手動(dòng)釋放)、當(dāng)然我們現(xiàn)在好面向?qū)ο蟪绦蚨加?垃圾回收機(jī)制'、會(huì)定期的把堆里沒(méi)用的對(duì)象清除出去。

??數(shù)據(jù)段:數(shù)據(jù)段通常用來(lái)存放程序中已初始化的全局變量和已初始化為非0的靜態(tài)變量的一塊內(nèi)存區(qū)域,屬于靜態(tài)內(nèi)存分配。直觀理解就是C語(yǔ)言程序中的全局變量(注意:全局變量才算是程序的數(shù)據(jù),局部變量不算程序的數(shù)據(jù),只能算是函數(shù)的數(shù)據(jù)

??代碼段:代碼段通常用來(lái)存放程序執(zhí)行代碼的一塊區(qū)域。這部分區(qū)域的大小在程序運(yùn)行前就已經(jīng)確定了,通常這塊內(nèi)存區(qū)域?qū)儆?strong>只讀,有些架構(gòu)也允許可寫(xiě),在代碼段中也有可能包含以下只讀的常數(shù)變量,例如字符串常量等。程序段為程序代碼在內(nèi)存中映射一個(gè)程序可以在內(nèi)存中有多個(gè)副本。

??下面舉個(gè)例子來(lái)看下代碼中各個(gè)部分再計(jì)算機(jī)中是如何排布的。

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

char big_array[1L<<24];     /*16 MB*/
char huge_array[1L<<31];    /*2 GB*/

int global = 0;

int useless() {return 0;}

int main()
{
  void *phuge1,*psmall2,*phuge3,*psmall4;
  int local = 0;
  phuge1 = malloc(1L<<28);    /*256 MB*/
  psmall2 = malloc(1L<<8);    /*256 B*/
  phuge3 = malloc(1L<<32);    /*4 GB*/
  psmall4 = malloc(1L<<8);    /*256 B*/
  /*some print statements....*/
}

??上述代碼中,程序中的各個(gè)變量在內(nèi)存的排布方式如下圖所示。根據(jù)顏色可以一一對(duì)應(yīng)起來(lái)。由于了local變量存放在棧區(qū),四個(gè)指針變量使用了malloc分配了空間,所以存放在堆上,兩個(gè)數(shù)組big_array,huge_array存放在數(shù)據(jù)段,main,useless函數(shù)的其他部分存放在代碼段中。

計(jì)算機(jī)中越界訪問(wèn)的后果

??下面再看一個(gè)例子,看下越界訪問(wèn)內(nèi)存會(huì)有什么結(jié)果。

typedef struct 
{
  int a[2];
  double d;
}struct_t;

double fun(int i){

  volatile struct_t s;
  s.d = 3.14;
  s.a[i] = 1073741824;  /*可能越界*/
  return s.d;
}

int main()
{
  printf("fun(0):%lf\n",fun(0));
  printf("fun(1):%lf\n",fun(1));
  printf("fun(2):%lf\n",fun(2));
  printf("fun(3):%lf\n",fun(3));
  printf("fun(6):%lf\n",fun(6));
  return 0; 
}

??打印結(jié)果如下所示

fun(0):3.14
fun(1):3.14
fun(2):3.1399998664856
fun(3):2.00000061035156
fun(6):Segmentation fault

??在上面的程序中,我們定義了一個(gè)結(jié)構(gòu)體,其中 a 數(shù)組中包含兩個(gè)整數(shù)值,還有 d 一個(gè)雙精度浮點(diǎn)數(shù)。在函數(shù)fun中,fun函數(shù)根據(jù)傳入的參數(shù)i來(lái)初始化a數(shù)組。顯然,i的值只能為0和1。在fun函數(shù)中,同時(shí)還設(shè)置了d的值為3.14。當(dāng)我們給fun函數(shù)傳入0和1時(shí)可以打印出正確的結(jié)果3.14。但是當(dāng)我們傳入2,3,6時(shí),奇怪的現(xiàn)象發(fā)生了。為什么fun(2)和fun(3)的值會(huì)接近3.14,而fun(6)會(huì)報(bào)錯(cuò)呢?

??要搞清楚這個(gè)問(wèn)題,我們要明白結(jié)構(gòu)體在內(nèi)存中是如何存儲(chǔ)的,具體如下圖所示。

??GCC默認(rèn)不檢查數(shù)組越界,除非加編譯選項(xiàng)。這也是C的bug之一,越界會(huì)修改某些內(nèi)存的值,得出我們意想不到的結(jié)果。即使有些數(shù)據(jù)相隔萬(wàn)里,也可能受到影響。當(dāng)一個(gè)系統(tǒng)這幾天運(yùn)行正常時(shí),過(guò)幾天可能就會(huì)崩潰。(如果這個(gè)系統(tǒng)是運(yùn)行在我們的心臟起搏器,又或者是航天飛行器上,那么這無(wú)疑將會(huì)造成巨大的損失?。?/p>

??如上圖所示,對(duì)于最下面的兩個(gè)元素,每個(gè)塊代表 4 字節(jié)。a數(shù)組占用8個(gè)字節(jié),d變量占用8字節(jié),d排布在a數(shù)組的上方。所以我們會(huì)看到,如果我引用 a[0] 或者 a[1],會(huì)按照正常修改該數(shù)組的值。但是當(dāng)我調(diào)用 fun(2) 或者 fun(3)時(shí),實(shí)際上修改的是這個(gè)浮點(diǎn)數(shù) d 的字節(jié)。這就是為什么我們打印出來(lái)的fun(2)和fun(3)的值如此接近3.14。當(dāng)輸入 6 時(shí),就修改了對(duì)應(yīng)的這塊內(nèi)存的值。原來(lái)這塊內(nèi)存可能存儲(chǔ)的其他用于維持程序運(yùn)行的內(nèi)容,而且是已經(jīng)分配的內(nèi)存。所示,我們程序就會(huì)報(bào)出Segmentation fault的錯(cuò)誤。當(dāng)我們理解了數(shù)據(jù)結(jié)構(gòu)的機(jī)器級(jí)表示以及它們是如何運(yùn)行的,處理這些漏洞也就很輕松了。

避免緩沖區(qū)溢出的三種方法

??為了在系統(tǒng)中插入攻擊代碼,攻擊者既要插入代碼,也要插入指向這段代碼的指針。這個(gè)指針也是攻擊字符串的一部分。產(chǎn)生這個(gè)指針需要知道這個(gè)字符串放置的棧地址。在過(guò)去,程序的棧地址非常容易預(yù)測(cè)。對(duì)于所有運(yùn)行同樣程序和操作系統(tǒng)版本的系統(tǒng)來(lái)說(shuō),在不同的機(jī)器之間,棧的位置是相當(dāng)固定的。因此,如果攻擊者可以確定一個(gè)常見(jiàn)的Web服務(wù)器所使用的??臻g,就可以設(shè)計(jì)一個(gè)在許多機(jī)器上都能實(shí)施的攻擊。

棧隨機(jī)化

??棧隨機(jī)化的思想使得棧的位置在程序每次運(yùn)行時(shí)都有變化。因此,即使許多機(jī)器都運(yùn)行同樣的代碼,它們的棧地址都是不同的。實(shí)現(xiàn)的方式是:程序開(kāi)始時(shí),在棧上分配一段0 ~ n字節(jié)之間的隨機(jī)大小的空間,例如,使用分配函數(shù)alloca在棧上分配指定字節(jié)數(shù)量的空間。程序不使用這段空間,但是它會(huì)導(dǎo)致程序每次執(zhí)行時(shí)后續(xù)的棧位置發(fā)生了變化。分配的范圍n必須足夠大,才能獲得足夠多的棧地址變化,但是又要足夠小,不至于浪費(fèi)程序太多的空間。

int main(){
	long local;
	printf("local at %p\n",&local);
	return 0;
}

??這段代碼只是簡(jiǎn)單地打印出main函數(shù)中局部變量的地址。在32位 Linux上運(yùn)行這段代碼10000次,這個(gè)地址的變化范圍為0xff7fc59c到0xffffd09c,范圍大小大約是\({2^{23}}\)。在更新一點(diǎn)兒的機(jī)器上運(yùn)行64位 Linux,這個(gè)地址的變化范圍為0x7fff0001b698到0x7ffffffaa4a8,范圍大小大約是 \({2^{32}}\)

??其實(shí),一個(gè)好的黑客專(zhuān)家,可以使用蠻力破壞棧的隨機(jī)化。對(duì)于32位的機(jī)器,我們枚舉\({2^{15}} = 32768\)個(gè)地址就能猜出來(lái)?xiàng)5牡刂贰?duì)于64位的機(jī)器,我們需要枚舉\({2^{24}} = 16777216\)次。如此看來(lái),棧的隨機(jī)化降低了病毒或者蠕蟲(chóng)的傳播速度,但是也不能提供完全的安全保障。

檢測(cè)棧是否被破壞

??計(jì)算機(jī)的第二道防線是能夠檢測(cè)到何時(shí)棧已經(jīng)被破壞。我們?cè)趀cho函數(shù)示例中看到,當(dāng)訪問(wèn)緩沖區(qū)越界時(shí),會(huì)破壞程序的運(yùn)行狀態(tài)。在C語(yǔ)言中,沒(méi)有可靠的方法來(lái)防止對(duì)數(shù)組的越界寫(xiě)。但是,我們能夠在發(fā)生了越界寫(xiě)的時(shí)候,在造成任何有害結(jié)果之前,嘗試檢測(cè)到它。

??GCC在產(chǎn)生的代碼中加人了一種棧保護(hù)者機(jī)制,來(lái)檢測(cè)緩沖區(qū)越界。其思想是在棧幀中任何局部緩沖區(qū)與棧狀態(tài)之間存儲(chǔ)一個(gè)特殊的金絲雀( canary)值,如下圖所示:

??這個(gè)金絲雀值,也稱(chēng)為哨兵值,是在程序每次運(yùn)行時(shí)隨機(jī)產(chǎn)生的,因此,攻擊者沒(méi)有簡(jiǎn)單的辦法能夠知道它是什么。在恢復(fù)寄存器狀態(tài)和從函數(shù)返回之前,程序檢查這個(gè)金絲雀值是否被該函數(shù)的某個(gè)操作或者該函數(shù)調(diào)用的某個(gè)函數(shù)的某個(gè)操作改變了。如果是的,那么程序異常中止。

英國(guó)礦井飼養(yǎng)金絲雀的歷史大約起始1911年。當(dāng)時(shí),礦井工作條件差,礦工在下井時(shí)時(shí)常冒著中毒的生命危險(xiǎn)。后來(lái),約翰·斯科特·霍爾丹(John Scott Haldane)在經(jīng)過(guò)對(duì)一氧化碳一番研究之后,開(kāi)始推薦在煤礦中使用金絲雀檢測(cè)一氧化碳和其他有毒氣體。金絲雀的特點(diǎn)是極易受有毒氣體的侵害,因?yàn)樗鼈兤匠ow行高度很高,需要吸入大量空氣吸入足夠氧氣。因此,相比于老鼠或其他容易攜帶的動(dòng)物,金絲雀會(huì)吸入更多的空氣以及空氣中可能含有的有毒物質(zhì)。這樣,一旦金絲雀出了事,礦工就會(huì)迅速意識(shí)到礦井中的有毒氣體濃度過(guò)高,他們已經(jīng)陷入危險(xiǎn)之中,從而及時(shí)撤離。

??GCC會(huì)試著確定一個(gè)函數(shù)是否容易遭受棧溢出攻擊,并且自動(dòng)插入這種溢出檢測(cè)。實(shí)際上,對(duì)于前面的棧溢出展示,我們不得不用命令行選項(xiàng)“-fno- stack- protector”來(lái)阻止GCC產(chǎn)生這種代碼。當(dāng)不用這個(gè)選項(xiàng)來(lái)編譯echo函數(shù)時(shí),也就是允許使用棧保護(hù),得到下面的匯編代碼

/*void echo */
subq $24,%rsp Allocate 24 bytes on stack
movq  %fs:40,%rax  Retrieve canary 
movq %rax,8(%rsp) Store on stack
xorl %eax, %eax Zero out register 
movq %rsp, %rdi  Compute buf as %rsp 
call gets Call gets 
movq ‰rsp,%rdi Compute buf as %rsp
call puts Call puts 
movq 8(%rsp),%rax Retrieve canary 
xorq %fs:40,%rax Compare to stored value
je .L9  If =, goto ok 
call __stack_chk_fail Stack corrupted 
.L9
addq $24,%rsp Deallocate stack space 
ret

??這個(gè)版本的函數(shù)從內(nèi)存中讀出一個(gè)值(第4行),再把它存放在棧中相對(duì)于%rsp偏移量為8的地方。指令參數(shù)各fs:40指明金絲雀值是用段尋址( segmented addressing)從內(nèi)存中讀入的,段尋址機(jī)制可以追溯到80286的尋址,而在現(xiàn)代系統(tǒng)上運(yùn)行的程序中已經(jīng)很少見(jiàn)到了。將金絲雀值存放在一個(gè)特殊的段中,標(biāo)志為“只讀”,這樣攻擊者就不能覆蓋存儲(chǔ)金絲雀值。在恢復(fù)寄存器狀態(tài)和返回前,函數(shù)將存儲(chǔ)在棧位置處的值與金絲雀值做比較(通過(guò)第12行的xorq指令)。如果兩個(gè)數(shù)相同,xorq指令就會(huì)得到0,函數(shù)會(huì)按照正常的方式完成。非零的值表明棧上的金絲雀值被修改過(guò),那么代碼就會(huì)調(diào)用一個(gè)錯(cuò)誤處理例程。

??棧保護(hù)很好地防止了緩沖區(qū)溢出攻擊破壞存儲(chǔ)在程序棧上的狀態(tài)。通常只會(huì)帶來(lái)很小的性能損失。

限制可執(zhí)行代碼區(qū)域

??最后一招是消除攻擊者向系統(tǒng)中插入可執(zhí)行代碼的能力。一種方法是限制哪些內(nèi)存區(qū)域能夠存放可執(zhí)行代碼。在典型的程序中,只有保存編譯器產(chǎn)生的代碼的那部分內(nèi)存才需要是可執(zhí)行的。其他部分可以被限制為只允許讀和寫(xiě)。許多系統(tǒng)允許控制三種訪問(wèn)形式:讀(從內(nèi)存讀數(shù)據(jù))、寫(xiě)(存儲(chǔ)數(shù)據(jù)到內(nèi)存)和執(zhí)行(將內(nèi)存的內(nèi)容看作機(jī)器級(jí)代碼)。以前,x86體系結(jié)構(gòu)將讀和執(zhí)行訪問(wèn)控制合并成一個(gè)1位的標(biāo)志,這樣任何被標(biāo)記為可讀的頁(yè)也都是可執(zhí)行的。棧必須是既可讀又可寫(xiě)的,因而棧上的字節(jié)也都是可執(zhí)行的。已經(jīng)實(shí)現(xiàn)的很多機(jī)制,能夠限制一些頁(yè)是可讀但是不可執(zhí)行的,然而這些機(jī)制通常會(huì)帶來(lái)嚴(yán)重的性能損失。

總結(jié)

??計(jì)算機(jī)提供了多種方式來(lái)彌補(bǔ)我們犯錯(cuò)可能產(chǎn)生的嚴(yán)重后果,但是最關(guān)鍵的還是我們盡量減少犯錯(cuò)。例如,對(duì)于gets,strcpy等函數(shù)我們應(yīng)替換為 fgets,strncpy等。在數(shù)組中,我們可以將數(shù)組的索引聲明為size_t 類(lèi)型,從根本上防止它傳遞負(fù)數(shù)。此外,還可以在訪問(wèn)數(shù)組前來(lái)加上num<ARRAY_MAX語(yǔ)句來(lái)檢查數(shù)組的上界??傊?,要養(yǎng)成良好的編程習(xí)慣,這樣可以節(jié)省很多寶貴的時(shí)間。同時(shí)最后也推薦兩本相關(guān)書(shū)籍,代碼大全(第二版) 高質(zhì)量程序設(shè)計(jì)指南

??養(yǎng)成習(xí)慣,先贊后看!如果覺(jué)得寫(xiě)的不錯(cuò),歡迎關(guān)注,點(diǎn)贊,轉(zhuǎn)發(fā),謝謝!

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
C 程序中10個(gè)與內(nèi)存有關(guān)的常見(jiàn)錯(cuò)誤
IoT上的緩沖區(qū)溢出漏洞
64位和32位的寄存器和匯編的比較
C++代碼優(yōu)化Tips
C# 的快捷鍵匯總(一)
BSTR到底該怎么用?
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服