zhizhuodemao/ai-reverse-toolkit/ast-deobfuscate
Claude Code and agent skill by zhizhuodemao/ai-reverse-toolkit
- community
Checking that the SKILL.md file is still in the repository.
用 Babel AST 还原混淆的 JS 代码(字符串解密、控制流还原、死代码删除)。
Install
npx vskill@latest install zhizhuodemao/ai-reverse-toolkit/ast-deobfuscateSKILL.md
ast-deobfuscate
对 $ARGUMENTS 执行 AST 解混淆,最大化还原可读代码。
工具链: @babel/parser + @babel/traverse + @babel/generator + @babel/types
工作目录约定
原则: 每个步骤读取上一步的中间文件,输出新的中间文件。出错时可从任意中间文件重新开始。
环境初始化
解混淆脚本基于 Babel 工具链运行在 Node.js 中。首次执行前检查并安装依赖:
执行策略
整体原则
本 skill 是百科全书,不是固定流水线。执行者根据实际代码灵活选择步骤:
- 进入计划模式: 先完成 Step 0 分析,然后进入计划模式,向用户展示分析结果和建议的步骤组合,获得确认后再执行
- 按需跳步: 没有字符串数组就跳过 Step 1,没有控制流平坦化就跳过 Step 4
- 随时调整: 任何步骤执行后发现新情况,都可以回退或插入额外步骤
- MCP 用于分析和验证: js-reverse MCP 用于获取源码、搜索特征、小规模验证方案可行性;大批量转换和验证通过 Node.js 脚本执行
MCP 使用时机
MCP 的定位是分析工具和验证探针,不是批量执行引擎。
| 阶段 | MCP 用法 | |
|---|---|---|
| 分析阶段 | search_in_sources 搜索混淆特征;get_script_source 获取目标脚本 | |
| 方案验证 | evaluate_script 执行几个解密调用,确认方案可行后再写批量脚本 | |
| 中间验证 | evaluate_script 抽样对比解混淆前后的函数输出 | |
| 控制流分析 | set_breakpoint + step_over 动态跟踪 switch-case 执行顺序 | |
| 最终验证 | 在浏览器中用解混淆后的代码替换原始代码,验证功能正常 |
大批量字符串解密、表达式简化、死代码移除等转换工作,全部通过 Node.js 脚本 + Babel AST 完成。
Subagent 并行策略
可并行的任务组合:
- Step 0 中:特征识别 + 反调试代码搜索
- Step 2 中:Proxy 函数识别 + 对象字典识别(互不依赖)
- 验证阶段:多组测试数据可并行验证
技术手册
以下是各类解混淆技术的详细参考。根据 Step 0 的分析结果,选择需要的章节执行。
Step 0: 预分析与特征识别
目标: 了解混淆类型和程度,为后续步骤提供参考(非硬性路由)。
0.1 获取源码
0.2 格式化: 用 prettier 或 babel generator 统一缩进,保存为 intermediate/target_step0.js
0.3 AST 体检报告(可选)
文件较小时直接全文阅读是最快最全面的方式。但即使能读全文,统计脚本的价值在于把非结构化代码转化为结构化数据 — "callee 频次 Top 5"这类信息,人肉读代码很难准确统计。写一个脚本对 AST 做全局扫描:
0.4 特征指纹(仅供参考)
| 特征 | 混淆类型 | 常见处理 | |
|---|---|---|---|
高频前缀(如 _0x/a0_)+ 大字符串数组 + 旋转 IIFE | Obfuscator.io 及变种 | Step 1→2→3→4→5→6 | |
| 高频前缀但无字符串数组 | 轻度混淆 | Step 2→3→5→6 | |
while(true){switch} + 顺序数组 | 控制流平坦化 | Step 2→4→5→6 | |
jsjiami.com 标记 | sojson | 先去壳,再按实际情况选步骤 | |
| Webpack/Parcel 模块包裹 | 打包工具 | 先 unpack 提取模块,再对单模块解混淆 | |
大量 eval / Function() | 代码加密 | 沙箱执行解密层,再按实际情况选步骤 |
0.5 移除反调试(如存在)
搜索并删除:
debugger语句(尤其在定时器/循环中)setInterval(() => { debugger }, ...)constructor("debu")反格式化检测console重写/禁用代码
0.6 进入计划模式
向用户展示:
- 识别到的混淆特征
- 建议执行的步骤组合
- 预估的复杂度
用户确认后开始执行。执行过程中发现新情况随时可调整计划。
产出: intermediate/target_step0.js + 分析报告
Step 0.5: Webpack/打包工具 Unpack(可选)
适用条件: 代码是 Webpack/Browserify/Parcel 打包的 bundle。识别特征:
处理方向
产出: intermediate/modules/module_N.js(每个模块独立文件)
⚠️ unpack 后,后续步骤对每个模块文件独立执行,而非对整个 bundle。
Step 1: 字符串解密与大数组回填
适用条件: 代码中存在字符串数组 + 访问器函数模式。若无此模式则跳过。
目标: 将所有加密/编码的字符串还原为明文。这是后续步骤的基础。
1.1 识别字符串数组结构
典型模式包含三部分(函数名前缀不固定,可能是 _0x、a0_、_$ 或任意混淆名):
- 字符串数组函数: 返回包含所有字符串的数组
- 旋转 IIFE: 对数组执行 push/shift 旋转,打乱原始顺序
- 访问器函数: 接受索引参数,返回数组中对应字符串(通常有偏移量计算)
识别方法: 通过 AST 体检报告中的"最大 ArrayExpression"和"CallExpression callee 频次 Top 5"定位
1.2 处理方向
1.3 转义字符串还原
1.4 数值还原
验证: 用 MCP evaluate_script 抽样对比几个解密结果是否正确
产出: intermediate/target_step1.js
Step 2: 表达式简化
适用条件: 几乎所有混淆代码都需要此步骤。与 Step 5 循环执行效果最佳。
2.1 常量折叠 (Constant Folding)
2.2 布尔值还原
2.3 Proxy 函数内联
2.4 对象属性字典内联
产出: intermediate/target_step2.js
Step 3: 引用与属性访问标准化
适用条件: 代码中大量使用 obj['prop'] 方括号访问。需在字符串解密(Step 1)之后执行。
3.1 方括号转点号
3.2 逗号表达式拆分
产出: intermediate/target_step3.js
Step 4: 控制流平坦化还原
适用条件: 代码中存在 while(true){ switch(...) { case... } } 结构。强依赖 Step 2 的常量折叠。
4.1 分析实际结构
不预设固定模式,根据实际代码分析控制流结构:
4.2 还原方向
验证: 用 MCP evaluate_script 执行还原后的函数,对比原始输出
产出: intermediate/target_step4.js
Step 5: 死代码移除
适用条件: 几乎所有混淆代码都需要。与 Step 2 循环执行效果最佳。
5.1 不可达分支清理
5.2 无用变量/函数剔除
5.3 空语句清理
5.4 循环策略(Step 2 + Step 5)— 必须实现,不可跳过
单次执行 Step 2 和 Step 5 会遗漏大量可简化代码。原因:死代码移除后暴露新的常量表达式,常量折叠后又暴露新的死代码。
每轮循环保存中间文件: intermediate/target_step5_round{N}.js
产出: intermediate/target_step5.js
Step 6: 变量重命名与最终整形
适用条件: 代码中存在无意义的混淆变量名时执行。仅执行确定性的模式化重命名,不做语义推导。
6.1 模式化重命名(确定性的)
不确定语义的变量保留原始混淆名,不做规则编号(如 var_1)或语义推导,避免引入错误。
6.2 代码整形
6.3 最终验证
产出: source/deobfuscated/target_deobf.js + scripts/deobfuscate_target.js
安全边界
- 沙箱隔离: 执行混淆代码必须在
vm模块、isolated-vm或浏览器(MCP)中,禁止直接eval - 迭代上限: Step 2↔5 循环设硬上限(50 次),防止无限循环
- 副作用保护: 删除代码前检查是否有副作用(网络请求、DOM 操作、赋值)
- 作用域安全: 重命名必须通过
path.scope.rename(),不能直接修改node.name - 验证: 每步完成后用
@babel/parser重新解析,确认语法合法
Babel 关键 API 速查
| 用途 | API | |
|---|---|---|
| 静态求值 | path.evaluate() → { confident, value } | |
| 布尔求值 | path.get("test").evaluateTruthy() → true/false/undefined | |
| 替换节点 | path.replaceWith(node) / path.replaceWithMultiple([nodes]) | |
| 删除节点 | path.remove() | |
| 获取绑定 | path.scope.getBinding(name) → { constant, referenced, references, referencePaths } | |
| 安全重命名 | path.scope.rename(oldName, newName) | |
| 刷新作用域 | path.scope.crawl() — 删除/替换节点后必须调用 | |
| 值转节点 | t.valueToNode(value) — 注意 Infinity/undefined 返回非 Literal |
注意事项
This is the start of the file. Read the full SKILL.md on GitHub.
Security
- Security scanPassed, 100 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/ast-deobfuscate/SKILL.md
Popularity
- Repository stars
- 130
- Repository forks
- 28
- 7-day trend score
- 24
Stars and forks are for the whole GitHub repository, not this skill alone. Refreshed 19 Mar 2026, 7 months ago.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/zhizhuodemao/ai-reverse-toolkit/ast-deobfuscate)