糜嫻雅 張怡 王寶生 國防科學技術大學
二進制軟件防篡改技術研究
糜嫻雅 張怡 王寶生 國防科學技術大學
隨著軟件安全性問題日益嚴重,軟件防篡改技術作為軟件保護的重要手段之一,越來越得到國內外研究者的重視。本文首先介紹軟件破解與保護的基本概念,針對軟件防篡改的主要目標,即能夠準確地檢測到正常功能之外的對程序進行的異常修改行為;對這種修改行為進行恰當的、有效的反應,重點介紹了幾種基于“檢測-響應”的二進制軟件防篡改技術,對其具體實現方法進行分類和總結,詳細分析和討論各類方法的優劣和局限性,提出了一套評價體系,并展望了軟件防篡改技術的發展前景,提出了自己的見解。
軟件保護;防篡改;檢測-響應
隨著軟件破解技術的發展,軟件安全性問題日益突出,保護軟件知識產權成為一個越來越艱巨的任務。攻擊者獲取軟件副本后,借助一些工具,通過技術手段可以輕易地理解和修改二進制代碼,從而達到破解軟件、非法使用的目的。二進制軟件防篡改技術作為軟件保護的重要方法之一,越來越得到國內外研究者的重視。本文研究了防篡改技術的基本原理和實現方法,對當前主流的防篡改技術進行分析和評價,并就該技術的應用和發展前景提出見解。
1.1 軟件篡改的實現方法
軟件篡改通常發生在攻擊者對代碼進行有效分析之后,具體說來有三種實現方法:(1)在可執行文件運行之前,刪掉其中的一些代碼,同時/或者往其中加一些代碼;(2)從正在運行的程序中,刪掉一些代碼,同時/或者往其中加入一些代碼;(3)借助模擬器、調試器或修改過的操作系統等工具,影響程序運行時的行為。其中(1)屬于靜態篡改,即直接修改二進制代碼,原代碼不會進入內存。(2)、(3)屬于動態篡改,即邊運行邊篡改,原代碼要進入內存,與調試的原理比較相似。
1.2 防篡改技術的主要目標

圖1 一個完整的防篡改系統示意圖
防篡改技術的主要目標在于檢測對程序的修改行為并做出相應的反應,因此其重要的技術原則有兩條:(1)能夠準確地檢測到正常功能之外的對程序進行的異常修改行為;(2)對這種修改行為進行恰當的、有效的反應。目前常見的軟件防篡改實現方法基本上都是基于這兩條原則實現的,即“檢測-響應”機制。從概念上來說,一個完整的防篡改系統應該是由CHECK和RESPOND兩個函數組成,如圖1所示,CHECK函數用來測試異常修改行為是否發生并返回結果,而RESPOND函數則根據CHECK函數的返回結果來判斷是否觸發對篡改行為的響應。
防篡改的具體實現方法有基于源代碼和基于二進制代碼兩種,由于源代碼方法有一定的局限性,本文主要研究基于二進制代碼的軟件防篡改技術。
根據CHECK和RESPOND函數的實現思想不同,當前主流的軟件防篡改實現方法可以分為4種,分別是:(1)基于保護網絡的防篡改方法,(2)基于Oblivious Hashing的防篡改方法,(3)遠程防篡改方法,以及(4)基于監測運行環境的防篡改方法。
2.1 保護網絡
Hoi Chang建立了一種由稱之為guards的代碼片段組成的保護網絡[1],guards分為兩類,一類是校驗和代碼,用來計算一段程序的校驗和并驗證完整性,即檢查是否被篡改。一旦發現被篡改,校驗和代碼會做出反應,觸發一定的行為,比如使軟件無法繼續使用、中斷程序等等,即檢查完整性功能。另一類是修復代碼,用來將被破壞的代碼和數據恢復到原來的樣子,具體方法是在別處存放該段代碼的原始備份,一旦被篡改則原樣復制過來,即自治愈功能。
2.2 Oblivious Hashing
實際上Hoi Chang的保護網絡所運用的是防篡改技術中非常普遍的一種方法:自監測原理,基本的思想就是計算某一代碼區域的hash值,并根據這個值做出反應。可以把hash值作為程序中將要進行的算數運算中的一部分數據,或者把hash值用在其他變量地址的計算上。然而,上述自監測算法有兩個根本性缺陷:(1)讀取自己代碼段的操作很容易被檢測出來,即算法隱蔽性不高;(2)只檢查代碼正確性,攻擊者可以修改運行時的數據來影響程序行為,比如使用調試器,在某個關鍵函數返回之前修改其返回值,即不能抗動態篡改。
由此產生了另一種防篡改思想:oblivious hashing[2],即“易遭忽視的hashing”,因為此方法中hash是作為軟件的一部分在正常的計算過程中被計算出來的,攻擊者很容易忽視它。圖2顯示了這種方法的基本原理,即通過結合源代碼中的指令和內存中的指令來計算hash值。
Y.Chen提出了一種巧妙的方法[3],直接在源碼中插入了hash計算代碼,根據變量的值和控制流控制語句輸出結果計算hash。它不記錄程序trace,而是往程序中插入相關代碼,計算trace的hash,來監測變量的改變和控制流執行情況。可以通過調整所插入的,用以計算hash的代碼數量來調和性能開銷和保護級別之間的矛盾。

