Android 反編譯利器,jadx 的高階技巧

承香墨影發表於2017-11-27

一、前言

今天介紹一個非常好用的反編譯的工具 jadx 。jadx 的功能非常的強大,對我而言,基本上滿足日常反編譯需求。

jadx 優點:

  1. 圖形化的介面。
  2. 拖拽式的操作。
  3. 反編譯輸出 Java 程式碼。
  4. 匯出 Gradle 工程。

這些優點都讓 jadx 成為我反編譯的第一選擇,它可以處理大部分反編譯的需求,基本上是我反編譯工具的首選。

接下來我們就來看看,jadx 如何使用吧。

二、使用 jadx

2.1 安裝 jadx

jadx 本身就是一個開源專案,原始碼已經在 Github 上開源了。

Jadx Github :

github.com/skylot/jadx

有興趣可以直接 clone 原始碼,然後本地自己編譯。但是多數情況下,我們是需要一個編譯好的版本。編譯好的版本,可以在 sourceforge 上下載到。

sourceforge 下載 jadx。

sourceforge.net/projects/ja…

直接下載最新版就可以了,現在的最新版是 jadx-0.6.1 。下載好解壓之後,你會獲得這樣的目錄結構:

jadx-path
jadx-path

對於 Mac 或者 Linux,使用 jadx-gui ,Windows 下就需要使用 jadx-gui.bat 了,雙擊可以直接執行,如果有安全警告,忽略它就可以了。(後文主要以 Mac 環境為講解,Windows 下的大部分操作都是類似的)

2.2 使用 jadx

前面提到,直接雙擊 jadx-gui 就可以直接執行。執行之後,會啟動一個 terminal ,在這裡你可以看到你所有操作的輸出,錯誤日誌也會輸出在這裡。

開啟之後,你可以選擇一個 apk、dex、jar、zip、class、aar 檔案,可以看到 jadx 支援的格式還是挺多的,基本上編譯成 Java 虛擬機器能識別的位元組碼,它都可以進行反編譯。除了選擇一個檔案,還可以直接將 apk 檔案,拖拽進去,這一點非常好用。

我隨便找了一個手邊的 Apk ,丟進去,看看反編譯後的效果。

jadx-run
jadx-run

這裡面就是反編譯後的程式碼了,對於 apk 而言,一些 xml 的資源,也一併被反編譯還原回來了,非常的方便。

三、jadx 的優點

jadx 使用起來非常的方便,而提供的 gui 程式,也很好用。下面開始介紹 jadx-gui 程式的一些好用的技巧。

3.1 強大的搜尋功能

jadx 提供的搜尋功能,非常強大,而且搜尋速度也不慢。

你可以點選 Navigation -> Text Search 或者 Navigation -> Class Search 啟用它,更方便的還是快捷鍵,我本機的快捷鍵是 control + shift + f,這個就因人而異了。

text-search
text-search

jadx 的搜尋,支援四種維度,Class、Method、Field、Code,我們可以根據我們搜尋的內容進行勾選,範圍最大的就是 Code ,基本上就是文字匹配搜尋。這裡反編譯的 Apk 整合了支付寶支付,所以能搜到 alipay 的內容。

3.2 直接搜尋到引用的程式碼

有時候找到關鍵程式碼了,還想看看在哪些地方呼叫或者引用了它。

jadx 也提供了這方面的支援,找到我們需要檢視的類或者方法,選中點選右鍵,選擇 Find Usage。

find-Usage
find-Usage

之後,它就會幫你搜尋出,在這個專案中,哪些地方引用了它。

usage-search
usage-search

點選就可以直接跳轉過去,非常的方便。

3.3 deobfuscation

一般 Apk 在釋出出去之前,都是會被混淆的,這基本上國內 App 的標配。這樣一個類,最終會被混淆成 a.b.c ,方法也會變成 a.b.c.a() ,這樣其實非常不利於我們閱讀。我們很難看到一個 a.java 的檔案,就確定它是哪一個,還需要根據包名來區分。

而 deobfusation 功能,可以為它們其一個特殊的名字,這樣它在這個專案中,名字就唯一了,方便我們識別和搜尋。

這個功能可以在 Tools -> deobfusation 中啟用。

接下來來看看它的效果。

