Apktool源碼分析
一、編譯
1.源碼下載: https://github.com/iBotPeaches/Apktool
2.編譯可以直接使用Apktool目錄下的gradlew.bat命令,這里使用了Android Studio來編譯源碼,為后續調試做準備。
3.導入源碼,步驟:File–>open–>源碼路徑,或者在導航頁面直接選擇import project
4.點擊右邊的Gradle(注意這里按鈕可能貼邊上,仔細找一下),點開找到一個類似刷新的按鈕,點擊一下即可
5.編譯:Apktool的主要類在brut.apktool:apktool-cli模塊里,運行”fatjar”任務生成項目的jar文件。
6.小結
總體遇到的問題比較少,編譯過程會有一些警告,但是并沒有大礙;第一次編譯Gradle的時候特別慢,于是翻山越嶺你懂的,到了第5步編譯時要記得斷開V*N,不然會報錯。
完整步驟及其他問題請移步參考 : ANDROID反編譯工具APKTOOL源碼調試過程
二、總體代碼解析
程序的主要類入口點在 apktool-cli–>java–>brut.apktool–>Main
如下是主要的四個用法:d 反編譯 、b 回編譯、if 安裝框架、處理arsc文件
Main類里其他部分可到我的github看完整版注釋
三、反編譯代碼解析
跟進路徑(Ctrl+B)一:
(1)、cmdDecode–>decoder.decode()–>decodeResourcesFull()–>fileDecoder.decode()–>ResRawStreamDecoder.decoder()
cmdDecode一開始解析選項,比如我們經常敲的命令 apktool d -d 1.apk,這里的-d就是d用法的選項,詳細移步Github注釋完整版
繼續往下看,找到關鍵的代碼 :
跟進去,進入ApkDecoder類,decode()方法,第一個邏輯判斷是否有arsc文件,否則判斷是否有manifest文件,接著判斷處理dex文件,最后處理原始的文件以及未知的文件,這里的未知文件為不屬于apktool自定義的一些后綴,可自行添加。
重點的函數應該是最后一個decodeResourcesFull,其他的函數完整版注釋也都有寫,有興趣可自行下載查看,這里我們跟進這個函數。
這個主要的處理res、xml以及value文件以及public.xml文件,后兩個函數相對簡單,這里選擇跟進fileDecoder.decode()
進入ResFileDecoder類,第一個decode函數主要是確定傳給第二個decode函數的decoder參數,再調用相應的解碼函數。如果怕跟丟,可以直接在apktool-lib-->java-->res-->decoder里找到相對應的解碼decoder。 主要有三類解碼器,raw、xml、9patch 這里9patch的解析需要熟悉其使用,就不跟進去 可參考: 關于安卓9patch圖片的探究 xml解碼等出來后再跟 這里跟進去raw解碼,其實相對簡單,簡單的copy,主要類為ResRawStreamDecoder
跟進路徑二: (2)、cmdDecode-->decoder.decode()-->decodeManifestFull()-->XmlPullStreamDecoder.decode()
這里是判斷是否有manifest.xml文件,跟進去最后還是到xml文件解碼的關鍵代碼處。這里如有按ctrl+b的話,需要按很多步驟,在完整版注釋中我都標注好了”xml解碼關鍵點”,按標注跟進去即可,也可以直接找到XmlPullStreamDecoder的decode函數。
可以看到這里拋出的異常是我們經常遇到的,所以,這一整個類是我們需要重點分析的地方,以及下斷點調試的關鍵地方。這里我把原來的異常拋出更改得更加詳細一點,可知是由哪個異常類拋出的異常,更加利于我們進行下斷點調試。
這里有J2EE編程經驗可能分析會相對簡單,否則建議學習一下,XmlPullWrapperFactory、XmlPullParserWrapper、XmlPullParser等Java類的使用。
跟進路徑三:
(3)、cmdDecode-->decoder.decode()-->decodeSourcesSmali()-->SmaliDecoder.decode()-->baksmali.disassembleDexFile()
判斷是否有dex,下面是判斷是否有多個dex,處理方式大同小異
看到這里最終還是調用了baksmali進行dex2smali的編譯,關于baksmali的源碼分析將會在近期發出,也請持續關注。
跟進路徑四:
以下是apkdecoder的最后幾個處理函數,分析,相對簡單,這里就不寫了。完整版的注釋分析也算相對詳細了。
四、回編譯代碼解析
cmdBuild-->Androlib(apkOptions).build()-->buildApk()
cmdBuild函數跟上面的反編譯函數差不多,先是處理選項,然后調用真正的處理函數Androlib(apkOptions).build()。
主要的處理函數集如下,大部分跟進去都只是復制目錄中的文件
跟進Buildapk函數,可以看到主要的處理方式是使用了aapt的工具,具體使用方法: android aapt用法
五、處理arsc代碼解析
安裝框架的代碼這里就不寫,代碼注釋我也有寫,可自行移步。
這里簡要寫一下處理arsc文件,
跟進路徑:cmdPublicizeResources()–>Androlib().publicizeResources()–>ARSCDecoder.decode()
可以看到這里也出現了經常遇到的反編譯拋出的異常,所以主要的有兩個地方,一個是讀取頭部出錯,一個是新建ARSData數據結構出錯,這兩步都可能是反編譯手段所在的地方。需要詳細的理解arsc的文件格式,具體可參考: 手把手教你解析Resources.arsc
六、總結
看完sqlmap的源碼,再來apktool的源碼,感覺天壤之別,apktool相對來說還是很好讀的,而且寫的思路也很明確,每個數據結構比較易懂,命名相對好一點,反正salmap的一個自定義的dict類要弄懂就折騰了好久,還有各種奇葩的命名。
看完apktool的源碼,最大的好處就是以后出現反編譯的問題可以自己動手進行調試,同時也可以研究反調試的手段及方法。
來自:http://www.tasfa.cn/index.php/2016/08/30/apktool-source-code-analysis/