圖2 通過內存中的指令和源代碼指令結合計算hash值
Mattias Jacob和Mariusz H.Jakubowski提出了另一種算法[3]。x86體系結構使用變長指令編碼方式且指令無需對齊,可以利用這兩個特性,把指令相互重疊,相互重疊的指令甚至可以屬于兩個不同的基本塊。這個算法就是通過重疊基本塊中的x86指令進行防篡改,當一個基本塊執行的時候,另一個基本塊的hash就被它“順便”算了出來。這一技術的優點在于,計算hash不需要顯式地讀取代碼,所以內存復制的攻擊方法對這個是無效的。這個算法的缺點是,無法預計監測代碼的及時性。
本節所闡述的方法的根本原理在于,運行時檢查程序中使用的數據值是否在正常的取值范圍之內,程序的控制流是否沿著一個合理的路徑流動。
2.3 遠程防篡改
遠程防篡改的思想是,將想要保護的程序C運行在攻擊者控制下的不可信主機(客戶端)上,客戶端必須和開發者的主機(服務器)上一個可信的程序S保持通信。除了向客戶端提供服務,服務器還必須對C可能遭到的篡改進行監測和響應。
Xiangyu Zhang把程序拆成兩個部分[4],一個是可以放在客戶端中運行的公開部分,另一個是放在服務器里運行的隱藏部分。此算法通過只考慮標量數據(處理數組和鏈式結構數據的函數全部放在客戶端中)和確保客戶端和服務器處于同一個局域網中這兩個方法來解決網絡延遲和帶寬這兩個問題。
Christian Collberg將反分析和防篡改的方法相結合,具體說來是將反靜態分析的自修改代碼的思想運用在了這種遠程防篡改的機制上。圖3顯示了這種遠程防篡改方法的運行原理。通過經常變化客戶端程序中的代碼,使它難以分析。理想情況下,攻擊者將會發現客戶端程序中的代碼變化太快,以至于在他完成分析并對當前的客戶端程序進行修改之前,服務器又發了一個新的程序過來。然而,這個思路雖然很好,卻還僅僅停留在理論上,目前還沒有已知系統實現了這個通過不斷改變代碼進行防篡改的想法。

