欢迎光临
我们一直在努力

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

前言

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

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

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

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

  • 多态 VM 的分析方法
  • AI + 人工的协作模式
  • 隐蔽的 SHA256 魔改如何发现

  • 一、挑战:多态 VM

    1.1 什么是多态 VM?

    普通 VM 保护:

    1

    2

    case 2 → 永远是 PUSH 操作

    case 5 → 永远是 POP 操作

    多态 VM 保护:

    1

    2

    3

    VM_A: case 2 → PUSH

    VM_B: case 2 → STORE

    VM_C: case 2 → CALL

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

    1.2 难度对比

    保护类型分析复杂度工具复用性
    字符串混淆
    控制流平坦化
    单 VM 保护 中高
    多态 VM 极高 极低

    1.3 具体挑战

  • 30+ 套 opcode 映射:每个 VM 都需要单独分析
  • 嵌套调用链:签名逻辑分散在多个 VM 中
  • 隐式参数传递:通过栈操作传递,难以追踪
  • 魔改标准算法:SHA256、Base64 都经过定制修改

  • 二、方法:AI 辅助分析

    2.1 整体流程

    1

    AST 解混淆 → 提取结构化数据 → AI 分析模式 → 人工验证 → AI 生成代码

    2.2 AST 解混淆

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

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

    Pass功能说明
    1 字符串解密函数还原 _4o5l4("xvvw") → "test"
    2 字符串数组还原 _1w8l4[42] → "appid"
    3 常量折叠 0x1a2b + 0x3c4d → 数值
    4 逗号表达式展开 (a=1, b=2, c()) → 多行
    5 变量语义重命名 _2n8l4 → Bytecode
    6 对象字典展开 _$wR.add(x,y) → x + y
    7-9 清理 死代码移除、未使用变量删除

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

    2.3 AI 分析 VM

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

    然后让 AI 识别:

    • 每个 VM 的 opcode 语义
    • VM 之间的调用关系
    • 关键算法的位置

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

    2.4 AI + 人工协作模式(重要干货)

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

    1

    2

    3

    4

    5

    ┌─────────────┐     分析代码,定位关键点     ┌─────────────┐

    │             │ ──────────────────────────→ │             │

    │     AI      │                             │    人工     │

    │             │ ←────────────────────────── │             │

    └─────────────┘     执行结果、变量值         └─────────────┘

    具体流程:

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

    • AI 阅读解混淆后的代码
    • 识别关键函数入口、可疑的魔改点
    • 告诉人工:「在第 X 行设置断点,观察变量 Y 的值」
  • 人工在浏览器中操作

    • 打开 DevTools,设置断点
    • 触发签名请求
    • 记录断点处的变量值、调用栈
  • 把结果反馈给 AI

    • 「断点触发了,变量 X = "abc123",调用栈是 A → B → C」
    • AI 根据实际值分析逻辑
  • AI 调整分析方向

    • 如果结果符合预期,继续下一个断点
    • 如果不符合,AI 重新分析,找新的断点位置
  • 为什么这种模式有效?

    • AI 擅长:阅读大量代码、识别模式、推理逻辑
    • 人工擅长:操作浏览器、获取运行时数据
    • 互补:AI 无法执行 JS,人工不想读混淆代码

    实际案例:

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

    1

    2

    3

    4

    5

    6

    AI: 「SHA256 结果不对,在 _append 函数入口设断点,看看传入的参数」

    人: 「参数是 "test",但 this.buffer 变成了 "testXXXXXX"」

    AI: 「说明 _append 内部有额外处理,让我分析这个函数…」

    AI: 「找到了,_append 调用了 _eData,在 _eData 设断点」

    人: 「_eData 返回值是原字符串 + 固定后缀」

    AI: 「这就是第二层魔改!」

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


    三、干货:SHA256 魔改还原

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

    3.1 发现过程

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

    1

    2

    标准 SHA256("test") = 9f86d08…

    京东 SHA256("test") = 完全不同的值

    于是开始追踪 SHA256 的实现。

    3.2 第一层魔改:_seData1 预处理

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

    1

    "test" → "test" + [10字符动态后缀]

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

    3.3 第二层魔改:_eData 预处理(最隐蔽)

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

    问题出在 _append 函数被魔改了。

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

    1

    2

    3

    4

    5

    6

    7

    8

    9

    // 标准实现

    _append(data) {

        this.buffer += data;

    }

    // 京东魔改

    _append(data) {

        this.buffer += _eData(data);  // _eData 会追加固定后缀

    }

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

  • 函数名没变,看起来是标准实现
  • 魔改逻辑在另一个 VM 中(eData VM)
  • 不仔细追踪调用链根本发现不了
  • 3.4 第三层魔改:字节交换

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

    1

    [a, b, c, d, …] → [c, b, a, d, …]

    3.5 完整调用链

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    jd_sha256(input)

        ↓

    _seData1(input)           ← 追加 10 字符动态后缀

        ↓

    _eData(result)            ← 追加固定后缀 (隐藏在 _append 中)

        ↓

    标准 SHA256

        ↓

    swap(byte[0], byte[2])    ← 字节交换

        ↓

    输出 64 位 hex

    3.6 教训

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

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


    四、VM 架构分析

    4.1 整体架构

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

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    signSync() 入口

        ↓

    ┌─────────────────────────────────────────────────────────┐

    │  l34 (签名入口 VM)                                       │

    │      ↓                                                  │

    │  l31 (h5st 组装 VM) ─────────────────────────────────┐  │

    │      │                                               │  │

    │      ├─→ l24 (密钥生成 VM)                            │  │

    │      │       └─→ l25 (辅助函数)                       │  │

    │      │                                               │  │

    │      ├─→ l28 (签名计算 VM) ──→ jd_sha256             │  │

    │      │       └─→ l29 (辅助函数)                       │  │

    │      │                                               │  │

    │      ├─→ l30 (签名数据 VM)                            │  │

    │      │                                               │  │

    │      ├─→ wm_encode (自定义 Base64 VM)                 │  │

    │      │                                               │  │

    │      └─→ l27 (最终组装 VM) ←─────────────────────────┘  │

    └─────────────────────────────────────────────────────────┘

    4.2 VM 分类

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

    签名核心 VM(6 个):

    VM功能说明
    l34 签名入口 signSync() 的实际实现
    l31 h5st 组装 协调各子 VM,组装最终结果
    l24 密钥生成 根据 token、fingerprint 等生成 key
    l28 签名计算 调用 jd_sha256 计算签名
    l30 签名数据 生成 signData 字段
    l27 最终组装 拼接 10 个字段生成 h5st

    加密算法 VM(6 个):

    VM功能说明
    wm_encode 自定义 Base64 5 步变换的编码算法
    seData1 SHA256 预处理 追加 10 字符动态后缀
    eData 数据编码 追加固定后缀(隐藏在 _append 中)
    sha256_seData SHA256 专用预处理 配合 seData1 使用
    append 数据追加 被魔改的辅助函数
    eKey HMAC 密钥处理 密钥相关处理

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

    4.3 多态 opcode 示例

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

    Opcodel34 (签名入口)l31 (h5st组装)l23 (环境检测)
    2 PUSH_IMM STORE_wK
    5 DUP_GET_PROP PUSH_IMM NE
    7 STORE_wR SET_PROP_CHAIN PUSH_STR
    12 POP PUSH_OBJ STORE_wF

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


    五、环境检测分析

    5.1 检测目的

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

  • 识别自动化工具(Selenium、Puppeteer 等)
  • 生成设备唯一标识
  • 检测运行环境是否正常
  • 5.2 检测项目

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

    运行时检测:

    检测项目标检测方式
    typeof Deno Deno 运行时 类型检查
    typeof Bun Bun 运行时 类型检查
    typeof process Node.js 类型检查
    navigator.webdriver Selenium/Puppeteer 属性检查
    window.phantom PhantomJS 属性检查
    window._phantom PhantomJS 属性检查
    window.callPhantom PhantomJS 属性检查

    浏览器指纹:

    5.3 envData 结构

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

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    {

        "sua": "Mozilla/5.0…",      // userAgent

        "pp": {},                      // 插件信息

        "extend": {

            "wd": false,               // webdriver

            "l": 0,                    // 语言数量

            "ls": "zh-CN",             // 语言

            "ml": 8,                   // 最大触摸点

            "pl": 5,                   // 插件数量

            "av": "5.0…",            // appVersion

            "ua": "Mozilla/5.0…",    // userAgent

            "pf": "MacIntel",          // platform

            "canvas": "…",           // canvas 指纹

            "webglFp": "…"           // webgl 指纹

        },

        "random": "xxxxxxxx"           // 随机值

    }

    5.4 绕过策略

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

  • 模拟完整的浏览器环境(navigator、screen、document 等)
  • 确保 webdriver 等检测项返回正常值
  • 生成合理的 canvas/webgl 指纹
  • 或者更简单的方式:直接固定 envData,因为这个字段主要用于风控,不影响签名验证。


    六、总结

    6.1 AI 辅助逆向的优势

  • 处理重复模式:30+ 个 VM 的 opcode 映射,AI 可以快速建立
  • 代码生成:还原后的算法,AI 可以直接生成目标语言实现
  • 调用链追踪:隐蔽的魔改点,AI 可以帮助快速定位
  • 6.2 方法论

    1

    2

    3

    1. 先整体后局部:理解架构再深入细节

    2. 先静态后动态:AST 分析 + 运行时验证

    3. 持续验证:每还原一部分就验证一部分

    6.3 AI 的局限性

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

    • 动态值提取:盐值、模板字符串等需要从字节码中定位
    • 最终验证:确保还原结果与原始实现一致
    赞(0)
    未经允许不得转载:171主机测评 » 使用AI完全还原某东h5st协议还原-如何用AI还原多态VM
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址