# 案例：AST 去混淆

## 目标
- 将混淆代码拆成“可读语义块”，而不是追求一次性还原成最终源码。
- 输出可验证证据：每一步静态改写都能在运行时对齐行为。

## 适用场景
- 字符串表 + 索引函数（`_0x***`）
- 平坦控制流（`while(true)+switch`）
- 花指令（永真/永假分支、死代码）
- IIFE 包裹 + 多层代理调用

## 输入要求
- 原始脚本（尽量保留 source map 信息）
- 目标函数名或目标关键字（用于聚焦）
- 最小运行样本（输入参数和预期输出）

## 流程（建议顺序）
1. 预扫描
- 统计 AST 指标：节点数、函数数、字面量比例、`eval/new Function` 出现次数。
- 标记高风险节点：动态执行、反调试、环境探针。

2. 字符串层去混淆
- 定位字符串表与解码函数。
- 执行“可证明等价”的替换：仅替换可静态求值表达式。
- 记录替换统计：替换数量、失败数量、失败样本。

3. 代理层折叠
- 识别代理函数（简单转发、参数重排、常量包裹）。
- 将可内联代理折叠为直接调用。
- 保留不可判定代理，避免误改业务逻辑。

4. 控制流还原
- 处理 `while-switch` 平坦化，按 dispatch 序列重建语句顺序。
- 删除不可达分支前，先跑一次覆盖验证。

5. 死代码清理
- 清理未引用声明、永假分支、无副作用表达式。
- 每次清理后执行语义对比（最小样本）。

6. 运行时回验
- 对核心函数做输入输出回放：
  - 原始代码输出
  - 改写后输出
- 输出必须一致，否则回滚最近变换。

## 验证口径
- 结构指标下降：
  - 节点数减少
  - 嵌套深度下降
  - 动态执行点减少
- 语义指标稳定：
  - 关键函数 I/O 一致
  - 关键请求参数一致（若涉及签名）

## 常见失败与回退
- 字符串解码依赖运行时状态：
  - 回退到“运行时采样 + 局部替换”，不要全量静态替换。
- 控制流恢复后行为漂移：
  - 仅恢复目标函数，缩小改写面。
- 清理死代码后崩溃：
  - 保留可疑副作用节点，分批次删除。

## 输出产物建议
- `before.js` / `after.stepN.js`
- `transform-log.json`（每步变换统计）
- `verify-report.md`（I/O 对比与差异解释）

## 安全边界
- 不在文档中写入可直接批量复用的站点特定 payload。
- 不提交包含真实凭证或业务敏感参数的样本输入。
