1. <nobr id="easjo"><address id="easjo"></address></nobr>

      <track id="easjo"><source id="easjo"></source></track>
      1. 
        

      2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
      3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>
          貴州做網站公司
          貴州做網站公司~專業!靠譜!
          10年網站模板開發經驗,熟悉國內外開源網站程序,包括DEDECMS,WordPress,ZBlog,Discuz! 等網站程序,可為您提供網站建設,網站克隆,仿站,網頁設計,網站制作,網站推廣優化等服務。我們專注高端營銷型網站,企業官網,集團官網,自適應網站,手機網站,網絡營銷,網站優化,網站服務器環境搭建以及托管運維等。為客戶提供一站式網站解決方案?。?!

          C語言緩沖區溢出詳解

          來源:互聯網轉載 時間:2024-01-29 08:25:33

          1 引言

          “緩沖區溢出”對現代操作系統與編譯器來講已經不是什么大問題,但是作為一個合格的 C/C++ 程序員,還是完全有必要了解它的整個細節。

          計算機程序一般都會使用到一些內存,這些內存或是程序內部使用,或是存放用戶的輸入數據,這樣的內存一般稱作緩沖區。簡單的說,緩沖區就是一塊連續的計算機內存區域,它可以保存相同數據類型的多個實例,如字符數組。而緩沖區溢出則是指當計算機向緩沖區內填充數據位數時超過了緩沖區本身的容量,溢出的數據覆蓋在合法數據上。

          2 C/C++中內存分配

          任何一個源程序通常都包括靜態的代碼段(或者稱為文本段)和靜態的數據段,為了運行程序,操作系統首先負責為其創建進程,并在進程的虛擬地址空間中為其代碼段和數據段建立映射。但是只有靜態的代碼段和數據段是不夠的,進程在運行過程中還要有其動態環境。

          一般說來,默認的動態存儲環境通過堆棧機制建立。所有局部變量及所有按值傳遞的函數參數都通過堆棧機制自動分配內存空間。如下圖。

          程序在內存的映射

          • 棧區(stack):由編譯器自動分配與釋放,存放為運行時函數分配的局部變量、函數參數、返回數據、返回地址等。其操作類似于數據結構中的棧。
          • 堆區(heap):一般由程序員自動分配,如果程序員沒有釋放,程序結束時可能有OS回收。其分配類似于鏈表。
          • 全局區(靜態區static):數據段,程序結束后由系統釋放。全局區分為已初始化全局區(data),用來存放保存全局的和靜態的已初始化變量和未初始化全局區(bss),用來保存全局的和靜態的未初始化變量。
          • 常量區(文字常量區):數據段,存放常量字符串,程序結束后有系統釋放。
          • 代碼區:存放函數體(類成員函數和全局區)的二進制代碼,這個段在內存中一般被標記為只讀,任何對該區的寫操作都會導致段錯誤(Segmentation Fault)。

          需要特別注意的是,堆(Heap)和棧(Stack)是有區別的,很多程序員混淆堆棧的概念,或者認為它們就是一個概念。簡單來說,它們之間的主要區別可以表現在如下五個方面。

          分配和管理方式不同

          堆是動態分配的,其空間的分配和釋放都由程序員控制。也就是說,堆的大小并不固定,可動態擴張或縮減,其分配由malloc()等這類實時內存分配函數來實現。當進程調用malloc等函數分配內存時,新分配的內存就被動態添加到堆上(堆被擴張);當利用free等函數釋放內存時,被釋放的內存從堆中被剔除(堆被縮減)。

          而棧由編譯器自動管理,其分配方式有兩種:靜態分配和動態分配。靜態分配由編譯器完成,比如局部變量的分配。動態分配由alloca()函數進行分配,但是棧的動態分配和堆是不同的,它的動態分配是由編譯器進行釋放,無需手工控制。

          申請的大小限制不同

          棧是向低地址擴展的數據結構,是一塊連續的內存區域,棧頂的地址和棧的最大容量是系統預先規定好的,能從棧獲得的空間較小。

          堆是向高地址擴展的數據結構,是不連續的內存區域,這是由于系統是由鏈表在存儲空閑內存地址,自然堆就是不連續的內存區域,且鏈表的遍歷也是從低地址向高地址遍歷的,堆的大小受限于計算機系統的有效虛擬內存空間,

          由此空間,堆獲得的空間比較靈活,也比較大。在 32 位平臺下,VC6 下默認為 1M,堆最大可以到 4G;

          申請效率不同

          • 棧由系統自動分配,速度快,但是程序員無法控制。
          • 堆是有程序員自己分配,速度較慢,容易產生碎片,不過用起來方便。

          產生碎片不同

          對堆來說,頻繁執行malloc或free勢必會造成內存空間的不連續,形成大量的碎片,使程序效率降低;而對棧而言,則不存在碎片問題。

          內存地址增長的方向不同

          • 堆是向著內存地址增加的方向增長的,從內存的低地址向高地址方向增長;
          • 棧的增長方向與之相反,是向著內存地址減小的方向增長,由內存的高地址向低地址方向增長。

          假設一個程序的函數調用順序為:主函數main調用函數func1,函數func1調用函數func2。當這個程序被操作系統調入內存運行時,其對應的進程在內存中的映射結果如下圖所示

          例子中的內存映射

          進程的棧是由多個棧幀構成的,其中每個棧幀都對應一個函數調用。當調用函數時,新的棧幀被壓入棧;當函數返回時,相應的棧幀從棧中彈出。由于需要將函數返回地址這樣的重要數據保存在程序員可見的堆棧中,因此也給系統安全帶來了極大的隱患。

          當程序寫入超過緩沖區的邊界時,就會產生所謂的“緩沖區溢出”。發生緩沖區溢出時,就會覆蓋下一個相鄰的內存塊,導致程序發生一些不可預料的結果:也許程序可以繼續,也許程序的執行出現奇怪現象,也許程序完全失敗或者崩潰等。

          緩沖區溢出

          對于緩沖區溢出,一般可以分為4種類型,即棧溢出、堆溢出、BSS溢出與格式化串溢出。其中,棧溢出是最簡單,也是最為常見的一種溢出方式。

          沒有保證足夠的存儲空間存儲復制過來的數據

          void?function(char?*str)?{???char?buffer[10];???strcpy(buffer,str);}

          上面的strcpy()將直接把str中的內容copybuffer中。這樣只要str的長度大于 10 ,就會造成buffer的溢出,使程序運行出錯。存在象strcpy這樣的問題的標準函數還有strcat(),sprintf(),vsprintf(),gets(),scanf()等。對應的有更加安全的函數,即在函數名后加上_s,如scanf_s()函數。

          • 嚴格檢查輸入長度和緩沖區長度。
          • 常見的高危函數

          函數

          嚴重性

          防范手段

          gets()

          最危險

          使用 fgets(buf, size, stdin)

          strcpy()

          很危險

          改為使用 strncpy()

          strcat()

          很危險

          改為使用 strncat()

          sprintf()

          很危險

          改為使用snprintf(),或者使用精度說明符

          scanf()

          很危險

          使用精度說明符,或自己進行解析

          sscanf()

          很危險

          使用精度說明符,或自己進行解析

          fscanf()

          很危險

          使用精度說明符,或自己進行解析

          vfscanf()

          很危險

          使用精度說明符,或自己進行解析

          vfscanf()

          很危險

          改為使用 vsnprintf(),或者使用精度說明符

          vscanf()

          很危險

          使用精度說明符,或自己進行解析

          vsscanf()

          很危險

          使用精度說明符,或自己進行解析

          streadd()

          很危險

          使用精度說明符,或自己進行解析

          整數溢出

          1. 寬度溢出:把一個寬度較大的操作數賦給寬度較小的操作數,就有可能發生數據截斷或符號位丟失
          #include<stdio.h>int?main(){??signed?int?value1?=?10;??usigned?int?value2?=?(unsigned?int)value1;}
          1. 算術溢出,該程序即使在接受用戶輸入的時候對a、b的賦值做安全性檢查,a+b 依舊可能溢出:
          #include<stdio.h>int?main(){??int?a;??int?b;??int?c=a*b;??return?0;}

          數組索引不在合法范圍內

          enum?{TABLESIZE?=?100};int?*table?=?NULL;int?insert_in_table(int?pos,?int?value)?{??if(!table)?{????table?=?(int?*)malloc(sizeof(int)?*TABLESIZE);??}??if(pos?>=?TABLESIZE)?{????return?-1;??}??table[pos]?=?value;??return?0;}

          其中:posint類型,可能為負數,這會導致在數組所引用的內存邊界之外進行寫入,可以將pos類型改為size_t避免

          空字符錯誤

          例如:

          //錯誤char?array[]={'0','1','2','3','4','5','6','7','8'};//正確的寫法應為:char?array[]={'0','1','2','3','4','5','6','7','8',’’};//或者char?array[11]={'0','1','2','3','4','5','6','7','8','9’};

          更多案例可以go公眾號:C語言入門到精通

          網絡推廣與網站優化公司(網絡優化與推廣專家)作為數字營銷領域的核心服務提供方,其價值在于通過技術手段與策略規劃幫助企業提升線上曝光度、用戶轉化率及品牌影響力。這...

          在當今數字化時代,公司網站已成為企業展示形象、傳遞信息和開展業務的重要平臺。然而,對于許多公司來說,網站建設的價格是一個關鍵考量因素。本文將圍繞“公司網站建設價...

          在當今的數字化時代,企業網站已成為企業展示形象、吸引客戶和開展業務的重要平臺。然而,對于許多中小企業來說,高昂的網站建設費用可能會成為其發展的瓶頸。幸運的是,隨...

          卡特大亂斗最強出裝?不祥之刃-卡特里娜颶風的最佳方式發揮在無序的斗爭:1。游戲順序:造谷人的鞋子,魔鬼的擁抱,中亞的虛空之杖,莫雷羅的秘籍2。游戲理念:山谷制造者是游戲中唯一能將總傷害轉化為真實傷害的裝備。這對卡特來說非常有利可圖。如果你想問,你可以選擇惡魔的支持,以提高你的生存能力。如果你想造成高傷害,你可以用破舊來代替??ㄌ卮髞y斗出裝?裝備1:黑暗收割者巫妖金體]提供高傷害并提高移動速度。巫妖...

          正能量的歌一直深得人心汪峰-《英雄》北京國安球隊隊歌,聽見這首歌情況下你是不是覺得心潮澎湃?是不是有一種想要去開辟大場面的想法?也許和平時期獲得一場比賽也是英雄。國安隊歌歌詞誰知道???漢化版綠茵場上叫喊著姓名 翠綠色影子也是我們的大牌明星 向著未來 噢 朝著全球 去拼搏大家憧憬的殊榮 獲勝始終屬于你 北京國安永遠爭第一 喔噢…… 北京國安 我們永遠支持你 噢…… 北京國安 大家永遠熱愛你 綠茵場上...

          360搶票王還可以搶票嗎?30票搶票王還能用。你可以試試。30搶票提供自動識別驗證碼、預約提醒、自動刷票等功能。搶到火車票的成功率翻倍,幫你買一張回家的火車票??梢酝ㄟ^驗證碼自動識別,自動放票。不過我每次買票都是用12306APP,是官方的搶票軟件,不會有第三方費用。如何用360搶票王搶下鋪火車票?打開軟件后,點擊右上角的“類型”,選擇“下鋪火車票”。30搶票王是360推出的全新搶票工具。是在常用...

          TOP
          国产初高中生视频在线观看|亚洲一区中文|久久亚洲欧美国产精品|黄色网站入口免费进人
          1. <nobr id="easjo"><address id="easjo"></address></nobr>

              <track id="easjo"><source id="easjo"></source></track>
              1. 
                

              2. <bdo id="easjo"><optgroup id="easjo"></optgroup></bdo>
              3. <track id="easjo"><source id="easjo"><em id="easjo"></em></source></track><option id="easjo"><span id="easjo"><em id="easjo"></em></span></option>