3.7 KiB
3.7 KiB
JS 逆向工作流总览
解法模式决策树
目标网站数据接口
│
├─ 能否抓到明确的数据接口?
│ ├─ 否 → WebSocket?→ 场景7
│ │ 页面渲染数据?→ 场景8(字体反爬/CSS干扰)
│ └─ 是 ↓
│
├─ 请求中有加密参数?
│ ├─ 否 → 直接请求即可,检查是否有 Cookie/Header 校验
│ └─ 是 ↓
│
├─ 加密逻辑在哪里?
│ ├─ 明文 JS(可直接定位)→ 模式A:纯 Node.js 还原
│ ├─ 混淆 JS(OB/CFF/eval)→ 反混淆后 → 模式A 或 模式B
│ ├─ 服务端返回 JS 动态执行 → 模式B:VM 沙箱执行
│ ├─ WASM 二进制 → 模式C:WASM 加载
│ ├─ JSVMP 虚拟机保护 → 先尝试 I/O 定位,失败则 → 模式D
│ └─ 无法脱离浏览器环境 → 模式D:浏览器自动化
│
├─ 纯请求方案是否可行?
│ ├─ 请求成功 → 完成
│ └─ 请求失败(token failed / 403)↓
│
└─ TLS 指纹 / HTTP/2 检测?
├─ 是 → 切换到模式D 或使用 HTTP/2
└─ 否 → 检查 Cookie、时间戳、参数拼接错误
模式详解
模式 A:纯 Node.js 算法还原
适用条件:
- 加密算法可用标准库实现(MD5/SHA/AES/DES/RSA/HMAC)
- 无浏览器环境检测
- 无 TLS 指纹校验
技术栈:
crypto(Node.js 内置)— MD5/SHA/AES/DES/HMACcrypto-js— CryptoJS 兼容实现node-rsa/node-forge— RSA 加解密axios/node-fetch— HTTP 请求http2(Node.js 内置)— HTTP/2 请求
模板:templates/node-request/
模式 B:Node vm 沙箱执行
适用条件:
- 服务端返回混淆 JS,需要 eval 执行生成 Cookie/Token
- 加密逻辑依赖大量上下文,手动还原成本过高
技术栈:
vm(Node.js 内置)— 沙箱执行vm2— 更安全的沙箱(可选)jsdom— 模拟 DOM 环境(可选)
注意事项:
- 必须构造最小沙箱环境(document、navigator、location 等)
- Cookie setter 需要拦截
- setTimeout/setInterval 需要提供但可能需要限制
模板:templates/vm-sandbox/
模式 C:WASM 加载还原
适用条件:
- 加密函数通过 WebAssembly 实现
- WASM 有明确的导出函数接口
技术栈:
fs(Node.js 内置)— 读取 .wasm 文件WebAssembly(Node.js 内置)— 加载和实例化
注意事项:
- 先验证 I/O,不要先反编译 WASM
- 检查
WebAssembly.Module.imports()了解环境依赖 - wasm-bindgen 生成的 WASM 需要补
Window类和 DOM unreachablepanic 通常是环境缺失
模板:templates/wasm-loader/
模式 D:浏览器自动化
适用条件:
- TLS 指纹检测,纯请求无法通过
- 复杂环境依赖(window 蜜罐、Canvas 指纹等)
- 加密逻辑过于复杂,还原成本远大于自动化
技术栈:
playwright/puppeteer— 浏览器自动化- chrome-devtools MCP — 直接操作已有 Chrome
注意事项:
- 复用本机 Chrome 实例避免指纹差异
- 注入脚本截取中间数据
- 控制请求频率避免触发风控
模板:templates/browser-auto/
通用调试流程
1. 打开 Network 面板
↓
2. 触发目标操作(搜索/翻页/登录)
↓
3. 找到数据接口,分析参数
↓
4. 搜索参数名定位 JS 源码
↓
5. 设置 XHR 断点追踪调用栈
↓
6. 在关键函数设置断点
↓
7. 单步调试确认加密逻辑
↓
8. 还原算法并对比中间值
↓
9. 编写 Node.js 脚本
↓
10. 运行验证