圖3 Christian Collberg的遠程防篡改方法示意圖
2.4. 監測運行環境
對于使用了自監測原理的防篡改方法,攻擊者早已形成了與之對應的攻擊方法。攻擊有兩種方法:(1)想辦法找到程序中的監測代碼或相應代碼,然后刪掉;(2)從外部進行攻擊,即修改程序執行的環境。
Glen Wurster提出了一種攻擊自hash算法,該算法的關鍵點在于,基于hash的防篡改算法中,代碼會被以兩種形式訪問:①當被執行時作為代碼,②當計算hash時作為數據。當把代碼當作數據讀取的時候,應該獲得未經修改的代碼,這可以保證代碼hash值不變;當執行代碼時,應執行修改后的代碼。此方法將同一個虛擬內存地址分別映射到兩個不同的物理內存地址上:如果被訪問的是代碼,則映射其中一個地址;如果被訪問的是數據,則映射到另一個地址上。對防篡改的攻擊有以下三個步驟:i.把程序P復制一份,復制品稱為;ii.對P進行修改,將其制成破解版;iii.修改操作系統的內核K,使計算機在讀取數據時從中讀取,而讀取代碼時則從中讀取。這一攻擊的具體實現方式有賴于具體的處理器型號和操作系統中內存管理模塊的設計方式。
為了應對這種攻擊,Jonathon Giffin提出了一種思路:向程序中加入新的代碼,監測程序是否運行在一個可信的環境中。他使用自修改代碼實現這種對抗攻擊的保護方法,如果程序監測到自己運行在一個修改只會作用于數據而不會影響代碼的系統中,它就會調用正常的篡改響應代碼。
3.1 小結
綜上所述,可以總結出5種能使程序變得難以修改的基本方法:
(1)向程序中加入新的代碼,監測程序中的代碼是否遭到了修改。Hoi Chang的保護網絡算法使用了這種方法。
(2)向程序中加入新的代碼,監測程序是否運行在一個可信的環境中。Jonathon Giffin的環境監測算法使用了這種思想。
(3)運行時檢查程序中使用的數據值是否在正常的取值范圍之內,程序的控制流是否沿著一個合理的路徑流動。Oblivious Hashing一節中的兩種算法使用了這種思想。
(4)遠程防篡改:把程序割裂成兩個部分,其中一個部分可以運行在服務器或者抗篡改硬件中,以避免被攻擊者修改。Xiangyu Zhang的拆分函數方法使用了這種思想。
(5)使用代碼混淆算法使攻擊者難以理解程序,因而也就難以篡改程序。Christian Collberg的自修改代碼機制使用了這種方法。
3.2 評價體系
在軟件防篡改技術研究領域中,尚無被普遍接受的評價體系。本文借鑒ChristianCollberg提出的代碼混淆的評價定義,建立了一套防篡改適用的評價標準,主要從防篡改強度、開銷、隱蔽性三個方面對上述防篡改實現方法作定性分析。
防篡改強度 表示該算法對抗攻擊者進行篡改的效果,可分為抗靜態篡改和抗動態篡改兩個方面。開銷分為空間開銷和性能開銷兩個方面,空間開銷包括代碼增加的大小、對于硬件和其他環境條件的需求等;性能開銷主要關注增加保護代碼之后程序運行時間的增加。隱蔽性表示該算法是否容易被攻擊者發現并進行篡改攻擊。
Hoi Chang的保護網絡方法有一個非常好的特性就是其提供的安全性可以由我們自己隨意調節,具體說來,就是通過調整保護代碼的數量和防御圖的復雜度來做到這一點。遠程防篡改方法從理論上來說,對于動態篡改的抵抗效果是非常好的。然而,Xiangyu Zhang的拆分函數方法顯然對服務器端的計算能力有很高的要求,對網絡實時帶寬的要求也比較高,因此實現成本是很高的。在性能開銷方面,如果硬件條件不夠好,會造成較大的延遲。此方法的性能開銷往往依賴于有多少代碼存放在服務器中。
監測運行環境的實現實際上是自修改代碼的一種應用。對于以內存復制為主的動態篡改方式,這種方法效果還是比較明顯的。據該算法的作者估計,在最壞的情況下將會導致一個與輕量級的系統調用近似的開銷。
通過對當前主流軟件防篡改技術的介紹,可以看出基本上沒有突破“檢測-響應”機制的框架。然而,響應部分往往是整個防篡改機制中的弱點,大部分攻擊防篡改的破解技術以此作為突破口,一旦攻破,會使整個防篡改機制失去功效。另外,當前軟件破解技術的主流傾向于將防篡改技術與其他軟件反破解技術進行結合。如防篡改技術與代碼混淆技術結合,增加“檢測-響應”機制的隱蔽性;防篡改技術與軟件水印技術結合,由于水印技術中的完整性驗證要求軟件遭到修改后水印即被破壞,實際上與防篡改技術的原理有相通之處,如何將二者結合亦是一項有意義的課題;總而言之,將防篡改技術與其他軟件保護技術相結合能夠大大增加軟件保護的力度。
[1] Chang H,Atallah M J.Protecting software by guards[M]//Security and privacy in digital rights management.Springer Berlin Heidelberg,2002:160-175.
[2] Y.Chen,R.Venkatesan,M.Cary,R.Pang,S.Sinha,and M. Jakubowski.Oblivious hashing:A stealthy software integrity verification primitive.In 5th Information Hiding Workshop(IHW),pages 400-414,October 2002.Springer LNCS 2578.
[3] Mattias Jacob,Mariusz H.Jakubowski,and Ramarathnam Venkatesan.Towards integral binary execution:implementing oblivious hashing using overlapped instruction encodings.In Proceedings of the 9th workshop on Multimedia & Security,pages 129-140,New York,2007.ACM
[4] Xiangyu Zhang and Rajiv Gupta.Hiding program slices for software security.In CGO'03: Proceedings of the International Symposium on code Generation and Optimization, pages 325-336, Washington,DC,2003.IEEE.