一、加固原理概述
Android 应用加固(壳)的核心思路:将原始 DEX 文件加密后打包进 APK,类加载时由壳代码动态解密 DEX,并通过自定义 ClassLoader 加载到 ART 虚拟机中。常见加固厂商包括:腾讯乐固、360 加固保、梆梆安全、阿里聚安全等。
加固层次分为:DEX 整体加密 → DEX 方法抽取 → DEX 指令虚拟化(VMP),难度依次递增。
二、检测加固类型
# 1. 解包 APK,观察结构 |
# 2. 检查 classes.dex 大小 |
三、内存 DEX 脱壳
加固的 DEX 最终必须加载到内存才能执行。利用此特点,在运行时从内存中 Dump 解密后的 DEX。
方法一:Frida Dump
// frida_dex_dump.js — attach 后自动 dump 所有已加载的 DEX |
frida -U -f com.target.app -l frida_dex_dump.js --no-pause |
方法二:DumpDex 工具
将设备 root 后,使用 DumpDex(https://github.com/WrBug/dumpDex)通过 Hook ClassLoader.loadClass 获取所有已加载的类,逐一 dump 出 DEX。
方法三:Objection
objection -g com.target.app explore |
四、对抗反调试
加固应用通常会检测调试状态:
# /proc/self/status 中的 TracerPid 为非 0 表示正在被调试 |
对抗 ptrace 反调试的方法:
// Frida 脚本:Hook ptrace 调用 |
对抗 TracerPid 检测:直接 patch /proc/self/status 的读取结果,或使用 MagiskHide 隐藏调试状态。
五、对抗 APK 签名校验
加固应用常调用 PackageManager.getPackageInfo() 校验 APK 签名:
// Frida Hook 签名校验 |
六、处理 Multi-DEX 应用
加固后的应用通常包含多个 DEX:
# JADX 打开所有 DEX |
面试常考问题
Q1:Frida 脱壳的原理是什么?被检测到怎么办?
A:Frida 脱壳利用应用运行时 DEX 已在内存中解密的特点,通过 Hook ClassLoader 或直接遍历内存将 DEX dump 出来。被检测的对抗措施:使用 Frida 的 anti-detection 脚本(frida-antidetect)、修改 Frida 进程名、使用定制版 Frida Server(如 hluda-server)绕过端口检测和 D-Bus 扫描。
Q2:什么是 VMP(虚拟化保护)?如何分析?
A:VMP 将 DEX 字节码转换为自定义的虚拟机指令,运行时由壳自带的解释器执行。传统反编译工具无法还原。分析需要逆向壳本身的虚拟机解释器,理解其指令编码格式,编写专用的反汇编器。常见思路:利用 trace 工具记录指令执行序列,结合符号执行推导原始逻辑。
Q3:加固应用如何做 so 层分析?
A:先用工具(如 Frida 的 dlopen Hook)确认 so 文件被加载到哪个内存地址,然后使用 IDA Pro 的 attach 功能进行动态调试。对于加密的 so,可以通过 /proc/pid/maps 查看内存布局后,用 dd 命令从内存中 dump 解密后的 so。


