代码形态
Android 端应用多以 Java / Kotlin 编写,编译链路大致为:源码 .class .dex APK。最终可执行逻辑全部落在 classes*.dex 中。借助 jadx、baksmali 等开源工具,任何人都能在数分钟内将 dex 反编为可阅读的 Java 源码。因此,加固工作的核心目标就是“让 dex 难以被还原”。
下文对当前市面上主流的几种加固思路做简要梳理,方便快速建立整体认知。
常见加固思路
1. 整体加密
1.1 落地解密
思路:将原始 dex 整体加密后塞进 APK,运行时先解密到 /data/data/<pkg>/ 目录,再用自定义 DexClassLoader 加载。
优点:实现简单,静态反编译直接失效。
缺点:解密后的明文 dex 躺在文件系统,root 设备直接拷走即可分析。
1.2 内存解密
思路:借助 Android 8.0+ 提供的 InMemoryDexClassLoader,把解密后的字节流直接喂给虚拟机,避免落盘。
优点:文件系统不再暴露明文。
缺点:整块解密后的 dex 在内存中是连续的,用 frida-dexdump 等工具仍可一键转储。
2. 类/方法抽取
思路:不加密整个 dex,仅把每个方法的 CodeItem 抠出来单独加密,类初始化时再动态“填回”。
优点:
静态反编译看到的只是空壳方法;
内存中不存在完整 dex 映像。
缺点:
运行时需频繁解密、填充,易被 JNI / ART Hook 拦截;
攻击者可逐步收集 CodeItem 并自动拼回 dex。
3. Java2C(字节码转 Native)
思路:把关键 Java 方法翻译成 C/C++ 函数,编译成 so,原方法仅保留一个 JNI 桩。
优点:
静态层面完全丢失 Java 实现;
逆向门槛提升到 Native 层。
缺点:
开发、调试、兼容性成本高;
so 本身仍可被 IDA/Ghidra 分析,JNI 调用也可被追踪。
4. Dex VMP(虚拟机壳)
思路:将 dex 指令转译为私有字节码,运行时由内置解释器执行。
优点:
逆向者需先还原整套虚拟机语义,工作量大;
天然支持动态反调试、指令校验、运行时混淆。
缺点:
性能损耗不可忽视;
加固 SDK 自身体积膨胀。
一站式加固示例:Virbox Protector
Virbox Protector 把上述方案做成了“积木式”组合,常用功能包括:
DEX 虚拟化:敏感函数直接跑在自定义虚拟机里;
字符串加密:运行时按需解密,静态不可见;
整体/部分 dex 加密:兼顾兼容性与安全级别;
反调试、反注入、签名校验、文件完整性校验;
Root/模拟器/多开/截屏 检测。
开发者只需勾选所需模块,即可在几分钟内完成加固,无需改动业务代码。
以上即当前 Android 端代码加固的主流路线。实际落地时,通常会根据业务敏感度、性能预算、维护成本等因素,选择“多层叠加”而非“单点依赖”。