


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