reverse-skills-max: initial public release (restored, redacted, hardened)
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
# 安全改写规则
|
||||
|
||||
这份文档只回答一个问题:当前节点是否“确定可还原”。
|
||||
|
||||
只有在答案明确为“是”时,才做 AST 替换。
|
||||
|
||||
## 可以直接替换的典型场景
|
||||
|
||||
- 数组字面量下标访问,且下标是 `NumericLiteral`,数组内容本身也稳定。
|
||||
- 已建立最小解密环境后,调用参数全是数字字面量或纯字面量。
|
||||
- `['a', 'b', 'c'].join('')`、`String.fromCharCode(...)`、`split('').reverse().join('')` 这类纯计算表达式。
|
||||
- 明确的字符串或数字别名链,例如 `var a = 'x'; var b = a;`。
|
||||
- 可以静态确认结果的恒真或恒假比较,例如 `if ('a' === 'a')`。
|
||||
|
||||
## 不要直接替换的高风险场景
|
||||
|
||||
- 依赖 `this`、`window`、闭包外部变量或浏览器环境的调用。
|
||||
- 含 getter、setter、代理对象、动态属性访问、副作用函数调用的表达式。
|
||||
- 不能确认 binding 是否稳定的别名链。
|
||||
- 顺序很关键的逻辑表达式、逗号表达式、条件测试表达式。
|
||||
- 需要跨作用域推断执行结果的节点。
|
||||
|
||||
## 默认判断顺序
|
||||
|
||||
1. 先看节点结果是否只依赖字面量和局部稳定绑定。
|
||||
2. 再看求值过程中是否存在副作用。
|
||||
3. 再看是否依赖执行顺序、宿主环境或外部状态。
|
||||
4. 任意一步无法确认,就不要替换。
|
||||
|
||||
## 常见误区
|
||||
|
||||
- 不要把所有 `CallExpression` 都拿去局部求值。
|
||||
- 不要把 `LogicalExpression` 默认折叠成左值或右值,尤其是含函数调用时。
|
||||
- 不要把 `StringLiteral`、`NumericLiteral`、`BooleanLiteral` 再次纳入“循环 evaluate 并回写”的流程。
|
||||
- 不要为了追求完全还原而牺牲稳定性。
|
||||
|
||||
## 推荐做法
|
||||
|
||||
- 先得到“结构可读、关键字符串已恢复、主控制流已展开”的结果。
|
||||
- 把不能静态确认的区域保留下来,等后续结合运行时证据再处理。
|
||||
- 每完成一批替换后重新 parse 一次,确保输出仍然稳定。
|
||||
Reference in New Issue
Block a user