evex-dev/expose-kit

GitHub: evex-dev/expose-kit

一款强调安全性与可验证性的 JavaScript 反混淆工具包,通过逐步 AST 转换帮助安全研究人员还原被混淆的代码逻辑。

Stars: 22 | Forks: 0

# Expose Kit ![release workflow](https://static.pigsec.cn/wp-content/uploads/repos/2026/05/a23825f95c081335.svg) [![](https://dcbadge.limes.pink/api/server/evex)](https://discord.gg/evex) [![技術者倫理 遵守済み](https://img.shields.io/badge/%E6%8A%80%E8%A1%93%E8%80%85%E5%80%AB%E7%90%86-%E9%81%B5%E5%AE%88%E6%B8%88%E3%81%BF-0a0a0a?style=for-the-badge&labelColor=ffffff)](https://xn--zwqt06btym6jly7j.com) ## 这是什么? JavaScript 反混淆工具随处可见。 但它们中的许多都**过于激进**,甚至会改写到代码崩溃。 Expose Kit 采用了一种**不同的方法**。 - 不使用暴力破解 - 逐步、可验证的转换 - 旨在 *不会* 默默破坏你的代码 每一次转换都旨在被**检查和验证**,因此你始终能知道问题 *何时* 出现。 除了反混淆,Expose Kit 还提供了一套实用的**实用工具**,用于处理混淆的 JavaScript。 ## 安装 只需一步: ``` npm i -g expose-kit # 或 bun i -g expose-kit ``` ``` expose --help expose parsable sample.js ``` ## 使用说明 ### 默认参数 - 第一个参数是输入文件 (也可以使用 `--file` / `--input`) - 如果缺少必需的选项,Expose Kit 会**提示你** - 默认启用超时以避免挂起 使用 `--unlimited` 进行长时间运行 ## 推荐工作流 首先,一个重要的前提: 原因包括: - 不可预测的执行(`eval`,动态代码) - AST 操作中的错误或边缘情况 因此,你应该**在每一步都验证代码**。 ### 1. 始终使用 `parsable` 验证 每次转换后,运行: ``` expose parsable file.js ``` 这可确保语法仍然有效。 ### 2. 首先使作用域安全 导致代码破坏的最常见原因之一是**变量名混淆**。 如果你尝试编写自己的反混淆逻辑(例如在 Python 中),你很快就会意识到正确跟踪作用域是多么痛苦。 这就是为什么你**应该始终从以下操作开始**: ``` expose safe-scope input.js ``` 这会按作用域重命名绑定,生成如下代码: ``` Before: var x = 810;((x) => console.log(x))(114514); After: var x = 810;((_x) => console.log(_x))(114514); ``` 仅凭这一点: - 代码变得更不容易被破坏 - 编写自定义反混淆逻辑变得更容易 - 你不再需要担心作用域冲突 ### 3. 逐步应用转换 在 `safe-scope` 之后,结合常见技术,例如: - `expand-array`、`expand-object` 等 在**每一步**之后,再次运行 `parsable` 和 `remove-unused`。 (即使不频繁,我们也可能会忽略某些被破坏的部分) 你做得越多,代码就越清晰。 Expose Kit 还会清楚地指出是否存在 **diff**,从而使检查变得容易。 重复此过程,原始代码将逐渐展现出来。 ## 命令 ### `expose parsable` 检查文件在语法上是否有效。 ``` parsable: const x = 810; not parsable: const ;x; == 810; ``` ``` expose parsable path/to/file.js ``` 参数: - 仅默认参数 ### `expose safe-scope` 按作用域重命名绑定,以便更安全地进行转换。 ``` expose safe-scope path/to/file.js --output path/to/file.safe-scope.js ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/safe-scope/mocks)。 参数: - `--o, --output ` 输出文件路径 - 无扩展名 → `file.safe-scope.js` - 有扩展名 → `file.safe-scope.` ### `expose pre-evaluate` 预计算 const 数字/字符串表达式。(安全计算) ``` const a = 1 + 2 * 3; // => 7 const c = "aaaa"; const b = "a" + c; // => "aaaaa" ``` ``` expose pre-evaluate path/to/file.js --output path/to/file.pre-evaluate.js ``` 参数: - `--o, --output ` 输出文件路径 - 无扩展名 → `file.pre-evaluate.js` - 有扩展名 → `file.pre-evaluate.` 注意: - 通过将返回安全数组字面量的零参数函数提升为 var 来内联它们。 ### `expose expand-array` 展开对原始值访问的数组索引。 ``` var a = [1, 1, 4, 5, 1, 4]; // before console.log(a[0], a[2], a[3]); // after console.log(1, 4, 5); ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/expand-array/mocks)。 ``` expose expand-array path/to/file.js --target arrayName --output path/to/file.expand-array.js ``` 参数: - `--target ` 目标数组变量名 - `--o, --output ` 输出文件路径 注意: - 每次替换都通过重新解析进行验证;跳过不安全的替换。 (此数组预期是不可变的,因此需要谨慎处理) ### `expose expand-object` 展开对原始值访问的对象属性。 ``` const obj = { a: 1, b: 2 }; // before console.log(obj.a, obj["b"]); // after console.log(1, 2); ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/expand-object/mocks)。 ``` expose expand-object path/to/file.js --target objectName --output path/to/file.expand-object.js ``` 参数: - `--target ` 目标对象变量名 - `--o, --output ` 输出文件路径 注意: - 每次替换都通过重新解析进行验证;跳过不安全的替换。 (此对象预期是不可变的,因此需要谨慎处理) ### `expose object-packer` 将连续的对象属性赋值打包为字面量。 ``` const obj = {}; // before obj.a = 0; obj["b"] = 1; // after const obj = { a: 0, b: 1 }; ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/object-packer/mocks)。 ``` expose object-packer path/to/file.js --output path/to/file.object-packer.js ``` 参数: - `--o, --output ` 输出文件路径 注意: - 仅打包空对象字面量之后的连续赋值。 - 当属性值引用对象本身时停止。 ### `expose key-simplify` 将安全的字符串字面量属性访问(`obj["foo"]`)替换为点号访问方式(`obj.foo`)。 ``` const obj = { foo: 1, bar_baz: 2 }; obj["foo"] = obj['bar']; console.log(obj["foo"], obj["bar_baz"]); ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/key-simplify/mocks)。 ``` expose key-simplify path/to/file.js --output path/to/file.key-simplify.js ``` 参数: - `--o, --output ` 输出文件路径 注意: - 仅重写为普通标识符的计算键。 - 保留无效的标识符键,以便输出保持可解析。 ### `expose remove-updater` 用 += 或 -= 替换安全的更新表达式。 ``` // before a++; --b; // after a += 1; b -= 1; ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-updater/mocks)。 ``` expose remove-updater path/to/file.js --output path/to/file.remove-updater.js ``` 参数: - `--o, --output ` 输出文件路径 注意: - 仅替换其值未被使用的更新表达式。 - 对表达式语句和 for 循环更新子句是安全的。 ### `expose remove-reassign` 内联安全的别名赋值和包装器调用。 ``` const a = 0; const b = a; const c = b; console.log(c); // => console.log(a); ``` ``` function a(arg) { return b(arg); } function c(arg) { return d[arg]; } a(0); // => b(0) c(0); // => d[0] ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-reassign/mocks)。 ``` expose remove-reassign path/to/file.js --output path/to/file.remove-reassign.js ``` 参数: - `--o, --output ` 输出文件路径 注意: - 仅内联 const/不可变的别名链。 - 跳过对象简写替换和被遮蔽的绑定。 - 包装器内联仅限于单次 return 的直通操作。 ### `expose remove-deadcode` 移除不可达的分支并简化条件表达式。 ``` if (true) { a(); } else { b(); } // after a(); const x = cond ? true : false; // after const x = !!cond; ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-deadcode/mocks)。 ``` expose remove-deadcode path/to/file.js --output path/to/file.remove-deadcode.js ``` 参数: - `--o, --output ` 输出文件路径 注意: - 仅移除带有字面量/数组/对象测试的分支。 - 当两个分支都是布尔值时简化三元表达式。 ### `expose remove-anti-tamper` 丢弃由反篡改脚本生成的自我保护包装器、调试防护和 console 劫持。 ``` var wrapper = (function () { var guard = true; return function (ctx, fn) { var thunk = guard ? function () { if (fn) { fn.apply(ctx, arguments); fn = null; } } : function () {}; guard = false; return thunk; }; })(); wrapper(this, function () { console.log("tamper"); }); console.log("safe"); ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-anti-tamper/mocks)。 ``` expose remove-anti-tamper path/to/file.js --output path/to/file.remove-anti-tamper.js ``` 参数: - `--o, --output ` 输出文件路径 注意: - 针对返回受保护辅助函数的包装器,并移除其调用。 - 在移除包装器之前清理 debug/console 辅助函数。 ### `expose control-flow-packer` 内联由基于字符串的状态机生成的控制流平坦化循环。 ``` const _0x1 = "a|b|c".split("|"); let _0x2 = 0; while (true) { switch (_0x1[_0x2++]) { case "a": console.log("a"); continue; case "b": console.log("b"); continue; case "c": console.log("c"); return; } break; } ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/control-flow-packer/mocks)。 ``` expose control-flow-packer path/to/file.js --output path/to/file.control-flow-packer.js ``` 参数: - `--o, --output ` 输出文件路径 注意: - 仅平坦化其状态数组来自字面量 `split` 的循环。 - 当某个分支返回或缺少状态 token 时停止。 ### `expose fn-inliner` 将代理函数调用内联到表达式中。 ``` const add = (a, b) => a + b; const sum = add(1, 2); // after const sum = 1 + 2; ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/fn-inliner/mocks)。 ``` expose fn-inliner path/to/file.js --output path/to/file.fn-inliner.js ``` 参数: - `--o, --output ` 输出文件路径 注意: - 仅内联返回单个表达式的函数。 - 跳过带有赋值、函数、块或序列的 return 表达式。 ### `expose sequence-split` 将序列表达式拆分为语句。 ``` // before a, b, c; // after a; b; c; ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/sequence-split/mocks)。 ``` expose sequence-split path/to/file.js --output path/to/file.sequence-split.js ``` 参数: - `--o, --output ` 输出文件路径 注意: - 将安全的序列表达式拆分为独立的语句。 - 也会规范化单语句的控制流块。 ### `expose remove-unused` 移除未使用的变量。 ``` // before var a = 0, b = 1; console.log(a); // after var a = 0; console.log(a); ``` 示例在[这里](https://github.com/evex-dev/expose-kit/tree/main/commands/remove-unused/mocks)。 ``` expose remove-unused path/to/file.js --output path/to/file.remove-unused.js ``` 参数: - `--o, --output ` 输出文件路径 ## 社区与支持 - 缺少某个功能? → [创建一个 issue](https://github.com/EdamAme-x/expose-kit/issues) - 不确定该使用哪个命令? → 加入我们的 [Discord](https://evex.land) ## 作者 - [EdamAme-x](https://github.com/EdamAme-x) 为研究而生,而非滥用。 想要更强大的混淆?那就构建一个这个工具无法逆向的东西。
标签:AST操作, AST解析, Bun, CMS安全, DAST, DNS 反向解析, GNU通用公共许可证, JavaScript, MITM代理, Node.js, npm包, 云安全监控, 云资产清单, 代码混淆, 代码转换, 代码还原, 反混淆, 威胁情报, 开发者工具, 恶意软件分析, 数据可视化, 暗色界面, 脚本分析, 自动化payload嵌入, 自动化攻击, 逆向工程, 静态分析