緩沖區(qū)溢出保護方法
【技術領域】
[0001] 本發(fā)明涉及計算機技術領域,具體涉及一種緩沖區(qū)溢出保護方法。
【背景技術】
[0002] 堆棧作為程序中必不可少的內(nèi)容,程序在運行時,內(nèi)存中會開辟出一塊連續(xù)的棧 空間,用于維護函數(shù)調(diào)用時所必須的上下文信息,包括舊的幀指針、返回地址、調(diào)用參數(shù)和 局部變量等。程序可以將上下文信息壓棧,也可以從棧頂彈出。然而緩沖區(qū)一旦分配完成, 大小和地址便固定下來。當使用緩沖區(qū)時,如果操作超出緩沖區(qū)邊界的區(qū)域,便可能會發(fā)生 棧緩沖區(qū)域溢出。緩沖區(qū)溢出攻擊包括棧溢出、堆溢出、格式化字符串攻擊等攻擊類型。其 防護手段包括靜態(tài)的數(shù)組邊界檢查、堆棧的不可執(zhí)行、動態(tài)的緩沖區(qū)溢出監(jiān)測以及庫函數(shù) 的安全增強等。而相比堆緩沖區(qū)溢出和格式化字符串攻擊的漏洞,棧緩沖區(qū)溢出漏洞仍占 多數(shù),且攻擊者利用棧緩沖區(qū)溢出漏洞的手段多樣化,攻擊更隱蔽。
[0003] 棧溢出一般會導致函數(shù)返回地址、棧幀指針等改變,進而導致程序控制流篡改、系 統(tǒng)宕機等。針對此問題,目前提出的普遍做法是通過在棧中添加棧保護(StackGuard)標簽 來保證棧的完整性、建立雙棧結構將控制流信息和數(shù)據(jù)流信息完全分離、棧幀指針加密等。
[0004] 但是,目前堆棧信息的保護大多都是基于緩沖區(qū)溢出攻擊中的某一種進行保護, 不能全面的解決緩沖區(qū)溢出問題。再者目前的雙棧結構等其在兼容性和性能方面仍然是一 個很大的不足,有時會導致性能等方面的大幅下降。
【發(fā)明內(nèi)容】
[0005] 本發(fā)明所要解決的技術問題是針對現(xiàn)有技術中存在上述缺陷,提供一種兼容安 全、高效、全面的緩沖區(qū)溢出保護方法。
[0006] 根據(jù)本發(fā)明,提供了一種緩沖區(qū)溢出保護方法,包括:根據(jù)原始棧形成一個備份 棧,其中備份棧備份了函數(shù)返回地址和堆棧幀指針,而且備份棧在調(diào)用函數(shù)入口處備份控 制流信息;在函數(shù)調(diào)用返回時通過比較原始棧與備份棧信息來判斷是否有溢出發(fā)生。
[0007] 優(yōu)選地,所有進程都有共享庫中代碼;在基礎庫鏈接過程中,不把所述共享庫拷貝 到輸出文件,而是使得所有進程共享一份它們用到的共享庫中的例程的拷貝。
[0008] 優(yōu)選地,通過設計一個庫來實現(xiàn)在調(diào)用函數(shù)入口處備份控制流信息。
[0009 ]優(yōu)選地,所述庫中定義了一個靜態(tài)數(shù)組用于保存控制流信息。
[0010]優(yōu)選地,所述庫中的函數(shù)實現(xiàn)棧的壓入和彈出操作,以及監(jiān)測到控制流信息被修 改時的處理機制。
[0011]優(yōu)選地,所述庫包括第一函數(shù)和第二函數(shù);其中第一函數(shù)在被編譯程序的每個函 數(shù)的入口處被調(diào)用,第一函數(shù)的輸入為當前函數(shù)的幀指針指向的內(nèi)存位置的內(nèi)容和返回地 址;第二函數(shù)在被編譯程序的每個函數(shù)的出口處被調(diào)用,其中第二函數(shù)的輸入為當前函數(shù) 的幀指針指向的內(nèi)存位置的內(nèi)容和返回地址。
[0012]優(yōu)選地,第一函數(shù)和第二函數(shù)被插入在目標函數(shù)的頭部和尾部的第一條指令前和 最后一條指令后。
[0013] 本發(fā)明提出的采用備份控制流信息方案的緩沖區(qū)溢出保護方法,既對堆棧中關鍵 的控制流信息做了保護,又保證了不同平臺的兼容性問題,并且也保證了程序的性能問題。
【附圖說明】
[0014] 結合附圖,并通過參考下面的詳細描述,將會更容易地對本發(fā)明有更完整的理解 并且更容易地理解其伴隨的優(yōu)點和特征,其中:
[0015]圖1示意性地示出了根據(jù)本發(fā)明優(yōu)選實施例的緩沖區(qū)溢出保護方法的流程圖。 [0016]圖2a和圖2b示意性地示出了根據(jù)本發(fā)明優(yōu)選實施例的緩沖區(qū)溢出保護方法采用 的備份控制流信息的示意圖。
[0017] 需要說明的是,附圖用于說明本發(fā)明,而非限制本發(fā)明。注意,表示結構的附圖可 能并非按比例繪制。并且,附圖中,相同或者類似的元件標有相同或者類似的標號。
【具體實施方式】
[0018] 為了使本發(fā)明的內(nèi)容更加清楚和易懂,下面結合具體實施例和附圖對本發(fā)明的內(nèi) 容進行詳細描述。
[0019] 本發(fā)明提出方案是對關鍵的控制流信息進行備份,在程序運行時比較備份值和原 始值來判斷是否有攻擊行為產(chǎn)生。
[0020] 具體地,圖1示意性地示出了根據(jù)本發(fā)明優(yōu)選實施例的緩沖區(qū)溢出保護方法的流 程圖。
[0021] 如圖1所示,根據(jù)本發(fā)明優(yōu)選實施例的緩沖區(qū)溢出保護方法包括:
[0022] 第一步驟S1:根據(jù)原始棧(例如圖2a所示的原始棧),形成一個備份棧(例如圖2b所 示的備份棧),其中備份棧備份了函數(shù)返回地址和堆棧幀指針,而且備份棧在調(diào)用函數(shù)入口 處備份控制流信息;
[0023] 第二步驟S2:在函數(shù)調(diào)用返回時通過比較原始棧與備份棧信息來判斷是否有溢出 發(fā)生。
[0024] 在本發(fā)明的【具體實施方式】中,可以通過設計一個庫來實現(xiàn)備份關鍵的控制流信 息。庫中定義了一個靜態(tài)數(shù)組__retarray保存控制流信息,庫中的函數(shù)實現(xiàn)棧的壓入和彈 出操作,以及監(jiān)測到控制流信息被修改時的處理機制。其主要函數(shù)實現(xiàn)示例可以如算法1和 算法2所示。
[0025] 下面給出具體的算法示例。
[0026] 備份函數(shù)入口處實現(xiàn)的算法具體實現(xiàn)算法如算法1:
[0027]
[0028] 備份函數(shù)出口處實現(xiàn)的算法具體如算法2:
[0029]
[0030]
[0031] 函數(shù)__retarray_p;rolog在被編譯程序的每個函數(shù)的入口處被調(diào)用,其輸入為當 前函數(shù)的幀指針指向的內(nèi)存位置的內(nèi)容和返回地址。__retarray_epilog函數(shù)在被編譯程 序的每個函數(shù)的出口處被調(diào)用。__retarray_epi1og函數(shù)輸入為當前函數(shù)的幀指針指向的 內(nèi)存位置的內(nèi)容和返回地址,將該輸入與數(shù)組_retarray中保存的內(nèi)容做比較,如果相同, 則表明堆棧中控制流信息未被篡改,否則有攻擊行為發(fā)生。
[0032] 本方法能夠以動態(tài)庫方式實現(xiàn),其中所有進程都有共享庫中代碼;基礎庫鏈接過 程中并不把共享庫拷貝到輸出文件,而是所有進程共享一份它們用到的共享庫例程的拷 貝,從而可以節(jié)省大量的存儲空間。而若某個進程修改了全局變量_retarray,則該進程獲 得該變量的一個副本,副本中保存了其對應變量的私有數(shù)據(jù)信息。這樣,即使是某個函數(shù)的 控制流信息被篡改,也不會影響其它函數(shù)對應保存的信息。因此,備份棧__ retarray不會有各進程之間沖突的問題。而攻擊者要想突破此種防御機制,必須同時修改 當前堆棧中的備份信息以及_retarray中對應的備份信息,這顯然增加了攻擊的難度。
[0033] 以具體程序為實例,左邊是程序設計人員正常編寫的程序。而右邊的程序則是編 譯器使用了控制流信息備份補丁后得到的代碼布局情況,其是對程序設計人員透明地在每 個函數(shù)的頭部和尾部的第一條指令前和最后一條指令后自動插入retarray_prolog和 retarray_epilog兩個函數(shù)調(diào)用。
[0035] 本發(fā)明的特征之一是:提出了部分控制流信息備份的方法,將原始堆棧中一些關 鍵的控制流信息保存在一個備份棧中。程序運行至每個函數(shù)的入口處,把棧中存放的當前 函數(shù)的返回地址和幀指針備份至內(nèi)存的另一區(qū)域。
[0036] 本發(fā)明的特征之二是:提出了用動態(tài)庫的方法實現(xiàn)該備份工作。所有進程都有共 享庫中代碼?;A庫鏈接過程中并不把共享庫拷貝到輸出文件,而是所有進程共享一份它 們用到的共享庫例程的拷貝,從而可以節(jié)省大量的存儲空間。
[0037]在本發(fā)明中,通過備份控制流信息,盡可能的避免了惡意程序對控制流信息的篡 改。同時,相比于雙棧與單棧結構,避免了對體系結構的改動,對兼容性和程序實現(xiàn)的復雜 度做了綜合權衡。在安全性方面,其對棧緩沖區(qū)的溢出的問題其可以對返回地址的直接攻 擊、幀指針的間接攻擊、指針篡改控制流等均能正確防護。在性能方面,動態(tài)庫方式的實現(xiàn) 在保證了性能損耗在5%以下。在兼容性方面,采用數(shù)組來保存?zhèn)浞菪畔?,故不會導致兼?性問題。
[0038]此外,需要說明的是,除非特別指出,否則說明書中的術語"第一"、"第二"、"第三" 等描述僅僅用于區(qū)分說明書中的各個組件、元素、步驟等,而不是用于表示各個組件、元素、 步驟之間的邏輯關系或者順序關系等。
[0039]可以理解的是,雖然本發(fā)明已以較佳實施例披露如上,然而上述實施例并非用以 限定本發(fā)明。對于任何熟悉本領域的技術人員而言,在不脫離本發(fā)明技術方案范圍情況下, 都可利用上述揭示的技術內(nèi)容對本發(fā)明技術方案作出許多可能的變動和修飾,或修改為等 同變化的等效實施例。因此,凡是未脫離本發(fā)明技術方案的內(nèi)容,依據(jù)本發(fā)明的技術實質對 以上實施例所做的任何簡單修改、等同變化及修飾,均仍屬于本發(fā)明技術方案保護的范圍 內(nèi)。
【主權項】
1. 一種緩沖區(qū)溢出保護方法,其特征在于包括: 根據(jù)原始棧形成一個備份棧,其中備份棧備份了函數(shù)返回地址和堆棧幀指針,而且備 份棧在調(diào)用函數(shù)入口處備份控制流信息; 在函數(shù)調(diào)用返回時通過比較原始棧與備份棧信息來判斷是否有溢出發(fā)生。2. 根據(jù)權利要求1所述的緩沖區(qū)溢出保護方法,其特征在于,所有進程都有共享庫中代 碼;在基礎庫鏈接過程中,不把所述共享庫拷貝到輸出文件,而是使得所有進程共享一份它 們用到的共享庫中的例程的拷貝。3. 根據(jù)權利要求1或2所述的緩沖區(qū)溢出保護方法,其特征在于,通過設計一個庫來實 現(xiàn)在調(diào)用函數(shù)入口處備份控制流信息。4. 根據(jù)權利要求3所述的緩沖區(qū)溢出保護方法,其特征在于,所述庫中定義了一個靜態(tài) 數(shù)組用于保存控制流信息。5. 根據(jù)權利要求3所述的緩沖區(qū)溢出保護方法,其特征在于,所述庫中的函數(shù)實現(xiàn)棧的 壓入和彈出操作,以及監(jiān)測到控制流信息被修改時的處理機制。6. 根據(jù)權利要求3所述的緩沖區(qū)溢出保護方法,其特征在于,所述庫包括第一函數(shù)和第 二函數(shù);其中第一函數(shù)在被編譯程序的每個函數(shù)的入口處被調(diào)用,第一函數(shù)的輸入為當前 函數(shù)的幀指針指向的內(nèi)存位置的內(nèi)容和返回地址;第二函數(shù)在被編譯程序的每個函數(shù)的出 口處被調(diào)用,其中第二函數(shù)的輸入為當前函數(shù)的幀指針指向的內(nèi)存位置的內(nèi)容和返回地 址。7. 根據(jù)權利要求6所述的緩沖區(qū)溢出保護方法,其特征在于,第一函數(shù)和第二函數(shù)被插 入在目標函數(shù)的頭部和尾部的第一條指令前和最后一條指令后。
【專利摘要】本發(fā)明提供了一種緩沖區(qū)溢出保護方法,包括:根據(jù)原始棧形成一個備份棧,其中備份棧備份了函數(shù)返回地址和堆棧幀指針,而且備份棧在調(diào)用函數(shù)入口處備份控制流信息;在函數(shù)調(diào)用返回時通過比較原始棧與備份棧信息來判斷是否有溢出發(fā)生。
【IPC分類】G06F21/56, G06F21/52
【公開號】CN105426752
【申請?zhí)枴緾N201510828343
【發(fā)明人】馬曉東, 謝汶兵, 漆鋒濱, 尉紅梅, 翟彥河, 陳茜
【申請人】無錫江南計算技術研究所
【公開日】2016年3月23日
【申請日】2015年11月24日