某宝系某麦SecurityGuard libsgmain签名Unidbg模拟执行实战
物料:
frida
IDA pro(没玩明白)
unidbg 0.9.8(必须用这个 别用最新版)
root安卓真机+模拟器
0x00 前言
在移动端逆向领域,阿里系的 SecurityGuard (无线安全组件) 始终是一座绕不开的大山。无论是某宝、某猫还是某麦,其核心业务接口都由 libsgmainso 守护。
该组件集成了极其复杂的指令混淆(LLVM-Obfuscator)、自解密插件、环境指纹扫描以及严苛的 anti-debug 策略。传统的 IDA
静态分析在这种“黑盒”面前效率极低。本文将分享如何利用 Unidbg 构建一套完整的模拟执行环境
---
0x01 环境准备:资产的“外科手术式”提取
SecurityGuard 并非独立的 SO,它是一个依赖物理环境的“生态系统”。更新版本后,必须从真机拉取以下关键资产:
1. 引擎层: libsgmainso-6.7.250903.so
2. 图腾层(Totem):yw_1222_27.jpg 作为密钥种子。
3. 插件层(SGLib): app_SGLib这里存放着下发的 DEX 插件和 AVMP 引擎数据。
---
所有的安全操作最终都会收敛到一个 Native 函数:doCommandNative
通过 Frida 挂钩这个函数,我们可以观察到一个极其关键的特性:状态累积(State Accumulation)。你不能直接调用 70102
(签名指令),必须先按顺序喂给它初始化指令。
实战捕获的初始化序列一共使用了 22 个:
环境初始化与密钥图片加载。
生成longToken。
生成 authToken
最终签名,产出 Map 结果。
---
0x03 Unidbg 模拟:
1. 后端选择与反调试绕过
由于 6.7.x 版本的 SO 包含大量高频 Syscall 检测,推荐使用 Dynarmic 后端。为了防止 SO 扫描 Frida 特征或 Root 文件,我们需要在 Java 层做以下动作:
1 // 1. 内存:SO 会检测 0x7000000000 附近的地址空间
2 emulator.getBackend().mem_map(0x7000000000L, 0x10000, 3);
3
4 // 2. Syscall 返回“未发现敏感文件”
5 @Override
6 public void hook(Backend backend, long address, int size, Object user) {
7 if (x8 == 61) { // getdents64
8 backend.reg_write(Arm64Const.UC_ARM64_REG_X0, 0L);
9 // ... 跳过指令
10 }
11 }
2. JNI 环境的深度补全
SG 内部会频繁使用反射。我们需要实现几个关键点:
- ClassLoader: 模拟返回真机的插件加载器,处理 loadClass 逻辑。
- HashMap: 必须实现 put 方法,用于接收 70102 返回的签名键值对。 ---
0x04 核心攻坚:0x29c8de12 Token 无效或签名校验失败 错误排查。
对策:
1. 上下文衔接: 检查 70102 传入的 INPUT 字符串
2. 时钟同步: 签名非常看重时间戳(ARG[0] 中的 ms 级时间),确保模拟器返回的时间与业务逻辑一致。
---
0x05 总结
模拟大麦 SecurityGuard 的核心不在于逆向它的算法,而在于完整还原它的“生命周期”。通过 Unidbg 的 rootfs 映射和精细的 JNI 方法补全,我们可以将其从复杂的Android 环境中解耦,实现高效的工程化调用。
目前,基于 Dynarmic 后端的模拟方案已能稳定产出:
- x-sign: azG34N007xAA...
- x-mini-wua: aNQSy8WXqK...
- x-umt: aaCJ/bFbB3E...
逆向之路,不仅是代码的博弈,更是对底层原理理解的深度较量。
小白第一次写文章,使用ai帮忙润色了一些 如果有写到不好的地方还请各位大佬指教。
欢迎一起交流有关问题一起学习。
最后不得不感慨一些现在ai的能力太强了,而且进步很快,依稀记得一年前代码能力连现在一半都不到
更多推荐
所有评论(0)