ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

JADX 完整教程:从 APK 反编译到 Java 源码还原

JADX 完整教程:从 APK 反编译到 Java 源码还原 做 Android 逆向或者开发调试时手里只有一个 APK 却没有源码很多人第一反应就是“反编译”。JADX 这个工具在我用过的一堆方案里算是体验最省心的下载、安装、把 APK 拖进去Java 源码就出来了。这篇教程我打算把 JADX 的下载、安装和首次使用从头到尾捋一遍从下载渠道到环境变量再到常见报错全部按实际操作来写。哪怕你之前没碰过逆向照着这篇走完也能把 JADX 跑起来。先说明一下教程里的“附安装包”不是说我在文末塞了一个网盘链接。JADX 更新速度不慢网盘里的版本很快就会过时还可能被第三方改动。我建议你直接去官方 GitHub Releases 页面下载最新版我会把每个平台该选哪个文件、下载之后怎么校验、怎么安装都写清楚。老规矩只反编译你自己有权限分析的 APK这既是对原作者的尊重也是这一行能持续下去的基础。1. 下载前的工具认知JADX 凭什么值得装1.1 一个 APK 在 JADX 里能变成什么JADX 全称是 Java Android Decompiler名字很直白。它的核心功能就是把 Android 应用安装包里的 dex 字节码转换成我们可以读的 Java 源码。过去传统方案是先用 dex2jar 把 dex 转成 jar再用 JD-GUI 打开 jar 看代码中间一旦遇到多 dex 或者复杂的字符串加密就容易断在某个环节。JADX 把这些步骤合并成了一个动作直接把 .apk 拖进窗口等待进度条走完左侧是包名树右侧就是还原出来的 Java 代码。JADX 能看到的还不止代码。AndroidManifest.xml、资源索引值、布局 XML、图片资源、字符串资源它都会帮你整理好。对于大多数做分析的人来说这意味着一个工具就能覆盖“看入口、看权限、看逻辑、看资源”的完整链路不用在多个软件之间来回切换。尤其是刚入行的朋友第一次把 APK 拖进 JADX看到完整源码的瞬间基本都会觉得这个工具值得装。1.2 和 dex2jar JD-GUI 那套老组合比优势在哪如果只用一句话概括我会说 JADX 把“看代码”这个核心体验做到了极致。JD-GUI 看反编译结果时经常会出现变量名退化成 a、b、c 之类或者代码结构错乱的情况JADX 在语法还原上更接近编译器源码。它对匿名内部类、lambda、switch 字符串哈希的处理都做了优化分析业务逻辑的时候干扰少很多。拿我自己的一个体验来说以前用 dex2jar 处理好几个 dex 的 App 时经常要手动 merge类重复定义的问题能把人逼疯。JADX 会自动合并所有 dex类名冲突的也会保留并标注。这一点在分析微信、淘宝这种大型应用时尤其重要。下表是我自己常用的几个工具横向对比方便你选型工具组合能否直接出源码资源处理上手难度适合场景JADX能一般可看可导出低快速分析业务逻辑、找入口、导出工程dex2jar JD-GUI能步骤多弱中老项目、临时看某个类apktool不能只出 smali强可重打包中修改资源、改包名、小改动回编译GDA能较弱中高偏移动安全审计需要多维度调试平时我把 JADX 当主力阅读工具遇到需要改资源再回编的情况才会搬出 apktool。如果某个 App 做了很强的代码混淆JADX 依然能给你一个可读的框架只是具体逻辑会像“被揉碎的纸片”这时候就要配合 smali 和动态调试继续往下追了这一点后面会单独讲。2. 下载安装前的环境准备2.1 到哪儿下载靠谱版本JADX 的官方发布地址在 GitHub 上项目名是 skylot/jadx。我不建议在搜索引擎首页随便点“高速下载”原因很简单这种会被 SEO 优化过的页面经常带捆绑软件你还没装上 JADX先被安装上一堆全家桶。正确做法是打开 GitHub Releases 页面认准发布的 tag一般形式是 v1.5.x。页面里会列出当前版本的发行包常见的有jadx-x.x.x.zip # 通用压缩包Windows / macOS / Linux 都能用 jadx-x.x.x.msi # Windows 安装程序 jadx-x.x.x.dmg # macOS 磁盘映像 jadx-x.x.x.tgz # Linux 压缩包选好文件后如果下载慢可以找找有没有镜像源但务必保证文件校验值和官方发布的一致。官方页面一般会提供 SHA256 散列值下载完之后用 PowerShell 或终端算一遍比对一致再解压。这一步看着麻烦却能过滤掉绝大多数第三方改包。Windows 下校验 SHA256 的命令是Get-FileHash .\jadx-1.5.1.zip -Algorithm SHA256macOS 和 Linux 用自带的shasum -a 256或sha256sum就能算。比对结果那串字符串和官方发布页是否一致一致再继续这是我多年下载工具养成的习惯。2.2 Java 环境检查与安装JADX 是用 Java 写的运行它必须要有 Java 运行时环境而且不是随便一个旧版本都行。当前主流 JADX 版本要求 Java 11 及以上我本机用的是 OpenJDK 17跑 1.5.x 没有任何问题。检查方法很简单打开终端窗口输入java -version如果系统提示找不到 java或者显示版本是 1.8那就要先去装一个 JDK。发行版不限Oracle JDK、Eclipse Temurin、Zulu、腾讯 Kona 都可以选一个比较全的开源版本安装。安装完之后关键一步是配环境变量Windows 用户在系统变量里新建JAVA_HOME指向 JDK 安装目录然后把%JAVA_HOME%\bin追加到Path。macOS 用户装完 .pkg 一般会自动配置好Linux 用户根据自己的包管理器安装即可。这里有一个经验如果你电脑上已经装过 Android Studio那么往往已经自带 JBRJetBrains RuntimeJADX 大概率能直接覆盖以前的版本。但如果你同时装了多个 Java 版本终端里的java -version显示的可能不是你想用的那个后续启动 JADX 报版本不足时优先检查这里。还有一个小技巧很多系统自带 Java 配置管理命令Windows 可以用where javamacOS/Linux 可以用which java来确认实际生效的是哪个路径。2.3 把命令行工具加进 PATH可选JADX 安装包里其实带了两套入口图形界面jadx-gui和命令行jadx。日常拖 APK 看代码用 GUI 就够了但如果你想写脚本批量反编译或者通过命令行导出工程就需要把bin目录加进 PATH。Windows 下解压后的目录假定是D:\tools\jadx-1.5.1那么在“系统属性 - 环境变量”里找到Path新增一行D:\tools\jadx-1.5.1\bin。macOS/Linux 下直接把解压目录里的bin做成软链接或者把这一行写进.bashrc/.zshrcexport PATH$HOME/tools/jadx-1.5.1/bin:$PATH配好之后重新打开终端输入jadx --version能看到版本号就说明环境没有问题了。这一步不是必须的但配好之后会让后面的命令行操作顺滑不少。尤其是后面讲批量反编译的时候不用每次都敲一长串绝对路径体验完全不同。3. JADX 安装全过程图文拆解3.1 Windows 用户zip 包免安装玩法我第一次用 JADX 的时候选的就是 zip 包原因是不需要注册表和安装记录解压就能用。具体流程如下下载jadx-x.x.x.zip建议放到一个不含中文和空格的路径下比如D:\tools\jadx-1.5.1因为后面的脚本对路径里的特殊字符可能会出问题。右键压缩包选择“解压到当前文件夹”完成后你会看到类似这样的目录结构D:\tools\jadx-1.5.1 │ ├─ bin │ ├─ jadx.bat │ ├─ jadx-gui.bat │ └─ jadx-gui │ └─ lib ├─ jadx-1.5.1.jar └─ ...打开bin目录双击jadx-gui.bat稍等一两秒会弹出一个深色主题的主窗口。如果双击后没有任何反应或者屏幕闪了一下就没了大概率是 Java 环境的问题。你先打开一个 cmd 窗口手动切到bin目录执行jadx-gui.bat这样屏幕上会留下具体的报错信息排查起来会清楚很多。等窗口启动成功后顶部菜单是File、View、Navigation、Tools这些标准菜单界面布局非常接近常见的 IDE几乎不需要学习成本。首次使用我建议先随便找一个 APK 打开滚动一下源码面板感受一下字体和配色不喜欢就去View - Theme里换主题。3.2 Windows 用户MSI 安装包玩法如果你习惯像装普通软件一样点“下一步”那选 MSI 安装包。双击运行安装向导一路 Next到选择安装目录那一步仍然建议改成纯英文路径。安装完成后开始菜单里会多出来一个 JADX 文件夹里面有jadx和jadx-gui两个快捷方式。MSI 版的好处是它会自动把相关命令注册好你不需要手动配 PATH缺点是卸载和更新的时候某些杀毒软件可能会把它当成可疑程序。遇到这种情况不用慌把jadx-gui.exe或者安装目录加入杀毒软件的信任列表就行。另外MSI 安装的版本如果以后要卸载记得别直接删安装目录不然注册表里留一堆垃圾。去“设置 - 应用 - 已安装的应用”找到 JADX 再卸载顺便能把 JADX 的缓存文件清理干净。这样下次装新版时不会出现环境冲突。3.3 macOS 用户DMG 拖拽安装macOS 下打开下载的.dmg文件系统会挂载出一个磁盘映像窗口里面一般有一个 JADX 应用图标和一个 Applications 文件夹的替身。你只需要把 JADX 图标拖到 Applications 文件夹里就完成了安装。首次启动时如果提示“无法打开因为 Apple 无法检查其是否包含恶意软件”去“系统偏好设置 - 安全性与隐私 - 通用”页面点击“仍要打开”即可。如果连这个按钮都没有可以在终端里执行xattr -dr com.apple.quarantine /Applications/jadx-gui.app之后再启动就不会被拦了。需要注意的是 macOS 版的 GUI 入口其实是jadx-gui这个可执行脚本如果你想把命令行工具软链到/usr/local/bin可以直接链过去。不少 macOS 用户还习惯用 Homebrew 安装 JADX命令是brew install jadx这种方式能自动处理 Java 依赖但版本更新可能略晚于官方 GitHub Release怎么方便怎么来。3.4 Linux 用户tgz 包快速部署Linux 用户下载.tgz压缩包或.zip都行解压后进入目录给 bin 下的脚本加上执行权限chmod x bin/jadx bin/jadx-gui ./bin/jadx-gui如果你是在无桌面环境的服务器上使用那就用命令行版./bin/jadx app.apk反编译结果会输出到指定目录。我经常在远程机器上跑批量反编译再用 scp 把结果拉到本地用 GUI 翻这样能省下不少本地内存。Linux 用户还需要注意一点如果用的是精简版系统可能缺少libgtk-3之类的图形库GUI 启动会报错。建议在带桌面的发行版上直接运行服务器环境老老实实用命令行版就好。4. 第一次实战从 APK 到 Java 源码4.1 准备一个测试 APK学习阶段不建议直接拿一个商业 App 练手。你可以去 GitHub 上找一个开源项目的 debug APK或者用 Android Studio 自己打一个包。这样做有好处第一代码本来就能看到方便你对照 JADX 反编译的结果准不准第二不会触碰使用条款避免不必要的麻烦。如果确实要分析某个 App请确保你有足够的授权或者是在合规的测试环境里进行。自己打测试包的时候我建议打开 Android Studio 的开发者选项里的“不压缩库文件”功能默认反编译资源时就不会被压缩干扰。如果你手头连 Android Studio 都没有也可以去一些开源社区找现成的 sample APK。总之先准备一个小体积、结构简单的包第一次运行会顺很多。4.2 jadx-gui 的界面操作打开 GUI 之后File - Open file...选择你要分析的 APK。文件会开始加载左下角的进度条会显示解析到哪个阶段。遇到大型 APK 时这一步可能持续几十秒耐心等待就好不要反复点击菜单。加载完成后左侧是一个树形结构按照包名层级展开右侧显示选中类对应的源码。很多新手第一次看到这一屏会很兴奋但要注意这个窗口不是简简单单的“源码阅读器”它还有很多实用功能藏得很深。常用的几个操作按CtrlShiftF全局搜索字符串或类名这对定位某个页面特别有用在左侧树里右键类名选择Find Usage可以查看这个方法被谁调用顶部Tools菜单里还有反混淆重命名、保存为 Gradle project 等功能。我个人最常用的是Navigation - Search class by name输入 Activity 名称秒跳到目标类。如果你要找某个应用的主入口可以看AndroidManifest.xml里带有MAIN和LAUNCHERaction 的 Activity再顺着它往下翻 onCreate整个启动流程就很清晰了。4.3 项目导出与命令行反编译GUI 适合人工分析批量场景还是要靠命令行。先把完整命令贴出来jadx -d output_dir your_app.apk-d指定输出目录运行结束后输出目录里会有sources文件夹和resources文件夹前者是还原出来的 Java 源码后者是资源文件。如果你想在 Android Studio 里导入继续改源码JADX 也支持导出 Gradle 工程GUI 里是File - Save as Gradle project...命令行参数是--export-gradle。用这种方式导出的工程结构和正经 Android 项目已经比较接近但不要指望能一行不改直接编译官方文档自己都说了“反编译后的代码只能作为参考”。这里还有一个非常实用的参数--show-bad-code遇到某些 JADX 无法完整还原的代码块时它会把这部分用近似代码展示出来而不是直接留空。分析疑难样本时我基本都会加上。命令行版的完整调用我常用的是jadx -d out --show-bad-code --no-res app.apk--no-res表示只反编译代码不导出资源文件速度会快很多。如果你只关心某个关键方法可以用--single-class来导出指定类减少无关干扰。5. 安装和使用中的高频问题与排查实录5.1 双击 bat 闪退的排查套路Windows 上最容易遇到的问题就是双击jadx-gui.bat后黑色窗口一闪而过GUI 没起来。绝大多数原因是 Java 没装好或者 Java 版本低于要求。首先要做的不是重装而是用当前用户的命令行窗口手动执行这个 bat。命令行会显示具体的错误如果提示java 不是内部或外部命令说明 Java 没配置到 PATH如果提示UnsupportedClassVersionError说明版本不够去装 Java 11 以上的 JDK。还有一个常见坑用户装的是 32 位 JDK而系统是 64 位也可能导致启动异常建议统一用 64 位版本。另外如果你把解压路径放在C:\Program Files这种带空格和权限控制的目录里也有概率遇到脚本找不到类路径的问题。把整个 JADX 目录移到D:\tools这种简单路径能省掉很多烦恼。还有一个容易被忽略的问题杀毒软件实时防护。有的安全软件会把jadx-gui.bat或java.exe的运行拦截掉导致界面闪退。去安全中心看拦截记录把 JADX 目录加白名单问题立刻消失。5.2 内存不足或卡在加载界面JADX 默认的 JVM 堆内存不是很大遇到几十 MB 甚至上百 MB 的 APK会卡在解析 dex 的过程里甚至直接报OutOfMemoryError。解决办法是修改脚本里的 JVM 参数。Windows 的jadx-gui.bat里会读取一个环境变量JADX_OPTS你可以在系统环境变量里新增JADX_OPTS-Xmx2gmacOS/Linux 下同样把JADX_OPTS导出后再启动。-Xmx2g表示最大堆内存 2GB如果你内存富余可以设到 4g。调大之后大型应用反编译的成功率会明显提高。另外反编译是 CPU 密集型任务多核机器可以加-j 0让 JADX 自动使用所有可用核心速度提升非常明显。如果你是在命令行版里跑直接写jadx -j 0 -Xmx2g -d out app.apk注意JVM 参数要放在java命令后面而不是jadx后面所以通过环境变量来传递是最稳妥的方式。5.3 中文注释乱码怎么处理有时反编译出来的源码里中文字符串全都变成了方块或问号。这一般不是 JADX 的问题而是文件编码没有设置为 UTF-8。GUI 启动时可以在jadx-gui.bat前加一行set JAVA_TOOL_OPTIONS-Dfile.encodingUTF-8或者在你的JADX_OPTS里补上-Dfile.encodingUTF-8。改完重启工具字符串基本就能正常显示了。某些资源文件本身就用了 GBK 编码这时要看原始 APK 的情况JADX 会尽可能地按声明编码去解。这个问题在 Windows 中文系统上尤其常见因为系统默认代码页是 GBKJava 读取文件时如果没有显式指定 UTF-8就会按系统默认编码去解析。建议在环境变量里把JAVA_TOOL_OPTIONS和JADX_OPTS都加上 UTF-8 配置。修改完记得重启终端和 JADX不然不生效。5.4 反编译结果与源码不一致正常吗很多新人看到反编译代码和自己写的源码对不上会以为工具坏了。其实 JADX 本质上是在做“翻译”它没有原始符号表只能根据字节码逆推。编译器做过内联、常量折叠、switch 优化之后反编译代码和原来写的多多少少会不一样。遇到明显不合理的逻辑可以先看看是不是混淆过的原因。混淆会把类名、方法名改成 a、b、c甚至加入无用代码JADX 再厉害也变不回人类命名的样子。这时候有两条路一是用 JADX 自带的反混淆功能它会给变量重新起有意义的名称二是对着 smali 逐行看虽然累但能看到最底层的东西。JADX 的反混淆功能在Tools - Deobfuscation菜单下它会尝试根据上下文推断变量含义但不能保证 100% 还原。对于严重混淆的代码我更推荐 JADX 配合--deobf参数在命令行里导出时自动做反混淆效果比 GUI 里的默认选项好一截。还有一个规律如果反编译后的代码里频繁出现goto或者异常 try/catch 嵌套往往说明源码用了 ASM 字节码插桩或者双护城河加固这时候不要死磕 JADX换个动态分析的思路可能更高效。6. 我的实操心得与后续扩展6.1 让 JADX 更好用的几个小配置第一次打开 JADX你会觉得深色主题很酷但长时间看字会觉得累。我习惯在View - Theme里切到浅色主题再把字体调成等宽字体比如 JetBrains Mono 或 Consolas。遇到某个类源码行数特别多时可以用View - Show Bytecode在源码和字节码之间快速切换定位到关键逻辑后再切回 Java 视图这种阅读效率比单纯抱着反编译源码啃高很多。还有一个快捷键值得记住在左侧树里按类名首字母能快速跳到对应的类在源码里按CtrlB可以直接跳转到方法定义。GUI 默认会在启动时加载上一次打开过的项目如果不希望泄露工作痕迹可以在Setting里关掉“Restore previous session”。我还会把Code area - Word wrap打开长行逻辑读起来不用横向拖滚动条。这些配置看起来都是小事但实际分析一整天代码后体验差别非常大。6.2 组合拳JADX apktool 动态调试JADX 不是万能的。碰到需要修改资源再回编译的场景我会用 apktool 解包和重打包碰到关键逻辑走不通时再用动态调试工具在系统层去验证。一个典型流程是这样先用 JADX 打开 APK定位到目标方法确认它最终调用了哪些 native 函数接着用 apktool 解包看看 so 文件在哪里最后用调试器 hook 一下参数看真正传给 native 层的数据是不是 JADX 里看到的那样。这套组合拳能覆盖大多数逆向分析的常规需求而 JADX 在其中承担的是“地图”的角色先有地图再去探索比直接深入底层高效得多。简单说就是 JADX 负责静态代码阅读apktool 负责资源修改和重打包动态调试负责验证运行时行为。三者各司其职缺一不可。如果你是刚开始接触可以把一个简单的开源 App 从 JADX 到动态调试完整走一遍比看一百篇教程都有用。6.3 学习方向与合规提醒如果你是因为兴趣开始接触 JADX我建议把 Android 开发四大组件、dex 文件格式、smali 语法这三块补一补。逆向分析不是只会按按钮理解了底层数据结构和系统启动流程你看到的反编译代码才会从“天书”变成“有逻辑的文档”。同时也提醒一句反编译别人的应用之前一定要确认授权边界。你可以用它来分析自己开发的 App 的加固是否到位也可以用它做安全研究但不要拿 JADX 去窃取别人的核心代码或绕过付费机制。工具本身没有立场使用方式决定了它的价值。最后分享一个我个人的操作习惯每次更新 JADX 版本前我会先把旧版本目录整个删掉再用新版本重新跑一遍平时常用的那批 APK。JADX 的更新经常带来反编译逻辑的改进有些老版本里崩溃的样本新版可能一次就解开了。留一台干净的环境能帮你更快发现新版本的脾气。
返回列表