一个用于反混淆JavaScript的可视化工作台。构建转换链,逐步执行,编写自己的插件。


此应用程序展示了JavaScript程序的抽象语法树(AST)。这个想法源于分析一个与obfuscatio.io相关的恶意软件样本,最终让我学习了更多关于使用BabelJS进行反混淆的知识。如果您曾尝试逆向工程混淆后的JS(例如:webpack捆绑包、obfuscator.io输出、打包的恶意软件样本),您知道这很痛苦。这个工具让您可以:
npm install
npm start
# 打开 http://localhost:3000
就是这样。
左侧边栏 – 所有可用的转换(内置插件 + 您的配方插件),包括配方链(想想Cyberchef)
中间 – 输入/输出编辑器。将混淆代码粘贴到左侧,在右侧查看转换后的代码。
右侧面板 – AST查看器、作用域分析器、易于查看的摘要。

BabelJS允许我们查看作用域和绑定。这对于查看是否存在未使用的变量尤其有用。此视图还允许我们查找变量被引用的位置。

点击+按钮或按Ctrl+N打开脚本编辑器。转换只是具有以下访问权限的JS代码:
// Available globals:
ast // The parsed Babel AST
traverse // Walk the tree: traverse({ Identifier(path) { ... } })
t // Babel types: t.isStringLiteral(node), t.identifier('x')
config // User config from the recipe card
stats // Track your changes: stats.replaced = 5
parser // Parse code: parser.parse('var x = 1')
generate // Generate code: generate(node).code
run // Eval helper: run('1+1') => 2 (DANGER. THIS IS MEANT TO BE RUN ON YOUR OWN MACHINE IN A SANDBOX)
示例 – 删除所有"debug"字符串(StringLiteral):
// The following two will appear as parameter in recipe chain as seen in the next screenshot
const targetValue = config.targetValue || 'debug';
const removeMatches = config.removeMatches !== false;
traverse({
StringLiteral(path) {
if (path.node.value === targetValue) {
if (removeMatches) {
path.remove();
stats.removed = (stats.removed || 0) + 1;
}
}
}
});
您可以选择:
下面的截图显示了:

请注意,这些转换可能因混淆技术而失败,可能需要自定义脚本。您也可以修改它们并另存为新自定义脚本。
将自己的 .js 文件放入 plugins/<category>/ 子文件夹中。它们会按文件夹分组显示在侧边栏中。

例如:
Bracket-to-dot-notation.js → "Decode Strings")plugins/Utilities/ → 类别 "nyx")/**
* Bracket to Dot Notation
* Changes things like console["log"] to console.log
*
* Category: utilities
*/
// Script Editor - Ctrl+Enter to run, Ctrl+E to close
// Use traverse(visitor) to modify the AST
// Access 't' for Babel types
traverse({
MemberExpression(path) {
if(path.node.computed === true){
// this is the bracket notation
prop = path.node.property
if(t.isStringLiteral(prop) &&
/^[a-zA-Z_][a-zA-Z_0-9]*$/.test(prop.value)
){
path.node.computed = false; // step 1
// step 2 change literal to identifier
path.node.property = t.identifier(prop.value)
}
}
}
});
有两种添加参数的方法:
targetValue 和 removeMatches)const targetValue = config.targetValue || 'debug';
const removeMatches = config.removeMatches !== false;

包括:

| 键 | 动作 |
|---|---|
Ctrl+E | 切换脚本编辑器 |
Ctrl+Shift+E | 切换eval面板(危险) |
Ctrl+S | 保存项目 |
请注意,如果存在大量嵌套节点,独立版本可能会出现一些问题。解决方法有时可能无效。
要使用npm构建,可以使用以下命令
npm run build # 仅限Windows
输出到 dist/ 目录。如果您想要自定义转换,请将 plugins/ 文件夹复制到exe旁边。
深度嵌套的代码(如JSFuck)可能导致堆栈溢出。构建脚本会尝试在Windows上自动增加堆栈大小。如果遇到堆栈溢出,请尝试通过 npm start 从源代码运行(使用 --stack-size=65536)。
我还没有弄清楚如何在构建为独立可执行文件时增加堆栈大小。如果您知道方法,请告诉我!
使用以下工具构建:

有疑问?有问题?请提交GitHub issue.
| 名称 | 功能 |
|---|
| Beautify | 美观地格式化代码 |
| Constant Folding | 1 + 2 → 3,"a" + "b" → "ab" |
| Decode Strings | 解码 \x48\x65\x6c\x6c\x6f → "Hello" |
| Inline Array Values | 内联简单的数组元素访问 |
| Inline String Array | 内联混淆器使用的字符串数组 |
| Opaque Predicate Removal | 移除始终为真/假的条件 |
| Remove Comments | 删除代码中的所有注释 |
| Remove IIFE | 解包 (function(){...})() 包装器 |
| Remove Unused Code | 删除死变量和函数 |
| Simplify Literals | !0 → true,void 0 → undefined |