摘 ?要:Android應(yīng)用程序在未經(jīng)任何加固處理的情況下極容易受到反編譯攻擊,存在較大的安全隱患。APP加固技術(shù)為應(yīng)用程序提供了有效的防護(hù)措施,增加了反編譯的難度,本文針對(duì)目前常用的反編譯手段提出了一種APP加固方案,該方案首先針對(duì)需要保護(hù)的資源文件進(jìn)行加密處理;然后針對(duì)DEX文件的反編譯,采用混淆代碼技術(shù)加固處理,針對(duì)二次打包,本文采用簽名校驗(yàn)技術(shù)。實(shí)驗(yàn)表明,本文提出的加固方案能夠有效地防患APK被反編譯,加大了二次打包的難度。
關(guān)鍵詞:APP反編譯;DEX加固;加殼保護(hù);二次打包
中圖分類號(hào):TP309.5 ? ? 文獻(xiàn)標(biāo)識(shí)碼:A
Abstract:Android applications without any reinforcement are extremely vulnerable to de-compilation attacks,with significant security risks.App reinforcement technology provides effective protection for applications and increases the difficulty of de-compilation.In this paper,an APP reinforcement scheme is proposed against the commonly used de-compilation methods.The scheme first encrypts the resource files to be protected;Then,for the DEX file recompilation,confusion code technology is used to reinforce the DEX file.For the secondary packaging,the signature verification technique is adopted in this paper.Experimental results show that the proposed reinforcement scheme can effectively prevent APK from being decompiled and thus increases the difficulty of secondary packaging.
Keywords:App de-compilation;DEX reinforcement;shell protection;secondary packing
1 ? 引言(Introduction)
Android程序在編譯后形成字節(jié)碼文件,經(jīng)過(guò)打包、優(yōu)化、簽名等工具處理后最終形成可發(fā)布的APK文件。然而,未經(jīng)加固處理的APK文件極容易被反編譯工具進(jìn)行逆向工程處理,暴露程序的實(shí)現(xiàn)細(xì)節(jié),甚至被植入惡意代碼[1]。Android APP加固技術(shù)能夠有效地防止程序被反編譯、破解、二次打包、注入等,提高程序的安全性,從而為維護(hù)知識(shí)版權(quán)增加了一道“防火墻”。
目前,Android APP加固技術(shù)[2]較多,常用的加固方法有混淆代碼、DEX加固、虛擬機(jī)加固、加密等。愛加密通過(guò)對(duì)APP進(jìn)行漏洞分析并采用DEX加殼保護(hù)、內(nèi)存和資源文件等的保護(hù)技術(shù)能夠有效地防止APP被二次打包。NAGA·IN[3]通過(guò)推出的手機(jī)客戶端安全檢測(cè)控件為銀行、基金、券商等手機(jī)軟件提供了有效的安全保障。360加固保[4]、阿里聚通過(guò)簽名校驗(yàn)、代碼加密壓縮、內(nèi)存動(dòng)態(tài)跟蹤等技術(shù)為移動(dòng)應(yīng)用提供專業(yè)性安全保護(hù)。本文在研究當(dāng)前各種加固技術(shù)的基礎(chǔ)上提出了一種Android APP加固方案,方案通過(guò)加密、混淆代碼、簽名校驗(yàn)等多種方法對(duì)目標(biāo)代碼進(jìn)行加固操作,經(jīng)實(shí)驗(yàn)驗(yàn)證,本文提出的加固方案能夠很好地對(duì)抗反編譯、二次打包、注入等攻擊。
2 ? APP反編譯概述(Overview of APP de-compilation)
2.1 ? Android APK結(jié)構(gòu)
APP反編譯無(wú)非是對(duì)Android應(yīng)用程序編譯打包后的APK進(jìn)行逆向工程,然后分析APK的目錄結(jié)構(gòu)和應(yīng)用程序的行為,并篡改應(yīng)用程序代碼、注入惡意代碼。不同的應(yīng)用程序APK結(jié)構(gòu)不同,但每一個(gè)APK中都包含基本目錄結(jié)構(gòu),也是逆向工程攻擊的目標(biāo)?;灸夸浗Y(jié)構(gòu)如下:
(1)classes.dex文件。該文件是JAVA源碼經(jīng)JDK編譯和DEX優(yōu)化后的DEX字節(jié)碼文件,可以直接運(yùn)行在Dalvik虛擬機(jī)上。DEX文件包括文件頭和文件主體兩部分,DEX文件頭主要包括校驗(yàn)字段、簽名字段偏移地址和長(zhǎng)度信息等,DEX文件的主體部分包括索引區(qū)和數(shù)據(jù)區(qū)。圖1是DEX文件的一個(gè)實(shí)例。
DEX文件的構(gòu)成如圖2所示。
(2)AndroidManifest.xml文件。該文件為應(yīng)用程序的配置文件,應(yīng)用程序建立時(shí)存在。配置文件描述了應(yīng)用程序的配置信息,如應(yīng)用的名稱、圖標(biāo)、版本、權(quán)限的授予、引用的庫(kù)信息等,在打包時(shí)配置文件經(jīng)過(guò)了壓縮。
(3)META-INF目錄。該目錄存放簽名文件,如CERT.RSA、CERT.SF和MANIFEST.MF。
(4)res目錄和assets目錄。這兩個(gè)目錄為應(yīng)用程序的資源文件目錄,目錄下的部分資源將被打包進(jìn)APK中。
(5)resources.arsc文件。該文件為二進(jìn)制資源文件的索引文件,程序運(yùn)行時(shí)引用資源ID,通過(guò)該索引文件的映射找到對(duì)應(yīng)的資源。
2.2 ? 反編譯工具
當(dāng)前,網(wǎng)絡(luò)上有許多反編譯之類的免費(fèi)工具,Android APP反編譯常用的工具有:
(1)APKTool:APKTool[5]是GOOGLE提供的APK編譯工具,利用該工具能夠獲取APK中的圖片、布局等資源文件和目錄結(jié)構(gòu)。
(2)dex2jar[6]:該工具能夠?qū)PK中的classes.dex文件轉(zhuǎn)換成JAR文件。
(3)JD-GUI:是反編譯工具之一,利用該工具能夠查看dex2jar生成的JAR文件,顯示反編譯后的JAVA源代碼。
利用以上三個(gè)工具能夠輕松地將APK反編譯成JAVA源代碼,其實(shí)現(xiàn)步驟如下:
步驟一:利用APKTool工具對(duì)APK實(shí)施第一輪反編譯,反編譯后得到APK的目錄結(jié)構(gòu)及資源文件。
步驟二:利用dex2jar工具將APK目錄下的classes.dex文件轉(zhuǎn)換成JAR文件,生成的JAR文件無(wú)法直接查看。
步驟三:利用JD-GUI工具查看將DEX文件轉(zhuǎn)換后的JAR文件,源代碼直接在該工具下查看,反編譯結(jié)束。
3 ? 反編譯分析(Analysis of de-compilation)
針對(duì)以上反編譯工具的使用我們不難發(fā)現(xiàn),沒(méi)有經(jīng)過(guò)加固的APK極容易被反編譯,應(yīng)用程序代碼的安全性存在巨大的隱患。下面本文分析隱患存在的原因:
(1)APK本身存在一定的開放性[7]。我們將APK文件的后綴名手工改成壓縮文件的后綴名,如.rar或.zip,其目錄結(jié)構(gòu)完全暴露出來(lái)。雖然部分文件如AndroidManifest.xml、classes.dex等文件經(jīng)過(guò)了編譯,但其目錄下的部分資源文件卻是原封不動(dòng)地被打包進(jìn)APK,如res、assets目錄下的資源文件。
(2)JAVA字節(jié)碼易被反編譯[8]。JAVA代碼經(jīng)編譯后形成字節(jié)碼保存在class文件中,而字節(jié)碼本身是一種中間代碼,是解析后的帶有豐富語(yǔ)義的跨平臺(tái)編碼,這些語(yǔ)義字節(jié)碼直接表達(dá)了程序的行為和動(dòng)機(jī),經(jīng)過(guò)極為簡(jiǎn)單的反編譯就能破解其中的語(yǔ)義信息。
(3)Android APP的簽名機(jī)制能夠被偽造[9]。在JDK 1.7版本前APK的簽名能夠輕易地被偽造,從而將反編譯后的文件進(jìn)行二次打包。雖然在后來(lái)的版本中使用原APK的簽名進(jìn)行二次打包是無(wú)效的,但二次打包工具卻能夠?yàn)榉淳幾g后的文件進(jìn)行重新簽名,從而誕生了一個(gè)全新的偽造的應(yīng)用程序。
4 ? 加固方案(Reinforcement scheme)
經(jīng)過(guò)對(duì)反編譯過(guò)程進(jìn)行分析我們不難發(fā)現(xiàn),如果需要提高應(yīng)用程序的安全性,增加APK的反編譯難度,就必須針對(duì)反編譯使用的手段采取相應(yīng)的措施來(lái)加固APK。本文在研究反編譯技術(shù)的基礎(chǔ)上提出一種加固Android APP的方案,該方案增加了反編譯的難度,能夠有效地防止APK被反編譯。
4.1 ? 加固方案描述
針對(duì)反編譯工具能夠輕易地提取APK中的資源文件,本文提出抽取需要保護(hù)的資源文件,并對(duì)其進(jìn)行加密處理;針對(duì)DEX文件的反編譯,本文采用混淆代碼加固處理;針對(duì)二次打包,本文采用簽名校驗(yàn)技術(shù)防患重簽名,從而加大了二次打包的難度。加固方案的基本操作流程如圖3所示。
4.2 ? 加固方案的實(shí)現(xiàn)
本方案的實(shí)現(xiàn)分三個(gè)步驟進(jìn)行:
第一步:對(duì)資源文件進(jìn)行加密、加殼處理。處理過(guò)程如下 :
(1)將APK文件的后綴名改成.zip或.rar,并將修改后的APK文件解壓至一文件下。
(2)抽取需要保護(hù)的資源文件。編寫JAVA文件讀取程序,由文件讀取程序以文件流方式讀取需要保護(hù)的資源文件。
(3)對(duì)抽取的文件采用加密處理,并隱藏加密文件。在文件讀取的過(guò)程中采用MD5加密算法對(duì)文件流進(jìn)行加密處理,并設(shè)置文件的屬性為隱藏。
(4)編寫資源解密恢復(fù)程序,并將代碼放置Application類的入口。在Application類的入口處編寫MD5解密算法,在程序正式執(zhí)行前調(diào)用解密算法,恢復(fù)加密的資源文件,以保證程序能夠正常訪問(wèn)資源文件。
經(jīng)過(guò)以上步驟處理,APK中的資源文件已經(jīng)被加密,反編譯工具得到的將是加密后的資源文件。而APK在正式執(zhí)行前已經(jīng)調(diào)用解密算法恢復(fù)了被加密的資源文件,加密方案并不影響程序?qū)Y源的正常訪問(wèn)。
第二步:對(duì)classes.dex進(jìn)行代碼混淆加固處理。處理過(guò)程如下:
(1)利用反編譯工具對(duì)classes.dex文件實(shí)施反編譯。常用的反編譯工具dex2jar和JD-GUI能夠輕松地對(duì)DEX文件進(jìn)行反編譯,反編譯后生成jar文件,從JD-GUI工具中能夠查看該jar文件中的源碼文件。以新建一個(gè)“HelloWorld”應(yīng)用程序?yàn)槔?,將該程序APK中的classes.dex文件經(jīng)反編譯后在JD-GUI中打開,我們能看到,未經(jīng)代碼混淆處理的APK經(jīng)反編譯后,其源代碼暴露無(wú)遺,圖4是“HelloWorld”應(yīng)用程序經(jīng)反編譯后的結(jié)果。
(2)利用ProGuard工具對(duì)反編譯后的應(yīng)用程序?qū)嵤┐a混淆。在Android SDK中集成了一個(gè)ProGuard免費(fèi)工具,也可使用其他版本的ProGuard工具,利用該工具可以對(duì)反編譯后的jar文件實(shí)施代碼混淆。ProGuard的執(zhí)行過(guò)程由六個(gè)步驟組成:
第一步:輸入:將原DEX文件反編譯后的jar文件作為輸入值。
第二步:壓縮:檢測(cè)并移除代碼中無(wú)用的類、字段、方法等。
第三步:優(yōu)化:移除無(wú)用指令,對(duì)字節(jié)碼進(jìn)行優(yōu)化。
第四步:混淆:使用a、b、c這樣的簡(jiǎn)短字母對(duì)類、字段和方法進(jìn)行重命名。
第五步:預(yù)檢:在Java平臺(tái)上對(duì)處理后的代碼進(jìn)行預(yù)檢,確保加載的class文件是可執(zhí)行的。
第六步:輸出:最后將混淆后的代碼以jar文件形式輸出。
ProGuard工具執(zhí)行過(guò)程如圖5所示。
第七步:重新打包和簽名。處理過(guò)程如下:
(1)新建文件夾,將反編譯后的所有工程文件夾和文件放置在該文件夾下。
(2)利用打包工具生成目標(biāo)APK,并利用重簽名工具對(duì)目標(biāo)APK實(shí)施重簽名。打包工具可以使用apktool,重簽名工具可以使用signapk工具。
5 ? 實(shí)驗(yàn)驗(yàn)證(Experimental verification)
為了驗(yàn)證本方案是否可行,本文以未經(jīng)任何加固處理的APK為實(shí)驗(yàn)對(duì)象,采用本方案提供的操作步驟,對(duì)實(shí)驗(yàn)對(duì)象實(shí)施加固處理。
(1)實(shí)驗(yàn)?zāi)康?/p>
通過(guò)方案提供的操作步驟驗(yàn)證采用本方案能否對(duì)目標(biāo)APK實(shí)施加固處理,并通過(guò)對(duì)加固處理后的APK實(shí)施反編譯,驗(yàn)證反編譯能否成功。
(2)實(shí)驗(yàn)預(yù)期結(jié)果
如果對(duì)加固后的APK實(shí)施反編譯不能成功,表明本方案的加固操作能夠有效地防患APK被反編譯,加大了二次打包的難度。
(3)實(shí)驗(yàn)過(guò)程
本實(shí)驗(yàn)以名為“Helpme.apk”的APK為實(shí)驗(yàn)對(duì)象,該APK未經(jīng)任何加固處理,其源代碼目錄結(jié)構(gòu)如圖6所示。
為了對(duì)APK中的需要保護(hù)的資源文件進(jìn)行加密處理,本文選擇APK中的圖片資源作為重要的保護(hù)資源,并對(duì)其實(shí)施MD5加密處理。加密過(guò)程調(diào)用事先編寫好的方法,以其中一張圖片“s4.png”為例,加密前后對(duì)比的結(jié)果如圖7所示。
接下來(lái)利用反編譯工具dex2jar對(duì)classes.dex文件實(shí)施反編譯。在cmd命令窗口定位到dex2jar所在的文件夾,并輸入如下命令:
d2j-dex2jar.bat classes.dex
命令執(zhí)行完畢后在dex2jar文件夾下新生成一個(gè)classes-dex2jar.jar文件,該文件為反編譯后生成的壓縮文件,不能直接打開,可以利用JD-GUI工具查看該文件的目錄結(jié)構(gòu)和文件,JD-GUI工具下查看的目錄結(jié)構(gòu)如圖8所示。
下面利用ProGuard工具對(duì)反編譯后的jar文件實(shí)施代碼混淆,為了代碼混淆的實(shí)施能夠順利進(jìn)行,并且能夠看到混淆后的結(jié)果,在實(shí)施混淆之前需要對(duì)相關(guān)參數(shù)進(jìn)行設(shè)置。
支持庫(kù)參數(shù):添加三項(xiàng)支持庫(kù),即:rt.jar、cocos2d-android.jar和android.jar。
輸出參數(shù):設(shè)置輸入文件為classes-dex2jar_pro.jar。
利用ProGuard工具實(shí)施代碼混淆的結(jié)果如圖9所示。
從圖8和圖9的對(duì)比可以看出,實(shí)施代碼混淆后的目錄結(jié)構(gòu)發(fā)生了變化,原目錄結(jié)構(gòu)下的文件被不能表達(dá)任何語(yǔ)義的簡(jiǎn)短字母代替,源代碼中的類、字段和方法等也被簡(jiǎn)短字母代替,從而增加了反編譯的難度。
雖然我們對(duì)DEX文件實(shí)施了代碼混淆,但利用相關(guān)工具依然能夠?qū)?shí)施代碼混淆后的DEX文件實(shí)施二次反編譯,為此,本文利用signapk工具進(jìn)行簽名校驗(yàn),由于篇幅所限,本文不再對(duì)簽名校驗(yàn)的過(guò)程做詳細(xì)說(shuō)明。
本文最后將加密后的資源文件和代碼混淆后的文件進(jìn)行重新打包,并使用簽名校驗(yàn)技術(shù)實(shí)施重簽名,將新打包的APK再次實(shí)施反編譯,最后實(shí)驗(yàn)結(jié)果表明,反編譯過(guò)程出現(xiàn)錯(cuò)誤,由此證明了本文提出的APP加固方案能夠有效地防患APK被反編譯,加大了二次打包的難度。再次對(duì)加固后的APK文件實(shí)施反編譯實(shí)驗(yàn)結(jié)果如圖10所示。
6 ? 結(jié)論(Conclusion)
本文系統(tǒng)地介紹了一種Android APP加固方案,方案為了對(duì)APP中的資源進(jìn)行有效的保護(hù),采用了加密方式對(duì)重要資源進(jìn)行加密處理,為了防止DEX文件被反編譯,采用了混淆代碼技術(shù)加固處理,為了防止APK被二次打包,采用了簽名校驗(yàn)技術(shù)。最后通過(guò)實(shí)驗(yàn)驗(yàn)證了本方案的可行性。
參考文獻(xiàn)(References)
[1] 吳敬征,武延軍,武志飛,等.基于有向信息流的Android隱私泄露類惡意應(yīng)用檢測(cè)方法[J].中國(guó)科學(xué)院大學(xué)學(xué)報(bào),2015,32(06):807-815.
[2] 宋言言,羅森林,尚海,等.函數(shù)Native化的Android APP加固方法[J].浙江大學(xué)學(xué)報(bào)(工學(xué)版),2019,53(03):555-562.
[3] 梆梆安全.梆梆加固[EB/OL].http://blog.csdn.net/justfwd/article/dct-ails/51164281,2018-02-10.
[4] 趙躍華,劉佳.安卓APP安全加固系統(tǒng)的分析與設(shè)計(jì)[J].計(jì)算機(jī)工程,2018,44(02):187-192.
[5] 鄭興生.Android應(yīng)用程序反編譯工具研究與設(shè)計(jì)[D].北京理工大學(xué),2016.
[6] 梁丹.基于動(dòng)態(tài)字節(jié)碼注入的Android沙盒模型[D].上海交通大學(xué),2015.
[7] 章宗美,桂盛霖,任飛.基于N-gram的Android惡意檢測(cè)[J].計(jì)算機(jī)科學(xué),2019,46(02):145-151.
[8] 劉奧,過(guò)辰楷,王偉靜,等.Android應(yīng)用Activity啟動(dòng)環(huán)研究[J/OL].計(jì)算機(jī)學(xué)報(bào),2019:1-18.
[9] 汪潤(rùn),唐奔宵,王麗娜.DroidFAR:一種基于程序語(yǔ)義的Android重打包應(yīng)用抗混淆檢測(cè)方法[J].武漢大學(xué)學(xué)報(bào)(理學(xué)版),2018,64(05):407-414.
作者簡(jiǎn)介:
彭守鎮(zhèn)(1979-),男,碩士,講師.研究領(lǐng)域:計(jì)算機(jī)應(yīng)用技術(shù),信息安全,軟件技術(shù).