Android 逆向工具篇—反編譯工具的選擇與使用
轉自:https://cloud.tencent.com/developer/article/1548700?from=article.detail.1661891
今天給大家介紹一下Android App 在Java層的逆向工具。
逆向工具的介紹
在過去,當我們想要了解一個 app 內部運作細節時,往往先通過 ApkTool 反編譯 APK,生成 smali 格式的反彙編程式碼[1],然後大佬和老手直接閱讀 smali 程式碼,適當的進行修改、插樁、除錯,經過一定的經驗和猜想,理解程式的執行邏輯和加解密細節,比如如下的 smali 程式碼。
smail
我們只要先這樣,再那樣,最後再這樣,對對對,就這樣,一個程式的加密就被破解出來了。 是不是迫不及待想來一次App的逆向之旅了?
事實上,這種方式對小白實在不友好,有沒有更加友好的方式呢?當然是有的,如果你百度或者 google 搜尋逆向相關的教程和分享,很容易就會發現下面這三個工具。在介紹工具之前,我們先補充一下APK結構的知識,我們以伊對這個社交 Apk 為例。
APK 檔案其實是一種特殊的 zip 格式,我們可以直接用 360 壓縮或者別的壓縮工具開啟。
為了滿足自身的功能和設計,幾乎每一個都會在基礎的檔案結構上新增不少東西,但有六個部分是不變的,我們羅列和稱述一下。
檔案或目錄 |
作用 |
---|---|
META-INF/ |
描述apk包資訊的目錄,主要存放了簽名信息,配置資訊,service註冊資訊 |
res/ |
存放apk資原始檔的目錄,比如圖片、圖示、字串、樣式、顏色 |
assets/ |
同樣是存放apk資原始檔的目錄,但和res有差異,和我們關係不大 |
resources.arsc |
資源索引,包含不同語言環境中res目錄下所有資源的型別、名稱與ID所對應的資訊 |
lib/ |
存放so檔案,越來越多的應用由C/C++編寫核心程式碼,以SO檔案的形式供上層JAVA程式碼呼叫,以保證安全性,這個目錄是逆向解密關注的重點 |
classes.dex(一個或數個) |
Android程式執行在Dalvik虛擬機器上,而dex就是Dalvik虛擬機器的可執行檔案, 相當於Windows平臺中的exe檔案,通過反編譯dex,可以獲得apk原始碼(這個說法不很準確,但方便理解) |
AndroidManifest.xml |
清單檔案,包含了App大量的的配置資訊,比如包名、應用需要擁有的許可權(打電話/錄音/網路通訊等等)、以及所有的介面和程式元件的資訊,無法解壓apk時直接開啟,因為清單檔案在apk打包過程中被編譯成了二進位制格式檔案 |
接下來我們介紹以下反編譯工具,看一下反編譯工具的作用
工具 |
作用 |
---|---|
ApkTool |
解析resources.arsc,AndroidManifest.xml等檔案,反編譯dex檔案為smali原始碼 |
Dex2jar |
將dex檔案轉化為jar檔案 |
Jd-gui |
反編譯jar,檢視java原始碼 |
比如使用 Dex2jar+Jd-gui, 最終得到這樣的結果。
是不是感覺友好很多?只需要cmd敲七八行命令就可以得到java原始碼。[2]
這樣做肯定沒問題,但能不能更加簡單一些呢?能不能直接將Apk拖到什麼軟體裡,然後電腦螢幕發亮,藍底黑字,日誌和指令不停流淌,過一會兒完整的java程式碼和apk結構就顯現出來?
前人種樹後人乘涼,真的有不少這樣的工具,通過這一類高整合度的逆向工具,我們可以方便快捷對Apk進行逆向分析。
這裡介紹幾款:JADX,JEB,Android Killer,GDA。
1.1 Android Killer
首先說一下Android killer,這也是我接觸的第一個反編譯工具,開場介面非常酷。
它集成了Apktool,Jd-Gui等工具實現了拖拽式反編譯,功能強大,並且可以安裝外掛,使用android killer進行smali一鍵插樁非常的暢爽。但由於更新慢,逐漸老舊,使用它反編譯apk越來越力不從心,而且它只可以在windows平臺使用,所以我們這邊不做過多介紹,但不可否認它有一些非常棒的功能。
1.2 GDA
GDA是國人制作的一款反編譯神器,功能強大,靈活至極。 我們先說一下它的優點,僅2.6M大小,簡直不可思議,而且它不需要JDK環境,測試時反編譯七八十兆大的apk也不會卡死,除此之外,它還附帶有反混淆,查殼等功能……
接下來我們說一下它的缺點:
一、反編譯出來的java程式碼展示性不夠友好,變數名不夠友好,大多是v0, v1, p1等(更像是原生暫存器的命名法)。
二、工具的文件和文章不算充分,在搜尋逆向工具教程時,比較難找到其相關介紹。
三、只能在windows平臺執行和使用,不支援mac等其他平臺,這很遺憾。
四、單論反編譯效果,JADX太好用了………………
1.3 JADX vs JEB
JADX:免費,開源,強大,更新快
優點:反編譯能力強,程式碼結構好,變數名合理,支援多平臺,完全就是個和我一樣完美的靚仔,是我心中逆向分析APK的第一工具。[3]
缺點:比較吃記憶體,一個50M大小的APK,使用JADX反編譯就需要佔用4G左右記憶體。
JEB:收費,可動態除錯
優點:可以動態除錯,而且JEB吃記憶體比較少,反編譯同等大小的APK,JEB只要Jadx一半記憶體就可以搞定。同時,埠自動轉發帶來了舒適方便的動態除錯體驗。
缺點:反編譯出來的java虛擬碼展示性不夠友好,變數名不夠友好,大多是v0, v1, p1。
我們測試對比一下GDA,JEB,JADX三個軟體的反編譯效果 如圖:HttpRequestEntity這個構造方法[4]反編譯效果的對比
可以看出,JADX反編譯的結果最為接近正常的java程式碼,在後續使用過程中,你還會發現它全域性搜尋功能的便捷和舒適。
接下來我們安裝一下這三個反編譯工具 連結:https://pan.baidu.com/s/1SDM9f2HxxbNzGg2XVBymPA 提取碼:i1k9
你可能會困惑,上面花了不是不少時間,分析和比較了幾個軟體的優缺點,又用證據說明了JADX是像你一樣的靚仔,那我們肯定毫不猶豫選擇你啊,呸,選JADX啊。為什麼要三個都裝呢?
原因很簡單,在技術嫻熟和精通之前,APP逆向是門不折不扣的玄學,既然是玄學,就會有很多不可控、隨機、稀奇古怪的狀況。當JADX中一個變數模糊不清的時候,你就需要去JEB中看一下它的反編譯結果,或者使用JEB進行動態除錯。當使用JEB 遇到頭疼的APK混淆時,就可以試一下開啟JADX的反混淆功能。因為這幾個軟體的逆向原理是不同的,所以在分析具體APK時各有優勢,它們的功能可以互補。多個工具結合使用可以一定程度彌補個人能力的不足,只需要幾百M空間放它們即可,何樂而不為呢。
1.4 JADX的配置和使用
直接下載,找個合適的地方解壓即可,按照自己的作業系統開啟相應的檔案即可。
可能出現的兩個問題:
- 為什麼雙擊jadx-gui.bat 出現控制檯一閃而過,沒有正確出現介面 因為你的JAVA_HOME環境變數沒有正確配置,但也不排除是JDK版本的問題。
- 反編譯卡死、閃退 Apk超過50M就很容易出現OOM(OutOfMemoryError),在win中,它預設使用4G記憶體,可以檢視介面底部居中部分。
如果你的window系統是8G或者更高執行記憶體,我們可以修改引數進行擴容。文字模式開啟jadx-gui.bat,將被框出的內容數值改為8g或者更大,如果電腦執行記憶體更大,也可以改成更高的數值。100M以內的App,8G記憶體足夠了。
接下來重新開啟JADX,記憶體就已經更改了。
如果你的windows系統只有4G執行記憶體,我們依然有很多辦法使用jadx,實戰中再說。
接下來說一下mac中的擴容,文字模式開啟jadx-gui這個檔案,找到和上述類似的位置,更改為更大的值即可。
JADX的使用和快捷鍵
- 搜尋程式碼、類、方法——Ctrl+N,建議不要使用左上角的搜尋類/搜尋文字,因為圖示太小,很容易按錯,如果你第一次搜尋用搜索類,第二次搜尋時選擇搜尋文字,那第一次的搜尋內容和設定是不會記錄下來的。所以不如直接看一下工具欄中的快捷鍵,只用一個。
- 檔案-首選項中,如果記憶體夠用,我建議勾選“自動進行後臺反編譯”,因為Jadx預設只有在你展開內容或者搜尋內容時,才會開始反編譯。不要勾選Unicode自動轉義,否則程式碼中的中文會被轉成unicode,不方便識別和搜尋。
- Ctrl+滑鼠左鍵,可以跳轉到方法內部,幾乎所有的程式碼編輯器都是這樣。
- 別的一些可以修改的地方我放在了下圖紅框裡,比如反編譯執行緒數,執行緒數越多,反編譯越快,但佔用記憶體也越多,建議根據電腦效能調整,不調整也OK。反混淆一般不用開。
1.5 JEB的配置和使用
同樣直接下載,找個合適的地方解壓,按照自己的作業系統開啟相應的檔案即可。 我們同樣要進行JEB的擴容,預設為1.8G,我們需要進行更改。
更改前
更改後
Windows中JEB的擴容
將整個紅框內容替換如下
:startjeb
set JEB="%~dp0bin\jeb1.exe"
if exist %JEB% goto :runlauncher
%JAVA% -jar -Xmx4g -Xms4g "%~dp0bin\app\jebc.jar" %*
exit 0
:runlauncher
%JEB% %*
exit 0
mac如何擴容我瞭解不多,如果遇到問題可以和我探討。
1.6 GDA的配置和使用
只有windows可以用,exe直接點開即可,以後會用到,到時候再說
[1]: Smali是dex檔案反編譯的結果,可以說,smali語言是Dalvik的反組合語言,下文會介紹DEX
[2]: 我們這一個系列的教程針對的是無殼App,而當你自己拿到一個未知的App時,第一步要做的一定一定得是查殼。
[3]: 得到的並不是Java原始碼,這是個錯誤的說法,但對初學者來說比較容易理解。不管你通過什麼工具反編譯apk,得到的java程式碼都和Apk開發時的原始碼相差甚遠。我們能得到的僅僅是一種虛擬碼,它可能存在錯誤的邏輯、奇怪的變數名、各種各樣的error,但程式碼總體上是靠譜的。
[4]: 為了閱讀和講解的循序漸進,我們這裡並沒有把IDA考慮進來,IDA是神器,在後面是避免不了的。
[5]: 這條註釋針對沒有JAVA基礎的小夥伴,建構函式在JAVA中非常常見,JAVA是一門面向物件的語言,建構函式是一種特殊的函式。其主要功能是用來在建立物件時初始化物件, 建構函式與類名相同。如果聽不懂也沒關係,知道是個函式即可,後續也會慢慢補充JAVA知識。