知道了Apktool 的基本用法Apktool 使用教程 - 簡書,以及Apktool的全部參數配置Apktool 參數詳解 - 簡書之后,對于Apktool的用法,可以說已經基本搞定,不過源碼的閱讀也是比不可少的,懂得源碼,能改會改,才是解決棘手問題的根本能力。
注意:本文使用的源碼為github上拉取的最新代碼,2.4.2版本,目前暫未發(fā)布。 -- 2020年3月18日
1、查看apktool.jar的入口類
? ? 通過查看jar包的Manifest.MF文件,看到入口類為brut.apktool.Main

2、使用Android studio打開apktool的源碼 ? ?

3、找到入口類?brut.apktool.Main
? ? main函數主要做了以下事情,很簡單,此處不詳述。
? ? (1)設置系統(tǒng)屬性?System.setProperty("java.awt.headless", "true");
? ??????????這里的system,系統(tǒng)指的是 JRE (runtime)system,不是指 OS。
? ? (2)new一個命令行解析器,后續(xù)進行命令行參數的解析
? ? (3)初始化配置類,包括各種配置,日志輸出等級,是否處理資源文件等等
????????????????分所屬分別存儲在 normalOptions;DecodeOptions;BuildOptions;等變量中
? ? (4)設置日志級別,初始化Logger,設置是否打印步驟日志
? ? (5)解析到底是反編譯、重新打包還是安裝framework等參數
4、反編譯資源
????private static void cmdDecode(CommandLine cli)
? ? (1)創(chuàng)建核心類ApkDecoder,其構造方法中,new了一個Androlib類
? ? (2)解析反編譯相關的配置,都設置到decoder中備用

????(3)創(chuàng)建輸出目錄 ? ?

? ? (4)調用反編譯核心方法 ? ?

????(5)decod方法
? ? ? ? ????將--keep-broken-res配置值,存入AndrolibResources類中
? ? ? ? ? ? 檢查輸出目錄,輸入文件是否OK,不OK拋出異常
? ? ? ? ? ? OK則創(chuàng)建輸出目錄

? ? ? ? ? ? 輸出我們最常見到的一句log

? ? ? ? ? ? ? 之后就開始主要的反編譯邏輯了。
? ? ? ? (6)處理資源

? ? (7)具體的解析流程,網上各位大神分析的很到位。這里推薦一個,部分注釋也是參考了這位的帖子內容!
????????ApkTool項目解析resources.arsc詳解 - 掘金
5、反編譯源碼
? ? ? ? (1)反編譯最基礎的classes.dex文件

? ? ? ? ? ? (2)輸出log,開始反編譯dex

? ? ? ? ? ? ? ? ? ? ? ? 進入?SmaliDecoder 的?decode 方法。
? ? ? ? ? ? ? ? ? ? ? ? 最終執(zhí)行Baksmali庫的方法進行反編譯

? ? ? ? ? ? ? ? ? ? ? ? 具體解析過程,后續(xù)我準備再寫一篇關于 Baksmali 文章吧。
? ? ? ? ? ? ? ? ? ? ? ? 解析 dex 可以參考:Android逆向筆記 —— DEX 文件格式解析 - 掘金
? ? ? ? ? ? ? ? (3)處理多個dex,和解析一個dex一個道理,不再重復

6、處理assets和libs

7、處理未知文件

? ? 未知文件指非apk固定文件的內容:
? ??????"classes.dex", "AndroidManifest.xml", "resources.arsc", "res", "r", "R", "lib", "libs", "assets", "META-INF", "kotlin"

? ? ? ? 將未知文件拷貝到?unknown 目錄,并且記錄下這些文件。
? ? ? ? 記錄不壓縮的文件,讀取文件壓縮等級,當文件壓縮等級為不壓縮或者文件符合下列類型時,不進行壓縮。



? ? ? ? 處理原始文件,如果你配置了?-c, --copy-original ,則會將?AndroidManifest.xml 和?META-INF 拷貝到?original 目錄下。如下圖:


8、生成 apktool.yml 文件


? ? apktool.yml 內容示例如下:

? ? ? ? (1)putUsesFramework(meta); 記錄使用的framework ? ---- ?usesFramework配置項
? ? ? ? (2)putSdkInfo(meta); 記錄sdkversion信息。 ----?sdkInfo配置項
? ? ? ? (3)putPackageInfo(meta);記錄packageInfo。 ?----?packageInfo配置項
? ? ? ? (4)putVersionInfo(meta); 記錄包體versioncode,versionname ? ---- versionInfo配置項
? ? ? ? (5)putSharedLibraryInfo(meta);記錄是否是一個庫。 ---- sharedLibrary配置項
? ? ? ? (6)putSparseResourcesInfo(meta); 這個暫時沒去了解。----?sparseResources配置項
? ? ? ? ? ? ? ? ? ? 不過看注釋,是與aapt2有關的東西,aapt1忽略這個。估計是aapt1和aapt2之間的處理差異,記錄下來,方便重新打包時進行不同的處理。

? ? ? ? (7)putUnknownInfo(meta); 記錄未知文件。 ----?unknownFiles配置項
? ? ? ? (8)putFileCompressionInfo(meta);記錄文件壓縮信息。 ----?doNotCompress配置項
8、小結
? ? 粗淺的寫了一些流程上的東西,目前只是總結了反編譯過程。具體的一些細節(jié),比如?resources.arsc 的解析過程,我也是參考網上大佬的帖子來進行一步步解析的,所以沒有自己再去重復寫,自己也肯定沒有大佬們寫的好。另外dex的反編譯因為apktool也是直接使用的baksmali庫來進行的,后續(xù)自己閱讀的時候再另起帖子說說。
? ? 下面一篇就還是寫寫重新打包就算完成任務啦。
附上apktool和baksmali的github地址
GitHub - iBotPeaches/Apktool: A tool for reverse engineering Android apk files