dsh-js-reverse-plugin 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/cordis.patch.yml +14 -0
  2. package/index.js +61 -0
  3. package/package.json +20 -0
  4. package/skills/iv8-env-runtime/SKILL.md +159 -0
  5. package/skills/iv8-env-runtime/assets/entry-report-template.txt +23 -0
  6. package/skills/iv8-env-runtime/assets/env_starter.py +100 -0
  7. package/skills/iv8-env-runtime/references/case-function-iwencai.md +96 -0
  8. package/skills/iv8-env-runtime/references/case-intercept-douyin.md +133 -0
  9. package/skills/iv8-env-runtime/references/config-defaults-cheatsheet.md +75 -0
  10. package/skills/iv8-env-runtime/references/cross-platform-install.md +108 -0
  11. package/skills/iv8-env-runtime/references/iv8-api-contract.md +97 -0
  12. package/skills/iv8-env-runtime/references/network-and-eventloop.md +113 -0
  13. package/skills/iv8-env-runtime/references/part1-entry-location.md +138 -0
  14. package/skills/iv8-env-runtime/references/part1-mcp-tool-map.md +77 -0
  15. package/skills/iv8-env-runtime/references/part2-discovery.md +80 -0
  16. package/skills/iv8-env-runtime/references/patching-principles.md +91 -0
  17. package/skills/iv8-env-runtime/references/trap-blacklist.md +60 -0
  18. package/skills/iv8-env-runtime/references/version-gotchas.md +128 -0
  19. package/skills/iv8-env-runtime/scripts/consistency_lint.py +211 -0
  20. package/skills/iv8-env-runtime/scripts/defaults_audit.py +143 -0
  21. package/skills/iv8-env-runtime/scripts/monitor_env.py +185 -0
  22. package/skills/iv8-env-runtime/scripts/network_bridge.py +147 -0
  23. package/skills/iv8-env-runtime/scripts/parity_check.py +175 -0
  24. package/skills/iv8-env-runtime/scripts/preflight.py +144 -0
  25. package/skills/iv8-env-runtime/scripts/reproduce_stub_error.py +165 -0
  26. package/skills/iv8-env-runtime/scripts/run_target.py +150 -0
  27. package/skills/iv8-jsvmp-recovery/SKILL.md +129 -0
  28. package/skills/iv8-jsvmp-recovery/agents/openai.yaml +4 -0
  29. package/skills/iv8-jsvmp-recovery/references/case-study-douyin-a-bogus.md +320 -0
  30. package/skills/iv8-jsvmp-recovery/references/controlled-oracle-and-equivalence.md +247 -0
  31. package/skills/iv8-jsvmp-recovery/references/static-trace-evidence.md +289 -0
  32. package/skills/iv8-jsvmp-recovery/references/vmp-domain-model.md +212 -0
  33. package/skills/iv8-jsvmp-recovery/scripts/verify-equivalence.py +281 -0
  34. package/skills/js-ast-deobfuscation/SKILL.md +140 -0
  35. package/skills/js-ast-deobfuscation/agents/openai.yaml +4 -0
  36. package/skills/js-ast-deobfuscation/references/anti-patterns.md +325 -0
  37. package/skills/js-ast-deobfuscation/references/first-pass.md +255 -0
  38. package/skills/js-ast-deobfuscation/references/interaction-and-stopping.md +758 -0
  39. package/skills/js-ast-deobfuscation/references/iv8-runtime-observation.md +773 -0
  40. package/skills/js-ast-deobfuscation/references/jsvmp-identification.md +328 -0
  41. package/skills/js-ast-deobfuscation/references/methods-and-evidence.md +460 -0
  42. package/skills/js-ast-deobfuscation/references/patterns-and-priority.md +516 -0
  43. package/skills/js-ast-deobfuscation/references/validation-contract.md +604 -0
  44. package/skills/js-ast-deobfuscation/scripts/prepare-source.mjs +921 -0
