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,205 @@
1
+ /**
2
+ * DeepSpider - 加密函数 Hook
3
+ * 运行时捕获加密函数的参数和密钥
4
+ */
5
+
6
+ import { HookBase } from './HookBase.js';
7
+
8
+ export class CryptoHook {
9
+ /**
10
+ * 生成 CryptoJS Hook 代码
11
+ */
12
+ generateCryptoJSHookCode() {
13
+ return HookBase.getBaseCode() + `
14
+ (function() {
15
+ const deepspider = window.__deepspider__;
16
+ if (!deepspider) return;
17
+
18
+ if (typeof CryptoJS !== 'undefined') {
19
+ // AES
20
+ ['encrypt', 'decrypt'].forEach(method => {
21
+ if (CryptoJS.AES && CryptoJS.AES[method]) {
22
+ const original = CryptoJS.AES[method];
23
+ CryptoJS.AES[method] = deepspider.native(function(data, key, options) {
24
+ const entry = deepspider.log('crypto', {
25
+ algo: 'CryptoJS.AES.' + method,
26
+ data: String(data).slice(0, 100),
27
+ key: String(key),
28
+ options: JSON.stringify(options)
29
+ });
30
+ deepspider.linkCrypto(entry);
31
+ return original.apply(this, arguments);
32
+ }, original);
33
+ }
34
+ });
35
+
36
+ // DES
37
+ if (CryptoJS.DES) {
38
+ ['encrypt', 'decrypt'].forEach(method => {
39
+ if (CryptoJS.DES[method]) {
40
+ const original = CryptoJS.DES[method];
41
+ CryptoJS.DES[method] = deepspider.native(function(data, key) {
42
+ const entry = deepspider.log('crypto', {
43
+ algo: 'CryptoJS.DES.' + method,
44
+ data: String(data).slice(0, 100),
45
+ key: String(key)
46
+ });
47
+ deepspider.linkCrypto(entry);
48
+ return original.apply(this, arguments);
49
+ }, original);
50
+ }
51
+ });
52
+ }
53
+
54
+ // Hash
55
+ ['MD5', 'SHA1', 'SHA256', 'SHA512'].forEach(algo => {
56
+ if (CryptoJS[algo]) {
57
+ const original = CryptoJS[algo];
58
+ CryptoJS[algo] = deepspider.native(function(message) {
59
+ const entry = deepspider.log('crypto', { algo: 'CryptoJS.' + algo, message: String(message).slice(0, 100) });
60
+ deepspider.linkCrypto(entry);
61
+ return original.apply(this, arguments);
62
+ }, original);
63
+ }
64
+ });
65
+
66
+ // HMAC
67
+ ['HmacMD5', 'HmacSHA1', 'HmacSHA256', 'HmacSHA512'].forEach(algo => {
68
+ if (CryptoJS[algo]) {
69
+ const original = CryptoJS[algo];
70
+ CryptoJS[algo] = deepspider.native(function(message, key) {
71
+ const entry = deepspider.log('crypto', { algo: 'CryptoJS.' + algo, message: String(message).slice(0, 100), key: String(key) });
72
+ deepspider.linkCrypto(entry);
73
+ return original.apply(this, arguments);
74
+ }, original);
75
+ }
76
+ });
77
+
78
+ console.log('[DeepSpider:crypto] CryptoJS Hook 已启用');
79
+ }
80
+ })();
81
+ `;
82
+ }
83
+
84
+ /**
85
+ * 生成国密 SM Hook 代码
86
+ */
87
+ generateSMCryptoHookCode() {
88
+ return HookBase.getBaseCode() + `
89
+ (function() {
90
+ const deepspider = window.__deepspider__;
91
+ if (!deepspider) return;
92
+
93
+ if (typeof sm2 !== 'undefined') {
94
+ const origEnc = sm2.doEncrypt;
95
+ sm2.doEncrypt = deepspider.native(function(msg, pubKey) {
96
+ const entry = deepspider.log('crypto', { algo: 'SM2.encrypt', msg: msg.slice(0, 100), publicKey: pubKey.slice(0, 50) });
97
+ deepspider.linkCrypto(entry);
98
+ return origEnc.apply(this, arguments);
99
+ }, origEnc);
100
+
101
+ const origDec = sm2.doDecrypt;
102
+ sm2.doDecrypt = deepspider.native(function(data) {
103
+ const entry = deepspider.log('crypto', { algo: 'SM2.decrypt', data: data.slice(0, 100) });
104
+ deepspider.linkCrypto(entry);
105
+ return origDec.apply(this, arguments);
106
+ }, origDec);
107
+ }
108
+
109
+ if (typeof sm3 !== 'undefined') {
110
+ const orig = sm3;
111
+ sm3 = deepspider.native(function(data) {
112
+ const entry = deepspider.log('crypto', { algo: 'SM3', data: String(data).slice(0, 100) });
113
+ deepspider.linkCrypto(entry);
114
+ return orig.apply(this, arguments);
115
+ }, orig);
116
+ }
117
+
118
+ if (typeof sm4 !== 'undefined' && sm4.encrypt) {
119
+ const orig = sm4.encrypt;
120
+ sm4.encrypt = deepspider.native(function(data, key) {
121
+ const entry = deepspider.log('crypto', { algo: 'SM4.encrypt', data: data.slice(0, 100), key });
122
+ deepspider.linkCrypto(entry);
123
+ return orig.apply(this, arguments);
124
+ }, orig);
125
+ }
126
+
127
+ console.log('[DeepSpider:crypto] SM Crypto Hook 已启用');
128
+ })();
129
+ `;
130
+ }
131
+
132
+ /**
133
+ * 生成 RSA Hook 代码
134
+ */
135
+ generateRSAHookCode() {
136
+ return HookBase.getBaseCode() + `
137
+ (function() {
138
+ const deepspider = window.__deepspider__;
139
+ if (!deepspider) return;
140
+
141
+ if (typeof JSEncrypt !== 'undefined') {
142
+ const proto = JSEncrypt.prototype;
143
+ const origSetPub = proto.setPublicKey;
144
+ proto.setPublicKey = deepspider.native(function(key) {
145
+ const entry = deepspider.log('crypto', { algo: 'RSA.setPublicKey', key: key.slice(0, 100) });
146
+ deepspider.linkCrypto(entry);
147
+ return origSetPub.apply(this, arguments);
148
+ }, origSetPub);
149
+
150
+ const origEnc = proto.encrypt;
151
+ proto.encrypt = deepspider.native(function(data) {
152
+ const entry = deepspider.log('crypto', { algo: 'RSA.encrypt', data: String(data).slice(0, 100) });
153
+ deepspider.linkCrypto(entry);
154
+ return origEnc.apply(this, arguments);
155
+ }, origEnc);
156
+ }
157
+
158
+ if (typeof forge !== 'undefined' && forge.pki && forge.pki.rsa) {
159
+ const orig = forge.pki.rsa.encrypt;
160
+ forge.pki.rsa.encrypt = deepspider.native(function(data) {
161
+ const entry = deepspider.log('crypto', { algo: 'forge.rsa.encrypt', data: String(data).slice(0, 100) });
162
+ deepspider.linkCrypto(entry);
163
+ return orig.apply(this, arguments);
164
+ }, orig);
165
+ }
166
+
167
+ console.log('[DeepSpider:crypto] RSA Hook 已启用');
168
+ })();
169
+ `;
170
+ }
171
+
172
+ /**
173
+ * 生成通用加密函数 Hook
174
+ */
175
+ generateGenericCryptoHookCode() {
176
+ return HookBase.getBaseCode() + `
177
+ (function() {
178
+ const deepspider = window.__deepspider__;
179
+ if (!deepspider) return;
180
+
181
+ const keywords = ['encrypt', 'decrypt', 'sign', 'hash', 'md5', 'sha', 'aes', 'des', 'rsa', 'hmac'];
182
+
183
+ for (const key in window) {
184
+ try {
185
+ if (typeof window[key] === 'function') {
186
+ const lk = key.toLowerCase();
187
+ if (keywords.some(kw => lk.includes(kw))) {
188
+ const orig = window[key];
189
+ window[key] = deepspider.native(function() {
190
+ const entry = deepspider.log('crypto', { algo: 'generic.' + key, args: Array.from(arguments).map(a => String(a).slice(0, 100)) });
191
+ deepspider.linkCrypto(entry);
192
+ return orig.apply(this, arguments);
193
+ }, orig);
194
+ }
195
+ }
196
+ } catch(e) {}
197
+ }
198
+
199
+ console.log('[DeepSpider:crypto] Generic Crypto Hook 已启用');
200
+ })();
201
+ `;
202
+ }
203
+ }
204
+
205
+ export default CryptoHook;
@@ -0,0 +1,157 @@
1
+ /**
2
+ * DeepSpider - 环境代码生成器
3
+ * 借鉴 v_jstools 的 make_env_1_v3.js
4
+ * 根据 Hook 收集的数据生成可在 Node.js 运行的浏览器环境代码
5
+ */
6
+
7
+ import { GETSET_LIST, FUNC_LIST, HTML_TAG_MAP } from './BrowserAPIList.js';
8
+
9
+ export class EnvCodeGenerator {
10
+ constructor() {
11
+ this.envData = {};
12
+ }
13
+
14
+ /**
15
+ * 从 Hook 日志生成环境代码
16
+ */
17
+ generateFromLogs(logs) {
18
+ this.parseEnvLogs(logs);
19
+ return this.generateCode();
20
+ }
21
+
22
+ /**
23
+ * 解析环境日志
24
+ */
25
+ parseEnvLogs(logs) {
26
+ for (const log of logs) {
27
+ if (log._type === 'env' && log.path) {
28
+ const parts = log.path.split('.');
29
+ const className = parts[0];
30
+ const propName = parts[1];
31
+ if (!this.envData[className]) {
32
+ this.envData[className] = { props: {}, methods: {} };
33
+ }
34
+ if (log.type === 'get' || log.type === 'set') {
35
+ this.envData[className].props[propName] = log.value;
36
+ } else if (log.type === 'call') {
37
+ this.envData[className].methods[propName] = log.result;
38
+ }
39
+ }
40
+ }
41
+ }
42
+
43
+ /**
44
+ * 生成环境代码
45
+ */
46
+ generateCode() {
47
+ const lines = [];
48
+ lines.push('// DeepSpider 生成的浏览器环境代码');
49
+ lines.push('// 生成时间: ' + new Date().toISOString());
50
+ lines.push('');
51
+ lines.push(this.generateSafeWrapper());
52
+ lines.push(this.generateBaseClasses());
53
+ lines.push(this.generateGlobalObjects());
54
+ return lines.join('\n');
55
+ }
56
+
57
+ /**
58
+ * 生成安全包装函数
59
+ */
60
+ generateSafeWrapper() {
61
+ return `
62
+ // 安全函数包装器
63
+ function v_saf(fn) {
64
+ return function() {
65
+ try { return fn.apply(this, arguments); }
66
+ catch(e) { return undefined; }
67
+ };
68
+ }`;
69
+ }
70
+
71
+ /**
72
+ * 生成基础类
73
+ */
74
+ generateBaseClasses() {
75
+ return `
76
+ // EventTarget 基类
77
+ class EventTarget {
78
+ constructor() { this._listeners = {}; }
79
+ addEventListener(type, fn) {
80
+ if (!this._listeners[type]) this._listeners[type] = [];
81
+ this._listeners[type].push(fn);
82
+ }
83
+ removeEventListener(type, fn) {
84
+ if (!this._listeners[type]) return;
85
+ this._listeners[type] = this._listeners[type].filter(f => f !== fn);
86
+ }
87
+ dispatchEvent(event) {
88
+ const fns = this._listeners[event.type] || [];
89
+ fns.forEach(fn => fn.call(this, event));
90
+ return true;
91
+ }
92
+ }
93
+
94
+ // Node 基类
95
+ class Node extends EventTarget {
96
+ constructor() {
97
+ super();
98
+ this.childNodes = [];
99
+ this.parentNode = null;
100
+ }
101
+ appendChild(node) { node.parentNode = this; this.childNodes.push(node); return node; }
102
+ removeChild(node) {
103
+ const idx = this.childNodes.indexOf(node);
104
+ if (idx > -1) this.childNodes.splice(idx, 1);
105
+ node.parentNode = null;
106
+ return node;
107
+ }
108
+ }`;
109
+ }
110
+
111
+ /**
112
+ * 生成全局对象
113
+ */
114
+ generateGlobalObjects() {
115
+ const nav = this.envData.navigator?.props || {};
116
+ const scr = this.envData.screen?.props || {};
117
+
118
+ return `
119
+ // Navigator
120
+ var navigator = {
121
+ userAgent: ${JSON.stringify(nav.userAgent || 'Mozilla/5.0')},
122
+ platform: ${JSON.stringify(nav.platform || 'Win32')},
123
+ language: ${JSON.stringify(nav.language || 'zh-CN')},
124
+ cookieEnabled: true,
125
+ onLine: true,
126
+ webdriver: false,
127
+ };
128
+
129
+ // Screen
130
+ var screen = {
131
+ width: ${scr.width || 1920},
132
+ height: ${scr.height || 1080},
133
+ colorDepth: 24,
134
+ };
135
+
136
+ // Location
137
+ var location = { href: '', protocol: 'https:', host: '', pathname: '/' };
138
+
139
+ // Document
140
+ var document = {
141
+ cookie: '',
142
+ createElement: function(tag) { return {}; },
143
+ getElementById: function(id) { return null; },
144
+ querySelector: function(sel) { return null; },
145
+ };
146
+
147
+ // Window
148
+ var window = this;
149
+ window.navigator = navigator;
150
+ window.screen = screen;
151
+ window.location = location;
152
+ window.document = document;
153
+ `;
154
+ }
155
+ }
156
+
157
+ export default EnvCodeGenerator;
@@ -0,0 +1,356 @@
1
+ /**
2
+ * DeepSpider - 环境自吐模块
3
+ * 通过 Proxy 递归代理全局对象,记录所有环境访问
4
+ */
5
+
6
+ import { HookBase } from './HookBase.js';
7
+
8
+ export class EnvDumper {
9
+ constructor() {
10
+ this.logs = [];
11
+ this.maxValueLength = 70;
12
+ }
13
+
14
+ /**
15
+ * 生成环境自吐注入代码
16
+ * @param {Object} options - 配置选项
17
+ * @returns {string} 可注入沙箱的 JS 代码
18
+ */
19
+ generateDumpCode(options = {}) {
20
+ const {
21
+ targets = ['window', 'document', 'navigator', 'location'],
22
+ maxValueLength = 70,
23
+ enableCallStack = false,
24
+ skipInternals = true,
25
+ } = options;
26
+
27
+ return HookBase.getBaseCode() + `
28
+ (function() {
29
+ const deepspider = window.__deepspider__ || global.__deepspider__;
30
+ if (!deepspider) {
31
+ console.error('[DeepSpider:env] 请先注入 HookBase');
32
+ return;
33
+ }
34
+ const MAX_VALUE_LENGTH = ${maxValueLength};
35
+ const ENABLE_CALL_STACK = ${enableCallStack};
36
+ const SKIP_INTERNALS = ${skipInternals};
37
+
38
+ // 截取值长度
39
+ function truncateValue(value) {
40
+ if (typeof value === "string" && value.length > MAX_VALUE_LENGTH) {
41
+ return value.substring(0, MAX_VALUE_LENGTH) + "...";
42
+ }
43
+ if (typeof value !== "object" || value === null) {
44
+ return value;
45
+ }
46
+ try {
47
+ const str = JSON.stringify(value);
48
+ if (str.length > MAX_VALUE_LENGTH) {
49
+ return str.substring(0, MAX_VALUE_LENGTH) + "...";
50
+ }
51
+ return str;
52
+ } catch {
53
+ return "[Object]";
54
+ }
55
+ }
56
+
57
+ // 序列化值
58
+ function serializeValue(value) {
59
+ if (value === undefined) return "undefined";
60
+ if (value === null) return "null";
61
+ if (typeof value === "function") return "[Function]";
62
+ if (typeof value === "symbol") return value.toString();
63
+ if (typeof value === "object") {
64
+ try {
65
+ return JSON.stringify(value);
66
+ } catch {
67
+ return "[Object]";
68
+ }
69
+ }
70
+ return String(value);
71
+ }
72
+
73
+ // 记录日志
74
+ function logEnv(type, path, details = {}) {
75
+ const entry = {
76
+ type,
77
+ path,
78
+ ...details
79
+ };
80
+ if (ENABLE_CALL_STACK) {
81
+ entry.stack = new Error().stack;
82
+ }
83
+ deepspider.log('env', entry);
84
+
85
+ // 格式化输出
86
+ const pathStr = ('"' + path + '"').padEnd(50, " ");
87
+ switch (type) {
88
+ case 'get':
89
+ console.log(\`[DeepSpider:env] 获取: \${pathStr} | 值= \${truncateValue(details.value)}\`);
90
+ break;
91
+ case 'set':
92
+ console.log(\`[DeepSpider:env] 设置: \${pathStr} | 值= \${truncateValue(details.value)}\`);
93
+ break;
94
+ case 'call':
95
+ console.log(\`[DeepSpider:env] 调用: \${pathStr} | 参数= \${truncateValue(details.args)}\`);
96
+ break;
97
+ case 'construct':
98
+ console.log(\`[DeepSpider:env] 构造: \${pathStr} | 参数= \${truncateValue(details.args)}\`);
99
+ break;
100
+ case 'missing':
101
+ console.log(\`[DeepSpider:env] 缺失: \${pathStr}\`);
102
+ if (typeof __recordMissing__ === 'function') {
103
+ __recordMissing__(path);
104
+ }
105
+ break;
106
+ }
107
+ }
108
+
109
+ // 判断是否跳过的内部属性
110
+ function shouldSkipKey(key, name) {
111
+ if (!SKIP_INTERNALS) return false;
112
+
113
+ const skipKeys = [
114
+ 'window', 'self', 'global', 'globalThis',
115
+ '_globalObject', 'prototype', '__proto__'
116
+ ];
117
+
118
+ if (skipKeys.includes(key) || key === name) return true;
119
+ if (typeof key === 'string' && (key.startsWith('__') && key.endsWith('__'))) return true;
120
+ if (typeof key === 'symbol') return true;
121
+
122
+ return false;
123
+ }
124
+
125
+ // 创建代理处理器
126
+ function createHandler(name) {
127
+ const proxyCache = new WeakMap();
128
+
129
+ return {
130
+ get(target, key, receiver) {
131
+ // 跳过 Symbol 和特殊属性
132
+ if (typeof key === 'symbol' || key === 'toString' || key === 'valueOf') {
133
+ return Reflect.get(target, key, receiver);
134
+ }
135
+
136
+ const value = target[key];
137
+ const fullPath = name + '.' + String(key);
138
+
139
+ // 内部属性简单返回
140
+ if (shouldSkipKey(key, name)) {
141
+ return value;
142
+ }
143
+
144
+ // 记录缺失
145
+ if (value === undefined && !(key in target)) {
146
+ logEnv('missing', fullPath);
147
+ return undefined;
148
+ }
149
+
150
+ // 处理函数
151
+ if (typeof value === 'function') {
152
+ // 检查是否是构造函数
153
+ const isConstructor = value.prototype !== undefined;
154
+
155
+ return new Proxy(value, {
156
+ apply(fn, thisArg, args) {
157
+ const result = Reflect.apply(fn, target, args);
158
+ logEnv('call', fullPath, { args: serializeValue(args), result: serializeValue(result) });
159
+ return result;
160
+ },
161
+ construct(fn, args, newTarget) {
162
+ logEnv('construct', fullPath, { args: serializeValue(args) });
163
+ return Reflect.construct(fn, args, newTarget);
164
+ },
165
+ get(fn, prop) {
166
+ // 代理函数的属性访问
167
+ if (prop === 'prototype' || typeof prop === 'symbol') {
168
+ return fn[prop];
169
+ }
170
+ const propValue = fn[prop];
171
+ if (typeof propValue === 'function') {
172
+ return new Proxy(propValue, createHandler(fullPath + '.' + String(prop)));
173
+ }
174
+ return propValue;
175
+ }
176
+ });
177
+ }
178
+
179
+ // 处理对象 - 递归代理
180
+ if (value !== null && typeof value === 'object') {
181
+ // 使用缓存避免重复代理
182
+ if (proxyCache.has(value)) {
183
+ return proxyCache.get(value);
184
+ }
185
+
186
+ logEnv('get', fullPath, { value: serializeValue(value) });
187
+
188
+ const proxy = new Proxy(value, createHandler(fullPath));
189
+ proxyCache.set(value, proxy);
190
+ return proxy;
191
+ }
192
+
193
+ // 基本类型
194
+ logEnv('get', fullPath, { value: serializeValue(value) });
195
+ return value;
196
+ },
197
+
198
+ set(target, key, value, receiver) {
199
+ const fullPath = name + '.' + String(key);
200
+ logEnv('set', fullPath, { value: serializeValue(value) });
201
+ return Reflect.set(target, key, value, receiver);
202
+ },
203
+
204
+ apply(target, thisArg, args) {
205
+ logEnv('call', name, { args: serializeValue(args) });
206
+ return Reflect.apply(target, thisArg, args);
207
+ },
208
+
209
+ construct(target, args, newTarget) {
210
+ logEnv('construct', name, { args: serializeValue(args) });
211
+ return Reflect.construct(target, args, newTarget);
212
+ }
213
+ };
214
+ }
215
+
216
+ // 代理指定的全局对象
217
+ const targets = ${JSON.stringify(targets)};
218
+
219
+ for (const target of targets) {
220
+ if (typeof global[target] !== 'undefined') {
221
+ try {
222
+ global[target] = new Proxy(global[target], createHandler(target));
223
+ } catch (e) {
224
+ console.log('[DeepSpider:env] 无法代理:', target, e.message);
225
+ }
226
+ }
227
+ }
228
+
229
+ console.log('[DeepSpider:env] 环境自吐已启用,监控目标:', targets.join(', '));
230
+ })();
231
+ `;
232
+ }
233
+
234
+ /**
235
+ * 生成基础环境桩代码
236
+ * 在注入自吐代码前,先创建基础的全局对象
237
+ */
238
+ generateBaseEnv() {
239
+ return `
240
+ // 基础环境桩
241
+ if (typeof window === 'undefined') {
242
+ global.window = global;
243
+ }
244
+ if (typeof self === 'undefined') {
245
+ global.self = global;
246
+ }
247
+ if (typeof document === 'undefined') {
248
+ global.document = {
249
+ cookie: '',
250
+ referrer: '',
251
+ URL: 'about:blank',
252
+ domain: '',
253
+ title: '',
254
+ body: null,
255
+ head: null,
256
+ documentElement: null,
257
+ createElement: function(tag) { return { tagName: tag }; },
258
+ getElementById: function() { return null; },
259
+ getElementsByTagName: function() { return []; },
260
+ getElementsByClassName: function() { return []; },
261
+ querySelector: function() { return null; },
262
+ querySelectorAll: function() { return []; },
263
+ addEventListener: function() {},
264
+ removeEventListener: function() {},
265
+ };
266
+ }
267
+ if (typeof navigator === 'undefined') {
268
+ global.navigator = {
269
+ userAgent: '',
270
+ platform: '',
271
+ language: 'zh-CN',
272
+ languages: ['zh-CN'],
273
+ cookieEnabled: true,
274
+ onLine: true,
275
+ hardwareConcurrency: 4,
276
+ maxTouchPoints: 0,
277
+ webdriver: false,
278
+ };
279
+ }
280
+ if (typeof location === 'undefined') {
281
+ global.location = {
282
+ href: 'about:blank',
283
+ protocol: 'https:',
284
+ host: '',
285
+ hostname: '',
286
+ port: '',
287
+ pathname: '/',
288
+ search: '',
289
+ hash: '',
290
+ origin: '',
291
+ };
292
+ }
293
+ if (typeof screen === 'undefined') {
294
+ global.screen = {
295
+ width: 1920,
296
+ height: 1080,
297
+ availWidth: 1920,
298
+ availHeight: 1040,
299
+ colorDepth: 24,
300
+ pixelDepth: 24,
301
+ };
302
+ }
303
+ if (typeof localStorage === 'undefined') {
304
+ const storage = {};
305
+ global.localStorage = {
306
+ getItem: (k) => storage[k] || null,
307
+ setItem: (k, v) => { storage[k] = String(v); },
308
+ removeItem: (k) => { delete storage[k]; },
309
+ clear: () => { for (const k in storage) delete storage[k]; },
310
+ get length() { return Object.keys(storage).length; },
311
+ key: (i) => Object.keys(storage)[i] || null,
312
+ };
313
+ }
314
+ if (typeof sessionStorage === 'undefined') {
315
+ global.sessionStorage = { ...global.localStorage };
316
+ }
317
+ `;
318
+ }
319
+
320
+ /**
321
+ * 解析环境日志,提取需要补全的环境
322
+ */
323
+ parseEnvLogs(logsJson) {
324
+ try {
325
+ const logs = JSON.parse(logsJson);
326
+ const missing = new Set();
327
+ const calls = [];
328
+ const gets = [];
329
+
330
+ for (const log of logs) {
331
+ switch (log.type) {
332
+ case 'missing':
333
+ missing.add(log.path);
334
+ break;
335
+ case 'call':
336
+ calls.push({ path: log.path, args: log.args });
337
+ break;
338
+ case 'get':
339
+ gets.push({ path: log.path, value: log.value });
340
+ break;
341
+ }
342
+ }
343
+
344
+ return {
345
+ missing: Array.from(missing),
346
+ calls,
347
+ gets,
348
+ total: logs.length,
349
+ };
350
+ } catch (e) {
351
+ return { error: e.message };
352
+ }
353
+ }
354
+ }
355
+
356
+ export default EnvDumper;