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,618 @@
1
+ /**
2
+ * DeepSpider - Hook 基础框架
3
+ * 统一的 Hook 反检测 + 日志管理
4
+ */
5
+
6
+ export class HookBase {
7
+ /**
8
+ * 获取 Hook 基础代码
9
+ * 包含:反检测、统一日志管理
10
+ */
11
+ static getBaseCode() {
12
+ return `
13
+ // === DeepSpider Hook Base ===
14
+ (function() {
15
+ if (window.__deepspider__) return;
16
+
17
+ const originalToString = Function.prototype.toString;
18
+ const hookedFns = new WeakMap();
19
+
20
+ // 统一日志存储
21
+ const logs = {
22
+ xhr: [],
23
+ fetch: [],
24
+ cookie: [],
25
+ crypto: [],
26
+ async: [],
27
+ timer: [],
28
+ env: [],
29
+ debug: [],
30
+ trace: [],
31
+ json: [],
32
+ eval: [],
33
+ dom: [],
34
+ storage: [],
35
+ encoding: [],
36
+ websocket: []
37
+ };
38
+
39
+ // 日志计数器(用于限制)
40
+ const logCounts = {};
41
+ const LOG_LIMIT = 50; // 每个 API 默认限制 50 条
42
+
43
+ // Hook 配置
44
+ const config = {
45
+ json: true,
46
+ eval: true,
47
+ crypto: true,
48
+ cookie: true,
49
+ xhr: true,
50
+ fetch: true,
51
+ dom: false, // DOM 查询默认关闭(太多)
52
+ storage: true,
53
+ encoding: true,
54
+ websocket: true,
55
+ env: false, // Navigator/Canvas 默认关闭(太多)
56
+ logLimit: LOG_LIMIT,
57
+ // 性能优化配置
58
+ captureStack: true, // 是否记录调用栈(关闭可提升性能)
59
+ stackDepth: 5, // 调用栈深度限制
60
+ minLogLength: 20, // 最小记录长度(过滤小数据)
61
+ // 反检测配置
62
+ protectDescriptor: true, // 保护 getOwnPropertyDescriptor
63
+ protectKeys: true, // 保护 Object.keys/getOwnPropertyNames
64
+ // 输出控制
65
+ silent: false, // 静默模式(不输出 console.log)
66
+ logToConsole: true // 是否输出到控制台
67
+ };
68
+
69
+ // 保存原始方法(用于反检测)
70
+ const originals = {
71
+ getOwnPropertyDescriptor: Object.getOwnPropertyDescriptor,
72
+ getOwnPropertyNames: Object.getOwnPropertyNames,
73
+ keys: Object.keys,
74
+ defineProperty: Object.defineProperty
75
+ };
76
+
77
+ // Hook 注册表(用于动态管理)
78
+ const hookRegistry = {
79
+ // name -> { enabled, restore, description }
80
+ };
81
+
82
+ // 保存的原始函数(用于恢复)
83
+ const savedOriginals = new Map();
84
+
85
+ // 性能统计
86
+ const perfStats = {};
87
+
88
+ // 请求上下文(用于关联加密和请求)
89
+ let requestContext = null;
90
+ let requestIdCounter = 0;
91
+
92
+ // DeepSpider 全局对象
93
+ window.__deepspider__ = {
94
+ version: '1.0.0',
95
+
96
+ // === 安全 Hook 函数 ===
97
+ hook: function(obj, prop, handler) {
98
+ if (!obj || typeof obj[prop] !== 'function') return false;
99
+
100
+ const original = obj[prop];
101
+ const origStr = originalToString.call(original);
102
+
103
+ const hooked = function() {
104
+ try {
105
+ return handler.call(this, original, this, arguments);
106
+ } catch (e) {
107
+ return original.apply(this, arguments);
108
+ }
109
+ };
110
+
111
+ // 保留属性
112
+ try {
113
+ Object.defineProperties(hooked, {
114
+ length: { value: original.length },
115
+ name: { value: original.name },
116
+ prototype: { value: original.prototype }
117
+ });
118
+ } catch(e) {}
119
+
120
+ hookedFns.set(hooked, origStr);
121
+ obj[prop] = hooked;
122
+ return true;
123
+ },
124
+
125
+ // === 包装函数(让 Hook 函数看起来像原生) ===
126
+ native: function(hookFunc, originalFunc) {
127
+ try {
128
+ Object.defineProperty(hookFunc, 'name', { value: originalFunc.name });
129
+ Object.defineProperty(hookFunc, 'length', { value: originalFunc.length });
130
+ } catch (e) {}
131
+ hookedFns.set(hookFunc, originalToString.call(originalFunc));
132
+ return hookFunc;
133
+ },
134
+
135
+ // === 统一日志管理 ===
136
+ log: function(type, data) {
137
+ // 检查 Hook 是否启用
138
+ if (config[type] === false) return null;
139
+
140
+ if (!logs[type]) logs[type] = [];
141
+
142
+ // 日志限制检查
143
+ const countKey = type + ':' + (data.action || data.algo || 'default');
144
+ logCounts[countKey] = (logCounts[countKey] || 0) + 1;
145
+
146
+ if (logCounts[countKey] > config.logLimit) {
147
+ if (logCounts[countKey] === config.logLimit + 1) {
148
+ console.warn('[DeepSpider] ' + countKey + ' 日志已达上限 ' + config.logLimit + ',后续调用不再记录');
149
+ }
150
+ return null;
151
+ }
152
+
153
+ // 性能优化:可配置是否记录调用栈
154
+ let stack = null;
155
+ if (config.captureStack) {
156
+ const err = new Error();
157
+ stack = err.stack;
158
+ }
159
+
160
+ const entry = {
161
+ ...data,
162
+ timestamp: Date.now(),
163
+ stack: stack,
164
+ requestId: requestContext?.id || null
165
+ };
166
+
167
+ // 限制每类日志最大数量,防止内存泄漏
168
+ if (logs[type].length >= 1000) {
169
+ logs[type].shift();
170
+ }
171
+ logs[type].push(entry);
172
+
173
+ // 颜色日志输出 (借鉴 v_jstools)
174
+ if (config.logToConsole && !config.silent) {
175
+ const colors = {
176
+ get: 'color: #4CAF50', // 绿色
177
+ set: 'color: #FF9800', // 橙色
178
+ func: 'color: #2196F3', // 蓝色
179
+ crypto: 'color: #E91E63', // 粉色
180
+ xhr: 'color: #9C27B0', // 紫色
181
+ fetch: 'color: #9C27B0',
182
+ };
183
+ const color = colors[data.action] || colors[type] || 'color: #666';
184
+ console.log('%c[DeepSpider:' + type + ']', color, data.action || '', data);
185
+ }
186
+ return entry;
187
+ },
188
+
189
+ // === 调用栈解析 ===
190
+ parseStack: function(stack, depth) {
191
+ if (!stack) return [];
192
+ const maxDepth = depth || config.stackDepth || 5;
193
+ // 过滤框架代码的关键词
194
+ const frameworkPatterns = [
195
+ /react|vue|angular|jquery|lodash|axios/i,
196
+ /node_modules/,
197
+ /webpack/,
198
+ /__deepspider__/
199
+ ];
200
+
201
+ return stack.split('\\n').slice(2).map(function(line) {
202
+ const match = line.match(/at\\s+(.+?)\\s+\\((.+?):(\\d+):(\\d+)\\)/) ||
203
+ line.match(/at\\s+(.+?):(\\d+):(\\d+)/);
204
+ if (match) {
205
+ return {
206
+ func: match[1] || 'anonymous',
207
+ file: match[2] || match[1],
208
+ line: parseInt(match[3] || match[2]),
209
+ col: parseInt(match[4] || match[3])
210
+ };
211
+ }
212
+ return { raw: line.trim() };
213
+ }).filter(function(f) {
214
+ if (!f.func && !f.raw) return false;
215
+ const str = f.file || f.raw || '';
216
+ return !frameworkPatterns.some(p => p.test(str));
217
+ }).slice(0, maxDepth);
218
+ },
219
+
220
+ // 获取简化的调用位置(只返回第一个业务代码位置)
221
+ getCaller: function() {
222
+ const stack = this.parseStack(new Error().stack);
223
+ return stack[0] || null;
224
+ },
225
+
226
+ // === 请求上下文管理 ===
227
+ startRequest: function(url, method) {
228
+ requestIdCounter++;
229
+ requestContext = {
230
+ id: requestIdCounter,
231
+ url: url,
232
+ method: method,
233
+ startTime: Date.now(),
234
+ cryptoCalls: [],
235
+ cookieOps: []
236
+ };
237
+ return requestContext.id;
238
+ },
239
+
240
+ endRequest: function() {
241
+ const ctx = requestContext;
242
+ requestContext = null;
243
+ return ctx;
244
+ },
245
+
246
+ getRequestContext: function() {
247
+ return requestContext;
248
+ },
249
+
250
+ // === 关联加密调用到当前请求 ===
251
+ linkCrypto: function(cryptoEntry) {
252
+ if (requestContext) {
253
+ requestContext.cryptoCalls.push(cryptoEntry);
254
+ }
255
+ },
256
+
257
+ getLogs: function(type) {
258
+ if (type) {
259
+ return JSON.stringify(logs[type] || []);
260
+ }
261
+ return JSON.stringify(logs);
262
+ },
263
+
264
+ clearLogs: function(type) {
265
+ if (type) {
266
+ if (logs[type]) logs[type].length = 0;
267
+ } else {
268
+ for (const key in logs) {
269
+ logs[key].length = 0;
270
+ }
271
+ }
272
+ },
273
+
274
+ // === 获取所有日志(合并) ===
275
+ getAllLogs: function() {
276
+ const all = [];
277
+ for (const type in logs) {
278
+ for (const entry of logs[type]) {
279
+ all.push({ _type: type, ...entry });
280
+ }
281
+ }
282
+ all.sort((a, b) => a.timestamp - b.timestamp);
283
+ return JSON.stringify(all);
284
+ },
285
+
286
+ // === 配置管理 ===
287
+ getConfig: function() {
288
+ return JSON.parse(JSON.stringify(config));
289
+ },
290
+
291
+ setConfig: function(key, value) {
292
+ if (key in config) {
293
+ config[key] = value;
294
+ console.log('[DeepSpider] 配置已更新:', key, '=', value);
295
+ return true;
296
+ }
297
+ return false;
298
+ },
299
+
300
+ // 重置日志计数器
301
+ resetLogCounts: function() {
302
+ for (const key in logCounts) {
303
+ delete logCounts[key];
304
+ }
305
+ console.log('[DeepSpider] 日志计数器已重置');
306
+ },
307
+
308
+ // 记录性能
309
+ recordPerf: function(name, duration) {
310
+ if (!perfStats[name]) {
311
+ perfStats[name] = { count: 0, total: 0, max: 0 };
312
+ }
313
+ perfStats[name].count++;
314
+ perfStats[name].total += duration;
315
+ if (duration > perfStats[name].max) {
316
+ perfStats[name].max = duration;
317
+ }
318
+ },
319
+
320
+ // 获取性能统计
321
+ getPerf: function() {
322
+ const result = {};
323
+ for (const name in perfStats) {
324
+ const s = perfStats[name];
325
+ result[name] = {
326
+ count: s.count,
327
+ avg: (s.total / s.count).toFixed(2) + 'ms',
328
+ max: s.max.toFixed(2) + 'ms'
329
+ };
330
+ }
331
+ return result;
332
+ },
333
+
334
+ // 搜索日志
335
+ searchLogs: function(keyword) {
336
+ const results = [];
337
+ const kw = String(keyword).toLowerCase();
338
+ for (const type in logs) {
339
+ for (const entry of logs[type]) {
340
+ const str = JSON.stringify(entry).toLowerCase();
341
+ if (str.includes(kw)) {
342
+ results.push({ _type: type, ...entry });
343
+ }
344
+ }
345
+ }
346
+ return JSON.stringify(results);
347
+ },
348
+
349
+ // 追踪值来源
350
+ traceValue: function(value) {
351
+ const results = [];
352
+ const val = String(value);
353
+ for (const type in logs) {
354
+ for (const entry of logs[type]) {
355
+ const str = JSON.stringify(entry);
356
+ if (str.includes(val)) {
357
+ results.push({
358
+ _type: type,
359
+ action: entry.action || entry.algo,
360
+ timestamp: entry.timestamp,
361
+ stack: this.parseStack(entry.stack).slice(0, 3)
362
+ });
363
+ }
364
+ }
365
+ }
366
+ return JSON.stringify(results);
367
+ },
368
+
369
+ // 自动关联请求参数与加密结果
370
+ correlateParams: function(requestBody) {
371
+ if (!requestBody) return [];
372
+ const matches = [];
373
+ const bodyStr = String(requestBody);
374
+
375
+ // 提取请求中的参数值
376
+ const params = [];
377
+ try {
378
+ // URL encoded
379
+ bodyStr.split('&').forEach(function(p) {
380
+ const kv = p.split('=');
381
+ if (kv[1] && kv[1].length > 8) params.push({ key: kv[0], value: decodeURIComponent(kv[1]) });
382
+ });
383
+ } catch(e) {}
384
+ try {
385
+ // JSON
386
+ const json = JSON.parse(bodyStr);
387
+ Object.keys(json).forEach(function(k) {
388
+ const v = json[k];
389
+ if (typeof v === 'string' && v.length > 8) params.push({ key: k, value: v });
390
+ });
391
+ } catch(e) {}
392
+
393
+ // 在加密日志中查找匹配
394
+ params.forEach(function(p) {
395
+ for (const entry of logs.crypto || []) {
396
+ const entryStr = JSON.stringify(entry);
397
+ if (entryStr.includes(p.value.slice(0, 20))) {
398
+ matches.push({
399
+ param: p.key,
400
+ value: p.value.slice(0, 50),
401
+ crypto: entry.algo,
402
+ timestamp: entry.timestamp
403
+ });
404
+ }
405
+ }
406
+ });
407
+ return matches;
408
+ },
409
+
410
+ // 快捷 API: 获取最近的加密调用
411
+ getRecentCrypto: function(n) {
412
+ const arr = logs.crypto || [];
413
+ return arr.slice(-Math.min(n || 10, arr.length));
414
+ },
415
+
416
+ // 快捷 API: 获取最近的请求
417
+ getRecentRequests: function(n) {
418
+ const all = (logs.xhr || []).concat(logs.fetch || []);
419
+ all.sort((a, b) => b.timestamp - a.timestamp);
420
+ return all.slice(0, n || 10);
421
+ },
422
+
423
+ // 快捷 API: 导出日志为 JSON 文件
424
+ exportLogs: function() {
425
+ const data = JSON.stringify(logs, null, 2);
426
+ const blob = new Blob([data], { type: 'application/json' });
427
+ const url = URL.createObjectURL(blob);
428
+ const a = document.createElement('a');
429
+ a.href = url;
430
+ a.download = 'deepspider-logs-' + Date.now() + '.json';
431
+ a.click();
432
+ URL.revokeObjectURL(url);
433
+ },
434
+
435
+ // === Hook 动态管理 API ===
436
+
437
+ // 注册 Hook
438
+ registerHook: function(name, options) {
439
+ if (hookRegistry[name]) {
440
+ console.warn('[DeepSpider] Hook 已存在:', name);
441
+ return false;
442
+ }
443
+ hookRegistry[name] = {
444
+ enabled: false,
445
+ description: options.description || '',
446
+ setup: options.setup,
447
+ restore: options.restore || null
448
+ };
449
+ return true;
450
+ },
451
+
452
+ // 启用 Hook
453
+ enableHook: function(name) {
454
+ // 内置 Hook 通过 config 控制
455
+ if (name in config && typeof config[name] === 'boolean') {
456
+ config[name] = true;
457
+ console.log('[DeepSpider] Hook 已启用:', name);
458
+ return true;
459
+ }
460
+ // 自定义 Hook
461
+ const hook = hookRegistry[name];
462
+ if (!hook) {
463
+ console.warn('[DeepSpider] Hook 不存在:', name);
464
+ return false;
465
+ }
466
+ if (hook.enabled) return true;
467
+ try {
468
+ if (hook.setup) hook.setup();
469
+ hook.enabled = true;
470
+ console.log('[DeepSpider] Hook 已启用:', name);
471
+ return true;
472
+ } catch (e) {
473
+ console.error('[DeepSpider] 启用 Hook 失败:', name, e);
474
+ return false;
475
+ }
476
+ },
477
+
478
+ // 禁用 Hook
479
+ disableHook: function(name) {
480
+ // 内置 Hook 通过 config 控制
481
+ if (name in config && typeof config[name] === 'boolean') {
482
+ config[name] = false;
483
+ console.log('[DeepSpider] Hook 已禁用:', name);
484
+ return true;
485
+ }
486
+ // 自定义 Hook
487
+ const hook = hookRegistry[name];
488
+ if (!hook) return false;
489
+ if (!hook.enabled) return true;
490
+ try {
491
+ if (hook.restore) hook.restore();
492
+ hook.enabled = false;
493
+ console.log('[DeepSpider] Hook 已禁用:', name);
494
+ return true;
495
+ } catch (e) {
496
+ console.error('[DeepSpider] 禁用 Hook 失败:', name, e);
497
+ return false;
498
+ }
499
+ },
500
+
501
+ // 列出所有 Hook(内置 + 自定义)
502
+ listHooks: function() {
503
+ const list = [];
504
+ // 内置 Hook(通过 config 控制)
505
+ const builtinHooks = [
506
+ { name: 'xhr', description: 'XHR 请求监控' },
507
+ { name: 'fetch', description: 'Fetch 请求监控' },
508
+ { name: 'cookie', description: 'Cookie 读写监控' },
509
+ { name: 'json', description: 'JSON.parse/stringify 监控' },
510
+ { name: 'eval', description: 'eval/Function 动态执行监控' },
511
+ { name: 'crypto', description: '加密库调用监控' },
512
+ { name: 'dom', description: 'DOM 查询监控' },
513
+ { name: 'storage', description: 'localStorage/sessionStorage 监控' },
514
+ { name: 'encoding', description: 'Base64/TextEncoder 监控' },
515
+ { name: 'websocket', description: 'WebSocket 通信监控' },
516
+ { name: 'env', description: 'Navigator/Canvas 环境检测监控' }
517
+ ];
518
+ builtinHooks.forEach(function(h) {
519
+ list.push({
520
+ name: h.name,
521
+ enabled: config[h.name] !== false,
522
+ description: h.description,
523
+ builtin: true
524
+ });
525
+ });
526
+ // 自定义 Hook
527
+ for (const name in hookRegistry) {
528
+ list.push({
529
+ name: name,
530
+ enabled: hookRegistry[name].enabled,
531
+ description: hookRegistry[name].description,
532
+ builtin: false
533
+ });
534
+ }
535
+ return list;
536
+ },
537
+
538
+ // 注入自定义 Hook 代码
539
+ injectHook: function(code) {
540
+ try {
541
+ const fn = new Function(code);
542
+ fn();
543
+ return { success: true };
544
+ } catch (e) {
545
+ return { success: false, error: e.message };
546
+ }
547
+ },
548
+
549
+ // 批量启用/禁用
550
+ setHooks: function(names, enabled) {
551
+ const results = {};
552
+ names.forEach(function(name) {
553
+ results[name] = enabled
554
+ ? window.__deepspider__.enableHook(name)
555
+ : window.__deepspider__.disableHook(name);
556
+ });
557
+ return results;
558
+ }
559
+ };
560
+
561
+ // 绕过 toString 检测
562
+ Function.prototype.toString = function() {
563
+ return hookedFns.has(this) ? hookedFns.get(this) : originalToString.call(this);
564
+ };
565
+ hookedFns.set(Function.prototype.toString, originalToString.call(originalToString));
566
+
567
+ // === 增强反检测:保护 getOwnPropertyDescriptor ===
568
+ if (config.protectDescriptor) {
569
+ const origGetDesc = originals.getOwnPropertyDescriptor;
570
+ Object.getOwnPropertyDescriptor = function(obj, prop) {
571
+ const desc = origGetDesc.call(Object, obj, prop);
572
+ // 如果是被 Hook 的函数,返回伪造的描述符
573
+ if (desc && typeof desc.value === 'function' && hookedFns.has(desc.value)) {
574
+ return {
575
+ value: desc.value,
576
+ writable: true,
577
+ enumerable: false,
578
+ configurable: true
579
+ };
580
+ }
581
+ return desc;
582
+ };
583
+ hookedFns.set(Object.getOwnPropertyDescriptor, originalToString.call(origGetDesc));
584
+ }
585
+
586
+ // === 增强反检测:保护 Object.keys/getOwnPropertyNames ===
587
+ if (config.protectKeys) {
588
+ // 隐藏 __deepspider__ 等内部属性
589
+ const hiddenProps = ['__deepspider__', '__deepspider_hooked__'];
590
+
591
+ const origKeys = originals.keys;
592
+ Object.keys = function(obj) {
593
+ const keys = origKeys.call(Object, obj);
594
+ if (obj === window) {
595
+ return keys.filter(k => !hiddenProps.includes(k));
596
+ }
597
+ return keys;
598
+ };
599
+ hookedFns.set(Object.keys, originalToString.call(origKeys));
600
+
601
+ const origNames = originals.getOwnPropertyNames;
602
+ Object.getOwnPropertyNames = function(obj) {
603
+ const names = origNames.call(Object, obj);
604
+ if (obj === window) {
605
+ return names.filter(n => !hiddenProps.includes(n));
606
+ }
607
+ return names;
608
+ };
609
+ hookedFns.set(Object.getOwnPropertyNames, originalToString.call(origNames));
610
+ }
611
+
612
+ console.log('[DeepSpider] Hook 基础框架已加载');
613
+ })();
614
+ `;
615
+ }
616
+ }
617
+
618
+ export default HookBase;