首页
社区
课程
招聘
[原创]AI逆向某视频签名算法X-Medusa全过程
发表于: 2小时前 198

[原创]AI逆向某视频签名算法X-Medusa全过程

2小时前
198

本文仅记录一次针对移动端 native 签名逻辑的逆向分析过程,用于安全研究、算法学习和逆向工程方法论交流。文中涉及的脚本、地址和结论均来自本地样本与模拟环境验证,不讨论任何绕过风控、批量请求或业务滥用场景。

这次分析的目标是某视频 App 29.3 版本中的一个 native 签名头:X-Medusa

样本位于 Android native so:

外层调用函数是:

这个函数会一次性生成多个签名头:

本文重点只讲 X-Medusa

我最终将 X-Medusa 主路径还原成了纯 Python,可以在不启动 native VM 的情况下,只输入同一次运行的动态值,生成和 native 一致的 X-Medusa

整个过程并不是一开始就直接进入算法还原。前半段我先用 Cursor 的 Opus 模型搭建和调通ExAndroidNativeEmu 调用环境,它帮我把 sub_D4F3C 的 native 签名调用跑起来,也就是能从本地 emu里拿到各个签名头。到这一步后,继续深入 X-Medusa 内部时,分析基本卡在 SM3 和周边混淆逻辑,无法继续稳定拆出后续 VM 路径。

后半段切到 Codex 后,分析方式变成了“动态 trace + 局部 Python lift + native 对照验证”。也就是本文后面记录的过程:不再只看静态伪代码,而是对每个 VM 片段抓输入、输出和内存副作用,再把能证明的局部逻辑写成 Python,最后组合成完整 pipeline。

最终验证结果:

也就是说,Python 重建出的明文 src_a 和最终 X-Medusa 都与 native 同一次运行完全一致。

本次使用的是一个基于 ExAndroidNativeEmu 的本地模拟环境。目录中已有调用示例:

它负责:

分析过程中还遇到一个环境问题:系统里存在不匹配的 Unicorn dylib,会影响 emu 运行。后面所有 native 对照命令都统一这样跑:

避免 Python 加载错误的 Unicorn 动态库。

一开始没有直接钻 VM,而是先观察 sub_D4F3C 的输出 map/string 插入位置。

最终确认各 header 的插入点:

其中 X-Medusa 的关键路径是:

这里最重要的是确定 VM 执行边界:

有了这个边界,后续 hook 只在 Medusa VM 活跃期间记录,避免被 JNI 初始化、其它 header 或环境探测逻辑干扰。

最开始静态看 0x445b8 这个 VM 入口,会发现它很像 MIPS 风格解释器:

但不能直接把它当标准 MIPS。

我写了一个 Python VM 模型和 native 状态对比脚本,核心思路是:

VM fetch/decode 点:

对比后得到一个重要结论:

也就是说,不能做这样的假设:

部分 R-type 指令的目标寄存器编码也和标准 MIPS 有差异。所以后续还原关键逻辑时,我没有完全依赖静态反汇编,而是优先使用动态 trace 的输入、输出和内存副作用。

接下来先看最终 X-Medusa 是什么。

通过跟踪 base64 调用链:

确认 X-Medusa 是标准 base64,使用普通字母表:

base64 解码后得到一个 raw packet。继续跟踪最终 packet 的 copy 序列,得到结构:

VM copy 点如下:

这个阶段先写出最外层 Python:

继续追 packet body,发现最终 body 来自一个中间 buffer,但不是直接复制出来的。

它的生成分成两步:

second_buffer 布局:

其中:

关键 VM 写点:

这一步对应的 Python lift:

验证方式是同一次 native run 中抓取 copy 的 source/destination/len,然后和 Python 拼出来的 buffer 做 byte-for-byte 比较。

first_intermediate 继续往前追,来到 VM 片段:

静态看这里时很容易把 source 和 destination 看反。所以我对这个范围做了窄范围动态 trace,记录每一轮:

最终确认真实逻辑:

也就是:

key 的来源在前面:

它调用一个短 VM helper,对 tail2 做 hash,取低 16 位组成 4 字节 key:

验证样例:

reverse-xor 的输入不是原始明文,而是:

继续追上游,发现:

进入 lib+0xd71bc 时参数:

这里一开始也容易误判为某种标准加密算法,但动态 trace 后发现它不是 AES/SM4 这种标准 block cipher,而是一个混淆过的字节状态机。

