Skip to content
Security
Skill

/dsl-vm-reverse

Reverse JavaScript-based custom DSL/VM interpreters, non-standard WASM-like runtimes, and risk-control engines. Use when analyzing IIFE or switch-based opcode dispatchers, extracting instruction tables, recovering bytecode semantics, capturing VM state at runtime, or

BOOST
From plugin
reverse-skill
39k46 skills
Install
$ npx -y skills add zhaoxuya520/reverse-skill --skill dsl-vm-reverse --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/dsl-vm-reverse

Context preview

The summary Claude sees to decide when to auto-load this skill.

Reverse JavaScript-based custom DSL/VM interpreters, non-standard WASM-like runtimes, and risk-control engines. Use when analyzing IIFE or switch-based opcode dispatchers, extracting instruction tables, recovering bytecode semantics, capturing VM state at runtime, or

SKILL.md

dsl-vm-reverse.SKILL.md
name: dsl-vm-reverse
description: Reverse JavaScript-based custom DSL/VM interpreters, non-standard WASM-like runtimes, and risk-control engines. Use when analyzing IIFE or switch-based opcode dispatchers, extracting instruction tables, recovering bytecode semantics, capturing VM state at runtime, or reconstructing execution flow.

🔄 DSL 自定义虚拟机逆向(DSL VM Reverse Engineering)

ACTION REQUIRED(读完后立刻执行)

1. `NOW`: 确认当前任务是自定义 JS opcode VM / 风控引擎,不是标准 WASM 或普通 webpack 2. `NOW`: `case-init` 直到 `scope.md` 就绪;离线样本用 `offline` / `lab` 3. `ACT`: 从「3. 通用逆向工作流」Phase 1 做文件分类,不要停在目录

> 用于逆向基于 JavaScript 实现的自定义 WASM 虚拟机/风控引擎

---

