为什么需要 unidbg
上一篇讲了 Frida RPC 方案:在真机上注入优酷 App,借 App 自己的代码算 x-sign。这个方案能用,但有几个硬伤:
- 依赖常驻设备,手机一挂服务就挂
- 单进程串行,并发上不去
- App 不能升级、不能清数据,维护成本高
unidbg 提供了另一条路:在 JVM 里模拟 ARM 指令集,直接加载并执行 App 的 SO 库。不需要手机,不需要 App 运行,一台服务器可以起几百个实例并发跑。
unidbg 原理简述
unidbg 是一个基于 unicorn(CPU 指令模拟器)的 Java 库,它做了三层模拟:
- 指令层:unicorn 模拟 ARM/ARM64 指令执行
- 系统层:模拟 Linux 系统调用(文件、内存、信号等)
- 运行时层:模拟 Android 的 JNI 环境、Dalvik VM、动态链接器
对逆向来说这意味着:把 App 的 .so 文件拖出来,unidbg 就能像 Android 系统一样加载它,并执行里面的 JNI 函数。
准备工作
先从手机里把 SecurityGuard 相关的库 pull 出来(以 6.6.241104 版本为例):
libsgmainso-6.6.241104.so # 主库,签名入口
libsgmiddletierso-6.6.241104.so # 中间层
libsgsecuritybodyso-6.6.241104.so # 安全体
libsgmiscso-6.5.9.so # 杂项
libsgnocaptchaso-6.5.8.so # 验证码组件除了 SO,还要把 App 数据目录下的 app_SGLib 整个目录 pull 下来——里面是 SecurityGuard 的运行时数据(设备指纹、密钥材料等)。没有它,签名要么算不出来,要么算出来也是无效的。
代码实现
核心代码骨架:
public class SgSign {
private final AndroidEmulator emulator;
private final VM vm;
public SgSign() {
// 1. 创建 32 位 ARM 模拟器
emulator = AndroidEmulatorBuilder.for32Bit()
.setProcessName("com.youku.phone")
.build();
// 2. 注册 Android 系统库解析器(API 23)
Memory memory = emulator.getMemory();
memory.setLibraryResolver(new AndroidResolver(23));
// 3. 创建 Dalvik VM
vm = emulator.createDalvikVM(new File("youku.apk"));
vm.setJni(this); // 缺失的 JNI 函数由本类补环境
vm.setVerbose(true);
// 4. 加载 sgmain 主库并执行 JNI_OnLoad
DalvikModule dm = vm.loadLibrary(
new File("sglib/libsgmainso-6.6.241104.so"), true);
dm.callJNI_OnLoad(emulator);
}
}加载成功后,就可以通过 vm.resolveClass() 拿到 Java 层的 SecurityGuard 入口类,调用它的签名方法,SO 内部会回调 Native 层完成计算:
DvmClass sgMain = vm.resolveClass(
"com/alibaba/wireless/security/mainplugin/SecurityGuardMainPlugin");补环境:unidbg 最大的工作量
SO 直接跑起来几乎一定会报各种缺失,因为 SecurityGuard 依赖大量 Android 环境:
- JNI 函数缺失:
RegisterNatives动态注册的函数,按日志逐个补 - 系统属性:
ro.product.model、ro.build.version.sdk等,通过 Hook 系统属性接口喂给它 - 文件读写:把 pull 下来的
app_SGLib目录映射到模拟器文件系统的对应路径 - 包名/签名校验:安全库会校验宿主包名和签名,补环境时要返回真实值
补环境的套路就是:跑 → 看日志报错 → 补 → 再跑,循环直到签名稳定输出。这个过程比较磨人,但只需要做一次。
效果对比
- Frida RPC:依赖真机/模拟器常驻,并发低(单进程),维护成本高
- unidbg:无设备依赖,多实例并发高,维护成本中
实际测试,unidbg 单次签名耗时在毫秒级,一台 4 核服务器轻松支撑每秒上百次签名,完全满足业务需求。
总结
unidbg 的本质是"用 CPU 模拟换部署自由":前期补环境很折磨,但一旦跑通,就彻底摆脱了对真机的依赖,签名服务可以像普通后端服务一样部署、扩容。
对于带 VMP 保护的阿里系 SO,这是目前最主流、最稳定的方案。