deepspider 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 (261) hide show
  1. package/.claude/agents/check.md +122 -0
  2. package/.claude/agents/debug.md +106 -0
  3. package/.claude/agents/dispatch.md +214 -0
  4. package/.claude/agents/implement.md +96 -0
  5. package/.claude/agents/plan.md +396 -0
  6. package/.claude/agents/research.md +120 -0
  7. package/.claude/commands/evolve/merge.md +80 -0
  8. package/.claude/commands/trellis/before-backend-dev.md +13 -0
  9. package/.claude/commands/trellis/before-frontend-dev.md +13 -0
  10. package/.claude/commands/trellis/break-loop.md +107 -0
  11. package/.claude/commands/trellis/check-backend.md +13 -0
  12. package/.claude/commands/trellis/check-cross-layer.md +153 -0
  13. package/.claude/commands/trellis/check-frontend.md +13 -0
  14. package/.claude/commands/trellis/create-command.md +154 -0
  15. package/.claude/commands/trellis/finish-work.md +129 -0
  16. package/.claude/commands/trellis/integrate-skill.md +219 -0
  17. package/.claude/commands/trellis/onboard.md +358 -0
  18. package/.claude/commands/trellis/parallel.md +193 -0
  19. package/.claude/commands/trellis/record-session.md +62 -0
  20. package/.claude/commands/trellis/start.md +280 -0
  21. package/.claude/commands/trellis/update-spec.md +213 -0
  22. package/.claude/hooks/inject-subagent-context.py +758 -0
  23. package/.claude/hooks/ralph-loop.py +374 -0
  24. package/.claude/hooks/session-start.py +126 -0
  25. package/.claude/settings.json +41 -0
  26. package/.claude/skills/deepagents-guide/SKILL.md +428 -0
  27. package/.cursor/commands/trellis-before-backend-dev.md +13 -0
  28. package/.cursor/commands/trellis-before-frontend-dev.md +13 -0
  29. package/.cursor/commands/trellis-break-loop.md +107 -0
  30. package/.cursor/commands/trellis-check-backend.md +13 -0
  31. package/.cursor/commands/trellis-check-cross-layer.md +153 -0
  32. package/.cursor/commands/trellis-check-frontend.md +13 -0
  33. package/.cursor/commands/trellis-create-command.md +154 -0
  34. package/.cursor/commands/trellis-finish-work.md +129 -0
  35. package/.cursor/commands/trellis-integrate-skill.md +219 -0
  36. package/.cursor/commands/trellis-onboard.md +358 -0
  37. package/.cursor/commands/trellis-record-session.md +62 -0
  38. package/.cursor/commands/trellis-start.md +156 -0
  39. package/.cursor/commands/trellis-update-spec.md +213 -0
  40. package/.env.example +11 -0
  41. package/.husky/pre-commit +1 -0
  42. package/.mcp.json +8 -0
  43. package/.trellis/.template-hashes.json +65 -0
  44. package/.trellis/.version +1 -0
  45. package/.trellis/scripts/add-session.sh +384 -0
  46. package/.trellis/scripts/common/developer.sh +129 -0
  47. package/.trellis/scripts/common/git-context.sh +263 -0
  48. package/.trellis/scripts/common/paths.sh +208 -0
  49. package/.trellis/scripts/common/phase.sh +150 -0
  50. package/.trellis/scripts/common/registry.sh +247 -0
  51. package/.trellis/scripts/common/task-queue.sh +142 -0
  52. package/.trellis/scripts/common/task-utils.sh +151 -0
  53. package/.trellis/scripts/common/worktree.sh +128 -0
  54. package/.trellis/scripts/create-bootstrap.sh +299 -0
  55. package/.trellis/scripts/get-context.sh +7 -0
  56. package/.trellis/scripts/get-developer.sh +15 -0
  57. package/.trellis/scripts/init-developer.sh +34 -0
  58. package/.trellis/scripts/multi-agent/cleanup.sh +396 -0
  59. package/.trellis/scripts/multi-agent/create-pr.sh +241 -0
  60. package/.trellis/scripts/multi-agent/plan.sh +207 -0
  61. package/.trellis/scripts/multi-agent/start.sh +310 -0
  62. package/.trellis/scripts/multi-agent/status.sh +828 -0
  63. package/.trellis/scripts/task.sh +1118 -0
  64. package/.trellis/spec/backend/deepagents-guide.md +337 -0
  65. package/.trellis/spec/backend/directory-structure.md +126 -0
  66. package/.trellis/spec/backend/examples/skills/deepagents-guide/README.md +11 -0
  67. package/.trellis/spec/backend/examples/skills/deepagents-guide/agent.js.template +20 -0
  68. package/.trellis/spec/backend/examples/skills/deepagents-guide/skills-config.js.template +13 -0
  69. package/.trellis/spec/backend/examples/skills/deepagents-guide/subagent.js.template +19 -0
  70. package/.trellis/spec/backend/hook-guidelines.md +178 -0
  71. package/.trellis/spec/backend/index.md +36 -0
  72. package/.trellis/spec/backend/quality-guidelines.md +201 -0
  73. package/.trellis/spec/backend/state-management.md +76 -0
  74. package/.trellis/spec/backend/tool-guidelines.md +144 -0
  75. package/.trellis/spec/backend/type-safety.md +71 -0
  76. package/.trellis/spec/guides/code-reuse-thinking-guide.md +92 -0
  77. package/.trellis/spec/guides/cross-layer-thinking-guide.md +94 -0
  78. package/.trellis/spec/guides/index.md +79 -0
  79. package/.trellis/tasks/archive/02-02-evolving-skills/prd.md +61 -0
  80. package/.trellis/tasks/archive/02-02-evolving-skills/task.json +29 -0
  81. package/.trellis/tasks/archive/2026-02/00-bootstrap-guidelines/prd.md +86 -0
  82. package/.trellis/tasks/archive/2026-02/00-bootstrap-guidelines/task.json +27 -0
  83. package/.trellis/tasks/archive/2026-02/02-02-skills-system/check.jsonl +3 -0
  84. package/.trellis/tasks/archive/2026-02/02-02-skills-system/debug.jsonl +2 -0
  85. package/.trellis/tasks/archive/2026-02/02-02-skills-system/implement.jsonl +5 -0
  86. package/.trellis/tasks/archive/2026-02/02-02-skills-system/prd.md +33 -0
  87. package/.trellis/tasks/archive/2026-02/02-02-skills-system/task.json +41 -0
  88. package/.trellis/workflow.md +407 -0
  89. package/.trellis/workspace/index.md +123 -0
  90. package/.trellis/workspace/pony/index.md +40 -0
  91. package/.trellis/workspace/pony/journal-1.md +7 -0
  92. package/.trellis/worktree.yaml +47 -0
  93. package/AGENTS.md +18 -0
  94. package/CLAUDE.md +292 -0
  95. package/README.md +134 -0
  96. package/agents/deepspider.md +142 -0
  97. package/docs/DEBUG.md +42 -0
  98. package/docs/GUIDE.md +334 -0
  99. package/docs/PROMPT.md +60 -0
  100. package/docs/USAGE.md +226 -0
  101. package/eslint.config.js +51 -0
  102. package/package.json +78 -0
  103. package/requirements-crypto.txt +14 -0
  104. package/src/agent/index.js +97 -0
  105. package/src/agent/logger.js +164 -0
  106. package/src/agent/middleware/filterTools.js +64 -0
  107. package/src/agent/middleware/report.js +79 -0
  108. package/src/agent/prompts/system.js +315 -0
  109. package/src/agent/run.js +575 -0
  110. package/src/agent/skills/anti-detect/SKILL.md +28 -0
  111. package/src/agent/skills/anti-detect/evolved.md +12 -0
  112. package/src/agent/skills/captcha/SKILL.md +37 -0
  113. package/src/agent/skills/captcha/evolved.md +12 -0
  114. package/src/agent/skills/config.js +30 -0
  115. package/src/agent/skills/crawler/SKILL.md +9 -0
  116. package/src/agent/skills/crawler/evolved.md +16 -0
  117. package/src/agent/skills/dynamic-analysis/SKILL.md +91 -0
  118. package/src/agent/skills/dynamic-analysis/evolved.md +12 -0
  119. package/src/agent/skills/env/SKILL.md +72 -0
  120. package/src/agent/skills/env/evolved.md +12 -0
  121. package/src/agent/skills/evolve.js +79 -0
  122. package/src/agent/skills/general/SKILL.md +12 -0
  123. package/src/agent/skills/general/evolved.md +12 -0
  124. package/src/agent/skills/js2python/SKILL.md +30 -0
  125. package/src/agent/skills/js2python/evolved.md +13 -0
  126. package/src/agent/skills/report/SKILL.md +21 -0
  127. package/src/agent/skills/report/evolved.md +12 -0
  128. package/src/agent/skills/sandbox/SKILL.md +22 -0
  129. package/src/agent/skills/sandbox/evolved.md +16 -0
  130. package/src/agent/skills/static-analysis/SKILL.md +93 -0
  131. package/src/agent/skills/static-analysis/evolved.md +12 -0
  132. package/src/agent/skills/xpath/SKILL.md +119 -0
  133. package/src/agent/subagents/anti-detect.js +45 -0
  134. package/src/agent/subagents/captcha.js +51 -0
  135. package/src/agent/subagents/crawler.js +138 -0
  136. package/src/agent/subagents/dynamic.js +64 -0
  137. package/src/agent/subagents/env-agent.js +82 -0
  138. package/src/agent/subagents/index.js +37 -0
  139. package/src/agent/subagents/js2python.js +72 -0
  140. package/src/agent/subagents/sandbox.js +55 -0
  141. package/src/agent/subagents/static.js +66 -0
  142. package/src/agent/tools/analysis.js +135 -0
  143. package/src/agent/tools/analyzer.js +85 -0
  144. package/src/agent/tools/anti-detect.js +89 -0
  145. package/src/agent/tools/antidebug.js +64 -0
  146. package/src/agent/tools/async.js +43 -0
  147. package/src/agent/tools/browser.js +324 -0
  148. package/src/agent/tools/captcha.js +223 -0
  149. package/src/agent/tools/capture.js +179 -0
  150. package/src/agent/tools/correlate.js +303 -0
  151. package/src/agent/tools/crawler.js +116 -0
  152. package/src/agent/tools/cryptohook.js +80 -0
  153. package/src/agent/tools/debug.js +246 -0
  154. package/src/agent/tools/deobfuscator.js +90 -0
  155. package/src/agent/tools/env.js +83 -0
  156. package/src/agent/tools/envdump.js +92 -0
  157. package/src/agent/tools/evolve.js +164 -0
  158. package/src/agent/tools/extract.js +114 -0
  159. package/src/agent/tools/extractor.js +54 -0
  160. package/src/agent/tools/file.js +224 -0
  161. package/src/agent/tools/hook.js +84 -0
  162. package/src/agent/tools/hookManager.js +178 -0
  163. package/src/agent/tools/index.js +137 -0
  164. package/src/agent/tools/nodejs.js +101 -0
  165. package/src/agent/tools/patch.js +46 -0
  166. package/src/agent/tools/preprocess.js +71 -0
  167. package/src/agent/tools/profile.js +122 -0
  168. package/src/agent/tools/python.js +627 -0
  169. package/src/agent/tools/report.js +124 -0
  170. package/src/agent/tools/runtime.js +132 -0
  171. package/src/agent/tools/sandbox.js +79 -0
  172. package/src/agent/tools/store.js +73 -0
  173. package/src/agent/tools/trace.js +74 -0
  174. package/src/agent/tools/tracing.js +201 -0
  175. package/src/agent/tools/utils.js +51 -0
  176. package/src/agent/tools/verify.js +184 -0
  177. package/src/agent/tools/webcrack.js +109 -0
  178. package/src/analyzer/ASTAnalyzer.js +387 -0
  179. package/src/analyzer/CallStackAnalyzer.js +379 -0
  180. package/src/analyzer/Deobfuscator.js +289 -0
  181. package/src/analyzer/EncryptionAnalyzer.js +99 -0
  182. package/src/analyzer/index.js +22 -0
  183. package/src/browser/EnvBridge.js +186 -0
  184. package/src/browser/cdp.js +168 -0
  185. package/src/browser/client.js +197 -0
  186. package/src/browser/collector.js +444 -0
  187. package/src/browser/collectors/RequestCryptoLinker.js +109 -0
  188. package/src/browser/collectors/ResponseSearcher.js +107 -0
  189. package/src/browser/collectors/ScriptCollector.js +158 -0
  190. package/src/browser/collectors/index.js +26 -0
  191. package/src/browser/defaultHooks.js +932 -0
  192. package/src/browser/hooks/crypto.js +55 -0
  193. package/src/browser/hooks/index.js +64 -0
  194. package/src/browser/hooks/native.js +9 -0
  195. package/src/browser/hooks/network.js +33 -0
  196. package/src/browser/index.js +42 -0
  197. package/src/browser/interceptors/NetworkInterceptor.js +116 -0
  198. package/src/browser/interceptors/ScriptInterceptor.js +76 -0
  199. package/src/browser/interceptors/index.js +6 -0
  200. package/src/browser/ui/analysisPanel.js +1782 -0
  201. package/src/browser/ui/confirmDialog.js +158 -0
  202. package/src/browser/ui/panel.html +152 -0
  203. package/src/browser/ui/selector.js +170 -0
  204. package/src/config/index.js +5 -0
  205. package/src/config/paths.js +71 -0
  206. package/src/config/patterns/crypto.js +36 -0
  207. package/src/config/profiles/chrome.json +71 -0
  208. package/src/config/profiles/firefox.json +44 -0
  209. package/src/config/profiles/safari.json +38 -0
  210. package/src/core/EnvMonitor.js +200 -0
  211. package/src/core/PatchGenerator.js +278 -0
  212. package/src/core/Sandbox.js +181 -0
  213. package/src/env/AntiAntiDebug.js +111 -0
  214. package/src/env/AsyncHook.js +68 -0
  215. package/src/env/BrowserAPIList.js +265 -0
  216. package/src/env/CookieHook.js +48 -0
  217. package/src/env/CryptoHook.js +205 -0
  218. package/src/env/EnvCodeGenerator.js +157 -0
  219. package/src/env/EnvDumper.js +356 -0
  220. package/src/env/EnvExtractor.js +220 -0
  221. package/src/env/HookBase.js +618 -0
  222. package/src/env/NetworkHook.js +159 -0
  223. package/src/env/modules/bom/history.js +29 -0
  224. package/src/env/modules/bom/location.js +26 -0
  225. package/src/env/modules/bom/navigator.js +70 -0
  226. package/src/env/modules/bom/screen.js +26 -0
  227. package/src/env/modules/bom/storage.js +23 -0
  228. package/src/env/modules/dom/document.js +110 -0
  229. package/src/env/modules/dom/event.js +51 -0
  230. package/src/env/modules/index.js +34 -0
  231. package/src/env/modules/webapi/fetch.js +46 -0
  232. package/src/env/modules/webapi/url.js +47 -0
  233. package/src/env/modules/webapi/xhr.js +48 -0
  234. package/src/index.js +27 -0
  235. package/src/mcp/server.js +89 -0
  236. package/src/store/DataStore.js +708 -0
  237. package/src/store/Store.js +158 -0
  238. package/src/store/Validator.js +24 -0
  239. package/test/analyze.test.js +90 -0
  240. package/test/envdump.test.js +74 -0
  241. package/test/flow.test.js +90 -0
  242. package/test/hooks.test.js +138 -0
  243. package/test/plugin.test.js +35 -0
  244. package/test/refactor-full.test.js +30 -0
  245. package/test/refactor.test.js +21 -0
  246. package/test/samples/obfuscated.js +61 -0
  247. package/test/samples/original.js +66 -0
  248. package/test/samples/v10_eval_chain.js +52 -0
  249. package/test/samples/v11_bytecode_vm.js +81 -0
  250. package/test/samples/v12_polymorphic.js +69 -0
  251. package/test/samples/v1_ob_basic.js +98 -0
  252. package/test/samples/v2_ob_advanced.js +99 -0
  253. package/test/samples/v3_jjencode.js +77 -0
  254. package/test/samples/v4_aaencode.js +73 -0
  255. package/test/samples/v5_control_flow.js +86 -0
  256. package/test/samples/v6_string_encryption.js +71 -0
  257. package/test/samples/v7_jsvmp.js +83 -0
  258. package/test/samples/v8_anti_debug.js +79 -0
  259. package/test/samples/v9_proxy_trap.js +49 -0
  260. package/test/samples.test.js +96 -0
  261. package/test/webcrack.test.js +55 -0
