@jshookmcp/jshook 0.2.2 → 0.2.3

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 (130) hide show
  1. package/LICENSE +661 -661
  2. package/README.md +4 -4
  3. package/README.zh.md +3 -3
  4. package/dist/native/scripts/linux/enum-windows.sh +12 -12
  5. package/dist/native/scripts/macos/enum-windows.applescript +22 -22
  6. package/dist/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
  7. package/dist/native/scripts/windows/enum-windows.ps1 +44 -44
  8. package/dist/native/scripts/windows/inject-dll.ps1 +21 -21
  9. package/dist/src/modules/analyzer/CodeAnalyzer.d.ts +1 -1
  10. package/dist/src/modules/analyzer/CodeAnalyzer.js +1 -1
  11. package/dist/src/modules/browser/BrowserDiscovery.d.ts +6 -5
  12. package/dist/src/modules/browser/BrowserDiscovery.js +1 -1
  13. package/dist/src/modules/browser/BrowserModeManager.d.ts +1 -1
  14. package/dist/src/modules/browser/BrowserModeManager.js +1 -1
  15. package/dist/src/modules/browser/UnifiedBrowserManager.js +1 -1
  16. package/dist/src/modules/captcha/AICaptchaDetector.d.ts +22 -22
  17. package/dist/src/modules/captcha/AICaptchaDetector.js +75 -75
  18. package/dist/src/modules/captcha/CaptchaDetector.d.ts +31 -17
  19. package/dist/src/modules/captcha/CaptchaDetector.js +1 -1
  20. package/dist/src/modules/collector/CodeCache.d.ts +2 -2
  21. package/dist/src/modules/collector/CodeCollector.d.ts +12 -9
  22. package/dist/src/modules/collector/CodeCollector.js +1 -1
  23. package/dist/src/modules/collector/DOMInspector.d.ts +3 -2
  24. package/dist/src/modules/collector/DOMInspector.js +1 -1
  25. package/dist/src/modules/crypto/CryptoDetector.d.ts +1 -1
  26. package/dist/src/modules/crypto/CryptoDetector.js +1 -1
  27. package/dist/src/modules/debugger/ScriptManager.impl.extract-function-tree.js +1 -1
  28. package/dist/src/modules/deobfuscator/Deobfuscator.d.ts +1 -1
  29. package/dist/src/modules/deobfuscator/Deobfuscator.js +1 -1
  30. package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.d.ts +1 -1
  31. package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.js +2 -2
  32. package/dist/src/modules/deobfuscator/PackerDeobfuscator.js +1 -1
  33. package/dist/src/modules/deobfuscator/VMDeobfuscator.d.ts +1 -1
  34. package/dist/src/modules/deobfuscator/VMDeobfuscator.js +82 -82
  35. package/dist/src/modules/emulator/AIEnvironmentAnalyzer.js +1 -1
  36. package/dist/src/modules/external/ExternalToolRunner.d.ts +1 -1
  37. package/dist/src/modules/external/ExternalToolRunner.js +1 -1
  38. package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.compose.js +5 -5
  39. package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.network.js +311 -311
  40. package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.runtime.js +410 -410
  41. package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.storage.js +122 -122
  42. package/dist/src/modules/monitor/ConsoleMonitor.impl.core.dynamic.js +194 -194
  43. package/dist/src/modules/monitor/PlaywrightNetworkMonitor.js +62 -62
  44. package/dist/src/modules/process/LinuxProcessManager.js +2 -2
  45. package/dist/src/modules/process/MacProcessManager.js +26 -26
  46. package/dist/src/modules/process/ProcessManager.impl.js +1 -1
  47. package/dist/src/modules/process/memory/availability.js +49 -49
  48. package/dist/src/modules/process/memory/injector.js +185 -185
  49. package/dist/src/modules/process/memory/reader.js +50 -50
  50. package/dist/src/modules/process/memory/regions.dump.js +51 -51
  51. package/dist/src/modules/process/memory/regions.enumerate.js +107 -107
  52. package/dist/src/modules/process/memory/regions.modules.js +80 -80
  53. package/dist/src/modules/process/memory/regions.protection.js +106 -106
  54. package/dist/src/modules/process/memory/scanner.darwin.js +41 -41
  55. package/dist/src/modules/process/memory/scanner.windows.js +124 -124
  56. package/dist/src/modules/process/memory/writer.js +54 -54
  57. package/dist/src/modules/security/ExecutionSandbox.js +44 -44
  58. package/dist/src/modules/stealth/StealthScripts.d.ts +3 -2
  59. package/dist/src/modules/stealth/StealthScripts.js +35 -1
  60. package/dist/src/modules/stealth/StealthVerifier.d.ts +1 -1
  61. package/dist/src/modules/stealth/StealthVerifier.js +1 -1
  62. package/dist/src/modules/trace/TraceDB.js +63 -63
  63. package/dist/src/native/CodeInjector.js +1 -1
  64. package/dist/src/native/HardwareBreakpoint.js +1 -1
  65. package/dist/src/server/MCPServer.js +1 -0
  66. package/dist/src/server/MCPServer.search.helpers.js +1 -1
  67. package/dist/src/server/MCPServer.tools.js +1 -1
  68. package/dist/src/server/ToolCallContextGuard.d.ts +5 -0
  69. package/dist/src/server/ToolCallContextGuard.js +77 -0
  70. package/dist/src/server/ToolRouter.d.ts +1 -1
  71. package/dist/src/server/ToolRouter.js +2 -2
  72. package/dist/src/server/domains/analysis/handlers.impl.d.ts +8 -8
  73. package/dist/src/server/domains/analysis/handlers.impl.js +8 -8
  74. package/dist/src/server/domains/analysis/handlers.web-tools.js +2 -2
  75. package/dist/src/server/domains/browser/definitions.tools.page-core.js +59 -59
  76. package/dist/src/server/domains/browser/definitions.tools.runtime.js +41 -41
  77. package/dist/src/server/domains/browser/definitions.tools.security.js +114 -114
  78. package/dist/src/server/domains/browser/handlers/facade-initializer.d.ts +3 -3
  79. package/dist/src/server/domains/browser/handlers/facade-initializer.js +3 -3
  80. package/dist/src/server/domains/browser/handlers/framework-state.js +210 -0
  81. package/dist/src/server/domains/browser/handlers/stealth-injection.js +8 -2
  82. package/dist/src/server/domains/browser/handlers.impl.d.ts +15 -11
  83. package/dist/src/server/domains/browser/handlers.impl.js +4 -4
  84. package/dist/src/server/domains/coordination/definitions.js +67 -0
  85. package/dist/src/server/domains/coordination/index.d.ts +18 -0
  86. package/dist/src/server/domains/coordination/index.js +132 -0
  87. package/dist/src/server/domains/coordination/manifest.js +15 -0
  88. package/dist/src/server/domains/graphql/handlers.impl.core.runtime.replay.js +2 -2
  89. package/dist/src/server/domains/graphql/handlers.impl.core.runtime.shared.js +77 -77
  90. package/dist/src/server/domains/hooks/ai-handlers.js +3 -3
  91. package/dist/src/server/domains/maintenance/handlers.d.ts +2 -2
  92. package/dist/src/server/domains/maintenance/handlers.js +2 -2
  93. package/dist/src/server/domains/platform/handlers/bridge-handlers.d.ts +1 -1
  94. package/dist/src/server/domains/platform/handlers/bridge-handlers.js +1 -1
  95. package/dist/src/server/domains/platform/handlers/miniapp-handlers.d.ts +1 -1
  96. package/dist/src/server/domains/platform/handlers/miniapp-handlers.js +1 -1
  97. package/dist/src/server/domains/process/handlers.impl.core.runtime.inject.js +1 -1
  98. package/dist/src/server/domains/trace/TraceSummarizer.d.ts +60 -0
  99. package/dist/src/server/domains/trace/TraceSummarizer.js +109 -0
  100. package/dist/src/server/domains/trace/definitions.tools.js +101 -71
  101. package/dist/src/server/domains/trace/handlers.d.ts +2 -1
  102. package/dist/src/server/domains/trace/handlers.js +59 -4
  103. package/dist/src/server/domains/trace/manifest.js +3 -1
  104. package/dist/src/server/domains/transform/handlers.impl.transform-base.js +103 -103
  105. package/dist/src/server/domains/wasm/handlers.js +2 -2
  106. package/dist/src/server/domains/workflow/handlers.impl.workflow-account-bundle.js +1 -1
  107. package/dist/src/server/domains/workflow/handlers.impl.workflow-api.js +51 -51
  108. package/dist/src/server/domains/workflow/handlers.impl.workflow-base.js +51 -51
  109. package/dist/src/server/extensions/ExtensionManager.roots.js +15 -5
  110. package/dist/src/server/http/HttpMiddleware.js +1 -1
  111. package/dist/src/server/registry/contracts.d.ts +6 -0
  112. package/dist/src/server/sandbox/MCPBridge.d.ts +9 -0
  113. package/dist/src/server/sandbox/MCPBridge.js +22 -0
  114. package/dist/src/server/sandbox/QuickJSSandbox.d.ts +4 -1
  115. package/dist/src/server/sandbox/QuickJSSandbox.js +149 -0
  116. package/dist/src/server/sandbox/SandboxHelpers.js +250 -250
  117. package/dist/src/server/sandbox/types.d.ts +13 -0
  118. package/dist/src/server/search/AffinityGraph.d.ts +7 -1
  119. package/dist/src/server/search/AffinityGraph.js +24 -3
  120. package/dist/src/services/LLMService.js +1 -1
  121. package/dist/src/utils/UnifiedCacheManager.d.ts +1 -1
  122. package/dist/src/utils/UnifiedCacheManager.js +2 -2
  123. package/dist/src/utils/cliFastPath.js +18 -4
  124. package/package.json +5 -3
  125. package/scripts/postinstall.cjs +37 -37
  126. package/src/native/scripts/linux/enum-windows.sh +12 -12
  127. package/src/native/scripts/macos/enum-windows.applescript +22 -22
  128. package/src/native/scripts/windows/enum-windows-by-class.ps1 +51 -51
  129. package/src/native/scripts/windows/enum-windows.ps1 +44 -44
  130. package/src/native/scripts/windows/inject-dll.ps1 +21 -21
