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,289 @@
1
+ # 静态分析与动态 Trace 证据
2
+
3
+ 本文说明不同证据能够证明什么,以及如何让它们共同服务于唯一主线:从声明的原始输入恢复独立可执行映射,并与受控 iv8 Oracle 的最终输出精确一致。
4
+
5
+ ## 目录
6
+
7
+ 1. 三类证据
8
+ 2. 静态分析能力
9
+ 3. Trace 能力
10
+ 4. 受控实验能力
11
+ 5. Handler 语义证明
12
+ 6. Trace 事件坐标
13
+ 7. 数据流与切片
14
+ 8. 控制流与函数边界
15
+ 9. 首个分歧
16
+ 10. 同值歧义
17
+ 11. 观测扰动
18
+ 12. 证据等级与声明
19
+
20
+ ## 1. 三类证据
21
+
22
+ 区分:
23
+
24
+ ```text
25
+ 静态证据
26
+ 来自解释器、字节码、元数据、CFG、Scope 和数据流
27
+
28
+ 动态 Trace
29
+ 来自某个声明输入下的 PC、Opcode、Operand、栈、Frame、Record 和值变化
30
+
31
+ 受控实验
32
+ 在只改变一个原始事实时,观察 Oracle 路径、中间值和最终输出的变化
33
+ ```
34
+
35
+ 三者回答不同问题:
36
+
37
+ | 问题 | 主要证据 |
38
+ |---|---|
39
+ | 这条指令可能读取哪个操作数 | 解释器和静态解码 |
40
+ | 这组输入实际走了哪条路 | Trace |
41
+ | 某个宿主属性是否决定了某个 bit | 静态依赖 + 单变量实验 |
42
+ | 未执行分支的公式是什么 | 静态 CFG/Scope |
43
+ | 独立实现在哪一步偏离 Oracle | 共同中间坐标和 Trace diff |
44
+ | 最终是否复现 | 同 RawInput 下的精确输出比较 |
45
+
46
+ 不用任一类证据取代其他类型才能回答的问题。
47
+
48
+ ## 2. 静态分析能力
49
+
50
+ 静态分析可以恢复:
51
+
52
+ - Opcode 解码、操作数宽度和符号/字节序;
53
+ - Handler 对栈、PC、Scope、Frame 和宿主状态的全部显式分支;
54
+ - Record 元数据、异常表和创建/调用关系;
55
+ - 基本块、普通跳转边、异常边和不可达区域;
56
+ - def-use、数据消费者、中间字段布局和算法公式;
57
+ - 当前 Trace 未覆盖的分支和边界条件。
58
+
59
+ 静态结论仍受以下因素限制:
60
+
61
+ - 间接索引、动态属性名和宿主回调;
62
+ - `eval`/动态载荷/WASM/运行时解密的新程序数据;
63
+ - 宿主 API 的 descriptor、prototype、异常、异步和运行时特殊语义;
64
+ - 别名、共享 Scope 和对象可变性导致的依赖扩散;
65
+ - 用途和作者意图,它们不能仅从公式中恢复。
66
+
67
+ 对不确定间接边保留候选集,不为生成一张“完整”图而随意选一条边。
68
+
69
+ ## 3. Trace 能力
70
+
71
+ 一份良好的 Handler Trace 可以证明:
72
+
73
+ - 某个 `recordId + PC + opcode` 实际被执行;
74
+ - 本次执行使用的操作数和下一 PC;
75
+ - 执行前后栈、Scope、Frame 或关键值的变化;
76
+ - 实际的 Record/Frame 进出和调用顺序;
77
+ - 某个原始输入实例最终影响了哪些中间值和输出字节。
78
+
79
+ 单次 Trace 不能自动证明:
80
+
81
+ - 未执行分支的存在条件和全部返回值;
82
+ - Handler 在不同操作数或类型下的所有语义;
83
+ - 一个数值的唯一业务来源;
84
+ - 所有可能的 Record、Frame 和源码函数数量;
85
+ - 观测 Hook 完全没有改变目标行为;
86
+ - 对未测输入的普遍等价。
87
+
88
+ 把 Trace 覆盖写成明确数字:
89
+
90
+ ```text
91
+ events captured / dropped / malformed
92
+ unique records reached
93
+ unique opcode IDs reached
94
+ unique (recordId, PC, opcode) coordinates
95
+ frame entries/exits
96
+ baseline input and output hash
97
+ ```
98
+
99
+ ## 4. 受控实验能力
100
+
101
+ 受控实验用于在竞争解释中做区分。例如,基线中一个字节为 `1`,可能来自固定基础位、某个环境布尔值或某个计数器。仅看基线无法区分,但改变相应原始事实后可以观察路径和字节是否变化。
102
+
103
+ 设计实验时:
104
+
105
+ 1. 从已稳定基线复制输入。
106
+ 2. 只修改一个原始事实,记录精确 diff。
107
+ 3. 保持时间、随机和初始状态的消费顺序一致,或明确记录分支使顺序发生变化。
108
+ 4. 同时检查 Record 返回值、下游写入位置和最终输出。
109
+ 5. 保留不支持预期的负结果,不只保留成功样本。
110
+
111
+ 实验结果可以验证静态公式,但不会自动恢复未触发分支的公式。
112
+
113
+ ## 5. Handler 语义证明
114
+
115
+ 为每个 Handler 建立机械合同:
116
+
117
+ ```text
118
+ opcode ids and variants
119
+ operand decoding
120
+ preconditions and consumed VM state
121
+ stack/register/scope reads
122
+ stack/register/scope writes
123
+ pc transition
124
+ frame/call/return transition
125
+ host side effects
126
+ exception/completion behavior
127
+ observed trace instances
128
+ untested variants
129
+ ```
130
+
131
+ 确定 Handler 语义的强证据组合是:
132
+
133
+ ```text
134
+ 解释器分支公式
135
+ → Bytecode 实例的操作数解码
136
+ → Trace 前后状态转移
137
+ → 下游消费者或受控变体
138
+ ```
139
+
140
+ 如果静态语义已经由解释器代码完整确定,未执行的分支可标记为“静态已确定,未专项动态覆盖”,不必降级为猜测。如果依赖未知宿主语义或间接索引,保留不确定性。
141
+
142
+ 业务名称要求额外证据。`BITWISE_OR` 可以由 Handler 本身证明,`runtimeRiskBits` 还需要连接具体环境探针和最终材料消费者。
143
+
144
+ ## 6. Trace 事件坐标
145
+
146
+ 使用稳定坐标使静态与动态可对账:
147
+
148
+ ```text
149
+ sourceHash
150
+ traceTargetHash
151
+ runId
152
+ recordId
153
+ frameId and parentFrameId
154
+ pcBefore
155
+ opcodeId
156
+ decodedOperands
157
+ pcAfter
158
+ stackBefore / stackAfter or declared slices
159
+ scope/register changes
160
+ host call or side effect
161
+ exception/completion
162
+ ```
163
+
164
+ 不要只用事件序号作为跨运行坐标,因为分支、异步和观测可使序号整体偏移。优先对齐 `recordId + PC + opcode + frame/call context`。
165
+
166
+ 序列化对象时区分:
167
+
168
+ - 原始值;
169
+ - 安全摘要或类型标签;
170
+ - 为避免 getter/proxy 副作用而省略的字段。
171
+
172
+ 不让 Trace 序列化本身额外读取目标 getter、展开 Proxy 或调用目标 `toJSON`。
173
+
174
+ ## 7. 数据流与切片
175
+
176
+ 使用正向数据流回答:
177
+
178
+ ```text
179
+ 某个原始输入被读取后,经过哪些 Record/Handler,最终写到哪些材料和输出?
180
+ ```
181
+
182
+ 使用反向切片回答:
183
+
184
+ ```text
185
+ 某个最终字节、摘要、header 或密文在当前执行中依赖哪些原始值和共享状态?
186
+ ```
187
+
188
+ 两者都是方法,不是固定顺序。入口少且输入边界清晰时,正向通常简单;最终输出已知但中间路径庞大时,反向切片可以快速收束主线。
189
+
190
+ 静态切片包含可能依赖,动态切片只包含当前执行实例的实际依赖。报告时标明切片类型。
191
+
192
+ ## 8. 控制流与函数边界
193
+
194
+ 静态 CFG 与动态路径不同:
195
+
196
+ ```text
197
+ static CFG edge 该边在程序语义上可能发生
198
+ dynamic edge 该边在当前运行中实际发生
199
+ ```
200
+
201
+ 使用 Trace 为静态边加覆盖标记,不删除未覆盖边。只在静态证据证明边不可达时标记不可达。
202
+
203
+ 函数边界使用创建、捕获 Scope、调用、Frame 进入和 Return/Completion 共同确定。不要用 Trace 中一次 Record 切换自动推出源码级函数边界。
204
+
205
+ ## 9. 首个分歧
206
+
207
+ 当独立实现最终输出不同时,不从最终密文随机猜测。按共同坐标比较:
208
+
209
+ 1. 原始输入读取顺序与值。
210
+ 2. 最早的探针、计数器、摘要或状态变化。
211
+ 3. 材料组装中的首个字节差异。
212
+ 4. 时间/随机源的首个调用次数或值差异。
213
+ 5. 打包、加密和编码的首个不同状态。
214
+
215
+ 首个分歧是当前证据中最早可观测的偏差,不必然是根因所在的源码行。继续检查它的输入和前置状态。
216
+
217
+ ## 10. 同值歧义
218
+
219
+ 基线中多个来源可能有相同数值,例如:
220
+
221
+ ```text
222
+ fixed bit = 1
223
+ boolean probe = true → 1
224
+ queue length = 1
225
+ invocation bucket = 1
226
+ version byte = 1
227
+ ```
228
+
229
+ 不要通过数值相同为字节赋予来源。使用:
230
+
231
+ - 静态 def-use;
232
+ - 中间写入的 PC/Record 坐标;
233
+ - 受控变体;
234
+ - 值类型、字节序和宽度;
235
+ - 下游多个消费位置。
236
+
237
+ 如果多个解释在所有现有证据中不可区分,保留竞争假设,设计能分离它们的变体,或在完成声明中限定范围。
238
+
239
+ ## 11. 观测扰动
240
+
241
+ Trace 代码可以影响:
242
+
243
+ - 时间和性能差;
244
+ - 随机调用顺序;
245
+ - getter、Proxy、descriptor 和对象枚举;
246
+ - 函数 `toString`、调用栈和 Error stack;
247
+ - event loop、Promise 和微任务时序;
248
+ - 反调试、完整性和自检分支。
249
+
250
+ 优先选择能回答当前问题的最小观测面。保存:
251
+
252
+ ```text
253
+ original source hash
254
+ derived trace target hash
255
+ instrumentation manifest
256
+ no-trace output
257
+ trace output
258
+ first output difference, if any
259
+ ```
260
+
261
+ 如果只有插桩目标可以运行,可用它提出假设和定位,但不要把其输出自动当作未修改原程序的 Oracle。
262
+
263
+ ## 12. 证据等级与声明
264
+
265
+ 使用以下标签保持表达准确:
266
+
267
+ ```text
268
+ proven-static
269
+ 公式、分支或边由解释器/Bytecode/CFG/Scope 确定
270
+
271
+ observed-dynamic
272
+ 在声明输入和运行条件下被 Trace 观测
273
+
274
+ validated-variant
275
+ 静态预期经受控变体验证
276
+
277
+ exact-end-to-end
278
+ 同 RawInput 下独立实现与 Oracle 最终输出精确相等
279
+
280
+ inferred
281
+ 现有证据支持但存在未排除的竞争解释
282
+
283
+ unknown
284
+ 证据不足以确定
285
+ ```
286
+
287
+ 同一结论可以同时具有多个标签,例如一个公式既是 `proven-static` 又是 `validated-variant`。
288
+
289
+ 最终完成仍回到主线:当前声明的原始输入范围内,独立实现是否能生成与受控 iv8 原程序精确相同的最终输出。Trace 和静态证据用来建立、解释和定位这个命题,不是另一个竞争性完成标准。
@@ -0,0 +1,212 @@
1
+ # VMP 领域对象与语义边界
2
+
3
+ 本文用于避免把 Handler、Opcode、Record、VM 函数、基本块和源码函数混为同一层。所有对象都服务于同一主线:恢复受控 iv8 原程序从声明的原始输入到最终输出的独立可执行映射。
4
+
5
+ ## 目录
6
+
7
+ 1. 分析层次
8
+ 2. Handler 与 Opcode
9
+ 3. Record、Frame 与 VM 函数
10
+ 4. 基本块、CFG 与调用图
11
+ 5. 机械语义与业务语义
12
+ 6. 字符串与数据恢复
13
+ 7. 数量口径
14
+ 8. 适度恢复
15
+
16
+ ## 1. 分析层次
17
+
18
+ 把常见 JSVMP 分成以下层次:
19
+
20
+ ```text
21
+ 宿主 JavaScript 与公开入口
22
+ → 解释器和加载器
23
+ → VM 程序数据 / Record 容器
24
+ → Bytecode / Opcode / Operand
25
+ → Handler 对 VM 状态的转移
26
+ → VM Frame / Scope / Value Stack / PC
27
+ → 虚拟基本块、函数和调用关系
28
+ → 业务输入、中间材料和最终输出
29
+ ```
30
+
31
+ 每层回答不同问题。不要用一层的数量、名称或边界直接代替另一层。
32
+
33
+ ## 2. Handler 与 Opcode
34
+
35
+ ### Opcode
36
+
37
+ Opcode 是 VM 程序数据中的指令编码。它可以是单字节、变长整数、经过映射的 ID,或与操作数共同解码的位域。
38
+
39
+ 确定 Opcode 时记录:
40
+
41
+ ```text
42
+ encoded form
43
+ decoded id
44
+ operand widths and decoding
45
+ next-PC rule
46
+ dispatch target
47
+ ```
48
+
49
+ ### Handler
50
+
51
+ Handler 是解释器对某类指令的实现。它通常读取操作数和 VM 状态,再改变 PC、值栈、Scope、Frame、Completion 或宿主对象。
52
+
53
+ 不假设两者一一对应。可能存在:
54
+
55
+ - 一个 Opcode 对应一个 Handler;
56
+ - 多个 Opcode 共用一个 Handler,由操作数或模式位分流;
57
+ - 一个 Opcode 通过二次分派进入多个语义分支;
58
+ - 无效、保留或未被当前程序使用的 Opcode;
59
+ - 仅在解释器内部使用、不从 Bytecode 直接取指的辅助操作。
60
+
61
+ 不要用“JS 中有多少个函数体”自动推出 Opcode 数量。使用实际取指空间、分派表、解码规则和 Bytecode 引用共同确定口径。
62
+
63
+ ## 3. Record、Frame 与 VM 函数
64
+
65
+ ### Record
66
+
67
+ Record 是样本定义的程序数据单元,没有跨 VM 的统一语义。它可能包含:
68
+
69
+ ```text
70
+ bytecode
71
+ formal bindings or parameter count
72
+ strict-mode flag
73
+ exception table
74
+ constant references
75
+ scope metadata
76
+ ```
77
+
78
+ 当前 VM 中的 Record 可以类似一个可调用代码对象,但不要把这个经验推广为定义。
79
+
80
+ ### Frame
81
+
82
+ Frame 是一次动态执行实例。同一个 Record 可能因递归、重入或多次调用产生多个 Frame。Frame 可能持有:
83
+
84
+ ```text
85
+ record id
86
+ pc
87
+ operand/value stack
88
+ arguments and this
89
+ lexical/environment chain
90
+ return continuation
91
+ completion or exception state
92
+ ```
93
+
94
+ 因此:
95
+
96
+ ```text
97
+ Record count != Frame count
98
+ Trace frame count != source function count
99
+ ```
100
+
101
+ ### VM 函数
102
+
103
+ VM 函数是可调用的虚拟语义单元。它可以由一个 Record 承载,也可以通过闭包创建指令把 Record 与当前 Scope 绑定后形成。
104
+
105
+ 确认 VM 函数边界时查看:
106
+
107
+ - 创建指令和捕获的 Scope;
108
+ - 调用指令和参数绑定;
109
+ - 入口 PC 和返回/Completion 规则;
110
+ - 动态 Frame 进出证据;
111
+ - 宿主函数与 VM 函数的转换边界。
112
+
113
+ ## 4. 基本块、CFG 与调用图
114
+
115
+ 基本块是单入口、在块内按顺序执行、以控制转移结束的指令序列。使用以下坐标划分候选块:
116
+
117
+ - Record 入口;
118
+ - 跳转目标;
119
+ - 条件或无条件跳转后的下一条指令;
120
+ - Return、Throw、Completion 或帧切换;
121
+ - 异常表入口。
122
+
123
+ 区分三种图:
124
+
125
+ ```text
126
+ intra-record CFG Record 内部控制流
127
+ VM call graph VM 函数/Record 间创建与调用关系
128
+ business dataflow 从原始输入到最终输出的值依赖
129
+ ```
130
+
131
+ 完整 CFG 是可用产物,但不是每个目标的必要前置。如果最终映射只依赖一个可证明的主线切片,先恢复该切片;如果间接跳转、异常、共享状态或未覆盖分支影响输出,再扩大图的范围。
132
+
133
+ ## 5. 机械语义与业务语义
134
+
135
+ 先给 Handler 建立低语义合同:
136
+
137
+ ```text
138
+ operands
139
+ values read
140
+ values written
141
+ stack before/after
142
+ scope/register effects
143
+ pc effect
144
+ frame/call effect
145
+ host side effect
146
+ exception/completion effect
147
+ ```
148
+
149
+ 例如:
150
+
151
+ ```text
152
+ LOAD_SCOPE depth, slot
153
+ GET_PROPERTY
154
+ CALL argc
155
+ JUMP_IF_FALSE relativeTarget
156
+ RETURN
157
+ ```
158
+
159
+ 这些名称只描述机械操作。只有在数据流连接真实宿主输入和消费者后,才使用 `runtimeRiskBits`、`behaviorBits`、`buildSignatureMaterial` 等业务名称。
160
+
161
+ 为每个语义名称标记级别:
162
+
163
+ ```text
164
+ mechanically proven
165
+ business-linked
166
+ inferred
167
+ unknown
168
+ ```
169
+
170
+ 不以可读性为理由消除不确定性。
171
+
172
+ ## 6. 字符串与数据恢复
173
+
174
+ 先分类再决定是否解密:
175
+
176
+ | 类型 | 特征 | 处理 |
177
+ |---|---|---|
178
+ | 普通常量 | 直接被属性、比较或 API 消费 | 直接标注消费者 |
179
+ | 字符串池 | 索引或简单 decoder 访问 | 恢复索引映射和真实字面量 |
180
+ | 编码/加密常量 | 经稳定 decoder 后进入主线 | 在前提和输入可固定时恢复 |
181
+ | 运行时派生字符串 | 依赖环境、时间、随机或状态 | 保留输入合同,不固化一次结果 |
182
+ | VM 程序数据 | 数字数组、Record 字节流或异常表 | 按格式解码,不冒充为文本解密 |
183
+
184
+ 只在恢复后能增强 `RawInput → FinalOutput` 映射时投入字符串解密。对不影响当前映射的调试文本、第三方资源和不可达常量保持低优先级。
185
+
186
+ ## 7. 数量口径
187
+
188
+ 报告数量时始终同时报告计数对象和发现方法:
189
+
190
+ ```text
191
+ N dispatch entries
192
+ N decoded opcode IDs
193
+ N handler implementation bodies
194
+ N raw records in the program container
195
+ N records reached by this trace
196
+ N dynamic frames
197
+ N recovered VM functions under the current definition
198
+ N source-level business functions, if proven
199
+ ```
200
+
201
+ 没有 Trace 也可以从静态程序容器和 Record 长度/元数据规则得到 Record 数量。Trace 只能告诉当前输入实际到达了哪些 Record 和产生了多少动态 Frame。
202
+
203
+ ## 8. 适度恢复
204
+
205
+ 用最终等价命题决定恢复深度:
206
+
207
+ - 不知道操作数宽度或 PC 规则时,先恢复指令格式。
208
+ - 不知道中间值如何影响输出时,恢复局部数据流和消费者。
209
+ - 间接跳转、异常或共享 Scope 影响主线时,扩大 CFG、Frame 或调用图。
210
+ - 独立实现已从原始输入与 Oracle 精确一致,且未知部分不影响声明范围时,停止为了形式完整扩展分析。
211
+
212
+ 最终不用“还原了多少对象”验收,而用“已声明的原始输入是否能由独立实现得到与受控 iv8 相同的最终输出”验收。