第 47 章 Android 加固与脱壳深度
第 10 章讲了 APK 逆向基础;本章深入 Android 加固(加壳)对抗:加固的原理架构、主流加固方案、脱壳技术的演进(静态脱壳 → 动态 dump → 主动调用脱壳),以及绕过加固中的反调试/反脱壳。
📍 知识点地图 | 主题:APK脱壳 | 前置:第10章 | 后续:— | 核心概念:加固原理、一代/二代/三代壳、主动调用
47.1 Android 加固原理(先懂敌人)
加固的本质: 把真正的 dex 藏起来,运行时再还原
经典加固架构:
APK
├─ 壳 DEX(classes.dex 是壳代码,含解密逻辑)
├─ 加密的真正 dex(存 assets/ 或加密进 so)
└─ 壳 so(native 层解密+加载,防静态脱壳)
执行流程:
App 启动 → 壳 Application(Stub)先执行
→ native 层解密真实 dex → 内存中加载
→ 替换/代理 ClassLoader → 正常业务代码运行
47.2 加固方案分类与特征
| 方案 | 厂商 | 特征 | 难度 |
|---|---|---|---|
| 一代壳(DEX 整体加密) | 早期/简单壳 | 加密整 dex + 内存解密 | ★ |
| 二代壳(函数抽取) | 梆梆/爱加密/360 | dex 壳 + 方法体运行时回填 | ★★★ |
| VMP 加固 | 腾讯乐固/娜迦 | 方法转虚拟指令 | ★★★★ |
| so 加固 | 各类 | 核心逻辑进 so | ★★★ |
| 混合 | 商业全家桶 | 多层组合 + 反调试 | ★★★★★ |
识别加固:jadx 解出的只有壳代码(特征:com.secneo、com.stub.StubApp、com.qihoo.util 等)、大量 native 加载、Application 被替换。
47.3 脱壳技术演进(核心知识)
第一代:静态脱壳(黑盒内存 dump)
原理: 启动 App → 等真实 dex 加载进内存 → dump
工具:
FART(脱壳机): 修改 ART 虚拟机,DexFile 加载时自动 dump
Youpk: 主动调用 + dump(处理抽取壳)
Frida dump 脚本: Hook ClassLoader 相关类 → 读 BaseDexClassLoader 的 dex 数组
流程:
1. 安装脱壳环境(模拟器/真机 + Magisk + 脱壳框架)
2. 运行 App(触发壳解密)
3. dump 内存中的 dex
4. 修复 dex(magic/checksum/SHA1)→ jadx 分析
第二代:函数抽取壳的对抗(方法体回填)
原理(抽取壳):
壳只保留 dex 的方法壳(方法体被清空成 nop/异常)
真实方法体存在 native 层
类加载时/方法调用时回填真实方法体
脱壳难点:
直接 dump 的 dex 方法体是空的(调用即崩溃)
脱壳思路:
1. 主动调用: 逐个调用方法 → 触发回填 → dump 回填后的 dex
2. 内存 hook: Hook ArtMethod 的入口(每个方法都有 ArtMethod 结构)
3. 时机抓取: 在回填完成瞬间 dump 整个 dex
4. FART 主动调用模式(自动遍历所有方法触发回填)
第三代:VMP / 反脱壳对抗
VMP 加固: 方法体被翻译成自定义指令 → dump 也是 VM 字节码
反脱壳: 检测 Frida/脱壳机特征、反调试、双进程保护、dex 校验
应对:
1. 先过反调试(spawn 早期 hook、刷机隐藏)
2. VM 方法: 动态跟踪执行(Frida hook ArtMethod)观察行为
3. 或放弃完整还原 → 行为级理解(第 40 章 6 节同理)
47.4 脱壳环境搭建(实战准备)
推荐环境:
1. Android 模拟器(或 Pixel 真机 + Magisk)
2. root/Magisk: 提供 su 权限
3. Frida server(对应架构版本)
4. 脱壳框架(按需): FART / Youpk / 黑盒脱壳机
5. 模拟器注意: 部分壳检测模拟器 → 用真机 + Magisk + MagiskHide/Zygisk
反调试对抗工具:
Frida spawn 模式(先于壳代码执行)
Magisk + Zygisk(隐藏 root)
Frida 特征隐藏(改名/改端口)
47.5 主动调用脱壳(核心方法论)
原理: 壳的"方法回填"只在方法被调用时发生 → 主动调用所有方法逼它回填
流程:
1. dump 壳解出的 dex(得到方法体为空的框架)
2. 遍历所有类/方法
3. 逐个调用(构造参数/忽略异常)
4. 每次调用后 dump ArtMethod 指向的真实方法体
5. 回填进 dex → 完整还原
工具: FART 的"主动调用"模式、Youpk、自写 Frida 脚本
局限: 需要参数的方法难触发、静态初始化副作用、VMP 方法无效
47.6 绕过反脱壳检查(对抗清单)
| 壳的反脱壳手段 | 绕过 |
|---|---|
| 检测 Frida 特征 | 改名/改端口/早期注入 |
| 检测 root | Magisk + Zygisk 隐藏 |
| 检测模拟器 | 真机 |
| dex 完整性校验 | hook 校验函数 / dump 后修复 |
| 双进程保护 | 分析父子进程协作逻辑 |
| 定时自毁 | 冻结时间/快速分析 |
| VMP 方法 | 接受行为级还原 |
47.7 脱壳后分析流程
1. 校验 dump 的 dex(magic/checksum/SHA1 修复)
2. jadx 打开 → 确认业务代码完整(不是壳)
3. 方法体为空的区域 → 定位对应壳技术(抽取/VMP)
4. 对空方法: 尝试主动调用回填
5. 最终无法还原的 → Frida 动态 Hook 观察行为
6. 产出: 完整业务逻辑 + 敏感点清单
47.8 脱壳检查清单
□ 识别加固方案(厂商特征/壳类型)
□ 环境就绪(root/Frida/脱壳框架)
□ 反调试对抗完成(spawn/隐藏)
□ dump 真实 dex(静态 or 主动调用)
□ dex 修复(magic/checksum)
□ 方法体完整性检查
□ 剩余 VMP 方法 → 动态观察兜底
□ 报告: 加固方案 + 脱壳路径 + 业务逻辑
动手练习
- 用官方/测试加固工具加固一个测试 APK(如开源加固项目),识别它的壳特征。
- 在模拟器 + Frida 环境 dump 一个测试壳的真实 dex,修复后 jadx 分析。
- 找一个函数抽取壳样本,练习主动调用脱壳(FART 或自写脚本)。
- 总结一次"壳反调试 → 绕过"的完整对抗过程(对照 47.6 清单)。
深入阅读
- 仓库:
skills/apk-reverse/SKILL.md(APK 逆向基础) - 仓库:
skills/mobile-reverse/SKILL.md+references/anti-detection-bypass.md(多层绕过) - 仓库:
skills/mobile-reverse/references/frida-objection-deep.md(Frida 深度) - 仓库:
skills/reverse-engineering/languages-platforms.md(DEX 运行时 patch、JNI 混淆) - 实战案例:
skills/field-journal/seed-008_apk-okhttp-ssl-pin-bypass.md