@@ -1,320 +1,320 @@
1
1
  export function generateXHRHook(action, customCode, _condition, _performance = false) {
2
- return `
3
- (function() {
4
- 'use strict';
5
-
6
- const XHR = XMLHttpRequest.prototype;
7
- const originalOpen = XHR.open;
8
- const originalSend = XHR.send;
9
- const originalSetRequestHeader = XHR.setRequestHeader;
10
-
11
- XHR.open = function(method, url, async, user, password) {
12
- this._hookData = {
13
- method: method,
14
- url: url,
15
- async: async !== false,
16
- timestamp: Date.now(),
17
- headers: {},
18
- stackTrace: new Error().stack
19
- };
20
-
21
- console.log('[XHR Hook] open:', {
22
- method: method,
23
- url: url,
24
- async: async !== false
25
- });
26
-
27
- ${action === 'block' ? 'return;' : ''}
28
-
29
- return originalOpen.apply(this, arguments);
30
- };
31
-
32
- XHR.setRequestHeader = function(header, value) {
33
- if (this._hookData) {
34
- this._hookData.headers[header] = value;
35
- console.log('[XHR Hook] setRequestHeader:', { header, value });
36
- }
37
-
38
- return originalSetRequestHeader.apply(this, arguments);
39
- };
40
-
41
- XHR.send = function(data) {
42
- const xhr = this;
43
-
44
- if (xhr._hookData) {
45
- xhr._hookData.requestData = data;
46
- xhr._hookData.sendTime = Date.now();
47
-
48
- console.log('[XHR Hook] send:', {
49
- url: xhr._hookData.url,
50
- method: xhr._hookData.method,
51
- headers: xhr._hookData.headers,
52
- data: data
53
- });
54
- }
55
-
56
- const originalOnReadyStateChange = xhr.onreadystatechange;
57
-
58
- xhr.onreadystatechange = function() {
59
- if (xhr.readyState === 4) {
60
- const responseTime = Date.now() - (xhr._hookData?.sendTime || 0);
61
-
62
- console.log('[XHR Hook] response:', {
63
- url: xhr._hookData?.url,
64
- status: xhr.status,
65
- statusText: xhr.statusText,
66
- responseTime: responseTime + 'ms',
67
- responseHeaders: xhr.getAllResponseHeaders(),
68
- responseType: xhr.responseType,
69
- responseURL: xhr.responseURL
70
- });
71
-
72
- try {
73
- if (xhr.responseType === '' || xhr.responseType === 'text') {
74
- console.log('[XHR Hook] responseText:', xhr.responseText?.substring(0, 500));
75
- } else if (xhr.responseType === 'json') {
76
- console.log('[XHR Hook] responseJSON:', xhr.response);
77
- } else {
78
- console.log('[XHR Hook] response:', typeof xhr.response);
79
- }
80
- } catch (e) {
81
- console.warn('[XHR Hook] Failed to log response:', e);
82
- }
83
- }
84
-
85
- if (originalOnReadyStateChange) {
86
- return originalOnReadyStateChange.apply(this, arguments);
87
- }
88
- };
89
-
90
- const originalAddEventListener = xhr.addEventListener;
91
- xhr.addEventListener = function(event, listener, ...args) {
92
- if (event === 'load' || event === 'error' || event === 'abort') {
93
- const wrappedListener = function(e) {
94
- console.log(\`[XHR Hook] event '\${event}':\`, {
95
- url: xhr._hookData?.url,
96
- status: xhr.status
97
- });
98
- return listener.apply(this, arguments);
99
- };
100
- return originalAddEventListener.call(this, event, wrappedListener, ...args);
101
- }
102
- return originalAddEventListener.apply(this, arguments);
103
- };
104
-
105
- ${customCode || ''}
106
-
107
- return originalSend.apply(this, arguments);
108
- };
109
-
110
- console.log('[Hook] XHR hooked successfully');
111
- })();
2
+ return `
3
+ (function() {
4
+ 'use strict';
5
+
6
+ const XHR = XMLHttpRequest.prototype;
7
+ const originalOpen = XHR.open;
8
+ const originalSend = XHR.send;
9
+ const originalSetRequestHeader = XHR.setRequestHeader;
10
+
11
+ XHR.open = function(method, url, async, user, password) {
12
+ this._hookData = {
13
+ method: method,
14
+ url: url,
15
+ async: async !== false,
16
+ timestamp: Date.now(),
17
+ headers: {},
18
+ stackTrace: new Error().stack
19
+ };
20
+
21
+ console.log('[XHR Hook] open:', {
22
+ method: method,
23
+ url: url,
24
+ async: async !== false
25
+ });
26
+
27
+ ${action === 'block' ? 'return;' : ''}
28
+
29
+ return originalOpen.apply(this, arguments);
30
+ };
31
+
32
+ XHR.setRequestHeader = function(header, value) {
33
+ if (this._hookData) {
34
+ this._hookData.headers[header] = value;
35
+ console.log('[XHR Hook] setRequestHeader:', { header, value });
36
+ }
37
+
38
+ return originalSetRequestHeader.apply(this, arguments);
39
+ };
40
+
41
+ XHR.send = function(data) {
42
+ const xhr = this;
43
+
44
+ if (xhr._hookData) {
45
+ xhr._hookData.requestData = data;
46
+ xhr._hookData.sendTime = Date.now();
47
+
48
+ console.log('[XHR Hook] send:', {
49
+ url: xhr._hookData.url,
50
+ method: xhr._hookData.method,
51
+ headers: xhr._hookData.headers,
52
+ data: data
53
+ });
54
+ }
55
+
56
+ const originalOnReadyStateChange = xhr.onreadystatechange;
57
+
58
+ xhr.onreadystatechange = function() {
59
+ if (xhr.readyState === 4) {
60
+ const responseTime = Date.now() - (xhr._hookData?.sendTime || 0);
61
+
62
+ console.log('[XHR Hook] response:', {
63
+ url: xhr._hookData?.url,
64
+ status: xhr.status,
65
+ statusText: xhr.statusText,
66
+ responseTime: responseTime + 'ms',
67
+ responseHeaders: xhr.getAllResponseHeaders(),
68
+ responseType: xhr.responseType,
69
+ responseURL: xhr.responseURL
70
+ });
71
+
72
+ try {
73
+ if (xhr.responseType === '' || xhr.responseType === 'text') {
74
+ console.log('[XHR Hook] responseText:', xhr.responseText?.substring(0, 500));
75
+ } else if (xhr.responseType === 'json') {
76
+ console.log('[XHR Hook] responseJSON:', xhr.response);
77
+ } else {
78
+ console.log('[XHR Hook] response:', typeof xhr.response);
79
+ }
80
+ } catch (e) {
81
+ console.warn('[XHR Hook] Failed to log response:', e);
82
+ }
83
+ }
84
+
85
+ if (originalOnReadyStateChange) {
86
+ return originalOnReadyStateChange.apply(this, arguments);
87
+ }
88
+ };
89
+
90
+ const originalAddEventListener = xhr.addEventListener;
91
+ xhr.addEventListener = function(event, listener, ...args) {
92
+ if (event === 'load' || event === 'error' || event === 'abort') {
93
+ const wrappedListener = function(e) {
94
+ console.log(\`[XHR Hook] event '\${event}':\`, {
95
+ url: xhr._hookData?.url,
96
+ status: xhr.status
97
+ });
98
+ return listener.apply(this, arguments);
99
+ };
100
+ return originalAddEventListener.call(this, event, wrappedListener, ...args);
101
+ }
102
+ return originalAddEventListener.apply(this, arguments);
103
+ };
104
+
105
+ ${customCode || ''}
106
+
107
+ return originalSend.apply(this, arguments);
108
+ };
109
+
110
+ console.log('[Hook] XHR hooked successfully');
111
+ })();
112
112
  `.trim();
113
113
  }
114
114
  export function generateFetchHook(action, customCode, _condition, _performance = false) {
115
- return `
116
- (function() {
117
- 'use strict';
118
-
119
- const originalFetch = window.fetch;
120
-
121
- window.fetch = new Proxy(originalFetch, {
122
- apply: function(target, thisArg, args) {
123
- const [resource, config] = args;
124
-
125
- let url, method, headers, body;
126
-
127
- if (resource instanceof Request) {
128
- url = resource.url;
129
- method = resource.method;
130
- headers = Object.fromEntries(resource.headers.entries());
131
- body = resource.body;
132
- } else {
133
- url = resource;
134
- method = config?.method || 'GET';
135
- headers = config?.headers || {};
136
- body = config?.body;
137
- }
138
-
139
- const hookContext = {
140
- url: url,
141
- method: method,
142
- headers: headers,
143
- body: body,
144
- timestamp: Date.now(),
145
- stackTrace: new Error().stack.split('\\n').slice(2, 5).join('\\n')
146
- };
147
-
148
- console.log('[Fetch Hook] request:', hookContext);
149
-
150
- ${action === 'block' ? 'return Promise.reject(new Error("Fetch blocked by hook"));' : ''}
151
- ${customCode || ''}
152
-
153
- const startTime = performance.now();
154
-
155
- return Reflect.apply(target, thisArg, args)
156
- .then(async response => {
157
- const endTime = performance.now();
158
- const duration = (endTime - startTime).toFixed(2);
159
-
160
- const clonedResponse = response.clone();
161
-
162
- const responseInfo = {
163
- url: url,
164
- status: response.status,
165
- statusText: response.statusText,
166
- ok: response.ok,
167
- redirected: response.redirected,
168
- type: response.type,
169
- headers: Object.fromEntries(response.headers.entries()),
170
- duration: duration + 'ms'
171
- };
172
-
173
- console.log('[Fetch Hook] response:', responseInfo);
174
-
175
- try {
176
- const contentType = response.headers.get('content-type') || '';
177
-
178
- if (contentType.includes('application/json')) {
179
- const json = await clonedResponse.json();
180
- console.log('[Fetch Hook] responseJSON:', json);
181
- } else if (contentType.includes('text/')) {
182
- const text = await clonedResponse.text();
183
- console.log('[Fetch Hook] responseText:', text.substring(0, 500));
184
- } else {
185
- console.log('[Fetch Hook] response type:', contentType);
186
- }
187
- } catch (e) {
188
- console.warn('[Fetch Hook] Failed to parse response:', e.message);
189
- }
190
-
191
- return response;
192
- })
193
- .catch(error => {
194
- const endTime = performance.now();
195
- const duration = (endTime - startTime).toFixed(2);
196
-
197
- console.error('[Fetch Hook] error:', {
198
- url: url,
199
- error: error.message,
200
- duration: duration + 'ms'
201
- });
202
-
203
- throw error;
204
- });
205
- }
206
- });
207
-
208
- console.log('[Fetch Hook] Successfully hooked window.fetch');
209
- })();
115
+ return `
116
+ (function() {
117
+ 'use strict';
118
+
119
+ const originalFetch = window.fetch;
120
+
121
+ window.fetch = new Proxy(originalFetch, {
122
+ apply: function(target, thisArg, args) {
123
+ const [resource, config] = args;
124
+
125
+ let url, method, headers, body;
126
+
127
+ if (resource instanceof Request) {
128
+ url = resource.url;
129
+ method = resource.method;
130
+ headers = Object.fromEntries(resource.headers.entries());
131
+ body = resource.body;
132
+ } else {
133
+ url = resource;
134
+ method = config?.method || 'GET';
135
+ headers = config?.headers || {};
136
+ body = config?.body;
137
+ }
138
+
139
+ const hookContext = {
140
+ url: url,
141
+ method: method,
142
+ headers: headers,
143
+ body: body,
144
+ timestamp: Date.now(),
145
+ stackTrace: new Error().stack.split('\\n').slice(2, 5).join('\\n')
146
+ };
147
+
148
+ console.log('[Fetch Hook] request:', hookContext);
149
+
150
+ ${action === 'block' ? 'return Promise.reject(new Error("Fetch blocked by hook"));' : ''}
151
+ ${customCode || ''}
152
+
153
+ const startTime = performance.now();
154
+
155
+ return Reflect.apply(target, thisArg, args)
156
+ .then(async response => {
157
+ const endTime = performance.now();
158
+ const duration = (endTime - startTime).toFixed(2);
159
+
160
+ const clonedResponse = response.clone();
161
+
162
+ const responseInfo = {
163
+ url: url,
164
+ status: response.status,
165
+ statusText: response.statusText,
166
+ ok: response.ok,
167
+ redirected: response.redirected,
168
+ type: response.type,
169
+ headers: Object.fromEntries(response.headers.entries()),
170
+ duration: duration + 'ms'
171
+ };
172
+
173
+ console.log('[Fetch Hook] response:', responseInfo);
174
+
175
+ try {
176
+ const contentType = response.headers.get('content-type') || '';
177
+
178
+ if (contentType.includes('application/json')) {
179
+ const json = await clonedResponse.json();
180
+ console.log('[Fetch Hook] responseJSON:', json);
181
+ } else if (contentType.includes('text/')) {
182
+ const text = await clonedResponse.text();
183
+ console.log('[Fetch Hook] responseText:', text.substring(0, 500));
184
+ } else {
185
+ console.log('[Fetch Hook] response type:', contentType);
186
+ }
187
+ } catch (e) {
188
+ console.warn('[Fetch Hook] Failed to parse response:', e.message);
189
+ }
190
+
191
+ return response;
192
+ })
193
+ .catch(error => {
194
+ const endTime = performance.now();
195
+ const duration = (endTime - startTime).toFixed(2);
196
+
197
+ console.error('[Fetch Hook] error:', {
198
+ url: url,
199
+ error: error.message,
200
+ duration: duration + 'ms'
201
+ });
202
+
203
+ throw error;
204
+ });
205
+ }
206
+ });
207
+
208
+ console.log('[Fetch Hook] Successfully hooked window.fetch');
209
+ })();
210
210
  `.trim();
211
211
  }
212
212
  export function generateWebSocketHook(action, customCode, _condition, _performance = false) {
213
- return `
214
- (function() {
215
- 'use strict';
216
-
217
- const OriginalWebSocket = window.WebSocket;
218
- let wsCounter = 0;
219
-
220
- window.WebSocket = function(url, protocols) {
221
- const wsId = ++wsCounter;
222
- const connectTime = Date.now();
223
-
224
- console.log(\`[WebSocket Hook #\${wsId}] connecting:\`, {
225
- url: url,
226
- protocols: protocols,
227
- timestamp: new Date().toISOString()
228
- });
229
-
230
- ${action === 'block' ? 'throw new Error("WebSocket blocked by hook");' : ''}
231
-
232
- const ws = new OriginalWebSocket(url, protocols);
233
-
234
- const originalSend = ws.send;
235
- ws.send = function(data) {
236
- const dataInfo = {
237
- wsId: wsId,
238
- url: url,
239
- timestamp: new Date().toISOString(),
240
- dataType: typeof data,
241
- size: data?.length || data?.byteLength || data?.size || 0
242
- };
243
-
244
- if (typeof data === 'string') {
245
- dataInfo.content = data.length > 500 ? data.substring(0, 500) + '...' : data;
246
- } else if (data instanceof ArrayBuffer) {
247
- dataInfo.content = \`ArrayBuffer(\${data.byteLength} bytes)\`;
248
- } else if (data instanceof Blob) {
249
- dataInfo.content = \`Blob(\${data.size} bytes, \${data.type})\`;
250
- }
251
-
252
- console.log(\`[WebSocket Hook #\${wsId}] send:\`, dataInfo);
253
-
254
- ${customCode || ''}
255
-
256
- return originalSend.apply(this, arguments);
257
- };
258
-
259
- ws.addEventListener('open', function(event) {
260
- const duration = Date.now() - connectTime;
261
- console.log(\`[WebSocket Hook #\${wsId}] open:\`, {
262
- url: url,
263
- readyState: ws.readyState,
264
- protocol: ws.protocol,
265
- extensions: ws.extensions,
266
- duration: duration + 'ms'
267
- });
268
- });
269
-
270
- ws.addEventListener('message', function(event) {
271
- const messageInfo = {
272
- wsId: wsId,
273
- url: url,
274
- timestamp: new Date().toISOString(),
275
- dataType: typeof event.data
276
- };
277
-
278
- if (typeof event.data === 'string') {
279
- messageInfo.content = event.data.length > 500 ? event.data.substring(0, 500) + '...' : event.data;
280
- } else if (event.data instanceof ArrayBuffer) {
281
- messageInfo.content = \`ArrayBuffer(\${event.data.byteLength} bytes)\`;
282
- } else if (event.data instanceof Blob) {
283
- messageInfo.content = \`Blob(\${event.data.size} bytes, \${event.data.type})\`;
284
- }
285
-
286
- console.log(\`[WebSocket Hook #\${wsId}] message:\`, messageInfo);
287
- });
288
-
289
- ws.addEventListener('error', function(event) {
290
- console.error(\`[WebSocket Hook #\${wsId}] error:\`, {
291
- url: url,
292
- readyState: ws.readyState,
293
- timestamp: new Date().toISOString()
294
- });
295
- });
296
-
297
- ws.addEventListener('close', function(event) {
298
- const duration = Date.now() - connectTime;
299
- console.log(\`[WebSocket Hook #\${wsId}] close:\`, {
300
- url: url,
301
- code: event.code,
302
- reason: event.reason,
303
- wasClean: event.wasClean,
304
- duration: duration + 'ms',
305
- timestamp: new Date().toISOString()
306
- });
307
- });
308
-
309
- return ws;
310
- };
311
-
312
- window.WebSocket.CONNECTING = OriginalWebSocket.CONNECTING;
313
- window.WebSocket.OPEN = OriginalWebSocket.OPEN;
314
- window.WebSocket.CLOSING = OriginalWebSocket.CLOSING;
315
- window.WebSocket.CLOSED = OriginalWebSocket.CLOSED;
316
-
317
- console.log('[WebSocket Hook] Successfully hooked window.WebSocket');
318
- })();
213
+ return `
214
+ (function() {
215
+ 'use strict';
216
+
217
+ const OriginalWebSocket = window.WebSocket;
218
+ let wsCounter = 0;
219
+
220
+ window.WebSocket = function(url, protocols) {
221
+ const wsId = ++wsCounter;
222
+ const connectTime = Date.now();
223
+
224
+ console.log(\`[WebSocket Hook #\${wsId}] connecting:\`, {
225
+ url: url,
226
+ protocols: protocols,
227
+ timestamp: new Date().toISOString()
228
+ });
229
+
230
+ ${action === 'block' ? 'throw new Error("WebSocket blocked by hook");' : ''}
231
+
232
+ const ws = new OriginalWebSocket(url, protocols);
233
+
234
+ const originalSend = ws.send;
235
+ ws.send = function(data) {
236
+ const dataInfo = {
237
+ wsId: wsId,
238
+ url: url,
239
+ timestamp: new Date().toISOString(),
240
+ dataType: typeof data,
241
+ size: data?.length || data?.byteLength || data?.size || 0
242
+ };
243
+
244
+ if (typeof data === 'string') {
245
+ dataInfo.content = data.length > 500 ? data.substring(0, 500) + '...' : data;
246
+ } else if (data instanceof ArrayBuffer) {
247
+ dataInfo.content = \`ArrayBuffer(\${data.byteLength} bytes)\`;
248
+ } else if (data instanceof Blob) {
249
+ dataInfo.content = \`Blob(\${data.size} bytes, \${data.type})\`;
250
+ }
251
+
252
+ console.log(\`[WebSocket Hook #\${wsId}] send:\`, dataInfo);
253
+
254
+ ${customCode || ''}
255
+
256
+ return originalSend.apply(this, arguments);
257
+ };
258
+
259
+ ws.addEventListener('open', function(event) {
260
+ const duration = Date.now() - connectTime;
261
+ console.log(\`[WebSocket Hook #\${wsId}] open:\`, {
262
+ url: url,
263
+ readyState: ws.readyState,
264
+ protocol: ws.protocol,
265
+ extensions: ws.extensions,
266
+ duration: duration + 'ms'
267
+ });
268
+ });
269
+
270
+ ws.addEventListener('message', function(event) {
271
+ const messageInfo = {
272
+ wsId: wsId,
273
+ url: url,
274
+ timestamp: new Date().toISOString(),
275
+ dataType: typeof event.data
276
+ };
277
+
278
+ if (typeof event.data === 'string') {
279
+ messageInfo.content = event.data.length > 500 ? event.data.substring(0, 500) + '...' : event.data;
280
+ } else if (event.data instanceof ArrayBuffer) {
281
+ messageInfo.content = \`ArrayBuffer(\${event.data.byteLength} bytes)\`;
282
+ } else if (event.data instanceof Blob) {
283
+ messageInfo.content = \`Blob(\${event.data.size} bytes, \${event.data.type})\`;
284
+ }
285
+
286
+ console.log(\`[WebSocket Hook #\${wsId}] message:\`, messageInfo);
287
+ });
288
+
289
+ ws.addEventListener('error', function(event) {
290
+ console.error(\`[WebSocket Hook #\${wsId}] error:\`, {
291
+ url: url,
292
+ readyState: ws.readyState,
293
+ timestamp: new Date().toISOString()
294
+ });
295
+ });
296
+
297
+ ws.addEventListener('close', function(event) {
298
+ const duration = Date.now() - connectTime;
299
+ console.log(\`[WebSocket Hook #\${wsId}] close:\`, {
300
+ url: url,
301
+ code: event.code,
302
+ reason: event.reason,
303
+ wasClean: event.wasClean,
304
+ duration: duration + 'ms',
305
+ timestamp: new Date().toISOString()
306
+ });
307
+ });
308
+
309
+ return ws;
310
+ };
311
+
312
+ window.WebSocket.CONNECTING = OriginalWebSocket.CONNECTING;
313
+ window.WebSocket.OPEN = OriginalWebSocket.OPEN;
314
+ window.WebSocket.CLOSING = OriginalWebSocket.CLOSING;
315
+ window.WebSocket.CLOSED = OriginalWebSocket.CLOSED;
316
+
317
+ console.log('[WebSocket Hook] Successfully hooked window.WebSocket');
318
+ })();
319
319
  `.trim();
320
320
  }