目录
  1. 1. 一、apktool 深度解析
    1. 1.1. 内部工作原理
    2. 1.2. smali/baksmali 引擎
  2. 2. 二、JADX 深度解析
    1. 2.1. 反编译流水线
    2. 2.2. 核心特性
    3. 2.3. JADX vs GDA vs BytecodeViewer
  3. 3. 三、实战工作流
  4. 4. 面试常考问题
【逆向安全技术-工具篇】反编译神器apktool和Jadx

一、apktool 深度解析

apktool(https://github.com/iBotPeaches/Apktool)是 Android 逆向的基石工具,主要功能是对 APK 进行解码(decode)重构建(rebuild)

内部工作原理

当执行 apktool d target.apk 时,apktool 执行以下步骤:

  1. 解析 AndroidManifest.xml:将二进制的 AXML 格式还原为可读的 XML
  2. 解析 resources.arsc:将二进制的资源表还原为 res/values/*.xml
  3. 反汇编 DEX:使用 smali/baksmali 库将 DEX 字节码转为 smali 汇编代码
  4. 提取资源文件:保留 res/ 下原始资源的目录结构
# 基础用法
apktool d target.apk -o output_dir # 解码
apktool d -d target.apk -o debug_dir # 调试模式(添加 .line、.local 等调试信息)
apktool d -s target.apk -o src_only # 跳过 DEX→smali 反汇编
apktool d -r target.apk -o no_res # 跳过资源解码

# 重打包
apktool b output_dir -o patched.apk # 构建新 APK
apktool b output_dir -c # 构建并复制原始 META-INF

smali/baksmali 引擎

apktool 的 DEX 处理能力来自 smali(https://github.com/JesusFreke/smali)。baksmali 负责 DEX → smali,smali 负责 smali → DEX。

# 直接使用 baksmali 将 DEX 反汇编为 smali
java -jar baksmali.jar d classes.dex -o smali_out/

# smali 将 smali 代码汇编为 DEX
java -jar smali.jar a smali_out/ -o new_classes.dex

二、JADX 深度解析

JADX(https://github.com/skylot/jadx)的作用是将 DEX 字节码反编译为 Java 源代码,质量在所有开源工具中名列前茅。

反编译流水线

DEX 文件 → baksmali 反汇编 → JADX 中间表示 (IR) → 控制流分析 → 变量恢复 → 类型推断 → Java 源码输出。

核心特性

搜索能力:

Ctrl+Shift+F → 全文搜索(字符串、方法名、类名)
Ctrl+N → 按类名搜索
Ctrl+H → 按方法名搜索
导航栏中支持正则表达式搜索

反混淆能力:

Tools → Deobfuscation → 重命名混淆的类/方法名
Tools → Quarks Plugin → 内置安全分析插件,搜索加密/网络调用

代码导航:

右键 → Find Usage         → 查找所有调用点
右键 → Go to Declaration → 跳转到声明处
右键 → Show Bytecode → 查看对应 smali 代码(对比验证)

JADX vs GDA vs BytecodeViewer

特性 JADX GDA BytecodeViewer
反编译质量 ★★★★★ ★★★★☆ ★★★★☆
搜索能力 ★★★★★ ★★★★☆ ★★★☆☆
GUI 体验 ★★★★☆ ★★★☆☆ ★★★☆☆
反混淆 ★★★★☆ ★★★★★ ★★★☆☆
Smali 对比 ★★☆☆☆ ★★★★★ ★★★★★
开源
仓库 github.com/skylot/jadx - github.com/Konloch/bytecode-viewer

三、实战工作流

推荐的逆向工作流:

# Step 1: apktool 解包(获得 smali 和资源)
apktool d target.apk -o step1_apktool/

# Step 2: JADX 反编译到 Java
jadx -d step2_jadx/ target.apk

# Step 3: 在 JADX 中找到目标方法 → 记录类名和方法名
# Step 4: 在 step1_apktool/smali/ 中定位对应 smali 文件
# Step 5: 修改 smali 逻辑 → apktool b 重打包 → 签名 → 安装

配合使用技巧: 当 JADX 反编译某个方法出错时,右键 → Show Bytecode 查看 smali;想修改代码逻辑时,在 apktool 输出的 smali 目录中操作,因为 JADX 只是查看工具。

面试常考问题

Q1:apktool 反编译后修改了资源,重打包失败的原因有哪些?
A:常见原因:(1)资源 ID 冲突或引用错误;(2)apktool 版本与 APK 的 aapt 版本不匹配;(3)使用了 -r/--no-res 跳过了资源解码但后续又引用了未解码的资源;(4)AndroidManifest.xml 中的 namespace 引用版本不兼容。解决方案:升级 apktool 到最新版,使用 -f 强制覆盖。

Q2:JADX 遇到反编译死循环或 OOM 怎么办?
A:在 JADX 偏好设置中调低反编译强度(关闭某些高级优化),或在命令行使用 --deobf 限制反混淆深度。针对特定类,在 GUI 中右键 → Exclude from decompilation 跳过,看 smali 替代。也可以分配更大堆内存:jadx-gui -Xmx4g target.apk

Q3:如何利用 apktool + JADX 配合实现代码注入?
A:(1)apktool d 获取 smali 代码;(2)编写注入代码并编译为 smali:javac Inject.java → dx --dex --output=inject.dex Inject.class → baksmali d inject.dex;(3)将生成的 smali 文件复制到 apktool 输出的 smali 目录中;(4)在目标方法的 smali 中添加 invoke-static 调用注入的方法;(5)apktool b 重打包签名。若目标 APK 使用 ProGuard 混淆,需注意注入类的包名不要与目标冲突。

打赏
  • 微信
  • 支付宝

评论