首页
社区
课程
招聘
[原创] 使用AI完全还原某东h5st协议还原-如何用AI还原多态VM
发表于: 3天前 1823

[原创] 使用AI完全还原某东h5st协议还原-如何用AI还原多态VM

3天前
1823

本文仅供安全研究和学习交流,请勿用于非法用途。

我一直使用 AI 辅助 JS 逆向分析。从简单的 OB 混淆、sojson,到单 VM 保护,AI 都能很好地完成任务。

但这次遇到了一个新挑战:多态虚拟机 (Polymorphic VM) 保护。

与单 VM 不同,多态 VM 有 30+ 个独立的 dispatcher,同一个 opcode 在不同 VM 中执行完全不同的操作。如果不使用 AI,这种多态 VM 几乎无法静态分析——光是建立 30 套 opcode 映射表就是噩梦。

但 AI 让多 VM 的静态还原成为可能。本文分享三个核心干货:

普通 VM 保护:

多态 VM 保护:

同一个数字,在不同 VM 中含义完全不同。

工作流程:Gemini 识别混淆类型 → Claude Code 编写 AST 脚本 → 迭代优化

拿到 450KB 的混淆代码后,先让 Gemini 识别混淆类型,然后让 Claude Code 编写 Babel AST 脚本。整个脚本分 9 个 Pass:

调试技巧:分 Pass 执行,每个 Pass 单独测试,报错信息直接发给 AI 修复。

解混淆后,用 AST 工具提取:字节码数组、字符串表、VM dispatcher 结构。

然后让 AI 识别:

关键点:用浏览器实际执行结果验证 AI 的分析,发现不一致时针对性重新分析。

这是我在分析过程中摸索出的高效协作模式:

具体流程

AI 分析代码,找到断点位置

人工在浏览器中操作

把结果反馈给 AI

AI 调整分析方向

为什么这种模式有效?

实际案例

发现 _append 魔改就是这样找到的:

这种「AI 指挥 + 人工执行」的模式,比纯静态分析效率高很多。

在所有算法还原中,魔改 SHA256 是最难的部分。不是因为 SHA256 本身复杂,而是魔改点极其隐蔽。

最初,我以为只需要找到 SHA256 的调用点,直接用标准库就行。但对比浏览器输出后发现结果不一致:

于是开始追踪 SHA256 的实现。

输入数据在进入 SHA256 前,会先经过 _seData1 函数处理,追加 10 个字符的动态后缀:

这 10 个字符是根据输入内容计算的,算法是将输入分成 10 块,每块计算字符码累加值,映射到自定义字符表。

找到 _seData1 后,我以为已经完成了。但验证时发现结果还是不对。

问题出在 _append 函数被魔改了

在标准 SHA256 实现中,_append 只是简单地追加数据。但京东的实现中,_append 内部调用了 _eData,会额外追加一个固定后缀:

这个魔改非常隐蔽,因为:

最后,SHA256 的输出还会进行字节交换——交换第 0 字节和第 2 字节:

这个案例说明:魔改可能发生在任何地方,包括看起来无害的辅助函数

如果不是 AI 帮我快速分析了所有相关 VM 的字节码,手动追踪这个调用链可能需要很长时间。

通过 AI 分析,我梳理出了签名的完整 VM 调用链:

分析了 17 个核心 VM,按功能分类:

签名核心 VM(6 个)

加密算法 VM(6 个)

辅助 VM(5 个):l25、l29、l32、l33、l23(环境检测)

同一个 opcode 数字在不同 VM 中的含义:

这就是为什么叫「多态」——同一个数字,在不同 VM 中执行完全不同的操作

签名过程中会收集大量浏览器指纹,用于:

通过分析 l23(环境检测 VM),发现以下检测项:

运行时检测

浏览器指纹

这些检测结果会被编码到 h5st 的第 8 个字段(envData)中:

如果要在非浏览器环境运行,需要:

