onlytrisdev/js-confuser-deobfuscator
GitHub: onlytrisdev/js-confuser-deobfuscator
一款基于 AST 和沙盒 VM 执行的 JavaScript 去混淆工具,专门逆向 JS-Confuser 生成的多种复杂混淆模式以恢复可读源代码。
Stars: 0 | Forks: 0
# JS-Confuser 去混淆器
一款强大且高性能的基于 AST 的去混淆器,专门用于逆向 **JS-Confuser** 生成的复杂混淆模式。通过利用 Babel 进行 AST 操作以及 Node.js VM 进行安全的沙盒执行,该工具能够完全解包、解密、传播和修剪混淆结构,从而恢复可读的源代码。
## 逆向的主要混淆技术
**JS-Confuser** 以其极其严苛的代码转换而闻名,这使得静态分析变得异常困难。本工具专门针对并逆向以下混淆技术:
* **全局注入器与函数包装器 (RGF)**:解包嵌套在 IIFE 闭包内或通过 `new Function(...)` 动态编译的代码(随机生成器函数)。
* **字符串与对象隐藏**:通过单参数/多参数解密调度器解析查找,并解密使用 XOR、Base64 或自定义算法加密的字符串。
* **变量掩码与遮蔽**:通过彻底的 Alpha 重命名消除变量作用域遮蔽。
* **控制流平坦化**:静态评估条件表达式和循环,以消除基于 switch 的平坦控制流。
* **死代码注入**:根除大量的垃圾代码块、未使用的辅助数组和死分支。
## 去混淆架构与流水线
去混淆器流水线包含 **8 个独立阶段**,旨在系统地剥离混淆层:
```
graph TD
Input[Obfuscated JS] --> Phase1[1. Dynamic VM Unpacking]
Phase1 --> Phase2[2. Alpha Renaming]
Phase2 --> Phase3[3. Dependency Graph Mapping]
Phase3 --> Phase4[4. Decryptor & Retrieve Identification]
Phase4 --> Phase5[5. Sandboxed VM Execution]
Phase5 --> Phase6[6. Multi-Pass AST Simplification]
Phase6 --> Phase7[7. Mark-and-Sweep DCE]
Phase7 --> Phase8[8. Unused Pruning]
Phase8 --> Output[Clean Deobfuscated JS]
```
### 1. 基于 VM 的动态解包
JS-Confuser 通常将整个脚本包装在 IIFE 中或通过 `new Function()` 进行编译。
* 我们在沙盒化的 `vm` 上下文中运行混淆代码,并重写全局 `Function` 构造函数。
* 我们拦截并捕获编译后的脚本。如果编译后的脚本是一个有效的 JS 代码块且大小合理,我们将其提取为下一层代码。
* 这个过程递归循环,以剥离嵌套的 `pack: true` 层。
### 2. Alpha 重命名
为了防止变量遮蔽破坏静态分析和替换,我们遍历 AST 并将子作用域内的所有标识符重命名为全局唯一的 UID(例如 `_name` -> `_name_uid`)。
### 3. 依赖映射
我们解析声明(`VariableDeclarator`、`FunctionDeclaration`)和赋值(`AssignmentExpression`),以构建完整的依赖图:
* **正向图**:追踪哪些顶层名称依赖于其他名称。
* **逆向图**:追踪哪些名称被其他名称所依赖。
### 4. 检索函数识别
我们通过两次扫描来识别候选的检索函数(解密器):
1. **静态模式匹配**:扫描标准的检索模式(例如,接收索引/密钥并进行数组偏移的函数)。
2. **样板启发式算法**:递归添加引用了样板数据变量(非常大的数组/字符串)或调用了已识别解密器的函数。
### 5. 沙盒 VM 执行与动态过滤
我们隔离所有的样板依赖项和解密器,生成一个干净的 `sandbox_debug.js` 文件。
* 我们在安全的 Node.js `vm` 上下文中运行此代码。
* **动态过滤**:为了避免误报,我们在沙盒内部调用每一个候选函数。如果它成功运行并返回有效的字符串/数字/对象,我们就确认它是一个解密器。这可以防止运行不安全的用户函数。
### 6. 多趟 AST 简化
我们循环运行 AST 简化,直到不再发生任何变化为止(最多 10 趟):
* **VM 求值**:将解密器调用(例如 `_0x12ab("0x5f")`)和属性查找替换为 VM 上下文中实际求值的输出结果。
* **常量折叠**:静态解析二元运算符(例如 `12 + 5` -> `17`,`"a" + "b"` -> `"ab"`)。
* **分支与控制流简化**:评估 `if`、`while`、`switch` 和条件表达式的测试表达式。死分支将被移除,并且被修剪分支中的任何 `var` 声明都会被提升(`hoistVars`),以避免破坏 runtime 引用。
* **状态数组传播**:将作为参数传递给函数的不可变数组中的值进行内联。
* **内联常量传播**:传播常量局部变量以解析中间变量。
### 7. 标记-清除 死代码消除 (DCE)
一旦解密器被解析完毕,它们庞大的辅助数组、索引轮转函数和解密工具将不再被调用。
* 我们从实际程序代码(可达根节点)开始,标记所有可达的符号。
* 我们清除任何不再可达的样板声明、变量和赋值,从而大幅减小文件体积(例如从 1.5MB 减小到 2KB)。
### 8. 未使用的顶层修剪
最后,我们运行一次清理过程,移除任何未使用的变量和函数声明,以生成干净、可读且准备进行美化的源代码。
## 目录结构
```
js-confuser-deobfuscator/
├── deobfuscator.js # Driver script coordinating the 8 phases
├── package.json # Node.js dependencies
└── src/
├── core/
│ ├── dce.js # Mark-and-Sweep DCE & unused identifier pruning
│ ├── sandbox-vm.js # Sandboxing setup and decryptor validation
│ └── simplifier.js # Multi-pass AST simplification loop
└── utils/
├── ast-utils.js # AST inspection, evaluation, and scope helpers
└── unpack-utils.js # IIFE and Function constructor static unpackers
```
## 安装与使用
### 1. 安装
克隆仓库并安装依赖项:
```
git clone https://github.com/onlytrisdev/js-confuser-deobfuscator.git
cd js-confuser-deobfuscator
npm install
```
### 2. 对文件进行去混淆
运行驱动脚本,传入混淆文件的路径和目标输出路径:
```
node deobfuscator.js
```
示例:
```
node deobfuscator.js input.js output.js
```
标签:Babel, CMS安全, GNU通用公共许可证, JavaScript, MITM代理, Node.js, 云安全监控, 代码反混淆, 数据可视化, 自定义脚本, 静态分析