整体结构:

把它 lift 成 Python:

然后用 native dump 的 src_a/key/dst 验证:

d71bc 的 key32 不是固定表,而是 SM3 结果。

调用链:

b"abc" 做验证后确认 lib+0xd9bc0 是标准 SM3:

key material 的构造:

所以:

这也解释了前面 tail2

同一个 rand 同时参与:

只在 Medusa VM 活跃期间 trace rand wrapper,确认共有三次:

分别对应:

这里有一个坑:--lock-time 并不会固定这三个 rand。模拟器里的 rand hook 来自 Python random.randint(0, 0xffffffff),所以想复现同一次签名,必须捕获这三个 rand,或者额外固定随机源。

d71bc 的输入 src_a 是一个 protobuf-like 明文消息。

入口参数里可以直接拿到:

解析后字段如下:

native 辅助函数也能印证这一点:

所以这一段不应该按加密算法理解,而应该按 protobuf builder 还原。

对应 Python 中实现了:

验证方式:

对 SM3 helper 的 IO 做 trace 后确认:

注意这里是 query,不包含 path,也不包含问号前面的部分。

样例:

src_a.f23 是一段嵌套环境 message,其中几个字段是动态值。

最终确认:

对应 native 证据:

这里要区分:

即使锁定 URL 里的 ts 或 emu 的 --lock-timef40 仍可能变化。要复现同一次签名,就必须使用 native run 里抓到的当前毫秒值。

src_a.f24 是 JSON 字符串,形态如下:

先从最终 JSON 里的 fkd/pd 回溯 source string:

确认:

继续追 uuid_source,发现它不是直接把 /dev/urandom 的 16 字节格式化成 UUID,而是:

PRNG 逻辑:

UUID 模板:

填充规则:

用固定 /dev/urandom 输入 --urandom-int 1 验证:

最终 packet 的 body 还会经过一层 bit-slice 处理。

流程:

提取位置:

patch 位置:

稀疏 bit lanes:

byte bit permutation:

这一步看起来很绕,但动态验证很直接:

vm+0x193800 附近能看到明显的 AES GF(2^8) 乘法痕迹:

但它不是标准 AES。

继续 trace S-box、state permutation、key schedule 和 round-key 顺序后,最终确认它是一个自定义 AES-like 变换:

固定材料:

输入:

输出:

其中:

这一阶段逐轮验证了:

到这里,所有局部块都已经能和 native 对上。

最终 Python pipeline:

最终封装成:

以及纯 Python 命令行:

端到端验证脚本会在同一次 native run 中抓取:

然后 Python 用这些值重新生成:

验证结果:

这说明:

如果要让纯 Python 和某一次 native 运行输出完全一致,至少要提供:

其中最容易忽略的是:

这篇文章标题里有 “AI逆向”,但它不是指把 so 丢给 AI 然后自动出结果。

这次更接近一种分阶段的人机协作式逆向。

第一阶段用的是 Cursor 的 Opus 模型,重点解决工程入口问题:

这个阶段的价值很大,因为没有稳定 emu 调用,就谈不上后续动态验证。但它继续深入时基本只能推到 SM3 和一些外层 helper,面对 VM 内部的数据流、buffer 来源、bit-slice patch、AES-like transform 时,很难继续拆下去。


[培训]《冰与火的战歌:Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

上传的附件:
收藏
免费 4
支持
分享
最新回复 (3)
雪    币: 4355
活跃值: (3140)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2

给大哥点赞!

------------

过去,逆向所谓的工作量,一方面在于定位算法,需要尽可能准确地找到最小单元的指令流和控制流,另一个方面在于从上一步获取的数据中依靠经验还原出算法。

而现在借助给大模型搭好完善的脚手架,后一步的工作量可以大幅度降低,但这个过程中,专家经验的输入仍然必不可少。

未来在更多领域,会有越来越多的“一人成军”,领域专家的知识我觉得不但不会被淘汰,反而会愈发重要。

最后于 2小时前 被Umiade编辑 ,原因:
2小时前
0
雪    币: 2046
活跃值: (9625)
能力值: ( LV11,RANK:180 )
在线值:
发帖
回帖
粉丝
3
2小时前
0
雪    币: 6553
活跃值: (4108)
能力值: (RANK:200 )
在线值:
发帖
回帖
粉丝
4
2小时前
0
游客
登录 | 注册 方可回帖
返回