@@ -0,0 +1,325 @@
1
+ # JavaScript 解混淆反例
2
+
3
+ 本 reference 用于设计检查、风险升级和前向测试。每条都使用同一结构:
4
+
5
+ - **错误做法**:容易出现的错误。
6
+ - **为什么错**:它破坏了哪条证据或交互边界。
7
+ - **正确分流**:遇到时应该怎样处理。
8
+
9
+ ## 目录
10
+
11
+ - [1. 分析反例](#1-分析反例)
12
+ - [2. Transform 反例](#2-transform-反例)
13
+ - [3. 交互反例](#3-交互反例)
14
+ - [4. 动态反例](#4-动态反例)
15
+ - [5. 完成度与阶段边界反例](#5-完成度与阶段边界反例)
16
+
17
+ ## 1. 分析反例
18
+
19
+ ### 1.1 跳过 Prettier
20
+
21
+ - **错误做法**:直接在压缩原文上建立完整画像。
22
+ - **为什么错**:模型难以完成连续、可复核的全文件阅读,源码锚点也不稳定。
23
+ - **正确分流**:冻结原始输入,只对派生副本使用本地 Node Prettier;格式化成功后再画像。
24
+
25
+ ### 1.2 原地格式化
26
+
27
+ - **错误做法**:在原始目标上运行 Prettier。
28
+ - **为什么错**:破坏原始 hash、运行证据和 self-defending 对照。
29
+ - **正确分流**:保留固定 hash 原件,把格式化结果写入独立分析副本。
30
+
31
+ ### 1.3 静默更换 formatter
32
+
33
+ - **错误做法**:本地没有 Prettier 时改用其他打印器,或者让 AST generator 冒充准备步骤。
34
+ - **为什么错**:违反固定准备契约,输出不可比较,也掩盖真实解析问题。
35
+ - **正确分流**:在隔离工作区本地安装 Prettier;安装或解析失败时进入 `FORMAT_BLOCKED`。
36
+
37
+ ### 1.4 只让脚本看代码
38
+
39
+ - **错误做法**:只读取 AST 统计、正则结果或自动分类摘要,模型不直接阅读完整格式化源码。
40
+ - **为什么错**:脚本只能回答预先编码的问题,会遗漏新结构并放大预设立场。
41
+ - **正确分流**:模型按连续区间直接阅读全文件,再用脚本复核数量和定位遗漏。
42
+
43
+ ### 1.5 抽样冒充全量
44
+
45
+ - **错误做法**:只看开头、中段和结尾,却声称已经识别全部当前可见模式。
46
+ - **为什么错**:大文件中的载荷、入口和消费者可能集中在未读区间。
47
+ - **正确分流**:记录已读区间并分块继续;未覆盖完整文件时保持 G3 进行中,不提交画像、不进入语义步骤,也不把部分读取包装成“下界画像”。
48
+
49
+ ### 1.6 混淆家族数与出现次数
50
+
51
+ - **错误做法**:用一个数字同时表示“有几种混淆”和“匹配了多少节点”。
52
+ - **为什么错**:结构复杂度和影响规模是不同概念。
53
+ - **正确分流**:分别记录家族数、每类出现次数和影响范围,并定义计数单位。
54
+
55
+ ### 1.7 把首轮画像当最终全集
56
+
57
+ - **错误做法**:初次扫描后宣称不会再出现新模式。
58
+ - **为什么错**:字符串恢复和载荷解包经常暴露新的代码层。
59
+ - **正确分流**:称为“当前视图中可见的模式”,每个通过步骤后重新画像。
60
+
61
+ ### 1.8 根据背景预判
62
+
63
+ - **错误做法**:根据文件名、站点、课程主题或历史案例直接套结论。
64
+ - **为什么错**:相同来源也可能更换构建器、版本、入口和混淆器。
65
+ - **正确分流**:先读真实片段和消费者,再用案例作为比较材料,不把案例当证据。
66
+
67
+ ### 1.9 看到 Base64 就宣布字符串池
68
+
69
+ - **错误做法**:只凭 Base64 外观认定它是字符串混淆。
70
+ - **为什么错**:它也可能是图片、证书、压缩资源、协议数据或 VM 记录。
71
+ - **正确分流**:读取生产链、解码链和消费者;无法确认时标为 `Unknown`。
72
+
73
+ ### 1.10 看到 switch 就宣布控制流平坦化
74
+
75
+ - **错误做法**:把每个大型 `switch` 都归类为 dispatcher。
76
+ - **为什么错**:状态机、协议解析器、编译器和 VM 解释器都有相同表面形态。
77
+ - **正确分流**:检查状态来源、更新、case 终止和代码角色;VM dispatcher 交接 VM 阶段。
78
+
79
+ ### 1.11 看到数字模块 ID 就猜业务名称
80
+
81
+ - **错误做法**:凭模块序号或少量字面量直接命名。
82
+ - **为什么错**:数字 ID 是打包器常见基础设施,猜名会污染后续分析。
83
+ - **正确分流**:先识别模块表、缓存、加载器和依赖图;证据不足时保留 ID 或使用中性名。
84
+
85
+ ### 1.12 识别第三方后直接删除
86
+
87
+ - **错误做法**:确认是 polyfill 或第三方库后将其移除。
88
+ - **为什么错**:来源分类不证明无引用、无副作用或不参与入口初始化。
89
+ - **正确分流**:默认保留;与目标无关时跳过内部清理,需要删除时升级询问并检查引用。
90
+
91
+ ### 1.13 把静态存在当运行事实
92
+
93
+ - **错误做法**:看到字符串、模块、分支、slot 或 API,就说它进入最终输出。
94
+ - **为什么错**:静态存在、可达和已观察执行是三个不同结论。
95
+ - **正确分流**:分别记录 `Observed / Inferred / Unknown`;需要运行事实时提出最小证据缺口。
96
+
97
+ ## 2. Transform 反例
98
+
99
+ ### 2.1 按文本全局替换
100
+
101
+ - **错误做法**:用字符串替换所有同名标识符。
102
+ - **为什么错**:不同作用域中相同文本可能解析到不同 binding,属性文本也不是局部变量。
103
+ - **正确分流**:只基于词法 binding、声明和引用进行修改;无法解析的目标保持不变。
104
+
105
+ ### 2.2 不解析 shadow 就重命名
106
+
107
+ - **错误做法**:只定位一个声明,不检查内外层 shadow 和新名称冲突。
108
+ - **为什么错**:会改变解析关系或制造捕获。
109
+ - **正确分流**:检查可见 binding、全部引用和 shadow;多个语义解释成立时使用中性名或询问。
110
+
111
+ ### 2.3 一步混合多个 transform 家族
112
+
113
+ - **错误做法**:一次同时恢复字符串、内联代理、删除死代码并语义重命名。
114
+ - **为什么错**:失败时无法定位原因,也无法准确统计和回滚。
115
+ - **正确分流**:每步只处理一种边界明确的结构,分别生成输入、输出和报告。
116
+
117
+ ### 2.4 为提高命中数扩大匹配
118
+
119
+ - **错误做法**:遇到不符合前提的节点时放宽条件,让 transform 尽量多改。
120
+ - **为什么错**:命中率上升不等于正确率上升,容易跨越语义边界。
121
+ - **正确分流**:超出前提的节点跳过或令本步停止,把残留写入下一候选。
122
+
123
+ ### 2.5 删除前不检查副作用
124
+
125
+ - **错误做法**:看到未使用声明、恒假分支或反调试信号就删除。
126
+ - **为什么错**:初始化、getter、异常、全局写入和遥测可能仍有行为。
127
+ - **正确分流**:检查引用、别名、动态属性和副作用;删除属于需要明确授权的高风险步骤。
128
+
129
+ ### 2.6 把快照 alias 当永久恒等
130
+
131
+ - **错误做法**:把一次 `alias = source` 推广为所有位置的双向等价。
132
+ - **为什么错**:后续重新赋值或对象替换会使关系失效。
133
+ - **正确分流**:限定赋值时点和控制流范围;证据不足时只记录潜在连接。
134
+
135
+ ### 2.7 用高语义名称填补未知
136
+
137
+ - **错误做法**:根据直觉把短名改成具体业务含义。
138
+ - **为什么错**:名称会把假设伪装成事实,并影响后续推理。
139
+ - **正确分流**:使用 loader、entry、slot、record 等中性角色名;业务名称必须询问或有更强证据。
140
+
141
+ ### 2.8 没有映射和残留就宣布成功
142
+
143
+ - **错误做法**:只展示几段变得可读的代码。
144
+ - **为什么错**:无法知道实际修改、跳过和未覆盖范围,也无法回到原始位置。
145
+ - **正确分流**:保存输入输出、修改范围、跳过、残留和原始到派生映射;验收交给 validation reference。
146
+
147
+ ## 3. 交互反例
148
+
149
+ ### 3.1 把“解混淆”当信息不足
150
+
151
+ - **错误做法**:要求用户先说出混淆类型、技术路线和最终产物。
152
+ - **为什么错**:用户使用 Skill 正是因为不知道这些技术事实。
153
+ - **正确分流**:自动冻结、格式化、直接阅读和画像;看到源码后再让用户反馈分析方向。
154
+
155
+ ### 3.2 首轮画像前询问最终用途
156
+
157
+ - **错误做法**:读代码前问用户要 static 还是 dynamic、是否进入 VM、最终解到哪一层。
158
+ - **为什么错**:用户没有源码画像就无法做有信息的选择。
159
+ - **正确分流**:先提交模式、依赖、收益和风险,再用普通语言提供选择。
160
+
161
+ ### 3.3 模型自动解到底
162
+
163
+ - **错误做法**:模型自行决定并连续执行所有语义步骤。
164
+ - **为什么错**:不同步骤的风险、成本和阶段边界不同,用户失去决策权。
165
+ - **正确分流**:默认 `interactive`,每次只提交一个推荐步骤和真正不同的替代项。
166
+
167
+ ### 3.4 一个批准覆盖后续全部步骤
168
+
169
+ - **错误做法**:用户同意字符串恢复后,自动继续控制流、删除和命名。
170
+ - **为什么错**:一个步骤的授权不能扩展到新的风险和语义范围。
171
+ - **正确分流**:批准默认只覆盖当前步骤;批次或 autonomous 必须由用户明确授权。
172
+
173
+ ### 3.5 只问“是否继续”
174
+
175
+ - **错误做法**:不给候选、收益、风险和不处理的影响。
176
+ - **为什么错**:用户只能盲目同意或拒绝。
177
+ - **正确分流**:提供推荐、替代、暂停或交接选项,并解释各自能得到什么。
178
+
179
+ ### 3.6 要求用户替模型选择技术模式
180
+
181
+ - **错误做法**:要求用户决定 static、hybrid、binding-aware rename 或 dispatcher unfold。
182
+ - **为什么错**:这些是模型应根据证据完成的技术判断。
183
+ - **正确分流**:模型先确定方法,用普通语言向用户说明结果、风险和范围。
184
+
185
+ ### 3.7 用户未回应仍继续
186
+
187
+ - **错误做法**:决策卡发出后默认用户同意。
188
+ - **为什么错**:沉默不是授权,尤其不能授权动态执行、删除或阶段切换。
189
+ - **正确分流**:进入 `READY_FOR_USER_DECISION` 并保留当前工作区。
190
+
191
+ ## 4. 动态反例
192
+
193
+ ### 4.1 因为有运行环境就默认动态
194
+
195
+ - **错误做法**:iv8、浏览器或调试器已经可用,所以先执行目标。
196
+ - **为什么错**:工具可用性不能代替证据需求,动态覆盖还可能更窄。
197
+ - **正确分流**:先明确当前问题和静态缺口;静态足够时不执行。
198
+
199
+ ### 4.2 静态步骤中途静默升级
200
+
201
+ - **错误做法**:用户只批准静态 transform,模型发现困难后直接运行目标。
202
+ - **为什么错**:动态执行改变风险、权限和证据边界。
203
+ - **正确分流**:停止本步,保留上一个通过版本,提交最小动态取证方案并重新请求批准。
204
+
205
+ ### 4.3 为局部 decoder 执行完整未知目标
206
+
207
+ - **错误做法**:为了取得一个确定性解码结果,加载整个文件、页面或网络流程。
208
+ - **为什么错**:扩大副作用和环境变量,降低证据可解释性。
209
+ - **正确分流**:优先隔离闭合 decoder;无法隔离时再说明具体依赖和升级理由。
210
+
211
+ ### 4.4 在原始 JS 中插日志
212
+
213
+ - **错误做法**:直接加入 `console.log`、`debugger` 或 collector 调用。
214
+ - **为什么错**:改变原始 hash、源码完整性、时间行为和运行证据。
215
+ - **正确分流**:先使用引擎日志、外部断点和宿主旁路;最后才对独立派生副本插桩。
216
+
217
+ ### 4.5 把源文件零修改称为绝对无侵入
218
+
219
+ - **错误做法**:runtime Hook 没改磁盘文件,就宣称运行完全不受影响。
220
+ - **为什么错**:Hook、断点、debug 模式和日志都可能改变对象可观察性或时序。
221
+ - **正确分流**:区分“源文件零修改”和“运行时零影响”;Hook 明确标记 `runtime patched`。
222
+
223
+ ### 4.6 Hook 后没有 A/B
224
+
225
+ - **错误做法**:安装 probe 后只运行一次并直接采用结论。
226
+ - **为什么错**:无法判断结果来自目标本身还是 probe。
227
+ - **正确分流**:保存无 probe 基线和有 probe 结果,使用相同输入、环境和触发做 A/B。
228
+
229
+ ### 4.7 因为已安装 iv8 就使用 iv8
230
+
231
+ - **错误做法**:一个纯静态或闭合局部问题也启动完整浏览器语义。
232
+ - **为什么错**:增加环境差异、成本和证据噪声。
233
+ - **正确分流**:只有问题依赖宿主 API、页面生命周期、事件循环等能力时才选择 iv8。
234
+
235
+ ### 4.8 异步值尚未稳定就读取
236
+
237
+ - **错误做法**:触发异步入口后立即读取结果。
238
+ - **为什么错**:任务队列、计时器、Promise 或事件尚未完成,空值不代表没有行为。
239
+ - **正确分流**:按运行时语义推进或排空事件循环,并记录推进方式和覆盖窗口。
240
+
241
+ ### 4.9 把 `node:vm` 当安全沙箱
242
+
243
+ - **错误做法**:使用 `node:vm` 执行不可信目标并称为安全隔离。
244
+ - **为什么错**:它不是不可信代码的安全边界。
245
+ - **正确分流**:缩小执行范围、限制权限;完整未知目标执行必须单独授权和采用真正隔离。
246
+
247
+ ### 4.10 执行派生视图冒充原始行为
248
+
249
+ - **错误做法**:运行格式化、重命名或插桩后的文件,并把输出当作原始目标证据。
250
+ - **为什么错**:分析视图不默认承诺行为等价。
251
+ - **正确分流**:行为证据优先运行固定 hash 原件;派生执行结果明确降低证据等级。
252
+
253
+ ### 4.11 把属性访问写成算法依赖
254
+
255
+ - **错误做法**:日志显示读取某 API,就说它进入最终签名或业务输出。
256
+ - **为什么错**:读取可能只是探测、缓存、无效分支或遥测。
257
+ - **正确分流**:记录“已观察访问”;要证明输出依赖,需要新的数据流或对照证据。
258
+
259
+ ### 4.12 不记录运行条件
260
+
261
+ - **错误做法**:只保存最终值,不记录输入、环境、时间、随机数、补丁、trigger 和覆盖路径。
262
+ - **为什么错**:结果不可复现,也无法限定适用范围。
263
+ - **正确分流**:保存执行目标 hash、配置、输入、环境状态、原始日志和未覆盖范围。
264
+
265
+ ### 4.13 把一次运行推广到所有路径
266
+
267
+ - **错误做法**:一次动态观测后做全局替换或删除所有未执行分支。
268
+ - **为什么错**:动态证据只覆盖特定输入、环境和路径。
269
+ - **正确分流**:将运行值映射到对应调用点;全局结论需要额外静态证明或多组覆盖。
270
+
271
+ ### 4.14 把完整补环境塞进 AST Skill
272
+
273
+ - **错误做法**:为推进一个候选,在 AST reference 中复制完整环境、网络桥接、指纹和服务器验收流程。
274
+ - **为什么错**:扩张了 Skill 边界并制造对特定框架的隐式依赖。
275
+ - **正确分流**:本 Skill 只定义最小动态证据;系统补环境交接专门的运行环境阶段。
276
+
277
+ ### 4.15 在 AST Skill 中插桩 VM 内部
278
+
279
+ - **错误做法**:记录 Opcode、PC、值栈、帧栈或虚拟函数轨迹。
280
+ - **为什么错**:这已经进入 VM 逆向,不再是外围 AST 解混淆。
281
+ - **正确分流**:只建立 VM 入口、数据区、宿主 binding 和公开 API 坐标,然后交接 VM Skill。
282
+
283
+ ## 5. 完成度与阶段边界反例
284
+
285
+ ### 5.1 语法通过就宣布完成
286
+
287
+ - **错误做法**:`node --check` 或重新 parse 成功后结束。
288
+ - **为什么错**:语法正确不证明 binding、结构、证据和分析目标正确。
289
+ - **正确分流**:按产物类型执行对应验收,再评估当前问题是否已经解决。
290
+
291
+ ### 5.2 因为还有第三方短名就拒绝结束
292
+
293
+ - **错误做法**:必须清理所有 polyfill 和依赖内部变量。
294
+ - **为什么错**:这通常只改善外观,不服务当前分析目标。
295
+ - **正确分流**:记录为已分类、低收益残留;不阻碍目标时默认跳过。
296
+
297
+ ### 5.3 因为分析视图不可执行就继续补
298
+
299
+ - **错误做法**:把 analysis-js 修成完整独立运行程序才肯结束。
300
+ - **为什么错**:分析视图的目标是可读、可搜、可定位和可映射,不默认替代原程序。
301
+ - **正确分流**:只有用户明确要求 executable-js 时才进入行为等价和运行修补。
302
+
303
+ ### 5.4 因为算法尚未纯算就判定 AST 未完成
304
+
305
+ - **错误做法**:必须恢复最终公式或脱离所有环境,才算解混淆结束。
306
+ - **为什么错**:算法还原、补环境和 AST 解混淆是不同阶段。
307
+ - **正确分流**:外围入口、输入、输出和边界已经稳定时,可以结束 AST 阶段并交接。
308
+
309
+ ### 5.5 在 AST 阶段解释 VM 语义
310
+
311
+ - **错误做法**:给 Opcode、虚拟栈和字节码使用确定业务含义。
312
+ - **为什么错**:没有 VM Trace 和虚拟控制流证据时,这些名称只是猜测。
313
+ - **正确分流**:使用 entry、slot、record 等中性坐标,把内部问题交接 VM Skill。
314
+
315
+ ### 5.6 用残留数量决定结束
316
+
317
+ - **错误做法**:只要还有任何混淆候选就继续。
318
+ - **为什么错**:低收益尾部可以无限存在,残留不等于仍阻碍目标。
319
+ - **正确分流**:相对于当前分析方向、收益和阶段边界提出关闭或交接。
320
+
321
+ ### 5.7 模型自行标记 COMPLETE
322
+
323
+ - **错误做法**:模型认为已经足够,就直接宣布任务全部完成。
324
+ - **为什么错**:用户可能要继续深入、换方向或转入下一阶段。
325
+ - **正确分流**:先进入 `READY_FOR_USER_CLOSURE`,提交成果、残留和交接选项;只有用户确认后标记 `COMPLETE`。
@@ -0,0 +1,255 @@
1
+ # 首轮调查与用户决策
2
+
3
+ 本文是普通解混淆任务在 `SKILL.md` 之外唯一必读的首轮 reference。它只负责:
4
+
5
+ ```text
6
+ 确认机械准备结果
7
+ → 直接阅读完整格式化源码
8
+ → 建立当前可见画像
9
+ → 通过字符串门
10
+ → 形成候选问题和初步证据路线
11
+ → 向用户提交第一次决策
12
+ ```
13
+
14
+ 它不规定具体 transform,不执行动态代码,不承担单步验收,也不继续路由其他 reference。
15
+
16
+ ## 目录
17
+
18
+ 1. [准备验收](#1-准备验收)
19
+ 2. [完整直读](#2-完整直读)
20
+ 3. [画像分类](#3-画像分类)
21
+ 4. [统计和证据](#4-统计和证据)
22
+ 5. [字符串门](#5-字符串门)
23
+ 6. [依赖与候选问题](#6-依赖与候选问题)
24
+ 7. [证据路线与排序](#7-证据路线与排序)
25
+ 8. [第一次用户决策](#8-第一次用户决策)
26
+ 9. [首轮完成条件](#9-首轮完成条件)
27
+
28
+ ## 1. 准备验收
29
+
30
+ 开始语义判断前确认准备报告至少包含:
31
+
32
+ ```text
33
+ 原始绝对路径
34
+ 原始大小与 SHA-256
35
+ 工作区和 run id
36
+ 原始副本路径与 SHA-256
37
+ 格式化视图路径与 SHA-256
38
+ Node 与 Prettier 版本
39
+ parser、命令和退出状态
40
+ 格式化结果的 parse / syntax 状态
41
+ 准备结束后的原始 SHA-256
42
+ ```
43
+
44
+ 必须满足:
45
+
46
+ - 源文件、原始副本和格式化视图是不同路径。
47
+ - 准备前后的源文件 SHA-256 相同。
48
+ - 格式化只写入派生文件。
49
+ - Prettier 来自已记录的本地可执行文件。
50
+ - 既有 run 目录和证据没有被覆盖。
51
+
52
+ 任何条件不成立时停止在 `FORMAT_BLOCKED`,保留报告和 stderr。不要通过修改原始源码或静默更换工具绕过失败。
53
+
54
+ ## 2. 完整直读
55
+
56
+ 以格式化视图为唯一首轮阅读视图,按连续区间覆盖到 EOF。
57
+
58
+ 建立阅读账本:
59
+
60
+ ```text
61
+ file: steps/00_formatted.js
62
+ total_lines:
63
+ read_ranges:
64
+ - start:
65
+ end:
66
+ notable_anchors:
67
+ remaining_ranges:
68
+ ```
69
+
70
+ 阅读顺序可以跨多轮,但必须连续推进。未读完整文件时只记录阅读进度,不提交完整画像,不让用户选择语义步骤。
71
+
72
+ 先从源码片段观察,再用搜索、AST 和统计复核。重点查看:
73
+
74
+ - 入口、导出、公开 API 和初始化顺序。
75
+ - 长字符串、数组、字符码、异常字面量和 decoder。
76
+ - 高频 helper、wrapper、alias、间接调用和动态属性。
77
+ - 模块表、加载器、数字模块 ID、polyfill 和第三方边界。
78
+ - `eval`、`Function`、脚本注入、压缩载荷和运行时生成代码。
79
+ - Cookie、Storage、DOM、网络、时间、随机数、环境检测和反调试。
80
+ - VM 数据、加载器、解释器外围、宿主 binding、slot、入口和公开初始化。
81
+
82
+ 不要根据文件名、课程主题、已知厂商或旧案例先给结构贴标签。
83
+
84
+ ## 3. 画像分类
85
+
86
+ 先判断结构属于哪一类:
87
+
88
+ | 分类 | 判断重点 |
89
+ |---|---|
90
+ | 真正混淆 | 有意隐藏值、调用、数据流、控制流或语义 |
91
+ | 压缩/转译 | 语义仍直接可追踪,只是短名、合并或编译产物 |
92
+ | 打包器 | 模块注册、缓存、加载、导出和 chunk 运行时 |
93
+ | polyfill/第三方 | 可识别的通用兼容层或外部库 |
94
+ | 环境检测/反调试 | 读取宿主差异、检测自动化或改变调试行为 |
95
+ | 动态载荷 | 运行时解码、生成、加载或执行的新代码 |
96
+ | VM 外围 | 先列解释器候选、数据区、宿主桥和公开初始化;数组、数字 ID 或 dispatcher 单独出现不足以确认 JSVMP |
97
+
98
+ 再按模式家族记录,例如:
99
+
100
+ ```text
101
+ 字符串池、轮转、偏移、编码、decoder wrapper
102
+ 常量表达式与字符码拼接
103
+ 代理函数、间接调用、alias 和动态属性名
104
+ 作用域隐藏、shadow 与 binding 混淆
105
+ 不透明谓词、死分支和控制流平坦化
106
+ 自修改、动态代码和压缩载荷
107
+ 反调试、环境探测和遥测
108
+ 打包器、数字模块、polyfill 和第三方内部
109
+ VM 加载器、数据区、宿主 binding 和 public init
110
+ ```
111
+
112
+ 模式家族数量、出现次数和影响范围是三个不同指标,不要混为“有多少种混淆”。
113
+
114
+ ## 4. 统计和证据
115
+
116
+ 每个候选写入 `ANALYSIS.md`:
117
+
118
+ ```text
119
+ pattern_id:
120
+ name:
121
+ representative_snippets:
122
+ source_anchors:
123
+ family:
124
+ occurrences:
125
+ count_basis: exact | lower-bound | estimate
126
+ affected_ranges:
127
+ main_consumers:
128
+ dependencies:
129
+ classification:
130
+ evidence: Observed | Inferred | Unknown
131
+ confidence:
132
+ counter_evidence:
133
+ current_question:
134
+ known_static_facts:
135
+ evidence_gap:
136
+ route:
137
+ expected_gain:
138
+ risk:
139
+ initial_action:
140
+ ```
141
+
142
+ 要求:
143
+
144
+ - `Observed` 必须能回到源码锚点或工具原始输出。
145
+ - `Inferred` 必须说明推理链和可反证条件。
146
+ - `Unknown` 必须说明缺少哪个事实,不能用猜测补齐。
147
+ - 计数工具必须说明口径;不确定时使用下界或估计。
148
+ - 短变量、数字 key、模块 ID 和大数组本身都不是混淆证据。
149
+
150
+ ## 5. 字符串门
151
+
152
+ 必须检查:
153
+
154
+ - 转义字面量和字符码拼接。
155
+ - 字符串池、轮转、偏移和索引变换。
156
+ - Base64、RC4、自定义编码和压缩文本。
157
+ - decoder wrapper、别名、缓存和动态属性名。
158
+ - 运行时 key、动态载荷和消费者。
159
+
160
+ 结果分三类:
161
+
162
+ 1. 确认是真实字符串隐藏,并阻碍入口、属性、调用或主要数据流:作为第一个语义推荐。
163
+ 2. 只是普通字面量、第三方数据、压缩资源或 VM 字节数据:记录理由,跳过字符串 transform。
164
+ 3. 静态无法确认:标记 `Unknown`,把最小证据缺口写成候选问题。
165
+
166
+ 字符串优先只决定推荐顺序,不代表已经获得执行 transform 或运行 decoder 的授权。
167
+
168
+ ## 6. 依赖与候选问题
169
+
170
+ 把模式画成依赖关系,而不是平铺清理清单:
171
+
172
+ ```text
173
+ 隐藏字符串
174
+ → 动态属性名
175
+ → helper / alias 消费者
176
+ → 模块入口或宿主 binding
177
+ → 后续算法与 VM 边界
178
+ ```
179
+
180
+ 每个高价值候选改写为可证伪问题:
181
+
182
+ ```text
183
+ 当前要回答什么?
184
+ 已经观察到什么?
185
+ 静态还缺少什么?
186
+ 取得哪个事实后才能继续?
187
+ 结果怎样改善阅读、观测或交接?
188
+ 结果怎样映射回当前视图?
189
+ ```
190
+
191
+ “解字符串”“清理控制流”只是模式名称,不是合格问题。
192
+
193
+ ## 7. 证据路线与排序
194
+
195
+ 首轮只做初步分流:
196
+
197
+ | 路线 | 使用条件 |
198
+ |---|---|
199
+ | `static` | AST、作用域、引用、常量和数据流已经足够 |
200
+ | `local-exec` | 闭合 decoder、冻结输入、无宿主依赖 |
201
+ | `dynamic` | 缺少的事实只有运行时才能取得 |
202
+ | `hybrid` | 静态定位、动态取证、AST 写回 |
203
+ | `blocked` | 缺少可信执行条件、输入或授权 |
204
+ | `handoff` | 需要系统补环境、真浏览器、算法或 VM 内部能力 |
205
+
206
+ 依次比较:
207
+
208
+ 1. 与当前入口、输入、输出和用户方向的相关性。
209
+ 2. 对关键调用关系、属性名和数据流的解锁能力。
210
+ 3. 对后续动态观测、算法分析或交接的改善。
211
+ 4. 影响范围和消费者数量。
212
+ 5. 证据强度。
213
+ 6. 语义风险、运行风险和成本。
214
+ 7. 是否仍属于 AST 边界。
215
+
216
+ 给出 `recommend`、`ask`、`skip`、`blocked` 或 `handoff`,但不要在首轮直接执行语义步骤。
217
+
218
+ ## 8. 第一次用户决策
219
+
220
+ 先用普通语言汇报:
221
+
222
+ ```markdown
223
+ ## 当前画像
224
+
225
+ - 已完整阅读:
226
+ - 当前可见模式:
227
+ - 真正混淆:
228
+ - 打包器、第三方或编译产物:
229
+ - 字符串门:
230
+ - 关键依赖:
231
+ - 仍然 Unknown:
232
+
233
+ ## 下一步
234
+
235
+ 1. 推荐:要解决的问题、预计得到的结果、证据路线和风险。
236
+ 2. 替代:真正不同的分析方向及其代价。
237
+ 3. 暂停或交接:当前已具备的成果和剩余问题。
238
+ ```
239
+
240
+ 不要问用户“选 static 还是 hybrid”“要不要做 binding analysis”。把技术选择翻译成结果。
241
+
242
+ ## 9. 首轮完成条件
243
+
244
+ 只有同时满足以下条件,才进入 `READY_FOR_USER_DECISION`:
245
+
246
+ - 机械准备报告通过。
247
+ - 格式化视图已连续读到 EOF,阅读账本无缺口。
248
+ - 当前可见模式都有源码锚点、分类和证据等级。
249
+ - 家族数量、出现次数和影响范围已经区分。
250
+ - 字符串门已经得出确认、跳过或 Unknown。
251
+ - 高价值候选已经改写为问题并建立依赖。
252
+ - 每个提交给用户的候选都有初步路线、收益、风险和边界。
253
+ - 已准备 2~3 个互斥、使用结果语言表达的选项。
254
+
255
+ 首轮只是当前视图,不是永久全集。用户选择一个步骤后,结果必须回到最新源码重新审视。