rea-reverse

JADX、JEB、Apktool 怎么选:三款 Android 反编译工具对比

基于 REA 6.4.0更新于 约 7 分钟读完
本页目录

结论先行(以 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 等格式。

常见搭配

  1. 先看逻辑: 用 jadx-gui 打开 APK,或者直接跑 jadx,搜到类,读 Java。
  2. 资源和精确字节码: 同时跑一遍 apktool d,JADX 标记了警告的方法就对照 smali 看。
  3. 在这两步之前: 把 APK 拖进本站的 APK 分析器,在浏览器里检查清单、权限、原生库和签名,文件不上传。它不反编译代码。
  4. 什么时候考虑 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 里。

下一步