李路鹿 張峰 李國繁
摘 ?要: 代碼混淆技術(shù)是一種語義保留的代碼變換技術(shù),是衡量代碼相似度檢測方法的重要指標(biāo)之一。本文主要對現(xiàn)有的代碼混淆手段的研究現(xiàn)狀和發(fā)展進(jìn)行了綜述。首先闡述了代碼混淆的相關(guān)定義,然后介紹了現(xiàn)有的幾種代碼混淆手段,對代碼混淆手段進(jìn)行了系統(tǒng)的分類,分別介紹了每種代碼混淆手段。最后對代碼混淆手段進(jìn)行了總結(jié)與評價(jià)。
關(guān)鍵詞:?代碼混淆;反編譯;代碼轉(zhuǎn)換
中圖分類號: TP309.2????文獻(xiàn)標(biāo)識(shí)碼:?A????DOI:10.3969/j.issn.1003-6970.2020.02.013
【Abstract】: Code obfuscation is a code transformation technique with semantic reservation, and it is one of the important indicators to measure source code similarity. This paper mainly reviews existing works of code obfuscation. Firstly, the definition of code obfuscation is described. Then, several existing methods of code obfuscation are introduced, and they are classified systematically. Finally, the paper summarizes and evaluates the methods of code obfuscation.
【Key words】: Code obfuscation; Decompile; Code transcoding
0??引言
代碼混淆是一種變換代碼的流程結(jié)構(gòu)及數(shù)據(jù)關(guān)系的技術(shù),其不會(huì)改變原代碼的語法和語義規(guī)則。最先提出代碼混淆技術(shù)的主要目的是保護(hù)軟件代碼的安全[1]。由于各種語言的程序會(huì)很容易的被反編譯或者惡意逆向工程攻擊,因此,通過對程序進(jìn)行混淆,使得程序源代碼變得更加難以理解,不易被反編譯工具破解,從而達(dá)到知識(shí)產(chǎn)權(quán)和保密信息不被竊取的目的[2-5]。
另外,代碼混淆技術(shù)也被抄襲者用來達(dá)到掩蓋自己抄襲代碼的目的[6]。隨著現(xiàn)代計(jì)算機(jī)和網(wǎng)絡(luò)的不斷進(jìn)步,獲取源代碼的途徑越來越多,代碼抄襲的難度也逐漸變低。代碼抄襲是一種為了達(dá)到目的去完全拷貝使用或修改后使用他人代碼的行為。據(jù)
統(tǒng)計(jì),在國外大約有85%的學(xué)生承認(rèn)曾抄襲過別人的代碼作業(yè)[7]。對編程作業(yè)研究分析發(fā)現(xiàn),有1%-?10%代碼為抄襲代碼,且這個(gè)比例正在逐年增長[8],可見代碼抄襲現(xiàn)象非常普遍。為了達(dá)到抄襲代碼且不被發(fā)現(xiàn)的目的,出現(xiàn)了各種代碼混淆技術(shù)。
為了全面分析和對比當(dāng)前已有的代碼混淆技術(shù),本文對已有的代碼混淆技術(shù)進(jìn)行分類和總結(jié),然后根據(jù)已有的常見代碼混淆手段對其進(jìn)行了解釋和舉例說明。
1 ?代碼混淆概述
代碼混淆指使用一定的代碼轉(zhuǎn)換手段把一個(gè)代碼轉(zhuǎn)換成另一個(gè)代碼的技術(shù), 并且這兩個(gè)代碼在可觀測行為上能夠保持語義等價(jià)[9]。代碼混淆的目的是隱藏程序的邏輯,以達(dá)到抄襲目的或者使混淆后的代碼更加難以理解和分析[10]。
一般可在源代碼、字節(jié)碼或者機(jī)器碼上進(jìn)行代碼混淆。代碼混淆可以人工進(jìn)行混淆,也可使用代碼混淆工具進(jìn)行自動(dòng)混淆,常見的代碼混淆工具有Sandmark、DexGuard、Upx、ProGuard等[11]。
代碼混淆技術(shù)一般從代碼布局、語法變換[12]以及語義變換三個(gè)方面來分類。目前常見的代碼混淆技術(shù)主要為代碼布局和語法變換兩類,很少涉及到語義信息的變換。語義信息變換的代碼混淆付出的代價(jià)比較大,且容易出現(xiàn)錯(cuò)誤,所以較少有涉及語義信息的代碼抄襲。此外,涉及語義信息變換的混淆代碼,也是目前已有的代碼相似度檢測工具無法檢測出來的。
2??代碼混淆技術(shù)的發(fā)展與分類
2.1??代碼混淆手段的發(fā)展
代碼混淆技術(shù)等相關(guān)概念最先是由Collberg[13]提出,并進(jìn)行性能評估和分類,提出代碼混淆技術(shù)分為預(yù)防混淆技術(shù)、外形混淆技術(shù)、控制流混淆技術(shù)以及數(shù)據(jù)混淆技術(shù)。其中控制流混淆技術(shù)和數(shù)據(jù)混淆技術(shù)是當(dāng)前比較流行的混淆技術(shù),兩者抗反編譯和惡意逆向工程攻擊能力較強(qiáng)。
Faidhi[14]在論文中提出,根據(jù)代碼抄襲所付出的代價(jià)不斷增加,可以把代碼抄襲手段分為以下7種:(1)完全不更改;(2)只修改注釋;(3)更換標(biāo)識(shí)符;(4)更改變量的位置;(5)過程組合; ????(6)更換代碼語句的順序;(7)等價(jià)控制結(jié)構(gòu)變換。
Joy[15]提出代碼混淆方法可以分為詞法變化和結(jié)構(gòu)變化兩類,前者包括代碼格式、行數(shù)、注釋以及變量名的變化;后者主要包括控制結(jié)構(gòu)語句和操作符的替換、在不更改程序結(jié)果的前提下調(diào)整語句的順序。Whale[16]在論文中另外提出了等價(jià)語句和數(shù)據(jù)類型的變換,添加冗余代碼等代碼混淆手段。
Jones[17]總結(jié)了10種常見的代碼抄襲手段,除以上幾種另外還提出更改代碼塊順序,并根據(jù)抄襲所付出的努力從易到難進(jìn)行了一個(gè)系統(tǒng)的排序。文獻(xiàn)[18]在進(jìn)行代碼相似度檢測時(shí)提出了常量替換和表達(dá)式拆分兩種代碼混淆手段。文獻(xiàn)[19]新提出了生成新函數(shù)這種較復(fù)雜的代碼混淆手段。
Myles[20]在進(jìn)行軟件相似度檢測時(shí)也提出生成新函數(shù)這種代碼混淆手段,另外還提到了循環(huán)展開代碼混淆手段,循環(huán)展開是指通過復(fù)制循環(huán)體來減少循環(huán)的次數(shù)。文獻(xiàn)[21]首次提出了不透明謂詞這種代碼混淆手段,不透明謂詞是一種控制流混淆技術(shù),指在不改變程序結(jié)果的基礎(chǔ)上在原程序中加入了大量的不可達(dá)路徑或者是不可達(dá)分支,屬于增加冗余代碼的一種。
2.2??代碼混淆手段總結(jié)分類
本文根據(jù)代碼抄襲時(shí)常用的幾種抄襲手段,進(jìn)行了總結(jié)和完善。常見的代碼抄襲手段從易到難主要分為以下14種,如圖1所示:(1)完全拷貝; ???(2)修改注釋;(3)重新排版;(4)標(biāo)識(shí)符重命名;(5)更改代碼塊排序;(6)調(diào)整代碼塊內(nèi)語句的順序;(7)常量替換;(8)改變表達(dá)式中操作符或操作數(shù)順序;(9)改變數(shù)據(jù)類型;(10)增加冗余代碼;(11)表達(dá)式拆分;(12)控制結(jié)構(gòu)等價(jià)變換; ???(13)循環(huán)展開;(14)函數(shù)生成和合并。為了更準(zhǔn)確的統(tǒng)計(jì)現(xiàn)有的代碼混淆手段,本論文對這14種手段的一些混淆手段進(jìn)行了細(xì)化。下面為14種代碼混淆手段的詳細(xì)介紹以及舉例說明。
(1)完全拷貝
完全拷貝是指拷貝代碼的一部分或者一個(gè)完整的程序,且不做任何的修改。
(2)修改注釋
修改注釋是指完全拷貝代碼,對代碼不做任何修改,為了達(dá)到混淆的目的對代碼中的注釋進(jìn)行 ?修改。
(3)重新排版
重新排版是指完全拷貝代碼后,不修改代碼,對代碼進(jìn)行空格或者空行,以調(diào)整代碼的格式。
(4)標(biāo)識(shí)符重命名
標(biāo)識(shí)符重命名指統(tǒng)一更改代碼中的變量名或函數(shù)名,屬于詞法變換。如圖1所示,圖1(1)為一段原代碼,圖1(2)為使用標(biāo)識(shí)符重命名混淆手段更改后的代碼。
(5)更改代碼塊排序
更改代碼塊排序是指在不改變代碼運(yùn)行順序的前提下,以基本塊為單位更換代碼的順序,以達(dá)到代碼混淆的目的?;緣K是指代碼順序執(zhí)行的語句序列,且只有一個(gè)入口和一個(gè)出口,入口就是其第—個(gè)語句,出口是其最后一個(gè)語句,執(zhí)行時(shí)只從其入口進(jìn)入,從其出口退出。如圖2所示,圖2(1)有if分支和for循環(huán)兩個(gè)基本塊,圖2(2)中兩個(gè)基本塊交換順序進(jìn)行混淆,但是并不影響程序的運(yùn)行結(jié)果。
(6)調(diào)整代碼塊內(nèi)語句的順序
調(diào)整代碼塊內(nèi)語句的順序是對基本塊中的語句進(jìn)行調(diào)換順序,且不影響程序執(zhí)行結(jié)果。如圖3所示,更改幾個(gè)賦值語句的順序。
(7)常量替換
常量是不隨時(shí)間變化的某些量的固定信息,也可以是某一數(shù)值的字符或字符串,屬于指令的一部分。如圖4所示,把原代碼中的常量100替換為101,且保證更改后不影響程序結(jié)果。
(8)改變表達(dá)式中操作符或操作數(shù)順序
代碼中表達(dá)式與數(shù)學(xué)中表達(dá)式的定義相似,且具有一定的值,用操作符把常數(shù)和變量連接起來的代數(shù)式。例如,m=2+3*4+5為一個(gè)表達(dá)式,為了混淆代碼,可以把這個(gè)表達(dá)式更改為m=3*4+5+2,程序的運(yùn)行結(jié)果不變,但是表達(dá)式中的操作符和操作數(shù)的順序改變了。
(9)改變數(shù)據(jù)類型
改變數(shù)據(jù)類型指在不改變代碼運(yùn)行結(jié)果的前提下更改部分變量的數(shù)據(jù)類型,以達(dá)到混淆代碼的目的。如圖5所示,原代碼中的變量為int類型,更改后為String類型,代碼運(yùn)行結(jié)果不改變。
(10)增加冗余代碼
增加冗余代碼指在代碼中加入不必要的、對程序沒有影響的代碼段。增加冗余代碼分為增加有數(shù)據(jù)依賴的冗余代碼和增加無數(shù)據(jù)依賴的冗余代碼,后者較前者更容易操作。有數(shù)據(jù)依賴的冗余代碼和無數(shù)據(jù)依賴的冗余代碼又都包含增加順序語句、增加可達(dá)分支和不透明謂詞。增加順序語句是指在代碼中加入可以運(yùn)行但不影響結(jié)果的順序執(zhí)行的代碼;增加可達(dá)分支是指在不改變結(jié)果的前提下加入冗余的可執(zhí)行的分支語句;不透明謂詞是指在不改變程序結(jié)果的基礎(chǔ)上在原程序中加入了大量的不可達(dá)路徑或不可達(dá)分支。如圖6所示,為不透明謂詞代碼混淆示例,在圖6(2)中加入一個(gè)if分支,不運(yùn)行且不影響程序的運(yùn)行結(jié)果。
(11)表達(dá)式拆分
表達(dá)式拆分指為了混淆代碼將一個(gè)復(fù)雜的表達(dá)式拆分成多個(gè)簡單的表達(dá)式。例如可以把表達(dá)式a=4*(b+3)拆分成c=b+3和a=4*c兩個(gè)簡單的表達(dá)式,以達(dá)到混淆代碼的目的。
(12)控制結(jié)構(gòu)等價(jià)變換
控制結(jié)構(gòu)等價(jià)變換指在不影響程序運(yùn)行結(jié)果的前提下,用相同功能的控制結(jié)構(gòu)替換代碼中的控制結(jié)構(gòu),以進(jìn)行代碼混淆。如圖7所示,用while循環(huán)結(jié)構(gòu)替換原代碼中的for循環(huán)結(jié)構(gòu),且代碼語義不變。
(13)循環(huán)展開
循環(huán)展開可以分為部分展開和全部展開。循環(huán)部分展開是通過復(fù)制部分循環(huán)體減少循環(huán)的次數(shù)以達(dá)到混淆代碼的目的,代碼結(jié)構(gòu)不變;循環(huán)全部展開是通過復(fù)制循環(huán)體來代替整個(gè)循環(huán)結(jié)構(gòu),代碼結(jié)構(gòu)發(fā)生變化。如圖8所示,(1)為原代碼,(2)中把原代碼中的循環(huán)結(jié)構(gòu)進(jìn)行了部分展開,代碼結(jié)構(gòu)不變;(3)把原代碼中的循環(huán)結(jié)構(gòu)通過復(fù)制循環(huán)體的形式,全部展開,循環(huán)結(jié)構(gòu)變成了多個(gè)賦值語句,但是程序運(yùn)行結(jié)果并沒有改變。
(14)函數(shù)生成和合并
函數(shù)生成指將代碼中特定功能的代碼塊封裝為一個(gè)新的函數(shù),用以調(diào)用。函數(shù)合并指將方法的調(diào)用語句替換為方法的具體實(shí)現(xiàn)語句。如圖9所示,把原代碼中的if分支代碼塊作為一個(gè)新的函數(shù)方法,進(jìn)行調(diào)用,以達(dá)到混淆代碼的目的,代碼結(jié)構(gòu)發(fā)生變化,但是不影響代碼運(yùn)行結(jié)果。
3??結(jié)束語
針對代碼混淆技術(shù),本文首先闡述了代碼混淆手段的發(fā)展進(jìn)程,然后詳細(xì)介紹了當(dāng)前常用的代碼混淆手段,并對其中一些混淆手段進(jìn)行了細(xì)化,然后通過舉例明確解釋了每種代碼混淆手段。
代碼混淆是軟件工程領(lǐng)域一項(xiàng)實(shí)用的技術(shù),軟件技術(shù)的發(fā)展會(huì)催生出更多復(fù)雜的代碼混淆手段,使得代碼混淆技術(shù)的研究也面臨新的問題和挑戰(zhàn),需要學(xué)術(shù)界和企業(yè)界們對代碼混淆問題進(jìn)行更深一步的研究。
參考文獻(xiàn)
Collberg C, Thomborson C, Low D. Manufacturing cheap, resilient, and stealthy opaque constructs[C]//Proceedings of the 25th ACM SIGPLAN-SIGACT symposium on Principles of programming languages. ACM, 1998: 184-196.
印杰, 李千目. 軟件代碼漏洞的電子取證技術(shù)綜述[J]. 軟件, 2015, 36(12): 49-59.
耿達(dá). 基于物聯(lián)網(wǎng)樓房照明系統(tǒng)設(shè)計(jì)和實(shí)現(xiàn)[J]. 軟件, 2018, 39(12): 222-225.
丁小盼, 周浩, 賀珊, 等. 基于OpenStack 的云測試平臺(tái)及其性能分析研究[J]. 軟件, 2015, 36(1): 6-11.
金昱東. 一種基于ReactNative 的代碼壓縮與動(dòng)態(tài)加載的實(shí)現(xiàn)方法[J]. 軟件, 2016, 37(02): 81-84.
熊浩, 晏海華, 郭濤, 等。代碼相似性檢測技術(shù): 研究綜述[J]. 計(jì)算機(jī)科學(xué), 2010, 37(8): 9-14.
Chuda D, Navrat P, Kovacova B, et al. The issue of (software) plagiarism: A student view[J]. IEEE Transactions on Education,?2011, 55(1): 22-28.
Georgina C, Mike J. Source-code plagiarism: A UK academic perspective[R]. Research Report RR-422, Department of Computer Science, University of Warwick,?2006.
Wu Z, Gianvecchio S, Xie M, et al. Mimimorphism: A new approach to binary code obfuscation[C]//Proceedings of the 17th ACM conference on Computer and communications security. ACM, 2010: 536-546.
Collberg C, Thomborson C, Low D. A taxonomy of obfuscating?transformations[R]. Department of Computer Science, The University of Auckland, New Zealand, 1997.
田振洲, 劉烴, 鄭慶華, 等.軟件抄襲檢測研究綜述[J]. 信息安全學(xué)報(bào), 2016, 1(3):?52-76.
馬培, 翟高壽. 面向硬件瞬時(shí)故障的Linux 設(shè)備驅(qū)動(dòng)敏感代碼的自動(dòng)分析與檢測[J]. 軟件, 2015, 36(12): 09-15.
Collberg C, Thomborson C, Low D. A taxonomy of obfuscating?transformations[R]. Department of Computer Science, The University of Auckland, New Zealand, 1997.
Faidhi J A W, Robinson S K. An empirical approach for detecting program similarity and plagiarism within a university?programming environment[J]. Computers & Education, 1987, 11(1): 11-19.
Joy M, Luck M. Plagiarism in programming assignments[J]. IEEE Transactions on education, 1999, 42(2): 129-133.
Whale G. Detection of plagiarism in student programs[C]//?Proceedings of the 9th Australian Computer Science Conference. Australian Computer Society, 1986: 231-241.
Jones E L. Metrics based plagiarism monitoring[J]. Proceedings?of?the 6th Annual CCSC Northeastern Conferene on the Journal?of Computing in Small Colleges,?2001,?16(4):?253-261.
趙長海, 晏海華, 金茂忠. 基于編譯和反匯編的程序相似性檢測方法[J]. 北京航空航天大學(xué)學(xué)報(bào), 2008, 34(6).
Ji J H, Woo G, Cho H G. A source code linearization technique for detecting plagiarized programs[C]//ACM SIGCSE?Bulletin. ACM, 2007, 39(3): 73-77.
Myles G, Collberg C. Detecting software theft via whole program?path birthmarks[C]//International Conference on Information Security. Springer, Berlin, Heidelberg, 2004: 404-415.
Hada S. Zero-knowledge and code obfuscation[C]//International Conference on the Theory and Application of Cryptology and Information Security. Springer, Berlin, Heidelberg, 2000: 443-457.
Roundy K A, Miller B P. Binary-code obfuscations in prevalent packer tools[J]. ACM Computing Surveys (CSUR), 2013, 46(1): 4.