deo-before
deo-before

開啟 deobfusation 之後的效果如下:

deo-after
deo-after

可以看到,a 變成了 p003a。不知道這樣看你覺得有方便一些嗎?

3.4 一鍵匯出 Gradle 工程

雖然,jadx-gui 可以直接閱讀程式碼,還是很方便的。但是畢竟沒有我們常見的編輯器來的方便。而正好 jadx 還支援將反編譯後的專案,直接匯出成一個 Gradle 編譯的工程。

可以通過 File -> Save as gradle project 來啟用這個功能。

save-gradle
save-gradle

最終輸出的目錄,是可以直接通過 Android Studio 開啟的。

gradle-project
gradle-project

不過雖然 AS 可以直接開啟它,但是大多數情況下你是編譯不起來的。但是這樣的功能,主要是為了藉助 AS 強大的 IDE 功能,例如方法跳轉、引用搜尋等等,讓我們閱讀起來更方便。

四、jadx 的錯誤處理

jadx 在使用過程中,也會有一些錯誤情況,這裡總結一些比較常見的錯誤。

4.1 inconsistent code

有時候有程式碼,反編譯的不完整,你會看到 JADX WARNING : inconsistent code 標誌的錯誤。

incon-before
incon-before

這一段程式碼,就已經不是 Java 的程式碼了,不利於我們的閱讀。而 jadx 為了應對這樣的情況,可以嘗試開啟 Show inconsistent code 開關。你可以在 File -> Preferences 中找到它。

show-pre
show-pre

開啟 inconsistent code 之後,我們再來看看這段程式碼,就感覺親切了。

code2
code2

這樣處理的程式碼,大部分為虛擬碼,可能會有錯誤的地方,具體問題具體分析吧。

Preferences 中,還有很多開關,有興趣的可以自行摸索一下。

4.2 反編譯錯誤或者卡頓

jadx 反編譯一些小的 Apk,一點壓力都沒有,但是對於一些比較重的 Apk,一般 Apk 大於 50MB 的,你都可能遇到使用 jadx 反編譯的時候卡死的問題。

如果你看了 terminal 中 Log 輸出,你應該可以發現,實際上它是因為 OOM 引起的。

oom
oom

官方對於這樣因為記憶體不足引發的問題,也提供了一些解決方案。

1、減少處理的執行緒數。

jadx 為了加快編譯的效率,所以是使用多執行緒處理的,而多個執行緒會耗費跟多的記憶體。所以減小反編譯時候的執行緒數,是一個有效的方法。

如果使用命令列的話,可以使用 -j 1 引數,配置執行緒數為 1,不配置的話,預設執行緒數為 4。

而使用 jadx-gui 的話,可以在 Preferences 中,通過配置 Processing threads count 來配置執行緒數。

2、修改 jadx 指令碼

直接編輯 ./bin 目錄下的 jadx 指令碼,配置找到 DEFAULT_JVM_OPTS ,將它設定為 DEFAULT_JVM_OPTS="-Xmx2500M" ,就可以配置當前使用的記憶體大小。

如果是 Windows 系統,你需要編輯 jadx.bat 檔案。

3、使用命令列命令

如果以上方式都不好用,在沒有更好的辦法的情況下,你可以直接使用命令列,通過 jadx 的命令進行放編譯。並將執行緒數配置為 1 ,這樣雖然慢一些,但是多數情況下,是可以正常輸出反編譯後的程式碼的。

舉個例子:

jadx -d out -j 1 classes.dex

更過命令,可以通過 jadx -h 命令進行檢視。

jadx-help
jadx-help

仔細看看 jadx 命令配置的引數,基本上都可以在 Preferences 中,找到對應的配置項,相互對照理解一下,應該不難發現它的使用方式。

五、總結

jadx 確實非常的好用,到這裡基本上已經把它的使用,都講解清楚了。

你在反編譯的過程中,使用 jadx 有沒有碰到什麼問題?還有什麼更好的工具推薦,可以在留言區給我留言,我們一起討論一下。

今天在承香墨影公眾號的後臺,回覆『成長』。我會送你一些我整理的學習資料,包含:Android反編譯、演算法、設計模式、kotlin、虛擬機器、Linux、Web專案原始碼。

推薦閱讀:

相關文章