十分钟把 APK 变成可读 Java:jadx 反编译上手指南
【免费下载链接】jadxDex to Java decompiler项目地址: https://gitcode.com/gh_mirrors/ja/jadx
jadx 是一个把 Android 的 APK / DEX 反编译成 Java 源码的命令行 + 图形界面工具,内置反混淆器,还能解码 AndroidManifest.xml 和 resources.arsc 资源。读完本文,你会装上它、跑通第一条反编译命令,学会反混淆和单类提取,并知道最常见的报错怎么处理。
只有安装包、没有源码?
你手上多半只有app-release.apk,却要回答「登录逻辑怎么写的」「加解密调的是哪个库」。直接读二进制不现实,逐行看 smali 又太痛苦。
jadx 解决的就是这一步:读 DEX 里的 Dalvik 字节码(Android 可执行字节码),经类型推断、控制流恢复等一系列 pass(处理步骤),输出带包名、import 和完整方法体的 Java 文件。它同时覆盖.apk、.dex、.jar、.class、.smali、.zip、.aar、.arsc、.aab、.xapk、.apkm、.apks等输入格式。
一句话定位:jadx = Dex to Java decompiler,官方定位就是「从 Android Dex 和 Apk 文件产出 Java 源码的命令行与图形界面工具」。
安装与第一条命令
运行要求64 位 Java 11+(with-jre离线包自带 JVM);从源码构建则需要 JDK 17+。
先验证环境里有没有可用的 Java 11+,再按平台二选一:
java -version # 要求 64 位 Java 11+,从源码构建需 JDK 17+ # macOS brew install jadx # Arch Linux sudo pacman -S jadx # Linux(Flatpak) flatpak install flathub com.github.skylot.jadx不想依赖包管理器,就下载官方 release 的 zip:解压后进入bin目录,jadx是命令行版,jadx-gui是图形界面版,Windows 直接双击.bat。
想尝鲜最新特性,可以从源码构建(Windows 用gradlew.bat),产物在build/jadx/bin:
git clone https://gitcode.com/gh_mirrors/ja/jadx cd jadx ./gradlew dist装完先跑最小示例,确认一切就绪:
jadx --version # 有版本号输出即安装成功 jadx -d out app.apk怎么判断它真的跑成功了:进度条走完且没有 ERROR,输出目录里出现sources和resources两个子目录——前者是还原出的 Java 源码,后者是解码后的AndroidManifest.xml和res资源。随便打开一个.java文件,看到的是包声明和 import,不是a.a.b()这种天书,就成了。
三个高频任务
反混淆,把 a.a.b 变回人能读的名字
任务目标:源码被 ProGuard / R8 混淆后全是a.a.b.c(),需要自动重命名。操作:
# --deobf 启动反混淆,重命名过短或过长的标识符 jadx --deobf --deobf-min 3 --deobf-max 50 -d out app.apk # --deobf-min: 短于 3 个字符的重命名(默认 3) # --deobf-max: 长于 50 个字符的重命名(默认 64)预期结果:a.a.b变成a.a.b_2这类稳定别名,自动生成的映射写入与输入文件同名的.jobf文件;下次反编译自动复用,同一份包多次分析名称不会漂移。如果还留着混淆阶段的 mapping 文件,直接--mappings-path mapping.txt(支持 Tiny 与 Enigma 格式),还原度比自动猜测高得多。
单类反编译,别为看一个方法跑全量
任务目标:只想确认MainActivity的逻辑,不想等全量。操作:
# 只反编译一个类,结果写入 MainActivity.java,秒级出结果 jadx --single-class com.example.demo.MainActivity \ --single-class-output MainActivity.java app.apk预期结果:输出目录只有一个.java文件,方法体完整。类名支持全名、原名或别名(配合反混淆后的名字)。
导出成 Gradle 工程
想直接编译反编译结果:
# -e 导出 Gradle 工程;android-app 模板按 APK 结构生成 jadx -e --export-gradle-type android-app -d gradle_out app.apk预期结果:gradle_out下是可导入 IDE 的 Gradle 项目(--export-gradle-type还可选android-library、simple-java、auto)。
四个让输出更好读的配置
| 选项 | 作用 | 什么时候用 |
|---|---|---|
-m反编译模式:auto(默认)/restructure/simple/fallback | 控制还原程度:simple输出带 goto 的线性指令 | 标准模式失败时降级到simple,仍不行再看fallback |
--show-bad-code | 显示被标记为「反编译可能不正确」的代码段,而不是跳过 | 排查缺失代码前先打开它 |
-j 8线程数(默认 CPU 核数的一半) | 并行处理类 | 小机器调低减少内存峰值 |
--log-level debug(默认progress) | 反编译日志级别 | 出问题时的第一排查手段 |
其他常用项:--comments-level(error / warn / info / debug / none)控制代码注释量,--add-debug-lines在字节码带行号时加出行号注释,--integer-format强制十进制或十六进制显示。
Kotlin 写的包默认就启用元数据插件恢复类名与参数名,需要时再显式开关:-Pkotlin-metadata.method-args=yes。插件选项统一是-P<插件名>.<选项>=<值>,比如-Pdex-input.verify-checksum=no可跳过 DEX 校验和检查。
排障速查
| 现象 | 可能原因 | 解决办法 |
|---|---|---|
| 方法体缺失或标红 | 代码被标记为不一致 | 加--show-bad-code查看,再降级-m simple |
| OutOfMemoryError | 默认线程数(CPU 核数一半)内存峰值高 | JAVA_OPTS="-Xmx4G" jadx ...加大堆,同时-j调低线程数 |
| DEX checksum 校验失败 | 样本损坏或被二次修改 | -Pdex-input.verify-checksum=no跳过校验继续解析 |
.jar/.class转换失败 | java 字节码转 dex 失败 | 加--use-dx,或-Pjava-convert.mode=both |
| 想保留原始类名却被改名 | 改名修正默认全开 | --rename-flags none关闭全部重命名 |
| 反编译日志刷屏 | 默认progress级仍有噪音 | --log-level error或-q静默 |
延伸方向
- 插件与管线:
plugins子命令可安装、列表、启用/禁用插件(-l列已装、-a列市场可用);作为库引入时用registerPlugin注册自定义JadxPass,把密钥提取、敏感 API 统计注入反编译管线。 - 读源码:核心引擎在 jadx-core/src/main/java/jadx/core/,反混淆逻辑在 jadx-core/src/main/java/jadx/core/deobf/,各输入格式的解析器拆在 jadx-plugins/ 下的独立模块。
- 参与贡献:发现某个 smali 写法反编译不对,按 CONTRIBUTING.md 提交带最小复现的用例——仓库的测试用例就放在 jadx-core/src/test/smali/ 下,照着加一个即可。
jadx 适合移动安全与 App 分析场景下的第一道静态分析工具,建议你现在就找一个真实 APK,把--deobf和--single-class各跑一遍——这两条用熟,日常分析就顺了。
【免费下载链接】jadxDex to Java decompiler项目地址: https://gitcode.com/gh_mirrors/ja/jadx
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考