@@ -0,0 +1,932 @@
1
+ /**
2
+ * DeepSpider - 默认 Hook 脚本
3
+ * 浏览器启动时自动注入
4
+ */
5
+
6
+ import { HookBase } from '../env/HookBase.js';
7
+ import { getAllCollectorScripts } from './collectors/index.js';
8
+ import { getAnalysisPanelScript } from './ui/analysisPanel.js';
9
+
10
+ /**
11
+ * 生成默认注入的 Hook 代码
12
+ */
13
+ export function getDefaultHookScript() {
14
+ return HookBase.getBaseCode()
15
+ + getNetworkHooks()
16
+ + getCookieHook()
17
+ + getJSONHooks()
18
+ + getEncodingHooks()
19
+ + getStorageHooks()
20
+ + getWebSocketHooks()
21
+ + getEvalHooks()
22
+ + getWebpackHooks()
23
+ + getCryptoHooks()
24
+ + getCanvasHooks()
25
+ + getNavigatorHooks()
26
+ + getDOMHooks()
27
+ + getProxyHooks()
28
+ + getErrorStackHooks()
29
+ + getAllCollectorScripts()
30
+ + getAnalysisPanelScript(); // 分析面板 UI
31
+ }
32
+
33
+ /**
34
+ * 网络请求 Hook (XHR + Fetch)
35
+ */
36
+ function getNetworkHooks() {
37
+ return `
38
+ // === XHR Hook ===
39
+ (function() {
40
+ const deepspider = window.__deepspider__;
41
+ if (!deepspider) return;
42
+
43
+ const OriginalXHR = XMLHttpRequest;
44
+
45
+ XMLHttpRequest = function() {
46
+ const xhr = new OriginalXHR();
47
+ const log = { method: '', url: '', requestHeaders: {}, requestBody: null, response: null, status: 0 };
48
+
49
+ const originalOpen = xhr.open;
50
+ xhr.open = deepspider.native(function(method, url) {
51
+ log.method = method;
52
+ log.url = url;
53
+ return originalOpen.apply(xhr, arguments);
54
+ }, originalOpen);
55
+
56
+ const originalSetHeader = xhr.setRequestHeader;
57
+ xhr.setRequestHeader = deepspider.native(function(name, value) {
58
+ log.requestHeaders[name] = value;
59
+ return originalSetHeader.apply(xhr, arguments);
60
+ }, originalSetHeader);
61
+
62
+ const originalSend = xhr.send;
63
+ xhr.send = deepspider.native(function(body) {
64
+ log.requestId = deepspider.startRequest(log.url, log.method);
65
+ log.requestBody = body;
66
+ deepspider.log('xhr', { action: 'send', ...log, body: body?.toString().slice(0, 200) });
67
+ return originalSend.apply(xhr, arguments);
68
+ }, originalSend);
69
+
70
+ xhr.addEventListener('load', function() {
71
+ log.status = xhr.status;
72
+ log.response = xhr.responseText?.slice(0, 500);
73
+ const ctx = deepspider.endRequest();
74
+ deepspider.log('xhr', {
75
+ action: 'response',
76
+ url: log.url,
77
+ status: log.status,
78
+ response: log.response?.slice(0, 100),
79
+ linkedCrypto: ctx?.cryptoCalls || []
80
+ });
81
+ });
82
+
83
+ return xhr;
84
+ };
85
+
86
+ XMLHttpRequest.prototype = OriginalXHR.prototype;
87
+ console.log('[DeepSpider] XHR Hook 已启用');
88
+ })();
89
+
90
+ // === Fetch Hook ===
91
+ (function() {
92
+ const deepspider = window.__deepspider__;
93
+ if (!deepspider) return;
94
+
95
+ const OriginalFetch = fetch;
96
+
97
+ fetch = deepspider.native(async function(url, options = {}) {
98
+ const log = {
99
+ url: typeof url === 'string' ? url : url.url,
100
+ method: options.method || 'GET',
101
+ headers: options.headers || {},
102
+ body: null,
103
+ response: null,
104
+ status: 0
105
+ };
106
+
107
+ log.requestId = deepspider.startRequest(log.url, log.method);
108
+
109
+ if (options.body) {
110
+ log.body = typeof options.body === 'string' ? options.body.slice(0, 500) : '[FormData/Blob]';
111
+ }
112
+
113
+ deepspider.log('fetch', { action: 'request', ...log });
114
+
115
+ const response = await OriginalFetch.apply(this, arguments);
116
+ log.status = response.status;
117
+
118
+ try {
119
+ const cloned = response.clone();
120
+ const text = await cloned.text();
121
+ log.response = text.slice(0, 500);
122
+ const ctx = deepspider.endRequest();
123
+ deepspider.log('fetch', {
124
+ action: 'response',
125
+ url: log.url,
126
+ status: log.status,
127
+ response: log.response.slice(0, 100),
128
+ linkedCrypto: ctx?.cryptoCalls || []
129
+ });
130
+ } catch (e) {
131
+ deepspider.endRequest();
132
+ }
133
+
134
+ return response;
135
+ }, OriginalFetch);
136
+
137
+ console.log('[DeepSpider] Fetch Hook 已启用');
138
+ })();
139
+ `;
140
+ }
141
+
142
+ /**
143
+ * Cookie Hook
144
+ */
145
+ function getCookieHook() {
146
+ return `
147
+ // === Cookie Hook ===
148
+ (function() {
149
+ const deepspider = window.__deepspider__;
150
+ if (!deepspider) return;
151
+
152
+ const cookieDesc = Object.getOwnPropertyDescriptor(Document.prototype, 'cookie') ||
153
+ Object.getOwnPropertyDescriptor(HTMLDocument.prototype, 'cookie');
154
+
155
+ if (cookieDesc) {
156
+ Object.defineProperty(document, 'cookie', {
157
+ get: function() {
158
+ const value = cookieDesc.get.call(document);
159
+ deepspider.log('cookie', { action: 'read', value: value?.slice(0, 100) });
160
+ return value;
161
+ },
162
+ set: function(val) {
163
+ deepspider.log('cookie', { action: 'write', value: val });
164
+ return cookieDesc.set.call(document, val);
165
+ },
166
+ configurable: true
167
+ });
168
+ }
169
+
170
+ console.log('[DeepSpider] Cookie Hook 已启用');
171
+ })();
172
+ `;
173
+ }
174
+
175
+ /**
176
+ * JSON.parse/stringify Hook
177
+ * 只记录较大的 JSON 数据,避免性能问题
178
+ */
179
+ function getJSONHooks() {
180
+ return `
181
+ // === JSON Hook ===
182
+ (function() {
183
+ const deepspider = window.__deepspider__;
184
+ if (!deepspider) return;
185
+
186
+ const OriginalParse = JSON.parse;
187
+ const OriginalStringify = JSON.stringify;
188
+ const MIN_LOG_LENGTH = 50; // 只记录长度超过 50 的数据
189
+
190
+ JSON.parse = deepspider.native(function(text, reviver) {
191
+ const textStr = String(text);
192
+ if (textStr.length >= MIN_LOG_LENGTH) {
193
+ deepspider.log('json', {
194
+ action: 'parse',
195
+ input: textStr.slice(0, 200),
196
+ len: textStr.length
197
+ });
198
+ }
199
+ return OriginalParse.call(JSON, text, reviver);
200
+ }, OriginalParse);
201
+
202
+ JSON.stringify = deepspider.native(function(value, replacer, space) {
203
+ const result = OriginalStringify.call(JSON, value, replacer, space);
204
+ if (result && result.length >= MIN_LOG_LENGTH) {
205
+ deepspider.log('json', {
206
+ action: 'stringify',
207
+ output: result.slice(0, 200),
208
+ len: result.length
209
+ });
210
+ }
211
+ return result;
212
+ }, OriginalStringify);
213
+
214
+ console.log('[DeepSpider] JSON Hook 已启用');
215
+ })();
216
+ `;
217
+ }
218
+
219
+ /**
220
+ * Base64 + TextEncoder/Decoder Hook
221
+ */
222
+ function getEncodingHooks() {
223
+ return `
224
+ // === Encoding Hook ===
225
+ (function() {
226
+ const deepspider = window.__deepspider__;
227
+ if (!deepspider) return;
228
+
229
+ // atob/btoa Hook
230
+ const OriginalAtob = atob;
231
+ const OriginalBtoa = btoa;
232
+
233
+ window.atob = deepspider.native(function(data) {
234
+ const result = OriginalAtob.call(window, data);
235
+ deepspider.log('encoding', {
236
+ action: 'atob',
237
+ input: String(data).slice(0, 100),
238
+ output: result.slice(0, 100)
239
+ });
240
+ return result;
241
+ }, OriginalAtob);
242
+
243
+ window.btoa = deepspider.native(function(data) {
244
+ const result = OriginalBtoa.call(window, data);
245
+ deepspider.log('encoding', {
246
+ action: 'btoa',
247
+ input: String(data).slice(0, 100),
248
+ output: result.slice(0, 100)
249
+ });
250
+ return result;
251
+ }, OriginalBtoa);
252
+
253
+ // TextEncoder Hook
254
+ if (window.TextEncoder) {
255
+ const OriginalEncode = TextEncoder.prototype.encode;
256
+ TextEncoder.prototype.encode = deepspider.native(function(input) {
257
+ const result = OriginalEncode.call(this, input);
258
+ if (input && input.length >= 20) {
259
+ deepspider.log('encoding', {
260
+ action: 'TextEncoder.encode',
261
+ input: String(input).slice(0, 100),
262
+ len: result.length
263
+ });
264
+ }
265
+ return result;
266
+ }, OriginalEncode);
267
+ }
268
+
269
+ // TextDecoder Hook
270
+ if (window.TextDecoder) {
271
+ const OriginalDecode = TextDecoder.prototype.decode;
272
+ TextDecoder.prototype.decode = deepspider.native(function(input) {
273
+ const result = OriginalDecode.call(this, input);
274
+ if (result && result.length >= 20) {
275
+ deepspider.log('encoding', {
276
+ action: 'TextDecoder.decode',
277
+ output: result.slice(0, 100),
278
+ len: result.length
279
+ });
280
+ }
281
+ return result;
282
+ }, OriginalDecode);
283
+ }
284
+
285
+ console.log('[DeepSpider] Encoding Hook 已启用');
286
+ })();
287
+ `;
288
+ }
289
+
290
+ /**
291
+ * localStorage/sessionStorage Hook
292
+ */
293
+ function getStorageHooks() {
294
+ return `
295
+ // === Storage Hook ===
296
+ (function() {
297
+ const deepspider = window.__deepspider__;
298
+ if (!deepspider) return;
299
+
300
+ function hookStorage(storage, name) {
301
+ const origGet = storage.getItem.bind(storage);
302
+ const origSet = storage.setItem.bind(storage);
303
+
304
+ storage.getItem = deepspider.native(function(key) {
305
+ const value = origGet(key);
306
+ deepspider.log('storage', { action: 'get', storage: name, key: key, value: value?.slice(0, 100) });
307
+ return value;
308
+ }, origGet);
309
+
310
+ storage.setItem = deepspider.native(function(key, value) {
311
+ deepspider.log('storage', { action: 'set', storage: name, key: key, value: String(value).slice(0, 100) });
312
+ return origSet(key, value);
313
+ }, origSet);
314
+ }
315
+
316
+ if (window.localStorage) hookStorage(localStorage, 'local');
317
+ if (window.sessionStorage) hookStorage(sessionStorage, 'session');
318
+
319
+ console.log('[DeepSpider] Storage Hook 已启用');
320
+ })();
321
+ `;
322
+ }
323
+
324
+ /**
325
+ * WebSocket Hook
326
+ */
327
+ function getWebSocketHooks() {
328
+ return `
329
+ // === WebSocket Hook ===
330
+ (function() {
331
+ const deepspider = window.__deepspider__;
332
+ if (!deepspider) return;
333
+ if (!window.WebSocket) return;
334
+
335
+ const OriginalWS = WebSocket;
336
+
337
+ window.WebSocket = function(url, protocols) {
338
+ deepspider.log('websocket', { action: 'connect', url: url });
339
+ const ws = new OriginalWS(url, protocols);
340
+
341
+ const origSend = ws.send.bind(ws);
342
+ ws.send = deepspider.native(function(data) {
343
+ deepspider.log('websocket', {
344
+ action: 'send',
345
+ url: url,
346
+ data: String(data).slice(0, 200)
347
+ });
348
+ return origSend(data);
349
+ }, origSend);
350
+
351
+ ws.addEventListener('message', function(e) {
352
+ deepspider.log('websocket', {
353
+ action: 'message',
354
+ url: url,
355
+ data: String(e.data).slice(0, 200)
356
+ });
357
+ });
358
+
359
+ ws.addEventListener('close', function(e) {
360
+ deepspider.log('websocket', { action: 'close', url: url, code: e.code });
361
+ });
362
+
363
+ ws.addEventListener('error', function() {
364
+ deepspider.log('websocket', { action: 'error', url: url });
365
+ });
366
+
367
+ return ws;
368
+ };
369
+
370
+ window.WebSocket.prototype = OriginalWS.prototype;
371
+ window.WebSocket.CONNECTING = OriginalWS.CONNECTING;
372
+ window.WebSocket.OPEN = OriginalWS.OPEN;
373
+ window.WebSocket.CLOSING = OriginalWS.CLOSING;
374
+ window.WebSocket.CLOSED = OriginalWS.CLOSED;
375
+
376
+ console.log('[DeepSpider] WebSocket Hook 已启用');
377
+ })();
378
+ `;
379
+ }
380
+
381
+ /**
382
+ * Webpack 模块 Hook - 检测闭包内的加密库
383
+ */
384
+ function getWebpackHooks() {
385
+ return `
386
+ // === Webpack Hook ===
387
+ (function() {
388
+ const deepspider = window.__deepspider__;
389
+ if (!deepspider) return;
390
+
391
+ // 加密特征检测
392
+ const cryptoPatterns = [
393
+ { name: 'CryptoJS', pattern: /CryptoJS|crypto-js/i },
394
+ { name: 'MD5', pattern: /\\bmd5\\b/i },
395
+ { name: 'SHA', pattern: /\\bsha(1|256|512)\\b/i },
396
+ { name: 'AES', pattern: /\\baes\\b/i },
397
+ { name: 'RSA', pattern: /\\brsa\\b/i },
398
+ { name: 'Base64', pattern: /base64|btoa|atob/i }
399
+ ];
400
+
401
+ // Hook webpackJsonp
402
+ function hookWebpack() {
403
+ if (window.webpackJsonp && !window.webpackJsonp.__hooked__) {
404
+ const orig = window.webpackJsonp.push;
405
+ window.webpackJsonp.push = function(chunk) {
406
+ deepspider.log('env', { action: 'webpack.chunk', id: chunk[0] });
407
+ return orig.apply(this, arguments);
408
+ };
409
+ window.webpackJsonp.__hooked__ = true;
410
+ }
411
+ }
412
+
413
+ // 定期检查
414
+ const check = setInterval(hookWebpack, 100);
415
+ setTimeout(function() { clearInterval(check); }, 5000);
416
+
417
+ console.log('[DeepSpider] Webpack Hook 已启用');
418
+ })();
419
+ `;
420
+ }
421
+
422
+ /**
423
+ * eval/Function Hook - 捕获动态代码执行 + debugger 绕过
424
+ */
425
+ function getEvalHooks() {
426
+ return `
427
+ // === Eval/Function Hook ===
428
+ (function() {
429
+ const deepspider = window.__deepspider__;
430
+ if (!deepspider) return;
431
+
432
+ const debuggerPattern = /\\bdebugger\\b/;
433
+
434
+ // Hook eval
435
+ const OriginalEval = eval;
436
+ window.eval = deepspider.native(function(code) {
437
+ let codeStr = String(code);
438
+ // debugger 绕过
439
+ if (debuggerPattern.test(codeStr)) {
440
+ codeStr = codeStr.replace(/\\bdebugger\\b/g, '/* debugger bypassed */');
441
+ deepspider.log('debug', { action: 'bypass', type: 'eval' });
442
+ }
443
+ deepspider.log('eval', {
444
+ action: 'eval',
445
+ code: codeStr.slice(0, 500)
446
+ });
447
+ return OriginalEval.call(window, codeStr);
448
+ }, OriginalEval);
449
+
450
+ // Hook Function constructor
451
+ const OriginalFunction = Function;
452
+ window.Function = deepspider.native(function() {
453
+ const args = Array.from(arguments);
454
+ const lastIdx = args.length - 1;
455
+ // debugger 绕过
456
+ if (lastIdx >= 0 && typeof args[lastIdx] === 'string' && debuggerPattern.test(args[lastIdx])) {
457
+ args[lastIdx] = args[lastIdx].replace(/\\bdebugger\\b/g, '/* debugger bypassed */');
458
+ deepspider.log('debug', { action: 'bypass', type: 'Function' });
459
+ }
460
+ deepspider.log('eval', {
461
+ action: 'Function',
462
+ args: args.map(a => String(a).slice(0, 200))
463
+ });
464
+ return OriginalFunction.apply(this, args);
465
+ }, OriginalFunction);
466
+ window.Function.prototype = OriginalFunction.prototype;
467
+
468
+ // Hook setTimeout/setInterval 字符串参数
469
+ const OriginalSetTimeout = setTimeout;
470
+ const OriginalSetInterval = setInterval;
471
+
472
+ window.setTimeout = deepspider.native(function(handler, delay) {
473
+ if (typeof handler === 'string') {
474
+ // debugger 绕过
475
+ if (debuggerPattern.test(handler)) {
476
+ handler = handler.replace(/\\bdebugger\\b/g, '/* debugger bypassed */');
477
+ deepspider.log('debug', { action: 'bypass', type: 'setTimeout' });
478
+ }
479
+ deepspider.log('eval', {
480
+ action: 'setTimeout',
481
+ code: handler.slice(0, 500),
482
+ delay: delay
483
+ });
484
+ return OriginalSetTimeout.call(window, handler, delay);
485
+ }
486
+ return OriginalSetTimeout.apply(window, arguments);
487
+ }, OriginalSetTimeout);
488
+
489
+ window.setInterval = deepspider.native(function(handler, delay) {
490
+ if (typeof handler === 'string') {
491
+ // debugger 绕过
492
+ if (debuggerPattern.test(handler)) {
493
+ deepspider.log('debug', { action: 'bypass', type: 'setInterval' });
494
+ return OriginalSetInterval.call(window, function(){}, delay);
495
+ }
496
+ deepspider.log('eval', {
497
+ action: 'setInterval',
498
+ code: handler.slice(0, 500),
499
+ delay: delay
500
+ });
501
+ }
502
+ // 检测高频 debugger 函数
503
+ if (typeof handler === 'function' && delay < 500) {
504
+ const code = handler.toString();
505
+ if (debuggerPattern.test(code)) {
506
+ deepspider.log('debug', { action: 'bypass', type: 'setInterval-func' });
507
+ return OriginalSetInterval.call(window, function(){}, delay);
508
+ }
509
+ }
510
+ return OriginalSetInterval.apply(window, arguments);
511
+ }, OriginalSetInterval);
512
+
513
+ console.log('[DeepSpider] Eval/Function Hook 已启用');
514
+ })();
515
+ `;
516
+ }
517
+
518
+ /**
519
+ * 加密函数 Hook (CryptoJS + JSEncrypt + 国密 + Web Crypto API)
520
+ * 使用 Object.defineProperty 拦截全局变量赋值,在加密库加载时立即 Hook
521
+ */
522
+ function getCryptoHooks() {
523
+ return `
524
+ // === Crypto Hook ===
525
+ (function() {
526
+ const deepspider = window.__deepspider__;
527
+ if (!deepspider) return;
528
+
529
+ // Hook CryptoJS 的方法
530
+ function hookCryptoJS(CryptoJS) {
531
+ if (CryptoJS.__deepspider_hooked__) return;
532
+ CryptoJS.__deepspider_hooked__ = true;
533
+
534
+ // 对称加密算法
535
+ ['AES', 'DES', 'TripleDES', 'RC4', 'Rabbit'].forEach(cipher => {
536
+ if (!CryptoJS[cipher]) return;
537
+ ['encrypt', 'decrypt'].forEach(method => {
538
+ if (CryptoJS[cipher][method]) {
539
+ const original = CryptoJS[cipher][method];
540
+ CryptoJS[cipher][method] = deepspider.native(function(data, key, options) {
541
+ const entry = deepspider.log('crypto', {
542
+ algo: 'CryptoJS.' + cipher + '.' + method,
543
+ data: String(data).slice(0, 100),
544
+ keyLen: key ? String(key).length : 0,
545
+ options: options ? Object.keys(options) : []
546
+ });
547
+ deepspider.linkCrypto(entry);
548
+ return original.apply(this, arguments);
549
+ }, original);
550
+ }
551
+ });
552
+ });
553
+
554
+ // 哈希算法
555
+ ['MD5', 'SHA1', 'SHA256', 'SHA512', 'SHA3', 'RIPEMD160'].forEach(algo => {
556
+ if (CryptoJS[algo]) {
557
+ const original = CryptoJS[algo];
558
+ CryptoJS[algo] = deepspider.native(function() {
559
+ const entry = deepspider.log('crypto', {
560
+ algo: 'CryptoJS.' + algo,
561
+ inputLen: arguments[0] ? String(arguments[0]).length : 0
562
+ });
563
+ deepspider.linkCrypto(entry);
564
+ return original.apply(this, arguments);
565
+ }, original);
566
+ }
567
+ });
568
+
569
+ // HMAC 算法
570
+ ['HmacMD5', 'HmacSHA1', 'HmacSHA256', 'HmacSHA512'].forEach(algo => {
571
+ if (CryptoJS[algo]) {
572
+ const original = CryptoJS[algo];
573
+ CryptoJS[algo] = deepspider.native(function() {
574
+ const entry = deepspider.log('crypto', {
575
+ algo: 'CryptoJS.' + algo,
576
+ inputLen: arguments[0] ? String(arguments[0]).length : 0
577
+ });
578
+ deepspider.linkCrypto(entry);
579
+ return original.apply(this, arguments);
580
+ }, original);
581
+ }
582
+ });
583
+
584
+ console.log('[DeepSpider] CryptoJS Hook 已启用');
585
+ }
586
+
587
+ // Hook JSEncrypt
588
+ function hookJSEncrypt(JSEncrypt) {
589
+ if (JSEncrypt.__deepspider_hooked__) return;
590
+ JSEncrypt.__deepspider_hooked__ = true;
591
+
592
+ const proto = JSEncrypt.prototype;
593
+ if (proto.encrypt) {
594
+ const origEnc = proto.encrypt;
595
+ proto.encrypt = deepspider.native(function(data) {
596
+ const entry = deepspider.log('crypto', { algo: 'RSA.encrypt', data: String(data).slice(0, 100) });
597
+ deepspider.linkCrypto(entry);
598
+ return origEnc.apply(this, arguments);
599
+ }, origEnc);
600
+ }
601
+ console.log('[DeepSpider] RSA Hook 已启用');
602
+ }
603
+
604
+ // Hook SM2
605
+ function hookSM2(sm2) {
606
+ if (sm2.__deepspider_hooked__) return;
607
+ sm2.__deepspider_hooked__ = true;
608
+
609
+ if (sm2.doEncrypt) {
610
+ const origEnc = sm2.doEncrypt;
611
+ sm2.doEncrypt = deepspider.native(function(msg, pubKey) {
612
+ const entry = deepspider.log('crypto', { algo: 'SM2.encrypt', msg: String(msg).slice(0, 100) });
613
+ deepspider.linkCrypto(entry);
614
+ return origEnc.apply(this, arguments);
615
+ }, origEnc);
616
+ console.log('[DeepSpider] SM2 Hook 已启用');
617
+ }
618
+ }
619
+
620
+ // Hook node-forge
621
+ function hookForge(forge) {
622
+ if (forge.__deepspider_hooked__) return;
623
+ forge.__deepspider_hooked__ = true;
624
+
625
+ // MD/SHA
626
+ ['md5', 'sha1', 'sha256', 'sha512'].forEach(function(algo) {
627
+ if (forge.md && forge.md[algo]) {
628
+ const orig = forge.md[algo].create;
629
+ forge.md[algo].create = function() {
630
+ const md = orig.apply(this, arguments);
631
+ const origUpdate = md.update;
632
+ md.update = function(data) {
633
+ deepspider.log('crypto', { algo: 'forge.' + algo, inputLen: data?.length });
634
+ return origUpdate.apply(this, arguments);
635
+ };
636
+ return md;
637
+ };
638
+ }
639
+ });
640
+
641
+ // AES
642
+ if (forge.cipher) {
643
+ const origCreate = forge.cipher.createCipher;
644
+ if (origCreate) {
645
+ forge.cipher.createCipher = function(algo, key) {
646
+ deepspider.log('crypto', { algo: 'forge.cipher.' + algo, keyLen: key?.length });
647
+ return origCreate.apply(this, arguments);
648
+ };
649
+ }
650
+ }
651
+ console.log('[DeepSpider] Forge Hook 已启用');
652
+ }
653
+
654
+ // Hook jsrsasign
655
+ function hookJsrsasign(KJUR) {
656
+ if (KJUR.__deepspider_hooked__) return;
657
+ KJUR.__deepspider_hooked__ = true;
658
+
659
+ if (KJUR.crypto && KJUR.crypto.Signature) {
660
+ const origSign = KJUR.crypto.Signature.prototype.sign;
661
+ if (origSign) {
662
+ KJUR.crypto.Signature.prototype.sign = function() {
663
+ deepspider.log('crypto', { algo: 'jsrsasign.sign' });
664
+ return origSign.apply(this, arguments);
665
+ };
666
+ }
667
+ }
668
+ console.log('[DeepSpider] jsrsasign Hook 已启用');
669
+ }
670
+
671
+ // 使用 defineProperty 拦截全局变量赋值
672
+ function watchGlobal(name, hookFn) {
673
+ let value = window[name];
674
+ if (value) {
675
+ hookFn(value);
676
+ return;
677
+ }
678
+
679
+ try {
680
+ Object.defineProperty(window, name, {
681
+ configurable: true,
682
+ enumerable: true,
683
+ get: function() { return value; },
684
+ set: function(newVal) {
685
+ value = newVal;
686
+ if (newVal) {
687
+ hookFn(newVal);
688
+ }
689
+ }
690
+ });
691
+ } catch (e) {
692
+ // 如果 defineProperty 失败,回退到轮询
693
+ const check = setInterval(function() {
694
+ if (window[name]) {
695
+ clearInterval(check);
696
+ hookFn(window[name]);
697
+ }
698
+ }, 50);
699
+ setTimeout(function() { clearInterval(check); }, 10000);
700
+ }
701
+ }
702
+
703
+ watchGlobal('CryptoJS', hookCryptoJS);
704
+ watchGlobal('JSEncrypt', hookJSEncrypt);
705
+ watchGlobal('sm2', hookSM2);
706
+ watchGlobal('forge', hookForge);
707
+ watchGlobal('KJUR', hookJsrsasign);
708
+
709
+ // Hook Web Crypto API (原生加密)
710
+ if (window.crypto && window.crypto.subtle) {
711
+ const subtle = window.crypto.subtle;
712
+ ['encrypt', 'decrypt', 'sign', 'verify', 'digest'].forEach(function(method) {
713
+ if (subtle[method]) {
714
+ const original = subtle[method].bind(subtle);
715
+ subtle[method] = deepspider.native(function(algorithm) {
716
+ const algoName = typeof algorithm === 'string' ? algorithm : algorithm.name;
717
+ deepspider.log('crypto', {
718
+ algo: 'WebCrypto.' + method,
719
+ algorithm: algoName
720
+ });
721
+ return original.apply(subtle, arguments);
722
+ }, original);
723
+ }
724
+ });
725
+ console.log('[DeepSpider] Web Crypto API Hook 已启用');
726
+ }
727
+ })();
728
+ `;
729
+ }
730
+
731
+ /**
732
+ * Canvas 指纹检测 Hook
733
+ */
734
+ function getCanvasHooks() {
735
+ return `
736
+ // === Canvas Hook ===
737
+ (function() {
738
+ const deepspider = window.__deepspider__;
739
+ if (!deepspider) return;
740
+
741
+ // toDataURL Hook
742
+ const origToDataURL = HTMLCanvasElement.prototype.toDataURL;
743
+ HTMLCanvasElement.prototype.toDataURL = deepspider.native(function() {
744
+ const result = origToDataURL.apply(this, arguments);
745
+ deepspider.log('env', {
746
+ action: 'canvas.toDataURL',
747
+ width: this.width,
748
+ height: this.height,
749
+ hash: result.slice(0, 50)
750
+ });
751
+ return result;
752
+ }, origToDataURL);
753
+
754
+ // getImageData Hook
755
+ const origGetImageData = CanvasRenderingContext2D.prototype.getImageData;
756
+ CanvasRenderingContext2D.prototype.getImageData = deepspider.native(function(x, y, w, h) {
757
+ const result = origGetImageData.apply(this, arguments);
758
+ deepspider.log('env', {
759
+ action: 'canvas.getImageData',
760
+ x: x, y: y, w: w, h: h
761
+ });
762
+ return result;
763
+ }, origGetImageData);
764
+
765
+ console.log('[DeepSpider] Canvas Hook 已启用');
766
+ })();
767
+ `;
768
+ }
769
+
770
+ /**
771
+ * Navigator/Screen 环境检测 Hook
772
+ */
773
+ function getNavigatorHooks() {
774
+ return `
775
+ // === Navigator Hook ===
776
+ (function() {
777
+ const deepspider = window.__deepspider__;
778
+ if (!deepspider) return;
779
+
780
+ // 监控 navigator 属性访问
781
+ const navProps = ['userAgent', 'platform', 'language', 'languages', 'hardwareConcurrency', 'deviceMemory', 'webdriver'];
782
+ navProps.forEach(function(prop) {
783
+ const desc = Object.getOwnPropertyDescriptor(Navigator.prototype, prop);
784
+ if (desc && desc.get) {
785
+ const origGet = desc.get;
786
+ Object.defineProperty(Navigator.prototype, prop, {
787
+ get: function() {
788
+ const val = origGet.call(this);
789
+ deepspider.log('env', { action: 'navigator.' + prop, value: String(val).slice(0, 100) });
790
+ return val;
791
+ },
792
+ configurable: true
793
+ });
794
+ }
795
+ });
796
+
797
+ console.log('[DeepSpider] Navigator Hook 已启用');
798
+ })();
799
+ `;
800
+ }
801
+
802
+ /**
803
+ * DOM 查询监控
804
+ */
805
+ function getDOMHooks() {
806
+ return `
807
+ // === DOM Hook ===
808
+ (function() {
809
+ const deepspider = window.__deepspider__;
810
+ if (!deepspider) return;
811
+
812
+ const methods = [
813
+ { obj: Document.prototype, name: 'getElementById' },
814
+ { obj: Document.prototype, name: 'getElementsByClassName' },
815
+ { obj: Document.prototype, name: 'getElementsByTagName' },
816
+ { obj: Document.prototype, name: 'querySelector' },
817
+ { obj: Document.prototype, name: 'querySelectorAll' },
818
+ { obj: Element.prototype, name: 'querySelector' },
819
+ { obj: Element.prototype, name: 'querySelectorAll' }
820
+ ];
821
+
822
+ methods.forEach(function(m) {
823
+ const original = m.obj[m.name];
824
+ if (!original) return;
825
+
826
+ m.obj[m.name] = deepspider.native(function() {
827
+ const selector = arguments[0];
828
+ const result = original.apply(this, arguments);
829
+ deepspider.log('dom', {
830
+ action: m.name,
831
+ selector: String(selector),
832
+ found: result ? (result.length !== undefined ? result.length : 1) : 0
833
+ });
834
+ return result;
835
+ }, original);
836
+ });
837
+
838
+ console.log('[DeepSpider] DOM Hook 已启用');
839
+ })();
840
+ `;
841
+ }
842
+
843
+ /**
844
+ * Proxy/Reflect Hook - 监控现代混淆常用的 Proxy 操作
845
+ */
846
+ function getProxyHooks() {
847
+ return `
848
+ // === Proxy Hook ===
849
+ (function() {
850
+ const deepspider = window.__deepspider__;
851
+ if (!deepspider) return;
852
+
853
+ const OriginalProxy = Proxy;
854
+
855
+ // 创建 trap 包装器(使用 IIFE 避免闭包问题)
856
+ function wrapTrap(trapName, trapFn) {
857
+ return function() {
858
+ deepspider.log('env', {
859
+ action: 'Proxy.' + trapName,
860
+ args: Array.from(arguments).slice(0, 2).map(function(a) {
861
+ return String(a).slice(0, 50);
862
+ })
863
+ });
864
+ return trapFn.apply(this, arguments);
865
+ };
866
+ }
867
+
868
+ window.Proxy = deepspider.native(function(target, handler) {
869
+ deepspider.log('env', {
870
+ action: 'Proxy.create',
871
+ targetType: typeof target,
872
+ traps: handler ? Object.keys(handler) : []
873
+ });
874
+
875
+ // 包装 handler
876
+ const wrappedHandler = {};
877
+ if (handler) {
878
+ for (const trap in handler) {
879
+ if (typeof handler[trap] === 'function') {
880
+ wrappedHandler[trap] = wrapTrap(trap, handler[trap]);
881
+ } else {
882
+ wrappedHandler[trap] = handler[trap];
883
+ }
884
+ }
885
+ }
886
+
887
+ return new OriginalProxy(target, wrappedHandler);
888
+ }, OriginalProxy);
889
+
890
+ // 保留静态方法
891
+ window.Proxy.revocable = OriginalProxy.revocable;
892
+
893
+ console.log('[DeepSpider] Proxy Hook 已启用');
894
+ })();
895
+ `;
896
+ }
897
+
898
+ /**
899
+ * Error.stack 保护 - 隐藏 Hook 相关的调用栈
900
+ */
901
+ function getErrorStackHooks() {
902
+ return `
903
+ // === Error Stack Hook ===
904
+ (function() {
905
+ const deepspider = window.__deepspider__;
906
+ if (!deepspider) return;
907
+
908
+ const stackDesc = Object.getOwnPropertyDescriptor(Error.prototype, 'stack');
909
+
910
+ if (stackDesc && stackDesc.get) {
911
+ const origGet = stackDesc.get;
912
+ Object.defineProperty(Error.prototype, 'stack', {
913
+ get: function() {
914
+ let stack = origGet.call(this);
915
+ if (stack && typeof stack === 'string') {
916
+ // 过滤掉 DeepSpider 相关的栈帧
917
+ stack = stack.split('\\n').filter(function(line) {
918
+ return !/__deepspider__|DeepSpider|deepspider\\.native/.test(line);
919
+ }).join('\\n');
920
+ }
921
+ return stack;
922
+ },
923
+ configurable: true
924
+ });
925
+ }
926
+
927
+ console.log('[DeepSpider] Error Stack Hook 已启用');
928
+ })();
929
+ `;
930
+ }
931
+
932
+ export default getDefaultHookScript;