或者更简单的方式:直接固定 envData,因为这个字段主要用于风控,不影响签名验证。

AI 不是万能的,以下场景仍需人工介入:

多态 VM 是目前 JS 保护的高级形态,传统工具和方法很难应对。但借助 AI 的模式识别和代码生成能力,可以大幅提升分析效率。

核心还是逆向工程的方法论:理解保护机制的原理,找到正确的切入点,持续验证和迭代。

希望本文对研究 VM 保护的朋友有所启发。

免责声明:本文仅用于安全研究和技术交流,请遵守相关法律法规。

case 2 → 永远是 PUSH 操作
case 5 → 永远是 POP 操作
case 2 → 永远是 PUSH 操作
case 5 → 永远是 POP 操作
VM_A: case 2 → PUSH
VM_B: case 2 → STORE
VM_C: case 2 → CALL
VM_A: case 2 → PUSH
VM_B: case 2 → STORE
VM_C: case 2 → CALL
保护类型 分析复杂度 工具复用性
字符串混淆
控制流平坦化
单 VM 保护 中高
多态 VM 极高 极低
AST 解混淆 → 提取结构化数据 → AI 分析模式 → 人工验证 → AI 生成代码
AST 解混淆 → 提取结构化数据 → AI 分析模式 → 人工验证 → AI 生成代码
Pass 功能 说明
1 字符串解密函数还原 _4o5l4("xvvw")"test"
2 字符串数组还原 _1w8l4[42]"appid"
3 常量折叠 0x1a2b + 0x3c4d → 数值
4 逗号表达式展开 (a=1, b=2, c()) → 多行
5 变量语义重命名 _2n8l4Bytecode
6 对象字典展开 _$wR.add(x,y)x + y
7-9 清理 死代码移除、未使用变量删除
┌─────────────┐     分析代码,定位关键点     ┌─────────────┐
│             │ ──────────────────────────→ │             │
│     AI      │                             │    人工     │
│             │ ←────────────────────────── │             │
└─────────────┘     执行结果、变量值         └─────────────┘
┌─────────────┐     分析代码,定位关键点     ┌─────────────┐
│             │ ──────────────────────────→ │             │
│     AI      │                             │    人工     │
│             │ ←────────────────────────── │             │
└─────────────┘     执行结果、变量值         └─────────────┘
AI: 「SHA256 结果不对,在 _append 函数入口设断点,看看传入的参数」
人: 「参数是 "test",但 this.buffer 变成了 "testXXXXXX"
AI: 「说明 _append 内部有额外处理,让我分析这个函数...」
AI: 「找到了,_append 调用了 _eData,在 _eData 设断点」
人: 「_eData 返回值是原字符串 + 固定后缀」
AI: 「这就是第二层魔改!」
AI: 「SHA256 结果不对,在 _append 函数入口设断点,看看传入的参数」
人: 「参数是 "test",但 this.buffer 变成了 "testXXXXXX"
AI: 「说明 _append 内部有额外处理,让我分析这个函数...」
AI: 「找到了,_append 调用了 _eData,在 _eData 设断点」
人: 「_eData 返回值是原字符串 + 固定后缀」
AI: 「这就是第二层魔改!」
标准 SHA256("test") = 9f86d08...
京东 SHA256("test") = 完全不同的值
标准 SHA256("test") = 9f86d08...
京东 SHA256("test") = 完全不同的值
"test" "test" + [10字符动态后缀]
"test" "test" + [10字符动态后缀]
// 标准实现
_append(data) {
    this.buffer += data;
}
 
// 京东魔改
_append(data) {
    this.buffer += _eData(data);  // _eData 会追加固定后缀
}
// 标准实现
_append(data) {
    this.buffer += data;
}
 
