JADX、JEB、Apktool 怎么选:三款 Android 反编译工具对比
本页目录
结论先行(以 2026-10-14 为准): 这三款工具其实谈不上互相替代。JADX 把 DEX 字节码还原成可读的 Java,想看懂逻辑就打开它。Apktool 把资源和清单解码成可编辑的 XML,并把 DEX 转成 smali(Android 运行时的汇编语言)。JEB 是 PNF Software 的商业分析平台,带自己的 Android 反编译器、反混淆模块和原生代码反编译器。大多数人是 JADX 和 Apktool 搭配使用,免费工具不够用了再考虑 JEB。
本文面向正在决定装什么工具的 Android 开发者和安全工程师。先在同一个开源 APK 上对比输出和耗时,再讲价格、许可证,以及 REA(morluto 的开源项目)分别如何调用这三款工具。
哪些跑了,哪些没跑。 我在 macOS(Apple M5 Pro,24 GB 内存,Temurin JDK 17.0.18)上运行了 JADX 1.5.6 和 Apktool 3.0.3,也运行了 REA 6.4.0 的 JADX 和 Apktool 命令。JEB 我没有运行:它是商业软件,而免费的社区版不含 Dalvik 反编译器。下文关于 JEB 的内容全部来自 PNF Software 官网,核对日期 2026-10-14。
示例 APK: F-Droid 客户端 2.0.1(versionCode 2000051),从 https://f-droid.org/F-Droid.apk 下载,12,537,183 字节。它以 GPL-3.0 开源,源码在 GitLab,所以反编译结果都能和原始代码核对。你可以对自己的 APK 做同样的操作。请只分析你自己的应用、开源应用或你有权检查的应用,并阅读 REA 的 DISCLAIMER.md。
一句话选型
| 你想要…… | 用 |
|---|---|
| 用 Java 读懂某个方法做了什么 | JADX |
以文本形式查看 AndroidManifest.xml、strings.xml 和布局 |
Apktool(JADX 也能解码) |
| 看精确的字节码,或修改自己应用的资源 | Apktool(smali) |
| 反混淆模块、同一工具里的 ARM/x86 原生反编译、厂商技术支持 | JEB |
| 只想看清单、权限、签名和 SDK 版本 | 本站浏览器内的 APK 分析器 |
同一个 APK 分别交给 JADX 和 Apktool
命令与耗时
jadx -d out/jadx F-Droid.apk
java -jar apktool_3.0.3.jar d -o out/apktool F-Droid.apk
java -jar apktool_3.0.3.jar d --no-src -o out/apktool-nosrc F-Droid.apk
每条命令都用 /usr/bin/time -l 包了一层。这些只是同一台机器上各跑一次的结果,看数量级即可:
| 运行 | 耗时 | 峰值内存 | 输出 |
|---|---|---|---|
jadx -d(全部代码和资源) |
20.0 秒 | 3.98 GB | 11,949 个 .java 文件 |
apktool d |
4.2 秒 | 795 MB | 24,520 个 .smali 文件 |
apktool d --no-src |
1.5 秒 | 492 MB | 只有资源和清单 |
JADX 干的活多得多:它要把每个方法都反编译成 Java,这次用了 7 个线程(它在这台机器上自动选的默认值)。运行最后输出 ERROR - finished with errors, count: 147。这并不代表失败:JADX 会把能写出的代码全部写出,没能干净反编译的方法在输出里用注释标出来。在应用自己的 org/fdroid 包里,990 个 Java 文件中有 293 个至少带一条 JADX WARN、JADX ERROR 或 “Code decompiled incorrectly” 注释。最常见的是 'super' call moved to the top of the method,只影响观感。大型 Kotlin 应用基本都会这样,读到被标记的方法时要多留个心。
同一个方法的两种视图
org.fdroid.CompatibilityCheckerUtils 这个类很小,适合对照。JADX 对其中一个方法的 Java 输出:
public final int minInstallableTargetSdk(int sdkInt) {
switch (sdkInt) {
case 34:
return 23;
case 35:
case 36:
case 37:
return 24;
default:
return 1;
}
}
Apktool 输出的同一方法的 smali:
.method public final minInstallableTargetSdk(I)I
.locals 0
.line 0
const/16 p0, 0x18
packed-switch p1, :pswitch_data_0
const/4 p0, 0x1
:pswitch_0
return p0
:pswitch_1
const/16 p0, 0x17
return p0
:pswitch_data_0
.packed-switch 0x22
:pswitch_1
:pswitch_0
:pswitch_0
:pswitch_0
.end packed-switch
.end method
再看 2.0.1 标签下的原始 Kotlin 源码(libs/index/src/androidMain/kotlin/org/fdroid/CompatibilityChecker.kt):
public fun minInstallableTargetSdk(sdkInt: Int = SDK_INT): Int {
return when (sdkInt) {
34 -> 23 // Android 6.0, M
35 -> 24 // Android 7.0, N
36 -> 24 // Android 7.0, N (didn't change)
37 -> 24 // Android 7.0, N (didn't change in SDK 37 beta 4)
else -> 1 // Android 1.0, BASE
}
}
JADX 的版本五秒钟就能看懂,而且和源码逻辑完全一致。smali 则是字节码层面的事实:一张从 0x22(即 34)开始的 packed-switch 表,编译器还复用了寄存器 p0。JADX 的输出看起来不对、或者带了警告时,就拿 smali 来核对。另外,JADX 还生成了 Kotlin 默认参数的桥接方法 minInstallableTargetSdk$default(源码里只是 = SDK_INT),并保留了 Kotlin 编译器写入的 @Metadata 注解。
资源
两款工具都能把 AndroidManifest.xml 和资源表解码成 XML。Apktool 输出的是一个可以直接工作的目录:res/ 里的 res/values/strings.xml 有 539 条字符串,apktool.yml 里写着 minSdkVersion: 24、targetSdkVersion: 37、versionName: 2.0.1,三个 DEX 分别对应 smali、smali_classes2、smali_classes3。JADX 则把解码后的资源放在 resources/ 下,和 sources/ 并列。
Apktool 还能把解码目录重新打包(apktool b),那是给你自己的应用改资源用的,不在本文范围内。
JEB:花钱能得到什么
以下来自 PNF Software 的 JEB 主页、价格页 和 更新日志,核对日期 2026-10-14:
- 当前版本: JEB 5.48,日期 2026-10-07。
- 版本划分: JEB Community Edition(免费)、JEB Android、JEB Pro。功能矩阵里,Dalvik 反编译器只在 JEB Android 和 JEB Pro 两列打勾,社区版没有。社区版包含 x86 / x86-64 反编译器和 Dalvik 反汇编器。
- 仅 Pro 提供: 针对“虚拟化”代码的反混淆模块、需要原生代码模拟(JNI)的高级反混淆、通用 APK 脱壳插件,以及“Automation / headless launcher”和“Work offline”两项。
- 标价: JEB Android 每用户每年 1,200 美元,或每用户每月 140 美元;JEB Pro 每用户每年 2,000 美元;JEB Pro Floating 每席位每年 4,000 美元。Pro 的优先支持另加 30%。
- MCP: 更新日志显示近几个版本内置了 MCP 服务器。5.41 新增命令行选项,可以无界面模式启动并开启 MCP 服务器(
jeb -c --mcp),并改用 streamable HTTP;5.47、5.48 又增加了更多 MCP 工具。
功能矩阵和更新日志都没有写明 MCP 服务器属于哪些版本。由于无界面模式在矩阵里只属于 Pro,如果打算在其他版本上做无界面的 agent 接入,请先向 PNF Software 确认。
REA 如何调用这三款工具
REA 6.4.0 一个都不替你安装,需要你把已装好的工具指给它。
JADX 通过 jadx-headless-mcp 接入。REA 锁定该 JAR 的 0.7.1 版本;我下载的文件 SHA-256 为 6e5eacf5...ff75,与 REA 记录的一致。把 REA_JADX_MCP_JAR 指向这个 JAR,并确保 PATH 上有完整的 JDK 17 及以上版本。对应命令是 inspect-android-package、search-android-classes、inspect-android-class、inspect-android-method 和 trace-android-references。在 F-Droid APK 上:
rea inspect-android-package /abs/F-Droid.apk --json
rea inspect-android-method /abs/F-Droid.apk org.fdroid.CompatibilityCheckerUtils minInstallableTargetSdk --overload-index 1 --json
包检查大约用了 5 秒,报告包名 org.fdroid.fdroid、版本 2.0.1、class_count 11,959、resource_count 973,引擎为 jadx-headless-mcp 0.7.1,堆上限 6,144 MiB。方法检查返回的 Java 与 JADX 命令行完全相同,附带 representation: "java"、fell_back: false、overload_count: 2(第二个重载就是 $default 桥接方法,所以必须指定 --overload-index)。完整配置见 JADX MCP 服务器配置。
Apktool 通过 REA_APKTOOL_COMMAND 接入,值是一个启动器的绝对路径。我用了一个两行的 shell 脚本,内容是执行 java -jar apktool_3.0.3.jar "$@"。rea inspect-apktool-client 报告 apktool_version: "3.0.3";rea decode-android-resources /abs/F-Droid.apk --json 大约 3 秒,它在临时工作目录里运行 apktool d --no-src,返回清单、版本和 SDK 信息、539 条默认字符串以及 45 个字符串语言区域。它的限制说明写明跳过了 smali,因为 Java 源码还原属于 JADX 一族的职责。
JEB 通过 MCP 接入。REA 6.4.0 连接你自己启动的 JEB 客户端,地址取 REA_JEB_MCP_URL,默认 http://127.0.0.1:8425/mcp,并且只接受回环地址。对应工具是 inspect_jeb_client、open_jeb_project、list_jeb_units 和 decompile_jeb_item。REA 从不安装或启动 JEB。这条路径我没有测试。
结合 ADB 和 Flutter 应用的完整流程,见 用 REA 分析 Android APK。
许可证与平台
| JADX | Apktool | JEB | |
|---|---|---|---|
| 最新版本(2026-10-14) | 1.5.6,2026-07-10 | 3.0.3,2026-07-20 | 5.48,2026-10-07 |
| 许可证 | Apache-2.0 | Apache-2.0 | 商业授权,社区版免费 |
| 运行环境 | 64 位 Java 11+(README) | Java 8+(安装文档) | 我参考的页面未说明 |
| 使用方式 | 命令行和 GUI | 命令行 | GUI、脚本 API、无界面模式(Pro)、MCP |
JADX 的发布页还提供一个自带 JRE 的 Windows GUI 包。按 --help 的说明,JADX 可以直接打开 .apk、.dex、.jar、.class、.smali、.aar、.aab、.xapk、.apkm 等格式。
常见搭配
- 先看逻辑: 用 jadx-gui 打开 APK,或者直接跑
jadx,搜到类,读 Java。 - 资源和精确字节码: 同时跑一遍
apktool d,JADX 标记了警告的方法就对照 smali 看。 - 在这两步之前: 把 APK 拖进本站的 APK 分析器,在浏览器里检查清单、权限、原生库和签名,文件不上传。它不反编译代码。
- 什么时候考虑 JEB: 混淆或虚拟化很重、需要在同一个项目里一起反编译原生库,或者团队需要厂商支持。买之前先在自己的目标上试用。
常见问题
JADX 比 dex2jar + JD-GUI 好吗? JADX 直接把 DEX 反编译成 Java,不需要先转成 JAR。本文没有测试 dex2jar。
为什么 JADX 输出里有 “Code decompiled incorrectly”?
有些方法无法还原成合法的 Java。JADX 不会因此中断,而是做上标记。这些方法请对照 smali 查看,或者加上 --show-bad-code。
Apktool 能反编译成 Java 吗? 不能。它输出 smali 和解码后的资源。
JEB 社区版够分析 APK 吗? 按功能矩阵,社区版有 Dalvik 反汇编器,但没有 Dalvik 反编译器,后者在 JEB Android 和 JEB Pro 里。
下一步
- 给 AI agent 配置 JADX:用 Claude Code 和 REA 搭建 JADX MCP 服务器
- 完整的 Android 静态分析流程:用 REA 分析 Android APK
- 解包 AAB 和资源文件:AAB 转 APK 与 APK 解包
- 在浏览器里检查 APK:APK 与 AAB 分析器