歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux綜合 >> 學習Linux >> 基於虛擬機的軟件保護技術

基於虛擬機的軟件保護技術

日期:2017/3/6 9:29:12   编辑:學習Linux

基於虛擬機的軟件保護技術


基於虛擬機的軟件保護技術


導讀基於虛擬機的軟件保護技術不確定是否首先由vmprotect提出,但vmprotect毫無疑問是將這項技術大力推廣至人所周知。現在基於虛擬機的軟件保護技術已經成為現代軟件安全防護的必備功能之一。

本文並不打算對vmprotect或其它某款軟件安全套件進行深入討論,而著眼於研究基於虛擬機的軟件保護技術的起源、思想和實現。

基於虛擬機的軟件保護技術基於虛擬機的軟件保護技術

現有軟件保護技術概述

傳統的軟件保護技術,根據針對對象不同,可分為反靜態調試和反動態調試兩大類。反靜態調試主要針對對象為反匯編器。反匯編器通過面向特定平台的反匯編引擎(如PC平台即為X86反匯編引擎),將編譯器生成的二進制文件還原成匯編代碼,有經驗的逆向工程師可以據此還原出算法等核心運算機制。反靜態調試主要是通過特定區段加密等方式,將核心信息保護起來,只在運行期才通過解密等算法動態還原,阻礙反匯編器靜態地將二進制文件還原成匯編碼。
反動態調試主要針對對象為調試器,由於經過靜態加密的二進制碼最終必須解密才能執行,因此通過Ollydbg等動態調試器仍然可以加以查看,反動態調試通過檢測調試器和屏蔽調試端口等各種反調試技術阻止逆向工程師通過調試器跟蹤軟件進程的運行情況,使得軟件的運行時狀況始終保持處於黑盒狀態。
被動型軟件保護概念上述兩種保護方案均采取主動出擊的策略,意圖“御敵於國之外”,中心思想是一個“擋字”,阻止逆向工程是窺視軟件內部機理,但盾與矛的對抗總是無休止的,並沒有任何一種主動型軟件保護手段能真正徹底阻斷逆向工程,因此另一種“以人為本”的被動型軟件保護技術開始走向斗爭舞台的中央。
被動型軟件保護手段基於一個假設,即逆向工程師已經通過各種辦法突破了主動型軟件保護措施,可以隨心所欲地觀察一切,此時“擋”已經擋不住了,只能采取“藏”的策略,通過提高核心代碼的隱蔽性來提高逆向工程在閱讀反匯編代碼階段的時間成本投入,間接起到軟件保護的效果。被動型軟件保護手段具體實現方式主要有亂序和混淆。
亂序是指在在程序執行流中添加跳轉指令,如jmp,通過這些跳轉指令將一個從上至下執行的完整代碼塊切分成若干執行先後順序不一致的代碼片段。亂序能夠一定程度上增加反匯編代碼的閱讀難度,但若只是簡單地植入無條件跳轉很容易被識別和去除,因此工業級的保護產品往往通過采用條件跳轉的方式增加識別難度。
基於虛擬機的軟件保護技術基於虛擬機的軟件保護技術
混淆是指通過加入無意義代碼(又稱為花指令或垃圾代碼)或者有意義代碼,增加反匯編碼的理解難度。俗話說要藏好一棵樹,最好的地點一定是森林,混淆技術就是通過代碼膨脹增加反匯編代碼的總量,為隱藏核心代碼構造出一片代碼“森林”。早期增加的混淆代碼為無意義代碼,實現類nop操作的執行效果,如push指令和pop指令搭配使用,但這類代碼無實際意義,去除後並不會對軟件運行產生影響,因此有經驗的逆向工程師往往會首先去除這些無意義的混淆代碼才開始進行反匯編碼的閱讀工作,使混淆技術失去效果。為了確保混淆代碼不被去除,工業級的保護產品更傾向於采用有意義的混淆代碼,核心思想是等價替換,通過多條指令實現核心代碼中一條指令的效果,如最簡單的賦值指令moveax,3可以替換成xoreax,eax;inceax;inceax;inceax這四條指令,操作效果一樣,但指令數量翻了兩番。被動型軟件保護技術究竟能否對軟件安全起到實質性的作用,業界一直存在爭論。反對的觀點主要集中在認為被動型軟件保護技術只是提高了閱讀反匯編代碼的難度和數量,讓人“眼花”而已,並沒有任何實質性的效果。本文認為,軟件安全不該簡單理解成讓軟件絕對安全不可攻破,而實際該是攻方與防方、投入與產出的反復博弈的過程,攻方人力的投入自然也是成本之一。一個人單位時間內閱讀代碼的數量是固定的,因此,提高了閱讀反匯編代碼的難度和數量,也就提高了閱讀反匯編代碼的時間,提高了攻方人力成本的投入,對軟件安全是有切實效果的。