目录

  • [1. 适用范围](#1-适用范围)
  • [2. DSL VM 识别特征](#2-dsl-vm-识别特征)
  • [3. 通用逆向工作流](#3-通用逆向工作流)
  • [4. Opcode 提取与分类](#4-opcode-提取与分类)
  • [5. 运行时捕获方案](#5-运行时捕获方案)
  • [6. 常见状态码](#6-常见状态码)
  • [7. Skill 自检清单](#7-skill-自检清单)

---

1. 适用范围

当目标文件符合以下 **任意特征** 时使用本 skill:

| # | 特征 | 说明 | |---|------|------| | 1 | IIFE 开头 + 大量单字母变量名 | `!function(){var U=void 0,y=parseInt,E0=Function,...}` | | 2 | 包含 `DG()` 或类似函数含 switch-case 循环 | 解释器主循环,`d[7]&31` 解码 opcode | | 3 | 大文件(500KB+)但零字节占比 < 1% | 非标准 WASM,纯 JS | | 4 | 包含 `C[number]` 常量表引用 | `C[9][xxx]` 函数表/字符串表 | | 5 | 单行压缩代码 | 583KB 单行,混淆变量名 |

排除规则

| 条件 | 非本 skill | 转至 | |------|-----------|------| | 文件以 `\x00asm` 开头 | 标准 WASM 二进制 | `reverse-engineering/languages.md` | | 文件以 `Uint8Array([0,97,115,109])` 含 WASM 魔术字 | WASM 嵌入式 | 提取 .wasm 后转 IDA/Ghidra | | 标准 Webpack 打包(`function(e,t,n){...}`) | 普通 JS | `js-reverse/` | | 零字节占比 > 20% | WASM 二进制 | `reverse-engineering/languages.md` |

---

2. DSL VM 识别特征

代码特征

// 特征 1: IIFE 入口,单字母变量映射数字常量
!function(){
    var U=void 0, y=parseInt, E0=Function, AN=Uint8Array;
    var E=15, l=10, m=12, x=16, S=13, $=11;
    // 数字常量映射为变量名,替代原始数字
    ...
}

// 特征 2: 解释器主循环 DG()
function DG(C, d, ...) {
    var d = [];  // 数组模拟 WASM stack/locals
    for (d[7] = x; d[7] !== U;) {
        var aE = d[7] & 31;         // 低 5 位 = opcode
        var O = d[7] >> 5 & 31;      // 高 5 位 = sub-operation
        switch (aE) {
            case 0: /* ... */ d[7] = 612; break;
            case 1: /* ... */
            // ... N 个 case
        }
    }
}

// 特征 3: 常量表 C[9] 存储函数索引和字符串
// C[9][0] = ["pc"]      → 函数参数描述
// C[9][667] = "string"  → 字符串常量
// C[9][x] = number      → 函数索引

// 特征 4: W(C[index], null, ...) 调用模式
// W = Function.prototype.call.bind(call)
// 所有内置函数通过 C[index] 索引调用

// 特征 5: 指令编码格式
// d[7] = opcode(bit 0-4) | subop(bit 5-9) | operand(bit 10+)

Opcode 编码格式

每条指令编码为 32 位整数:

bit 0-4:   opcode (0-N)
bit 5-9:   sub-operation (0-31)
bit 10-31: operand/立即数

解码:
  aE = d[7] & 31        → opcode
  O  = d[7] >> 5 & 31   → sub-operation
  d[other] = d[7] >> 10  → operand

---

3. 通用逆向工作流

Phase 1: 文件分类(5 分钟)

# 检查是否为 DSL VM
python3 << 'EOF'
with open('target.js', 'rb') as f:
    head = f.read(100)

# 1. 检查 WASM 魔术字
if head[:4] == b'\x00asm':
    print("标准 WASM 二进制")
    exit()

# 2. 检查零字节占比
data = open('target.js', 'rb').read()
zero_pct = data.count(b'\x00') / len(data) * 100
print(f"零字节占比: {zero_pct:.1f}%")

if zero_pct > 20:
    print("WASM 二进制")
elif head[:2] == b'!f':
    # 检查单字母变量模式
    if b'var U=void 0' in head or b'U=void 0,y=parseInt' in head:
        print("→ DSL VM!")
    else:
        print("普通 JS IIFE")
EOF

Phase 2: 变量映射表提取(10 分钟)

import re

with open('target.js', 'r', errors='replace') as f:
    s = f.read()

# 提取开头 2000 字符的 var X=数字 映射
mappings = re.findall(r'var\s+(\w+)\s*=\s*(\d+)', s[:2000])
print('常量映射:')
for name, val in mappings:
    print(f"  {name:4s} = {val:3d} (0x{int(val):02x})")

Phase 3: Opcode 提取与分类(15 分钟)

# 1. 提取所有 case
all_cases = re.findall(r'case\s+(\d+):', s)
unique = sorted(set(int(c) for c in all_cases))

print(f"总 case: {len(all_cases)} 个")
print(f"唯一 opcode: {len(unique)} 个: {unique}")

# 2. 分类每个 opcode
for op in unique:
    idx = s.find(f'case {op}:')
    snippet = s[idx:idx+200]
    if 'd[7]=' in snippet:
        op_type = 'BRANCH'
    elif 'return' in snippet:
        op_type = 'RETURN'
    elif 'W(C[' in snippet:
        op_type = 'CALL'
    elif 'new' in snippet:
        op_type = 'ALLOC'
    elif 'try' in snippet or 'catch' in snippet:
        op_type = 'EXCEPTION'
    else:
        op_type = 'ARITH/STORE'
    print(f"  opcode {op:2d}: {op_type}")

Phase 4: 常量表分析(30 分钟)

const_refs = re.findall(r'C\[9\]\[(\d+)\]', s)
unique_refs = sorted(set(int(x) for x in const_refs))

print(f"C[9] 引用: {len(unique_refs)} 个索引")
print(f"范围: {min(unique_refs)} - {max(unique_refs)}")

# 对每个引用分析上下文
for ref in unique_refs[:20]:
    idx = s.find(f'C[9][{ref}]')
    ctx = s[max(0,idx-50):idx+80]
    clean = ''.join(c if c.isprintable() else ' ' for c in ctx)
    print(f"  C[9][{ref}] → {clean}")

Phase 5: 导出函数追踪(1-2 小时)

导出函数(如 `getToken`)通过以下路径定位:

1. 找 AWSCInner.register() 或类似注册调用
2. 确定注册的模块和工厂函数
3. 找工厂函数返回的对象 → 导出函数定义位置
4. 若函数名不在 JS 中 → 在 C[9] 常量表中作字节码存储
5. 追踪调用链:
   AWSCInner._modules['fy'].getToken()
   → W(C[函数索引], null, ...)
   → DG() 解释器执行编码后的指令序列

Phase 6: 运行时注入(若纯静态分析不够)

// 注入最小 AWSC 兼容环境
const fakeEnv = {
    AWSCInner: {
        _modules: {},
        register(name, moduleName, factory) {
            this._modules[moduleName] = factory();
        }
    }
};

// 执行 DSL VM 代码
dslVmCode();

// 获取导出
const token = fakeEnv.AWSCInner._modules['fy'].getToken({});

---

4. Opcode 提取与分类

参考 opcode 对照表(基于已有案例)

| Opcode | 操作类型 | 特征 | |--------|---------|------| | 0 | **BRANCH** | `d[7]=xxx` 无条件跳转 | | 1 | **CALL** | `W(C[Y],null,function(){...})` 嵌入函数调用 | | 2 | **ARITH** | `d[4]=0`, `d[7]=72` 变量赋值 | | 3 | **ARITH** | `d[0]=d[1][C[x]]`, `d[5]=d[0]<d[3]` 比较运算 | | 4 | **STORE** | `d[8]=d[5]in d[4]` 属性访问/存在检查 | | 5 | **ARITH** | `d[8]=d[4]-d[8]` 算术运算 | | 6 | **RETURN** | `return gV`, `throw` 返回/抛出异常 | | 7 | **ALLOC** | `d[6]=[]`, `d[6][C[8]](...)` push 操作 | | 8 | **BRANCH** | `d[7]=d[k]?512:425` 条件跳转 | | 9 | **STRING** | `d[6][C[t]]=d[m]`, `new

Read more
Ships withreverse-skill

Reverse Engineering / Authorized Penetration Testing / Security Research Skill Router Pack AI-powered routing + On-demand toolchain bootstrapping + Self-evolving knowledge base Supports Claude Code, Kiro, Cursor, Cline, and other AI coding clients 逆向/渗透/安全技能路由包 - AI 自动路由 + 按需自举工具链 + 自动进化经验库 | 支持 Claude Code / Kiro / Cursor / Cline 等代码 AI 客户端

Get the whole plugin
Stats
39,460
Stars
5,492
Forks
Active
Maintenance
PowerShell
Language
MIT
License
11d ago
Last commit
4mo ago
Created
3h ago
Added

Repo: zhaoxuya520/reverse-skill

Other skills on reverse-skill.

binary-diff
Skill

binary-diff

跨版本符号迁移与二进制差分。当你有旧版本的符号/逆向结果,需要快速迁移到新版本时使用。 适用场景:内核缺 PDB 用旧版符号推导、程序更新后批量迁移函数名、应用更新后快速定位新偏移。…