葛 華, 余沛釗, 夏夢森
(武漢理工大學(xué) a.信息工程學(xué)院; b.計算機科學(xué)與技術(shù)學(xué)院, 武漢 430072)
一種JAVA控制流混淆方案
葛 華a, 余沛釗a, 夏夢森b
(武漢理工大學(xué) a.信息工程學(xué)院; b.計算機科學(xué)與技術(shù)學(xué)院, 武漢 430072)
在逆向分析的領(lǐng)域里,JAVA軟件最需要保護的地方毫無疑問是整個軟件的結(jié)構(gòu)。本文在總結(jié)代碼混淆領(lǐng)域中的一些混淆策略后,提出一個基于結(jié)構(gòu)代碼塊的控制流混淆方案。該方案不是以基本代碼塊為基礎(chǔ)來提出具體的混淆策略,而是從軟件結(jié)構(gòu)角度上,只對那些復(fù)雜的結(jié)構(gòu)塊進行混淆處理。該方案首先插入含有垃圾代碼塊的分支路徑,然后以結(jié)構(gòu)代碼塊為基礎(chǔ)進行壓扁操作。分析表明該方案具有較好的效率。
代碼混淆;控制流混淆;代碼塊
當(dāng)我們將一段JAVA代碼通過混淆變化后生成一段新的代碼,在保證前后運行結(jié)果相同的情況下,如果新生成的代碼比原來的代碼更具有迷惑作用,我們就把這個過程稱為代碼混淆[1-3]。
依據(jù)混淆原理與所需進行混淆處理的對象的不同,可以將代碼混淆分成以下幾類[4-5]:
圖1 代碼混淆分類
控制流混淆是靜態(tài)混淆的一種,近來得到學(xué)者的廣泛關(guān)注。
對于JAVA應(yīng)用來說,攻擊者大多是通過解析出來的程序結(jié)構(gòu)來進行破解,數(shù)據(jù)混淆和結(jié)構(gòu)混淆對于這種情況是沒有明顯的作用,因為攻擊者依舊能夠?qū)⒊绦蚪Y(jié)構(gòu)重新構(gòu)造出來,要想對JAVA應(yīng)用有一個很好的保護,運用控制流混淆去隱蔽并且改變它的運行結(jié)構(gòu)是個很好的選擇[6-8]。
將一段按照先后次序運行的語句稱作為基本代碼塊,它先從首條語句開始運行,直到最后一條語句執(zhí)行完就結(jié)束。由多個基本代碼塊組成的結(jié)構(gòu)稱之為結(jié)構(gòu)代碼塊。
壓扁的思想是將一個正常按照次序執(zhí)行的程序塊打亂,并把這些打亂的程序塊通過結(jié)構(gòu)進行重新排列組合,將放在一個循環(huán)里,每次在程序塊運行結(jié)束之前對一個全局變量進行。這樣做不但打亂了原有的結(jié)構(gòu)而且確保能夠按照原來正確的次序運行。結(jié)構(gòu)如圖2所示:
圖2 結(jié)構(gòu)圖
本文的控制流混淆方案分為兩步執(zhí)行:
第一步模仿原基本代碼塊構(gòu)造出結(jié)構(gòu)相似但是數(shù)據(jù)不同的垃圾代碼塊,將垃圾代碼安插到原程序結(jié)構(gòu)中形成分支路徑,再往里面添加一個不透明謂詞來使得逆向攻擊者不知道程序接下來往哪條路徑走。
第二步將部分的垃圾代碼塊和原基本塊進行處理,為了控制混淆帶來的花銷,剩下的垃圾代碼塊將進行刪除操作。
本文基于結(jié)構(gòu)代碼塊JAVA控制流混淆過程是:首先對原程序進行仔細(xì)的分析研究,對于一些結(jié)構(gòu)不是很復(fù)雜的結(jié)構(gòu)代碼塊我們將不進行混淆操作,而對于那些結(jié)構(gòu)比較復(fù)雜的結(jié)構(gòu)代碼塊,我們把里面的基本代碼塊全部提取出來,接著對其進行插入分支路徑的操作,然后對不同種類的基本代碼塊進行對應(yīng)的壓扁混淆操作,經(jīng)過這一系列的操作后得到一個混淆后的程序。
3.1 基于不透明謂詞的分支路徑
在對原程序進行插入分支路徑前,我們首先要對整個JAVA代碼進行遍歷分析,選取復(fù)雜度高的結(jié)構(gòu)進行接下來的混淆操作。插入分支路徑第一步就是選取不透明謂詞和構(gòu)造垃圾代碼塊[9-10]。當(dāng)我們在對一JAVA代碼進行保護的時候,如果一個表達式的值我們很容易得到,但是逆向攻擊者卻要花費巨大時間來判定這個表達式的值,那么這個表達式就被叫做不透明謂詞。本文用PT來代表值永遠為真的不透明謂詞,用PF來代表值永遠為假,用P?代表值真假不確定,在圖3中,實線箭頭表示運行程序時會走到的路徑,虛線箭頭表示運行程序時永遠不會到達的路徑即分支路徑。
圖3 不透明謂詞類別
在虛線箭頭的一邊插入垃圾代碼塊。這里需要指出的是插入垃圾代碼只會給原軟件帶來文件大小上的開銷,因為其永遠不會被運行到,所以不會增加程序的運行時間。垃圾代碼最好構(gòu)造得和原代碼塊外形看起來一樣,我們常常通過保持兩者程序結(jié)構(gòu)相同的情況下改變垃圾代碼塊中的數(shù)據(jù),這樣做會使混淆后的程序變得更加難以逆向破解。
3.2 壓扁控制流
在進行插入多余分支路徑后我們接下來對程序進行壓扁操作,使整個程序結(jié)構(gòu)更難被逆向攻擊。本文的壓扁控制流的特點是只對部分的原程序塊和垃圾代碼塊進行壓扁操作[11-13],剩下的垃圾代碼塊直接刪除。
由基本塊的判斷條件不同將壓扁控制流相關(guān)算法細(xì)分為if語句,while語句,for語句,switch語句,do-while語句等基本代碼塊算法。
當(dāng)我們對原程序進行壓扁操作的時候,其實我們利用的條件基本代碼塊的壓扁控制流算法,首先將整個程序看成一個結(jié)構(gòu)塊,然后對每一層進行分析,得到該層的嵌套類型,由此就知道了我們接下來將要調(diào)用哪一個壓扁控制流算法。
(1)分支結(jié)構(gòu)壓扁控制流算法
該算法首先分析程序結(jié)構(gòu),只對程序結(jié)構(gòu)復(fù)雜的進行壓扁操作,在進行壓扁的時候抽取一半的原基本代碼塊和1/4的垃圾代碼塊進行壓扁,剩余的垃圾代碼塊直接刪除。
下面是一個具體基于基本代碼塊壓扁控制流混淆算法的范例,將if語句進行壓扁控制流混淆。
圖4(a) 原if語句代碼
圖4(b) 混淆后if語句代碼
圖5(a) 原if語句控制流
圖5(b) 壓扁后的if語句控制流
圖4 (a)是原if語句代碼,圖4 (b)混淆后if語句代碼,圖5(a)和圖5(b)是混淆前后的控制流圖,混淆之后的代碼與原代碼語義等價,但結(jié)構(gòu)不同。
(2)循環(huán)語句基本代碼塊壓扁控制流算法
在這里需要指出的是,循環(huán)語句的判斷條件有時候可能是隨機條件或者根據(jù)本循環(huán)基本代碼塊結(jié)構(gòu)以外的條件隨機產(chǎn)生的,這樣我們就不能確切的指定出循環(huán)的次數(shù)。本文按照在程序運行前是否能確定循環(huán)次數(shù)的條件,將循環(huán)語句基本代碼塊壓扁控制流算法分為兩種情況來討論。
(1)不能確定循環(huán)次數(shù)的情況下,抽取一半的原基本代碼塊和1/4的垃圾代碼塊進行壓扁,剩余的垃圾代碼塊直接刪除。
(2)能確定循環(huán)次數(shù)的情況下,將程序結(jié)構(gòu)分成兩個部分,對前一半的結(jié)構(gòu)不進行壓扁操作,我們只對后一半的結(jié)構(gòu)進行壓扁操作。
下面是一個具體的基本代碼塊壓扁控制流混淆范例,將語句進行壓扁控制流混淆。
圖6(a) 原while語句代碼
圖6(b) 壓扁后while語句代碼
圖7(a) 原while語句控制流
圖7(b) 壓扁后while語句控制流
圖6 (a)是原while語句代碼,圖6 (b)混淆后while語句代碼,圖7(a)和圖7(b)是壓扁前后的控制流圖,壓扁之后的代碼與原代碼語義等價,但結(jié)構(gòu)不同。
本文首先對代碼混淆的定義和分類做出了介紹,接著詳細(xì)介紹了控制流混淆方案,抽取結(jié)構(gòu)復(fù)雜度較高的結(jié)構(gòu)代碼塊進行混淆。選擇正確的位置插入不透明分支路徑和進行壓扁操作,最后對分支機構(gòu)和循環(huán)結(jié)構(gòu)基本塊的混淆算法做出了非常詳細(xì)的論述,并且將混淆前后范例代碼和結(jié)構(gòu)圖進行了展現(xiàn)。
[1]Cimato S, De Santis A, Ferraro Petrillo U. Overcoming the obfuscation of Java programs by identifier renaming[J]. Journal of Systems & Software, 2005, 78(1):60-72.
[2]宋亞奇, 李莉. 基于隨機插入策略的Java混淆器設(shè)計與實現(xiàn)[J]. 計算機工程與設(shè)計, 2009, 30(4):887-889.
[3]Sun Y, Huang G. A control flow obfuscation scheme based on garbage code[J]. Journal of Theoretical & Applied Information Technology, 2012.
[4]蔣華, 劉勇, 王鑫. 基于控制流的代碼混淆技術(shù)研究[J]. 計算機應(yīng)用研究, 2013, 30(3):897-899.
[5]Kulkarni A, Metta R. A New Code Obfuscation Scheme for Software Protection[C]// IEEE, International Symposium on Service Oriented System Engineering. IEEE, 2014:409-414.
[6]陳喆, 王志, 王曉初, 賈春福. 基于代碼移動的二進制程序控制流混淆方法[J]. 計算機研究與發(fā)展, 2015, 52(8):1902-1909.
[7]邵孟良, 齊德昱, 劉東文. 一種多態(tài)內(nèi)聯(lián)代碼混淆算法[J]. 計算機應(yīng)用研究, 2015, 32(6):1787-1790.
[8]王志, 賈春福, 劉偉杰, 王曉初, 張海寧, 于曉旭,等. 一種抵抗符號執(zhí)行的路徑分支混淆技術(shù)[J]. 電子學(xué)報,2015,(5):870-878.
[9]Ceccato M, Penta M D, Falcarin P, et al. A family of experiments to assess the effectiveness and efficiency of source code obfuscation techniques[J]. Empirical Software Engineering, 2014, 19(4):1040-1074.
[10]姚琴. 基于數(shù)據(jù)混淆的軟件保護研究[D]. 武漢理工大學(xué), 2010.
[11]趙玉潔, 湯戰(zhàn)勇, 王妮, 房鼎益, 顧元祥. 代碼混淆算法有效性評估[J]. 軟件學(xué)報, 2012, 23(3):700-711.
[12]付劍晶, 王珂. 軟件迷惑變換的魯棒性量化評價[J]. 軟件學(xué)報, 2013, 24(4):730-748.
[13]林水明, 吳偉民, 陶桂華, 林志毅, 蘇慶. 基于主成分分析的代碼混淆有效性綜合評估模型[J]. 計算機應(yīng)用研究, 2016, 33(9):2819-2822.
A Code Obfuscation Policy for Java Control Flows
GE Hua, YU Pei-zhao, XIA Meng-sen
(School of Information Engineering, Wuhan 430072, China)
In the reverse analysis field, the structure of Java-based software often needs to be protected. This paper proposes a control flow obfuscation policy based on the structure code blocks under the conclusion of certain conventional code obfuscation policies. This policy is built on the complex structure blocks based on the software structure rather than on basic code. It firstly embeds the branches with junk code blocks, and then carries out the flattening operations based on the structure code blocks. The analysis of the policy indicates that this policy is rather efficient in practice.
code obfuscation; control flow obfuscation; code block
2017-01-15
葛 華(1977-),女,湖北武漢人,副教授,研究方向為電子信息。 余沛釗(1996-),男,湖北宜昌人,研究方向為電子科學(xué)與技術(shù)。本文的共同第一作者、通訊作者。 夏夢森(1992-), 男,碩士研究生,研究方向為信息安全。
TP31
A
1674-344X(2017)2-0034-04