• 
    

    
    

      99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看

      ?

      基于底層虛擬機(jī)的標(biāo)識(shí)符混淆方法

      2022-08-24 06:30:36田大江李成揚(yáng)黃天波文偉平
      計(jì)算機(jī)應(yīng)用 2022年8期
      關(guān)鍵詞:標(biāo)識(shí)符程序函數(shù)

      田大江,李成揚(yáng),黃天波,文偉平

      (北京大學(xué)軟件與微電子學(xué)院,北京 102600)

      0 引言

      軟件保護(hù)涉及政府、企業(yè)和個(gè)人的利益,盡管從20 世紀(jì)80 年代[1]至今已經(jīng)出現(xiàn)了眾多保護(hù)技術(shù),包括軟件防篡改[2]、代碼混淆[3]、軟件多樣性[4]等,但軟件保護(hù)仍是當(dāng)今時(shí)代極具挑戰(zhàn)的問題之一。商業(yè)軟件聯(lián)盟(Bussiness Software Alliance,BSA)2018 年發(fā)布的全球軟件研究報(bào)告表明,個(gè)人計(jì)算機(jī)領(lǐng)域中使用的盜版軟件高達(dá)37%,造成全球公司近3 590 億美元損失的同時(shí),致使用戶數(shù)據(jù)處于易被竊取的危險(xiǎn)狀態(tài)。

      源于軟件保護(hù)的需求,代碼混淆在20 世紀(jì)90 年代被提出用于保護(hù)Java 代碼,增大軟件逆向分析的難度,進(jìn)而保護(hù)代碼的核心知識(shí)產(chǎn)權(quán),避免泄露用戶的隱私數(shù)據(jù)。因其在安全性方面低開銷、高回報(bào)[5]的特性,在商業(yè)軟件中得到廣泛的使用[6]。雖然Barak 等[7]指出并不存在混淆器可以完全隱藏程序的內(nèi)部信息,因?yàn)槌绦虻妮斎牒洼敵鐾猓嫦蛉藛T還是可以獲取很多有助于程序理解的信息。但文獻(xiàn)[1]從實(shí)際需求出發(fā)認(rèn)為相較于抽象的完美工具,是否存在實(shí)用的混淆工具用于具體的軟件保護(hù)更加重要。

      Collberg 等[8]將混淆技術(shù)分為布局混淆、數(shù)據(jù)混淆、控制流混淆和預(yù)防性混淆,本文關(guān)注布局混淆中的標(biāo)識(shí)符混淆算法,在幾乎無時(shí)空開銷的前提下提高逆向分析的難度,以增強(qiáng)軟件抵抗靜態(tài)分析[9]的能力。為了突顯性能和跨平臺(tái)的通用性,本文主要研究基于底層虛擬機(jī)(Low Level Virtual Machine,LLVM)[10]的標(biāo)識(shí)符混淆方法。

      本文主要工作在于給出四種獨(dú)立的標(biāo)識(shí)符混淆算法和一個(gè)融合四種技術(shù)的創(chuàng)新混合算法。在保證正常語(yǔ)義的前提下,強(qiáng)化標(biāo)識(shí)符混淆方法的保護(hù)能力?;贚LVM 實(shí)現(xiàn)的標(biāo)識(shí)符混淆方法不僅有著性能開銷小、隱蔽性強(qiáng)的優(yōu)點(diǎn),而且適用于LLVM 平臺(tái)所支持的所有語(yǔ)言[11],更具通用性和廣泛性。

      1 相關(guān)知識(shí)

      1.1 代碼混淆

      代碼混淆技術(shù)[8,12]是一種軟件保護(hù)技術(shù),在保證不改變程序原有功能的同時(shí),通過對(duì)源代碼或者匯編碼進(jìn)行修改,包括但不限于控制流和數(shù)據(jù)流方面的修改,降低源碼的可理解性,阻止逆向工具的處理,以達(dá)到軟件保護(hù)的目的。代碼混淆技術(shù)從20 世紀(jì)90 年代開始出現(xiàn),最開始關(guān)注指令替換和花指令的添加[13];之后Collberg 等[8]對(duì)代碼混淆技術(shù)進(jìn)行分類,并給出混淆效果的評(píng)估指標(biāo),包括混淆程度[12](potency)、混淆強(qiáng)度(resilience)、性能開銷(cost)和隱蔽性(stealth);為了加強(qiáng)安全性,隨后出現(xiàn)控制流混淆[14]和數(shù)據(jù)混淆[15]的方案。盡管Barak 等[7]從理論上證明并不存在足夠安全的混淆器,但隨著工業(yè)界對(duì)代碼混淆需求的上漲,后續(xù)出現(xiàn)了眾多實(shí)用的功能增強(qiáng)方案,包括:混淆中結(jié)合加密方案[16];添加垃圾指令,構(gòu)建虛假控制流和虛假跳轉(zhuǎn)表阻止靜態(tài)反編譯[17];結(jié)合指針分析和數(shù)值分析的方法研究x86 可執(zhí)行程序的靜態(tài)分析算法[18],防止二進(jìn)制文件的惡意混淆技術(shù)的攻擊;針對(duì)切片的混淆[19];在LLVM 層實(shí)現(xiàn)的OLLVM(Obfuscator LLVM)[20]給出了跨平臺(tái)、跨語(yǔ)言混淆的可行性;同時(shí)出現(xiàn)了針對(duì)模型的混淆方案[21]和新的混淆參數(shù)的評(píng)定指標(biāo)[22]。

      廣義的代碼混淆目前的研究方向主要有兩方面:一方面是實(shí)用性混淆方法的提出,包括現(xiàn)有算法的強(qiáng)化和創(chuàng)新,以適用于新的場(chǎng)景;另一方面是理論性研究,結(jié)合密碼學(xué)的研究思路,追求可證明的混淆方式。狹義的代碼混淆可以等效理解為實(shí)用性混淆方法,本文研究的標(biāo)識(shí)符混淆方法即歸屬于這一類。

      1.2 標(biāo)識(shí)符混淆

      標(biāo)識(shí)符混淆的定義[23]:設(shè)p是一個(gè)給定的程序,Up是p中出現(xiàn)的所有名稱的集合,是針對(duì)混淆的名稱集合。p的標(biāo)識(shí)符混淆方法是將p中的每個(gè)標(biāo)識(shí)符n∈Np替換為另一個(gè)標(biāo)識(shí)符n′(=t(n)),獲得混淆程序p′,其中t是一對(duì)一的映射(t:Np→Np′(Np′?Up′)),t可以視為不同的標(biāo)識(shí)符混淆方法。

      標(biāo)識(shí)符混淆方法為了隱藏程序邏輯,降低代碼的可讀性,多數(shù)采用替換的思路。其中霍建雷[24]提出Java 標(biāo)識(shí)符重命名混淆算法及其實(shí)現(xiàn)方式,用四種算法構(gòu)造出Java 混淆器JIRO(Java Identifier Renaming Obfuscator),但在實(shí)現(xiàn)上存在通用性不強(qiáng)的缺點(diǎn),僅限于Java,且未考慮算法間的協(xié)同處理以達(dá)到最優(yōu)效果。Ceccato 等[25]通過具體的逆向?qū)嶒?yàn)證明,標(biāo)識(shí)符混淆增大了逆向的難度,使有經(jīng)驗(yàn)的逆向人員和經(jīng)驗(yàn)欠缺的人員都面臨同等棘手的問題。Al-Hakimi 等[26]提出混合混淆的策略,在字符串混淆階段,先將標(biāo)識(shí)符替換為垃圾代碼,然后用Unicode 字符替換系統(tǒng)關(guān)鍵字,最后結(jié)合字符串加密技術(shù)實(shí)現(xiàn)字符串混淆,混淆方案本身取得較好的效果,但在標(biāo)識(shí)符混淆實(shí)現(xiàn)部分,更多的是替換方案,思路過于單一。Cimato 等[27]提出針對(duì)標(biāo)識(shí)符混淆的對(duì)抗方法,核心思路為針對(duì)字節(jié)碼優(yōu)先進(jìn)行處理,提出兩種實(shí)現(xiàn)思路:第一種是利用現(xiàn)有的工具,將字節(jié)碼文件中的標(biāo)識(shí)符轉(zhuǎn)變?yōu)閱我坏暮戏?biāo)識(shí)符(如字母或數(shù)字)后,使用反混淆工具將字節(jié)碼轉(zhuǎn)變?yōu)樵创a;第二種思路是實(shí)現(xiàn)ADAM(Another Decompilation Assistant Methodology),在處理字節(jié)碼文件時(shí),使用實(shí)體-標(biāo)識(shí)符-信息(Entity-Number-Info)的形式進(jìn)行標(biāo)識(shí)符重命名,再將其轉(zhuǎn)變?yōu)樵创a。但思路僅限于Java 語(yǔ)言,較為單一且反混淆的質(zhì)量取決于info,即類相關(guān)信息的抽取,而混淆可以對(duì)這部分信息進(jìn)行處理。

      綜上所述,現(xiàn)有的標(biāo)識(shí)符混淆技術(shù)大多針對(duì)某一具體平臺(tái)或語(yǔ)言,不具有通用性;圍繞隱藏標(biāo)識(shí)符信息,標(biāo)識(shí)符算法主要分為替換和重載兩種思路,但現(xiàn)有的文章中并未對(duì)兩者結(jié)合后的理論或?qū)嶋H效果進(jìn)行分析。針對(duì)現(xiàn)有問題,本文所提出的基于LLVM 的標(biāo)識(shí)符混淆方法,適用于LLVM 平臺(tái)所支持的所有編程語(yǔ)言和后端架構(gòu),目前前端有Ada、C、C++、D、Delphi、Fortran、Haskell、Julia、Objective-C、Rust and Swift,后端有x86、x86-64、ARM、ARM64 等指令集。后文實(shí)驗(yàn)部分對(duì)結(jié)合替換和重載思路的算法效果進(jìn)行分析。

      1.3 LLVM框架

      LLVM[10]的命名最早源自于底層虛擬機(jī)(Low Level Virtual Machine)的首字母縮寫,隨著發(fā)展,原生的內(nèi)涵也發(fā)生了轉(zhuǎn)變,現(xiàn)在LLVM 代表著模塊化和可重用的編譯器和工具鏈技術(shù)的集合。

      LLVM 是基于傳統(tǒng)的三段式架構(gòu)(前端、優(yōu)化、后端)設(shè)計(jì)[28]的編譯器。如圖1 所示,模塊間更易于解耦:一方面利于拓展新的前端和后端,支持更多的語(yǔ)言和設(shè)備;另一方面,可以高度復(fù)用優(yōu)化階段的工作,在優(yōu)化過程中對(duì)LLVM IR(Intermediate Representation)[29]的工作可以無縫鏈接到不同的前端和后端。本文方法對(duì)IR 文件進(jìn)行修改和優(yōu)化,因而理論上適用于LLVM 支持的所有前端和后端。

      圖1 LLVM三段式設(shè)計(jì)Fig.1 LLVM three-stage design

      LLVM 支持三種等效的IR 格式,如圖2 所示:可讀的匯編格式(.ll);內(nèi)存中編譯IR 內(nèi)存格式;適用于即時(shí)編譯(Just-In-Time compilation,JIT)快速加載的位碼格式(.bc)。為了實(shí)現(xiàn)程序持久性的優(yōu)化,本文主要針對(duì).ll 和.bc 文件進(jìn)行操作,通過編寫趟(Pass)實(shí)現(xiàn)具體的混淆功能。

      圖2 LLVM編譯器架構(gòu)Fig.2 LLVM compiler architecture

      2 標(biāo)識(shí)符混淆方法

      本文針對(duì)文獻(xiàn)[24]提出的標(biāo)識(shí)符混淆算法進(jìn)行重新設(shè)計(jì)。不同于以往的算法實(shí)現(xiàn),在LLVM 層進(jìn)行開發(fā),使其不再局限于Java 等某一特定編程語(yǔ)言;對(duì)算法細(xì)節(jié)進(jìn)行調(diào)整,包括隨機(jī)標(biāo)識(shí)符、非法標(biāo)識(shí)符的構(gòu)造,增強(qiáng)算法本身的效果。使用現(xiàn)有生活用語(yǔ)構(gòu)造混淆后的字符:一方面隱藏真實(shí)標(biāo)識(shí)符信息;另一方面增強(qiáng)混淆字符的隱蔽性。并對(duì)提出的四種算法進(jìn)行混合,在保證程序正常執(zhí)行的情況下,令四種算法效果達(dá)到最佳,在不會(huì)帶來額外開銷[30]的同時(shí),讓攻擊者幾乎不可能將標(biāo)識(shí)符恢復(fù)到原始狀態(tài)。

      2.1 標(biāo)識(shí)符混淆域及混淆對(duì)象

      在源代碼中,當(dāng)一個(gè)標(biāo)識(shí)符被混淆時(shí),與之相關(guān)的函數(shù)、調(diào)用等都要隨之變化,否則會(huì)影響代碼的正常執(zhí)行;并且涉及到標(biāo)準(zhǔn)庫(kù)和第三方庫(kù)的方法,因?yàn)榘鏅?quán)等方面原因,不能隨意混淆。因此,有必要提出混淆域[23]的概念:在不影響程序正常執(zhí)行的前提下,可以混淆的代碼范圍。

      標(biāo)識(shí)符混淆的對(duì)象理論上應(yīng)是混淆域內(nèi)的所有標(biāo)識(shí)符,但源程序中的局部變量名、注釋、自定義類型等信息在編譯后已經(jīng)被去除[31]。在LLVM 層,源代碼轉(zhuǎn)化為L(zhǎng)LVM IR 后,局部變量以“%”字符開頭,全局變量以“@”字符開頭,并且為了編譯器快速給出臨時(shí)變量,避免符號(hào)表沖突,會(huì)配合無符號(hào)整數(shù)作為標(biāo)識(shí)符的名稱(如%12、@2),所以在正式混淆前,標(biāo)識(shí)符已經(jīng)產(chǎn)生變化。但程序的符號(hào)表會(huì)持有函數(shù)名稱的引用,加之函數(shù)名在程序理解中的重要作用[32],本文提出的標(biāo)識(shí)符混淆方法主要對(duì)程序中的函數(shù)名進(jìn)行處理。

      本文標(biāo)識(shí)符混淆方法針對(duì)的混淆域?yàn)楫?dāng)前文件或項(xiàng)目生成的IR 文件,混淆對(duì)象為混淆域內(nèi)自定義并初始化的函數(shù)名、全局變量名和自定義的結(jié)構(gòu)體,不包括庫(kù)函數(shù)和第三方應(yīng)用程序接口(Application Programming Interface,API)。

      2.2 標(biāo)識(shí)符混淆方法設(shè)計(jì)

      混淆方法設(shè)計(jì)分為三部分,分步驟完成混淆目標(biāo):

      1)中間語(yǔ)言處理部分。通過Clang 等前端將程序源碼編譯成對(duì)應(yīng)的LLVM IR 文件,再通過LLVM-Link 或WLLVM(Whole-program-LLVM)將所有的IR 文件鏈接成一個(gè)包含源程序所有信息的IR 文件。

      2)標(biāo)識(shí)符混淆部分。作為整個(gè)混淆方法的核心部分,主要用于對(duì)鏈接后生成的IR 文件進(jìn)行優(yōu)化處理,可以分為以下3 個(gè)子步驟完成標(biāo)識(shí)符混淆處理:

      ①全局?jǐn)?shù)據(jù)處理。獲取到代碼的全局變量、函數(shù)名稱等標(biāo)識(shí)符信息。

      ②標(biāo)識(shí)符篩選。對(duì)①中獲取到的標(biāo)識(shí)符進(jìn)行條件篩選,排除標(biāo)準(zhǔn)庫(kù)和第三方庫(kù)方法的標(biāo)識(shí)符,保留滿足混淆域要求的標(biāo)識(shí)符。

      ③標(biāo)識(shí)符混淆。對(duì)②中篩選后的標(biāo)識(shí)符進(jìn)行混淆處理,利用實(shí)現(xiàn)的LLVM Pass 對(duì)標(biāo)識(shí)符進(jìn)行混淆。不同的Pass 文件對(duì)應(yīng)著不同的混淆算法。

      3)生成部分。通過用戶指定或者目標(biāo)平臺(tái)識(shí)別,將優(yōu)化處理后的IR 文件,由后端編譯成適用于目標(biāo)機(jī)器的可執(zhí)行文件。

      2.3 標(biāo)識(shí)符混淆算法

      本文混淆方法給出四種標(biāo)識(shí)符混淆算法,包括隨機(jī)標(biāo)識(shí)符算法、高頻詞替換算法、異常標(biāo)識(shí)符算法、重載歸納算法,最后給出了將四種算法混合使用的混合標(biāo)識(shí)符算法。其中隨機(jī)標(biāo)識(shí)符算法和重載歸納算法基于已有的設(shè)計(jì)[24],在LLVM 平臺(tái)實(shí)現(xiàn);高頻詞算法的混淆字典、異常標(biāo)識(shí)符混淆的異常字符選取屬于原創(chuàng)性設(shè)計(jì),同時(shí)為了充分利用現(xiàn)有混淆算法,在算法的結(jié)合上進(jìn)行了新的嘗試,即混合混淆算法。每種算法均為L(zhǎng)LVM Pass 文件,且對(duì)IR 文件進(jìn)行操作,生成優(yōu)化后的IR 文件以達(dá)到混淆目的。

      算法1 中的T即標(biāo)識(shí)符重命名方法,包括隨機(jī)標(biāo)識(shí)符算法、高頻詞替換算法、異常標(biāo)識(shí)符算法。重載歸納算法如算法2 所示。

      算法2 中初始化工作包括混淆對(duì)象的選取,主體邏輯如下:標(biāo)識(shí)符替換的算法通過編寫Module Pass 進(jìn)行實(shí)現(xiàn),在獲取模塊(module)后首先針對(duì)全局變量和自定義的結(jié)構(gòu)體名稱進(jìn)行換名,module 提供對(duì)應(yīng)的API 進(jìn)行處理:全局變量可以通過遍歷module.begin()和module.end()進(jìn)行獲取;結(jié)構(gòu)體可以通過StructTypes.run(module,true)獲取相關(guān)的信息;函數(shù)名則通過遍歷模塊內(nèi)的所有函數(shù)進(jìn)行篩選,這里只選取用戶自定義的函數(shù),通過LLVM 提供的API 結(jié)合函數(shù)類型和鏈接類型進(jìn)行有效的判斷。

      對(duì)于重載歸納算法,還要多做一步,因?yàn)樵贑/C++中存在名稱改寫(name mangling)機(jī)制,因此在重載時(shí),先對(duì)函數(shù)名進(jìn)行處理,獲取去除不相關(guān)字符后真正的函數(shù)名再進(jìn)行處理。最后,每更改一次,都需要進(jìn)行全局更新,防止后續(xù)運(yùn)行時(shí)找不到鏈接的函數(shù)。

      2.3.1 隨機(jī)標(biāo)識(shí)符算法

      隨機(jī)標(biāo)識(shí)符算法:遍歷混淆域內(nèi)的所有標(biāo)識(shí)符,隨后通過自定義的隨機(jī)函數(shù)產(chǎn)生隨機(jī)且無意義的名字替代之前的標(biāo)識(shí)符命名。其中隨機(jī)函數(shù)隨機(jī)選取大小寫字母和下劃線等字符,隨機(jī)組合成X位的毫無意義[33]的字符串(如統(tǒng)一設(shè)置11 位字符串jK2iOy3yewc)。

      這里的代碼示例中源碼選擇avl-tree(https://www.geeksforgeeks.org/avl-tree-set-1-insertion/)代碼。查看混淆前后的IR 文件中的符號(hào)表信息,統(tǒng)計(jì)相關(guān)函數(shù)名信息如表1 所示。后文中的算法效果示例均如此。

      表1 標(biāo)識(shí)符混淆算法示例Tab.1 Identifier obfuscation algorithm examples

      2.3.2 高頻詞替換算法

      高頻詞替換算法:將生活中常見的英文單詞用于重命名標(biāo)識(shí)符,在掩蓋標(biāo)識(shí)符本身含義的情況下,誘導(dǎo)攻擊者以為程序未被混淆。使用2019 年經(jīng)濟(jì)學(xué)人的詞頻統(tǒng)計(jì)作為源數(shù)據(jù),在構(gòu)造混淆字典時(shí),為了更具真實(shí)性以抵抗混淆檢測(cè)算法,借鑒當(dāng)前識(shí)別標(biāo)識(shí)符混淆的研究,如文獻(xiàn)[34]將代碼中是否存在標(biāo)識(shí)符長(zhǎng)度小于3 作為是否被混淆的指標(biāo)之一,因此選擇字符個(gè)數(shù)不少于3 且不屬于保留字的字符。在整理的109 932 項(xiàng)條目中,最后僅保留1 071 項(xiàng)作為混淆字典的條目。對(duì)于標(biāo)識(shí)符數(shù)目龐大的代碼,實(shí)現(xiàn)上通過補(bǔ)充下劃線的方式進(jìn)行擴(kuò)容,使混淆庫(kù)足夠豐富,以備替換。

      高頻詞替換算法產(chǎn)生的標(biāo)識(shí)符名稱是具有現(xiàn)實(shí)意義的,只不過和源程序的函數(shù)意義沒有任何關(guān)聯(lián),進(jìn)而引申出追求更高層級(jí)的標(biāo)識(shí)符混淆,不是去除標(biāo)識(shí)符,也不是簡(jiǎn)單地使用無意義的標(biāo)識(shí)符進(jìn)行替換,而是使用有意義但無實(shí)際聯(lián)系的字符進(jìn)行替換,更能迷惑逆向分析人員。針對(duì)如何使用有意義但無實(shí)際聯(lián)系的標(biāo)識(shí)符進(jìn)行概念說明:

      有意義但無實(shí)際聯(lián)系的標(biāo)識(shí)符,指源于生活、相關(guān)領(lǐng)域認(rèn)可且具有共識(shí)認(rèn)知的詞匯或者表示,但和函數(shù)本身的功能不存在指向關(guān)系。應(yīng)當(dāng)滿足特性:首先,“有意義”體現(xiàn)在標(biāo)識(shí)符本身是被認(rèn)可的,且被該領(lǐng)域或相關(guān)領(lǐng)域的主體認(rèn)同;其次,“無實(shí)際聯(lián)系”體現(xiàn)在標(biāo)識(shí)符本身和函數(shù)本身的功能沒有任何關(guān)聯(lián),可以沒有任何聯(lián)系,可以相反,也可以相同,因?yàn)楸旧砘旌显谝粋€(gè)系統(tǒng)中,真假難辨反而更容易迷惑逆向人員。

      2.3.3 異常標(biāo)識(shí)符算法

      異常標(biāo)識(shí)符算法:針對(duì)混淆域內(nèi)的所有標(biāo)識(shí)符,使用形似保留字的標(biāo)識(shí)符或下劃線進(jìn)行替換,以混淆視聽。該算法分為兩種思路,本節(jié)將分別敘述。

      異常標(biāo)識(shí)符算法1,該思路旨在生成形似保留字的標(biāo)識(shí)符以迷惑攻擊者。過程分為三步:第一步生成一個(gè)帶有希臘字母“保留字”的集合,先找出所有和英文字母類似的希臘字母,用這些希臘字母對(duì)保留字中的英文字母進(jìn)行替換;第二步獲取程序中出現(xiàn)的標(biāo)識(shí)符;第三步使用自定義集合里的“保留字”替代程序中的標(biāo)識(shí)符,以混淆視聽。

      異常標(biāo)識(shí)符算法2,通過由下劃線組成的標(biāo)識(shí)符(如:“__”)替代原有標(biāo)識(shí)符,通過下劃線個(gè)數(shù)作區(qū)分,隨著下劃線的遞增,標(biāo)識(shí)符區(qū)分度也逐漸降低。而程序可以依照個(gè)數(shù)的不同調(diào)用目標(biāo)函數(shù),實(shí)現(xiàn)對(duì)程序的保護(hù)目的。

      2.3.4 重載歸納算法

      重載歸納算法:利用面向?qū)ο笳Z(yǔ)言的重載特性對(duì)標(biāo)識(shí)符進(jìn)行易名,使程序含有盡可能多的相同名字、不同參數(shù)類型的函數(shù)。

      重載歸納算法不同于上述的替換思路,算法獲取程序中出現(xiàn)的函數(shù)名,對(duì)其進(jìn)行排序,根據(jù)參數(shù)類型或數(shù)量不同,采用同名替換的方式使程序盡可能多地含有同名函數(shù)。程序可以采用重載的方法調(diào)用目標(biāo)函數(shù),并不會(huì)影響到正常運(yùn)行,而攻擊者卻難以區(qū)分函數(shù),可以對(duì)調(diào)用的函數(shù)起到保護(hù)作用。

      不同于前三種算法,重載算法并沒有對(duì)混淆域內(nèi)的所有函數(shù)名進(jìn)行保護(hù),會(huì)保留源程序的部分標(biāo)識(shí)符信息。

      前四種算法對(duì)混淆域內(nèi)的標(biāo)識(shí)符提供了一定的保護(hù)能力,為了進(jìn)一步增加混淆的隱蔽性和復(fù)雜性,可以將算法進(jìn)行有效的組合,即混合標(biāo)識(shí)符混淆算法。

      2.3.5 混合標(biāo)識(shí)符混淆算法

      前三種算法雖然達(dá)到隱藏標(biāo)識(shí)符的目的,但是標(biāo)識(shí)符依舊具有區(qū)分度;重載歸納法雖然降低了區(qū)分度,但是依舊保留了標(biāo)識(shí)符的部分信息。為了充分利用現(xiàn)有的標(biāo)識(shí)符混淆算法,取得最佳的混淆效果,將上述四種算法混合使用,命名為混合標(biāo)識(shí)符混淆算法。

      如果僅是線性地將四種算法進(jìn)行組合,如前三種算法進(jìn)行混淆后,再進(jìn)行重載歸納算法混淆得到可執(zhí)行文件,但使用IDA(Interactive DisAssembler professional)等逆向工具進(jìn)行逆向處理時(shí),會(huì)因?yàn)楹瘮?shù)缺乏必要的參數(shù)信息,而對(duì)相同的函數(shù)添加后綴以示區(qū)分,所以為了對(duì)抗類似于IDA 這樣的機(jī)制,在將替換和重載兩類算法進(jìn)行混合時(shí),對(duì)前三種算法進(jìn)行修改,考慮名稱改寫機(jī)制,僅處理函數(shù)名稱,保留原本的參數(shù)列表信息,再使用重載歸納算法處理。一方面因?yàn)樘砑又剌d函數(shù)名,強(qiáng)化第一類替換算法的效果;另一方面,替換算法進(jìn)一步抹除原本的函數(shù)名信息,強(qiáng)化了重載算法的安全性。

      算法3 的整體流程如圖3 所示,首先初始化工作,篩選程序中的標(biāo)識(shí)符,獲取到四種算法可處理的混淆對(duì)象;然后,根據(jù)動(dòng)態(tài)生成的隨機(jī)數(shù)在替換類算法(算法1~3)中進(jìn)行隨機(jī)選擇,對(duì)全局變量、結(jié)構(gòu)體和函數(shù)名稱分別進(jìn)行混淆處理,同時(shí)在算法實(shí)現(xiàn)上進(jìn)行了部分調(diào)整,在針對(duì)函數(shù)名稱替換時(shí),保留參數(shù)列表信息;最后,針對(duì)替換類算法處理后的程序,調(diào)用重載歸納算法?;谔鎿Q后的函數(shù)名稱作進(jìn)一步的復(fù)用工作,使攻擊者無法有效恢復(fù)標(biāo)識(shí)符信息。因?yàn)樵诨煜龝r(shí)僅涉及標(biāo)識(shí)符的替換,沒有增加額外的邏輯處理,所以理論上對(duì)時(shí)空開銷幾乎無影響。

      圖3 混合標(biāo)識(shí)符混淆算法過程Fig.3 Mixed identifier obfuscation algorithm process

      3 標(biāo)識(shí)符混淆方法實(shí)驗(yàn)

      3.1 實(shí)驗(yàn)環(huán)境和數(shù)據(jù)

      實(shí)驗(yàn)在Intel Core i7-9750H、16 GB 內(nèi)存的Ubuntu18.04 64 位機(jī)上實(shí)現(xiàn),基于LLVM10 release 版進(jìn)行開發(fā),使用IDA Free 7.6 進(jìn)行效果的對(duì)比。實(shí)驗(yàn)分為性能分析和混淆效果分析:性能分析關(guān)注混淆后程序在時(shí)空上增加的開銷[35];混淆效果分析關(guān)注混淆的標(biāo)識(shí)符數(shù)量占符號(hào)表標(biāo)識(shí)符總量的比率。為了保證實(shí)驗(yàn)數(shù)據(jù)的準(zhǔn)確性,性能分析中使用腳本進(jìn)行數(shù)據(jù)的獲取;效果分析使用IDA Free 7.6 對(duì)混淆前后的可執(zhí)行文件進(jìn)行逆向處理,統(tǒng)計(jì)更改名稱的函數(shù)所占的比率。

      其中,性能分析以C++實(shí)現(xiàn)的算法庫(kù)(https://github.com/xtaci/algorithms)和Rust 算法庫(kù)(https://github.com/TheAlgorithms/Rust)為測(cè)試數(shù)據(jù):一方面說明混淆方法對(duì)算法的時(shí)空開銷;另一方面說明本文方法的通用性——LLVM支持眾多的前端。本次實(shí)驗(yàn)選取目前為止始終擁有良好維護(hù)的C++和Rust 以展示效果;混淆效果分析中,選取項(xiàng)目文件,包括std 的map 實(shí)現(xiàn)、數(shù)獨(dú)游戲sudoku(https://github.com/mayerui/sudoku)、字符轉(zhuǎn)換工具flowchar(https://github.com/Gusabary/FlowChar)和Google 開源的leveldb(https://github.com/google/leveldb),以展示本文方法在多文件中的使用效果。

      3.2 性能分析

      實(shí)驗(yàn)選取C++和Rust 語(yǔ)言的算法文件作為測(cè)試文件,以時(shí)空增長(zhǎng)作為測(cè)試指標(biāo),從而評(píng)估混淆的性能。本節(jié)先進(jìn)行理論分析,后面輔以實(shí)驗(yàn)說明。

      依據(jù)Collberg 等[8]提出的混淆指標(biāo)對(duì)本文方法進(jìn)行理論評(píng)估,在性能代價(jià)(cost)上表現(xiàn)為無代價(jià)(free)。性能開銷分為dear、costly、cheap 和free 四種等級(jí),由于本文方法僅針對(duì)標(biāo)識(shí)符混淆層面,所以在性能開銷上是free 級(jí)別。

      對(duì)60 個(gè)C 文件和24 個(gè)Rust 文件進(jìn)行混淆處理。為了減小機(jī)器運(yùn)行時(shí)造成的時(shí)間誤差,每個(gè)測(cè)試用例執(zhí)行100 次求平均值作為統(tǒng)計(jì)的運(yùn)行時(shí)間。同時(shí),為了更好地展示不同方法間的差異,對(duì)算法庫(kù)文件單獨(dú)使用混淆算法后,對(duì)每個(gè)文件統(tǒng)計(jì)其時(shí)空增長(zhǎng)倍數(shù),然后在圖4 中以各自均值進(jìn)行表示,如針對(duì)C++項(xiàng)目的60 個(gè)文件,使用隨機(jī)標(biāo)識(shí)符算法后,時(shí)間增長(zhǎng)倍數(shù)的均值在1.07。

      圖4 性能分析Fig.4 Performance analysis

      橫坐標(biāo)是5 類混淆算法(異常標(biāo)識(shí)符算法存在兩種實(shí)現(xiàn),共6 種算法),縱坐標(biāo)表示混淆后相較于混淆前的增長(zhǎng)倍數(shù)。對(duì)應(yīng)可以得到如下的結(jié)論:

      1)混淆算法對(duì)C++處理后,在時(shí)空上幾乎無變化,考慮到機(jī)器運(yùn)行的時(shí)間誤差,混淆增加的時(shí)間倍數(shù)可以進(jìn)一步減小。

      2)混淆算法對(duì)Rust 處理后,時(shí)間開銷平均增加20%的同時(shí),極大地減小了空間開銷,空間上平均變?yōu)樵镜?%。

      3)雖然混淆算法針對(duì)C++和Rust 在時(shí)空開銷上影響不同,但是可以驗(yàn)證本文算法的通用性。

      3.3 混淆效果分析

      為了更客觀地評(píng)估混淆效果,選取項(xiàng)目文件進(jìn)行混淆。選擇不同標(biāo)識(shí)符量級(jí)的項(xiàng)目,涵蓋幾十到幾萬(wàn)量級(jí),同時(shí)兼顧項(xiàng)目的不同類型,最終以C++標(biāo)準(zhǔn)庫(kù)中的map 實(shí)現(xiàn),數(shù)獨(dú)游戲sudoku,字符轉(zhuǎn)換工具flowchar 和Google 開源的leveldb作為實(shí)驗(yàn)數(shù)據(jù)。通過IDA 對(duì)混淆后的可執(zhí)行文件逆向處理,得到混淆后的標(biāo)識(shí)符所占的比例。下文先對(duì)標(biāo)識(shí)符混淆的混淆強(qiáng)度進(jìn)行理論分析,再輔以實(shí)驗(yàn)說明。

      依據(jù)Collberg 等[8]提出的混淆指標(biāo)對(duì)本文方法進(jìn)行理論評(píng)估,在混淆強(qiáng)度(resilience)上表現(xiàn)為強(qiáng)(strong)?;煜龔?qiáng)度指標(biāo)主要是為了度量混淆后的程序?qū)ψ詣?dòng)化反混淆器的抵抗能力,包括兩個(gè)方面的表現(xiàn):一方面是有針對(duì)性地編寫一個(gè)自動(dòng)化反混淆器付出的代價(jià);另一方面是使用自動(dòng)化反混淆器進(jìn)行反混淆所付出的代價(jià)[12]。

      第一個(gè)方面的代價(jià)分為多項(xiàng)式時(shí)間復(fù)雜度和指數(shù)時(shí)間復(fù)雜度,本文提供的標(biāo)識(shí)符技術(shù)復(fù)雜度是O(n2),屬于多項(xiàng)式時(shí)間復(fù)雜度,而對(duì)應(yīng)的第二個(gè)方面所指代的反混淆付出的代價(jià)分為full、strong、weak 和trivial 四個(gè)級(jí)別,分別對(duì)應(yīng)interprocess、interprocedural、global 和local 四個(gè)層面[8]。本文將所有的中間文件鏈接在一起統(tǒng)一對(duì)其混淆,可以確定該技術(shù)是在interprocedural 層面進(jìn)行的,所以在混淆強(qiáng)度指標(biāo)上表現(xiàn)為強(qiáng)(strong)。

      從混淆算法角度出發(fā),本文提出的6 種具體的混淆算法,又可以歸于三大類算法:1)替換算法,包括隨機(jī)標(biāo)識(shí)符算法、高頻詞替換算法、異常標(biāo)識(shí)符算法(所能影響的標(biāo)識(shí)符數(shù)量是相同的,只是標(biāo)識(shí)符替換的策略不同);2)重載算法;3)替換和重載結(jié)合的混合算法。

      圖5 中白色區(qū)域表示已混淆標(biāo)識(shí)符的數(shù)量,黑色區(qū)域表示未混淆標(biāo)識(shí)符的數(shù)量。部分標(biāo)識(shí)符未混淆,因?yàn)樗惴ㄔO(shè)計(jì)時(shí)僅針對(duì)用戶自定義的函數(shù),對(duì)于庫(kù)函數(shù)和第三方API 并不進(jìn)行處理。

      圖5 不同混淆算法的混淆效果圖Fig.5 Obfuscation effect diagram of different identifier obfuscation algorithms

      針對(duì)四個(gè)項(xiàng)目分別使用三類算法(第一類替換算法,運(yùn)行時(shí)通過隨機(jī)數(shù)隨機(jī)指定)得到如下結(jié)論:

      1)第三類算法影響的標(biāo)識(shí)符數(shù)量和第一類算法是相同的,第二類算法影響的數(shù)量是最少的。如圖5 四個(gè)子圖中均存在較小的白色區(qū)域,即重載算法所占的比重。

      2)第三類算法保留了前兩類算法的優(yōu)點(diǎn),對(duì)其各自的缺點(diǎn)進(jìn)行了彌補(bǔ):第一類算法可以混淆更多的標(biāo)識(shí)符,但是標(biāo)識(shí)符仍然具有唯一性,第二類算法使用重載,標(biāo)識(shí)符不再具有唯一性,但是混淆的數(shù)量較少,且會(huì)保留部分源程序的語(yǔ)義信息。而第三類算法在取得極大混淆數(shù)量的同時(shí),徹底去除原本的語(yǔ)義信息,且借助于重載使標(biāo)識(shí)符不再具有唯一性。

      3)針對(duì)不同標(biāo)識(shí)符量級(jí)的項(xiàng)目,混淆算法的平均比率在77.5%,如圖6 所示。

      圖6 混合混淆算法的混淆比例Fig.6 Obfuscation ratio of mixed obfuscation algorithm

      4)在混淆的標(biāo)識(shí)符中,重載歸納算法的比例較小,和程序本身的特性相關(guān),極端情況下無效果。

      5)混淆效果和項(xiàng)目的標(biāo)識(shí)符數(shù)量無關(guān)聯(lián),和程序本身自定義的函數(shù)和函數(shù)參數(shù)的設(shè)計(jì)相關(guān)。

      同時(shí),因?yàn)閟trip 用于去除符號(hào)表,和本文所討論的標(biāo)識(shí)符替換存在關(guān)聯(lián)。對(duì)兩者進(jìn)行分析,得到如下結(jié)論:

      1)在Rust 程序上進(jìn)行測(cè)試,除同strip 一樣可以極大減小符號(hào)表體積外,不同于strip 直接去除符號(hào)表,本文方法可保留迷惑性的信息以干擾逆向人員的分析。

      2)本文方法針對(duì)自動(dòng)化逆向工具分析時(shí),目前效果不大于strip 的效果,甚至自動(dòng)化工具會(huì)直接去除符號(hào)表信息,以規(guī)避標(biāo)識(shí)符混淆的效果。

      3)目前LLVM 支持的前端中包括靜態(tài)編譯語(yǔ)言和動(dòng)態(tài)解釋語(yǔ)言,本文方法在生成靜態(tài)語(yǔ)言可執(zhí)行文件時(shí),可能受制于strip,但如果動(dòng)態(tài)解釋語(yǔ)言得到進(jìn)一步的優(yōu)化和維護(hù)后,可以在本文方法上進(jìn)行進(jìn)一步的研究和推進(jìn)。

      4 結(jié)語(yǔ)

      基于軟件保護(hù)的應(yīng)用場(chǎng)景和編程語(yǔ)言多樣的需要,本文提出基于LLVM 的標(biāo)識(shí)符混淆方法。該混淆方法融合四種算法的優(yōu)勢(shì),在84 個(gè)單文件的測(cè)試用例和不同類型的項(xiàng)目中,均有較為穩(wěn)定的混淆效果。混淆方法有效地隱藏了標(biāo)識(shí)符信息,提高代碼的安全性;同時(shí)由于LLVM 的跨平臺(tái)性,方法適用于LLVM 支持的所有語(yǔ)言和架構(gòu)。

      但是對(duì)于動(dòng)態(tài)調(diào)試,本文所提供的技術(shù)無法提供足夠的保護(hù),這是接下來的工作之一。同時(shí),本文標(biāo)識(shí)符混淆方法多數(shù)停留于標(biāo)識(shí)符替換層面,反編譯人員可以經(jīng)過分類等方法,大致確認(rèn)函數(shù)的作用。接下來的工作:一方面是增強(qiáng)對(duì)動(dòng)態(tài)調(diào)試的抵抗力;另一方面是提高抵抗機(jī)器學(xué)習(xí)攻擊[36]的能力,消除strip 的影響,提供功能更為豐富的混淆方法也是今后的重點(diǎn)工作。

      猜你喜歡
      標(biāo)識(shí)符程序函數(shù)
      淺析5G V2X 通信應(yīng)用現(xiàn)狀及其側(cè)鏈路標(biāo)識(shí)符更新技術(shù)
      二次函數(shù)
      第3講 “函數(shù)”復(fù)習(xí)精講
      二次函數(shù)
      函數(shù)備考精講
      基于區(qū)塊鏈的持久標(biāo)識(shí)符系統(tǒng)①
      試論我國(guó)未決羈押程序的立法完善
      “程序猿”的生活什么樣
      英國(guó)與歐盟正式啟動(dòng)“離婚”程序程序
      數(shù)字美術(shù)館“數(shù)字對(duì)象唯一標(biāo)識(shí)符系統(tǒng)”建設(shè)需求淺議
      乌拉特前旗| 清苑县| 汉阴县| 蒲城县| 浦江县| 呼图壁县| 古丈县| 个旧市| 太原市| 新竹县| 吴堡县| 灵川县| 四川省| 雷州市| 通河县| 渝中区| 凭祥市| 微山县| 金门县| 新化县| 辉南县| 衡阳县| 临汾市| 徐闻县| 禹城市| 南宫市| 都昌县| 鄂伦春自治旗| 灵台县| 金华市| 灵宝市| 双流县| 游戏| 张北县| 嘉峪关市| 龙门县| 光泽县| 佛山市| 从化市| 竹山县| 阿尔山市|