// 京东魔改
_append(data) {
    this.buffer += _eData(data);  // _eData 会追加固定后缀
}
[a, b, c, d, ...] → [c, b, a, d, ...]
[a, b, c, d, ...] → [c, b, a, d, ...]
jd_sha256(input)
    
_seData1(input)           ← 追加 10 字符动态后缀
    
_eData(result)            ← 追加固定后缀 (隐藏在 _append 中)
    
标准 SHA256
    
swap(byte[0], byte[2])    ← 字节交换
    
输出 64 hex
jd_sha256(input)
    
_seData1(input)           ← 追加 10 字符动态后缀
    
_eData(result)            ← 追加固定后缀 (隐藏在 _append 中)
    
标准 SHA256
    
swap(byte[0], byte[2])    ← 字节交换
    
输出 64 hex
signSync() 入口
    
┌─────────────────────────────────────────────────────────┐
│  l34 (签名入口 VM)                                       │
│      ↓                                                  │
│  l31 (h5st 组装 VM) ─────────────────────────────────┐  │
│      │                                               │  │
│      ├─→ l24 (密钥生成 VM)                            │  │
│      │       └─→ l25 (辅助函数)                       │  │
│      │                                               │  │
│      ├─→ l28 (签名计算 VM) ──→ jd_sha256             │  │
│      │       └─→ l29 (辅助函数)                       │  │
│      │                                               │  │
│      ├─→ l30 (签名数据 VM)                            │  │
│      │                                               │  │
│      ├─→ wm_encode (自定义 Base64 VM)                 │  │
│      │                                               │  │
│      └─→ l27 (最终组装 VM) ←─────────────────────────┘  │
└─────────────────────────────────────────────────────────┘
signSync() 入口
    
┌─────────────────────────────────────────────────────────┐
│  l34 (签名入口 VM)                                       │
│      ↓                                                  │
│  l31 (h5st 组装 VM) ─────────────────────────────────┐  │
│      │                                               │  │

[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!

收藏
免费 75
支持
分享
最新回复 (39)
雪    币: 344
活跃值: (1800)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
6666
3天前
0
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
感谢分享
3天前
0
雪    币: 1
活跃值: (1105)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
6
3天前
0
雪    币: 6
活跃值: (2411)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
666
3天前
0
雪    币: 6
活跃值: (2411)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
感觉文章都是AI生成的
3天前
0
雪    币: 6241
活跃值: (6035)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
66
3天前
0
雪    币: 3631
活跃值: (3246)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
听君一席话 如听一席话
3天前
0
雪    币: 104
活跃值: (7406)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
tql
3天前
0
雪    币: 234
活跃值: (340)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
3天前
0
雪    币: 566
活跃值: (1598)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
1
3天前
0
雪    币: 7
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
12
感谢分享
3天前
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
13
感谢分享
3天前
0
雪    币: 464
活跃值: (182)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
14
lookzo 感觉文章都是AI生成的[em_011]
文章是AI生成的,但是内容是自己写的,AI只是润色了。并且我的逆向分析全流程都是AI,自己没写任何一行代码。
3天前
0
雪    币: 3907
活跃值: (4335)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
6
3天前
0
雪    币: 293
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16
66666666
3天前
0
雪    币: 8788
活跃值: (6607)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
感谢分享
3天前
0
雪    币: 45
活跃值: (1122)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
111
3天前
0
雪    币: 4210
活跃值: (3451)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
答辩
3天前
0
雪    币: 2
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
20
1
3天前
0
雪    币: 220
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21
1
3天前
0
雪    币: 2533
活跃值: (2187)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
高科技呀 学习
3天前
0
雪    币: 1411
活跃值: (1337)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
23
111
3天前
0
雪    币: 1411
活跃值: (1337)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
24
有没有具体的分析步骤
3天前
0
雪    币: 464
活跃值: (182)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
25
半个大西瓜 有没有具体的分析步骤
太详细的不能发,发了帖子就没了
3天前
0
游客
登录 | 注册 方可回帖
返回