apk是安卓工程打包的最終形式,將apk安裝到手機或者模擬器上就可以使用APP浑劳。反編譯apk則是將該安卓工程的源碼阱持、資源文件等內(nèi)容破解出來進行分析∧а客戶端QA可能會遇到的問題是衷咽,本地測試包與正式發(fā)布的apk包之間可能存在差異(debug與release)。如果能夠進行最終上線前的apk反編譯蒜绽,一方面可以校驗apk是否有遺漏的Jar包或者資源文件镶骗,另一方面也可以簡要核對本版本apk的基本信息是否正確∽仪希可加入產(chǎn)品上線前最終上線清單確認的環(huán)節(jié)中卖词。本文主要介紹了apk反編譯的基本原理和主要方法,最后介紹了目前比較成熟的反編譯工具。
一此蜈、APK反編譯基本原理
1.APK分析
apk文件的本質(zhì)是壓縮文件即横,我們將apk文件修改后綴名為zip或者rar等,可以直接解壓縮查看apk文件夾裆赵。下圖即為一個基本的apk文件夾結(jié)構(gòu)圖东囚。
我們簡要看下每個文件夾和文件里都有什么內(nèi)容:
- assets文件夾:原始資源文件夾,對應(yīng)著Android工程的assets文件夾战授,一般用于存放原始的圖片页藻、txt、css等資源文件植兰。
- lib:存放應(yīng)用需要的引用第三方SDK的so庫份帐。比如一些底層實現(xiàn)的圖片處理、音視頻處理楣导、數(shù)據(jù)加密的庫等废境。而該文件夾下有時會多一個層級,這是根據(jù)不同CPU 型號而劃分的筒繁,如 ARM噩凹,ARM-v7a,x86等毡咏。
- META-INF:保存apk簽名信息驮宴,保證apk的完整性和安全性。
- res:資源文件夾呕缭,其中的資源文件包括了布局(layout)堵泽,常量值(values),顏色值(colors)臊旭,尺寸值(dimens)落恼,字符串(strings),自定義樣式(styles)等离熏。
- AndroidManifest.xml文件:全局配置文件佳谦,里面包含了版本信息、activity滋戳、broadcasts等基本配置钻蔑。不過這里的是二進制的xml文件,無法直接查看奸鸯,需要反編譯后才能查看咪笑。
- classes.dex文件:這是安卓代碼的核心部分,,dex是在Dalvik虛擬機上可以執(zhí)行的文件娄涩。這里有classes.dex和classes2.dex兩個文件窗怒,說明工程的方法數(shù)較多映跟,進行了dex拆分。
- resources.arsc文件:記錄資源文件和資源id的映射關(guān)系扬虚。
直接查看apk壓縮文件努隙,只有assets可以直接查看,我們可以校驗其中是否已加入必需的資源文件辜昵。但是對于版本的基本情況荸镊、所需的JAR包等都是無法直接查看的,需要進行apk反編譯處理堪置。了解apk的反編譯原理躬存,需要從apk打包原理講起。
2.從APK打包講起
使用IDE進行安卓開發(fā)舀锨,便捷的打包調(diào)試使得打包的很多細節(jié)都忽略了岭洲,安卓官網(wǎng)給出了apk打包的基本流程圖,圖中紅框是我對打包流程幾個主要模塊的劃分:
我們從中梳理出apk打包的基本流程模塊如下:
-
資源處理
這一過程中主要使用appt工具進行資源文件的處理雁竞,分析AndroidManifest.xml中的資源文件钦椭,生成R.java和resources.arsc文件;aidl工具負責處理aidl文件碑诉,生成對應(yīng)的java接口文件。 -
代碼編譯
將上一過程中產(chǎn)生的R.java侥锦、java接口文件以及工程源代碼一起通過Java Compiler編譯成.class文件进栽,打成Jar包(這部分可以加入代碼混淆),然后與第三方庫的Jar包一起通過dx工具轉(zhuǎn)換成.dex文件恭垦。
通過apkbuilder工具將aapt生成的resources.arsc快毛、classes.dex(可能多個)、其他的資源一塊打包生成未經(jīng)簽名的apk文件番挺。 -
添加簽名
通過Jarsigner對生成的未簽名的apk進行簽名唠帝。
再通過zipalign對簽名后的apk進行對其處理,使apk中所有資源文件距離文件起始偏移為4字節(jié)的整數(shù)倍玄柏,從而在通過內(nèi)存映射訪問apk文件時會更快襟衰。
3.APK反編譯原理
通過回顧apk的打包原理,反編譯要做的事情也就明了了粪摘。反編譯要做的瀑晒,一是要將apk里的dex文件轉(zhuǎn)換成Jar包,再通過工具查看編譯前的java源文件徘意。二是通過工具查看apk里對應(yīng)的AndroidManifest.xml苔悦、resources.arsc、res各布局文件等二進制文件椎咧。反編譯所需要的工具主要有以下幾個:
二玖详、APK反編譯實踐
1.使用dex2jar將dex文件轉(zhuǎn)換成Jar包
在Mac上下載的dex2jar-2.0.zip包直接解壓縮即可,關(guān)鍵需要用到的文件是d2j-dex2jar.sh和d2j-dex2jar_invoke.sh,需要對這兩個文件先添加可執(zhí)行權(quán)限蟋座。然后將目標apk改為zip后綴劳澄,解壓縮直接拿到其中的dex文件。在終端輸入命令:
./d2j-dex2jar/d2j-dex2jar.sh classes.dex
注意要輸入classes.dex的正確路徑蜈七。
命令結(jié)束后會在當前目錄下生成classed-dex2jar.jar文件秒拔。如下圖所示:
ps:如果apk的方法數(shù)超過了65535,會生成多個dex文件飒硅,反編譯的話需要對這多個dex文件均進行轉(zhuǎn)換Jar包處理砂缩。
2.使用jd-gui將Jar包文件反編譯成java源文件
jd-gui下載解壓后,直接打開文件夾里面的JD-GUI三娩,即可打開圖形化界面庵芭。將我們上一個步驟生成的classes-dex2jar.jar直接拖動進入界面中,就可以看到反編譯之后的源碼結(jié)構(gòu)了雀监。
ps:這里有時候會看到諸如a.a.a双吆、b等字母標示的包名、類名或者方法名会前,這是由于在某些apk打包的時候進行代碼混淆導(dǎo)致的好乐。使用反編譯工具只能看到混淆之后的代碼結(jié)構(gòu),真正未混淆前的源碼還需要結(jié)合mapping.txt文件進行分析瓦宜。mapping.txt文件里即標注出了代碼混淆前后的文件名稱對應(yīng)關(guān)系蔚万。
3.使用apktool工具查看apk里的二進制文件
下載下來apktool并解壓縮后,調(diào)用java命令執(zhí)行临庇,命令如下:
java -jar apktool.jar d yourApkName.apk
命令執(zhí)行完后反璃,會在當前目錄下新增yourApkName文件夾,其中可以看到可讀的AndroidManifest.xml假夺、res目錄下的各布局文件淮蜈、assets文件夾等。
original文件夾是原始的AndroidManifest.xml文件已卷,res文件夾是反編譯出來的資源梧田,smali文件夾是反編譯出來的代碼。注意悼尾,smali是有點類似于匯編的語法柿扣,是Android虛擬機所使用的寄存器語言。
三闺魏、其他APK反編譯工具
以上是apk反編譯常用的主要工具和方法未状,現(xiàn)在也有一些工具可以將這些反編譯步驟全部集成起來,常用的有:
1.Android-classyshark
下載地址:https://github.com/google/android-classyshark/releases析桥,下載下來之后是一個可執(zhí)行的jar文件司草,在終端執(zhí)行java -jar classyshark.jar即可打開圖形化界面艰垂。在打開的圖形操作界面中拖入待目標apk,即可展示出反編譯之后的結(jié)果埋虹。
點擊上方的“Methods count”還能看到各個類中具體的方法數(shù)猜憎。
2.Android Studio 2.2的APK Analyzer
Android Studio 2.2版本新增了APK Analyzer功能,使用方法很簡單搔课,只需要將目標apk拖入到Android Studio 2.2中即可胰柑。
功能十分強大,可以直接將APK全部反編譯出來爬泥,在Android Studio界面上可以直接看到apk版本的信息柬讨,直接查看AndroidManifest.xml、R.java等文件袍啡。點擊classes.dex可以直接查看反編譯之后的代碼結(jié)構(gòu)踩官。可以說是集合了apktool境输、dex2jar蔗牡、jd-gui等反編譯工具的全部功能,十分便捷嗅剖。
上述是比較常見且較為成熟的apk反編譯工具辩越,但是稍有遺憾的是,以上工具均只能反編譯至混淆后的代碼窗悯,如何結(jié)合mapping.txt恢復(fù)成源代碼区匣,還沒有發(fā)現(xiàn)比較好的工具。
四蒋院、結(jié)語
在日常安卓端產(chǎn)品測試過程中,曾經(jīng)出現(xiàn)過的問題是本地測試打包與上線打包有差異莲绰,原因可能是開發(fā)誤以為某些jar包和資源文件只是本地測試需要欺旧,上線不需要,也可能是本地測試打包與上線打包的build types不同蛤签,導(dǎo)致本地測試通過辞友,而上線后出現(xiàn)了異常情況。這類問題測試的難點在于震肮,待上線的apk包對于某些情況無法經(jīng)過QA實時校驗称龙、缺少的jar包和資源文件并不會導(dǎo)致回歸測試的功能異常等。為了避免這種問題戳晌,對于apk正式上線前的上線清單鲫尊,可考慮加入待發(fā)布apk的反編譯資源包確認。QA可仔細核驗最終待發(fā)布的apk沦偎,可以通過反編譯的手段進一步對apk進行分析疫向,查看是否新增的jar包和資源文件咳蔚、so文件等均沒有遺漏,回歸測試功能點也沒有異常搔驼,才能正式上線谈火。
總之,產(chǎn)品發(fā)布是一件需謹慎對待的事情舌涨,增加對待上線apk的反編譯分析糯耍,一定程度上可以對產(chǎn)品質(zhì)量做最后一道把關(guān)。