Android 反編譯利器,jadx的高級技巧
一、前言
今天介紹一個非常好用的 Android 反編譯的工具 jadx 。jadx 的功能非常的強大,對我而言,基本上滿足日常反編譯需求。
jadx 優(yōu)點:
- 圖形化的界面。
- 拖拽式的操作。
- 反編譯輸出 Java 代碼。
- 導(dǎo)出 Gradle 工程。
這些優(yōu)點都讓 jadx 成為我反編譯的第一選擇,它可以處理大部分反編譯的需求,基本上是我反編譯工具的首選。
接下來我們就來看看,jadx 如何使用吧。
二、使用 jadx
2.1 安裝 jadx
jadx 本身就是一個開源項目,源代碼已經(jīng)在 Github 上開源了。
Jadx Github :
https://github.com/skylot/jadx
有興趣可以直接 clone 源代碼,然后本地自己編譯。但是多數(shù)情況下,我們是需要一個編譯好的版本。編譯好的版本,可以在 sourceforge 上下載到。
sourceforge 下載 jadx。
https://sourceforge.net/projects/jadx/files/
直接下載最新版就可以了,現(xiàn)在的最新版是 jadx-0.6.1 。下載好解壓之后,你會獲得這樣的目錄結(jié)構(gòu):
對于 Mac 或者 Linux,使用 jadx-gui ,Windows 下就需要使用 jadx-gui.bat 了,雙擊可以直接運行,如果有安全警告,忽略它就可以了。(后文主要以 Mac 環(huán)境為講解,Windows 下的大部分操作都是類似的)
2.2 使用 jadx
前面提到,直接雙擊 jadx-gui 就可以直接運行。運行之后,會啟動一個 terminal ,在這里你可以看到你所有操作的輸出,錯誤日志也會輸出在這里。
打開之后,你可以選擇一個 apk、dex、jar、zip、class、aar 文件,可以看到 jadx 支持的格式還是挺多的,基本上編譯成 Java 虛擬機能識別的字節(jié)碼,它都可以進行反編譯。除了選擇一個文件,還可以直接將 apk 文件,拖拽進去,這一點非常好用。
我隨便找了一個手邊的 Apk ,丟進去,看看反編譯后的效果。
這里面就是反編譯后的代碼了,對于 apk 而言,一些 xml 的資源,也一并被反編譯還原回來了,非常的方便。
三、jadx 的優(yōu)點
jadx 使用起來非常的方便,而提供的 gui 程序,也很好用。下面開始介紹 jadx-gui 程序的一些好用的技巧。
3.1 強大的搜索功能
jadx 提供的搜索功能,非常強大,而且搜索速度也不慢。
你可以點擊 Navigation -> Text Search 或者 Navigation -> Class Search 激活它,更方便的還是快捷鍵,我本機的快捷鍵是 control + shift + f,這個就因人而異了。
jadx 的搜索,支持四種維度,Class、Method、Field、Code,我們可以根據(jù)我們搜索的內(nèi)容進行勾選,范圍最大的就是 Code ,基本上就是文本匹配搜索。這里反編譯的 Apk 集成了支付寶支付,所以能搜到 alipay 的內(nèi)容。
3.2 直接搜索到引用的代碼
有時候找到關(guān)鍵代碼了,還想看看在哪些地方調(diào)用或者引用了它。
jadx 也提供了這方面的支持,找到我們需要查看的類或者方法,選中點擊右鍵,選擇 Find Usage。
之后,它就會幫你搜索出,在這個項目中,哪些地方引用了它。
點擊就可以直接跳轉(zhuǎn)過去,非常的方便。
3.3 deobfuscation
一般 Apk 在發(fā)布出去之前,都是會被混淆的,這基本上國內(nèi) App 的標配。這樣一個類,最終會被混淆成 a.b.c ,方法也會變成 a.b.c.a() ,這樣其實非常不利于我們閱讀。我們很難看到一個 a.java 的文件,就確定它是哪一個,還需要根據(jù)包名來區(qū)分。
而 deobfusation 功能,可以為它們其一個特殊的名字,這樣它在這個項目中,名字就唯一了,方便我們識別和搜索。
這個功能可以在 Tools -> deobfusation 中激活。
接下來來看看它的效果。
開啟 deobfusation 之后的效果如下:
可以看到,a 變成了 p003a。不知道這樣看你覺得有方便一些嗎?
3.4 一鍵導(dǎo)出 Gradle 工程
雖然,jadx-gui 可以直接閱讀代碼,還是很方便的。但是畢竟沒有我們常見的編輯器來的方便。而正好 jadx 還支持將反編譯后的項目,直接導(dǎo)出成一個 Gradle 編譯的工程。
可以通過 File -> Save as gradle project 來激活這個功能。
最終輸出的目錄,是可以直接通過 Android Studio 打開的。
不過雖然 AS 可以直接打開它,但是大多數(shù)情況下你是編譯不起來的。但是這樣的功能,主要是為了借助 AS 強大的 IDE 功能,例如方法跳轉(zhuǎn)、引用搜索等等,讓我們閱讀起來更方便。
四、jadx 的錯誤處理
jadx 在使用過程中,也會有一些錯誤情況,這里總結(jié)一些比較常見的錯誤。
4.1 inconsistent code
有時候有代碼,反編譯的不完整,你會看到 JADX WARNING : inconsistent code 標志的錯誤。
這一段代碼,就已經(jīng)不是 Java 的代碼了,不利于我們的閱讀。而 jadx 為了應(yīng)對這樣的情況,可以嘗試開啟 Show inconsistent code 開關(guān)。你可以在 File -> Preferences 中找到它。
開啟 inconsistent code 之后,我們再來看看這段代碼,就感覺親切了。
這樣處理的代碼,大部分為偽代碼,可能會有錯誤的地方,具體問題具體分析吧。
Preferences 中,還有很多開關(guān),有興趣的可以自行摸索一下。
4.2 反編譯錯誤或者卡頓
jadx 反編譯一些小的 Apk,一點壓力都沒有,但是對于一些比較重的 Apk,一般 Apk 大于 50MB 的,你都可能遇到使用 jadx 反編譯的時候卡死的問題。
如果你看了 terminal 中 Log 輸出,你應(yīng)該可以發(fā)現(xiàn),實際上它是因為 OOM 引起的。
官方對于這樣因為內(nèi)存不足引發(fā)的問題,也提供了一些解決方案。
1、減少處理的線程數(shù)。
jadx 為了加快編譯的效率,所以是使用多線程處理的,而多個線程會耗費跟多的內(nèi)存。所以減小反編譯時候的線程數(shù),是一個有效的方法。
如果使用命令行的話,可以使用 -j 1 參數(shù),配置線程數(shù)為 1,不配置的話,默認線程數(shù)為 4。
而使用 jadx-gui 的話,可以在 Preferences 中,通過配置 Processing threads count 來配置線程數(shù)。
2、修改 jadx 腳本
直接編輯 ./bin 目錄下的 jadx 腳本,配置找到 DEFAULT_JVM_OPTS ,將它設(shè)置為 DEFAULT_JVM_OPTS="-Xmx2500M" ,就可以配置當(dāng)前使用的內(nèi)存大小。
如果是 Windows 系統(tǒng),你需要編輯 jadx.bat 文件。
3、使用命令行命令
如果以上方式都不好用,在沒有更好的辦法的情況下,你可以直接使用命令行,通過 jadx 的命令進行放編譯。并將線程數(shù)配置為 1 ,這樣雖然慢一些,但是多數(shù)情況下,是可以正常輸出反編譯后的代碼的。
舉個例子:
- jadx -d out -j 1 classes.dex
更過命令,可以通過 jadx -h 命令進行查看。
仔細看看 jadx 命令配置的參數(shù),基本上都可以在 Preferences 中,找到對應(yīng)的配置項,相互對照理解一下,應(yīng)該不難發(fā)現(xiàn)它的使用方式。
五、總結(jié)
jadx 確實非常的好用,到這里基本上已經(jīng)把它的使用,都講解清楚了,還有一些小技巧,自己摸索一下就好了。
【本文為51CTO專欄作者“張旸”的原創(chuàng)稿件,轉(zhuǎn)載請通過微信公眾號聯(lián)系作者獲取授權(quán)】