Files
reverse-skills-max/vendor-new/xbsReverseSkill/ast-deobfuscation/references/sequence-normalization.md

2.1 KiB

逗号表达式与结构标准化

这份文档用于处理 SequenceExpression、表达式语句、if/for 中的逗号表达式,以及部分可安全收敛的结构标准化。

总原则

  • 不要把所有逗号表达式都统一拆成多条语句。
  • 必须先看父节点,再决定改写方式。
  • 必须保证执行顺序和副作用顺序不变。

按父节点判断

ExpressionStatement

  • 通常可以直接拆成多条表达式语句。
  • 但如果末尾结果还被后续逻辑隐式依赖,先确认再拆。

IfStatement.test

  • if (a(), b(), test) 可以改写为:
    1. 先把 a()、b() 提到 if 之前。
    2. 保留 if (test)。

ForStatement.init

  • for (a(), b(), c(); test; update) 中的 init 逗号表达式最适合先拆,因为它只执行一次。

ForStatement.test

  • for (init; a(), b(), test; update) 可以改写为:
    1. 保留循环头里的稳定部分。
    2. 把 a()、b() 放到循环体开头。
    3. 在顶部加基于 test 的 break 守卫。

ForStatement.update

  • 只在循环体中不存在 continue 风险时再拆。
  • 如果存在 continue,把更新表达式搬到循环体尾部可能会改变行为,应保守跳过。

ReturnStatement 与 VariableDeclarator

  • 这两类需要分别处理,不能简单套用表达式语句的拆法。
  • 如果暂时没有足够稳定的模板,宁可不动。

可顺手清理的结构

  • 零参数、立即执行、纯包裹的 IIFE。
  • 表达式语句里的简单三元噪声。
  • 可静态确认且不改变副作用顺序的简单逻辑表达式语句。

不要做的事

  • 不要把复杂 LogicalExpression 默认改写成 if。
  • 不要在不知道父节点语义的情况下使用批量 replaceWithMultiple。
  • 不要只因为“文本更好看”就重排表达式执行顺序。

验证建议

  • 结构标准化后立即重新 parse。
  • 对 for.test 和 for.update 的改写,优先用代表性样本回归一次。
  • 如果改写后只提升了少量可读性,却增加了行为不确定性,就回退。