虛擬機軟件保護技術虛擬機軟件保護的思想

虛擬機軟件保護技術是被動型軟件保護技術的分支,具體來說是添加有意義的混淆代碼的一種變型使用。
虛擬機技術目前在軟件領域應用廣泛,根據應用層級不同,基本可分為硬件抽象層虛擬機、操作系統層虛擬機和軟件應用層虛擬機。用於保護軟件安全的虛擬機屬於軟件應用層虛擬機,同層的虛擬機還包括高級語言虛擬機,如java程序語言運行環境jvm和.net程序語言運行環境CLR,後者采用虛擬機的原因是便於移植,因此編譯器沒有直接生成可直接在機器上執行的nativecode,而改為生成中間代碼byte-code,再通過在不同機器環境下安裝對應版本的虛擬機對byte-code進行解釋執行,從而實現跨平台運行。
用於保護軟件安全的虛擬機采用類似的流程。虛擬機保護軟件首先會對被保護的目標程序的核心代碼進行“編譯”——需要注意的是,這裡被編譯的不是源文件,而是二進制文件——並生成效果等價的byte-code,然後為軟件添加虛擬機解釋引擎。用戶最終使用軟件時,虛擬機解釋引擎會讀取byte-code,並進行解釋執行,從而實現用戶體驗完全一致的執行效果。

虛擬機軟件保護的實現

編譯生成byte-code
要設計一套虛擬機保護軟件,首先要設計一套虛擬機指令,也即是byte-code的指令集表,生成byte-code的過程,實際是將原始機器指令流等價轉譯成虛擬機指令流的過程。

虛擬機指令集表應滿足以下兩條設計原則:
第一條設計原則是虛擬機指令集表與原始機器指令集表越正交越好,安全系數越高。最壞的情況是虛擬機指令集表與原始機器指令集表為一一對應的關系,采用這種指令集的虛擬機保護程序安全系數趨近與零,對於逆向工程師而言只需要進行簡單的換算,即可還原出原始代碼。
另一條設計原則是應盡可能地具備圖靈完備性,能夠完整地表達出原始機器指令的所有可能表達。圖靈完備性越好,則虛擬機保護引擎的保護的覆蓋范圍越廣,健壯性越高。理想狀態下,虛擬機指令集應完整地實現對原始機器指令集的等價替代,需要完全滿足圖靈完備性。但實際上完整替代的代價過高甚至不太可能實現,如x86指令集的FCLEX、FPTAN等指令,仿真難度較高,且核心代碼使用這類指令的可能性很小,綜合效費比考慮,虛擬機指令集通常並不涵蓋這些“生僻”指令。對於不能仿真的指令,可以采取退出虛擬機執行,獲取執行結果再進入虛擬機的方法解決。

解釋執行byte-code
在軟件運行時,編譯產生的Byte-code由內嵌入軟件可執行文件中的虛擬機解釋引擎,采用讀取-分派的方式解釋執行。
虛擬機解釋引擎分為兩大部分,分別為Dispatcher和handle。

基於虛擬機的軟件保護技術基於虛擬機的軟件保護技術

Dispatcher的中文字面意思為“分派器”,相當於虛擬機解釋引擎的CPU,負責讀取Byte-code,並指派對應的handle進行解釋執行。Handle的中文字面意思為“處理”,實際作用為虛擬機指令通過平台nativecode(如PC平台即為x86指令)的實現。Handle的數量與虛擬機指令集的指令數量是一致的。
虛擬機的進入和退出問題
軟件保護虛擬機與高級語言虛擬機並不完全一樣,主要體現在高級語言虛擬機由始至終均在虛擬機環境下執行,但軟件保護虛擬機必須經歷本地環境與虛擬機環境的切換,為了保證執行結果的一致性,必須要求虛擬機環境能夠正確獲取和還原本地環境的執行上下文。較為便捷的方法是采用堆棧機模型,即虛擬機基於堆棧來進行數據操作。進入虛擬機前,先將本地環境壓棧,虛擬機直接以棧地址執行指令流操作,退出虛擬機後,再一一出棧,從而保證了上下文在不同執行環境的無縫切換。

結語

基於虛擬機的軟件保護技術可以大大增加了逆向工程還原代碼的難度,一套設計良好的軟件保護虛擬機能夠顯著增加代碼還原所需的時間,從而抬高了逆向工程的成本,達到軟件保護的效果。但采用虛擬機並非有百利而無一害,和高級語言虛擬機一樣,軟件保護虛擬機同樣面臨會導致執行效率降低的問題,安全和效率總是處於相生相斥的關系,具體偏重只能根據生產環節的要求具體權衡。

原文來自:http://www.weixianmanbu.com/article/125.html

本文地址:http://www.linuxprobe.com/software-protection-virtual.html


http://xxxxxx/Linuxjc/1144506.html TechArticle

Copyright © Linux教程網 All Rights Reserved