@ai-jshook/mcp 0.1.1

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 (271) hide show
  1. package/.env.example +38 -0
  2. package/CLAUDE.md +170 -0
  3. package/README.md +564 -0
  4. package/bun.lock +1484 -0
  5. package/dist/index.d.ts +3 -0
  6. package/dist/index.d.ts.map +1 -0
  7. package/dist/index.js +57 -0
  8. package/dist/index.js.map +1 -0
  9. package/dist/modules/analyzer/AISummarizer.d.ts +41 -0
  10. package/dist/modules/analyzer/AISummarizer.d.ts.map +1 -0
  11. package/dist/modules/analyzer/AISummarizer.js +186 -0
  12. package/dist/modules/analyzer/AISummarizer.js.map +1 -0
  13. package/dist/modules/analyzer/CodeAnalyzer.d.ts +28 -0
  14. package/dist/modules/analyzer/CodeAnalyzer.d.ts.map +1 -0
  15. package/dist/modules/analyzer/CodeAnalyzer.js +1287 -0
  16. package/dist/modules/analyzer/CodeAnalyzer.js.map +1 -0
  17. package/dist/modules/analyzer/IntelligentAnalyzer.d.ts +114 -0
  18. package/dist/modules/analyzer/IntelligentAnalyzer.d.ts.map +1 -0
  19. package/dist/modules/analyzer/IntelligentAnalyzer.js +1176 -0
  20. package/dist/modules/analyzer/IntelligentAnalyzer.js.map +1 -0
  21. package/dist/modules/browser/BrowserModeManager.d.ts +31 -0
  22. package/dist/modules/browser/BrowserModeManager.d.ts.map +1 -0
  23. package/dist/modules/browser/BrowserModeManager.js +241 -0
  24. package/dist/modules/browser/BrowserModeManager.js.map +1 -0
  25. package/dist/modules/captcha/AICaptchaDetector.d.ts +32 -0
  26. package/dist/modules/captcha/AICaptchaDetector.d.ts.map +1 -0
  27. package/dist/modules/captcha/AICaptchaDetector.js +387 -0
  28. package/dist/modules/captcha/AICaptchaDetector.js.map +1 -0
  29. package/dist/modules/captcha/CaptchaDetector.d.ts +28 -0
  30. package/dist/modules/captcha/CaptchaDetector.d.ts.map +1 -0
  31. package/dist/modules/captcha/CaptchaDetector.js +513 -0
  32. package/dist/modules/captcha/CaptchaDetector.js.map +1 -0
  33. package/dist/modules/collector/CodeCache.d.ts +37 -0
  34. package/dist/modules/collector/CodeCache.d.ts.map +1 -0
  35. package/dist/modules/collector/CodeCache.js +188 -0
  36. package/dist/modules/collector/CodeCache.js.map +1 -0
  37. package/dist/modules/collector/CodeCollector.d.ts +107 -0
  38. package/dist/modules/collector/CodeCollector.d.ts.map +1 -0
  39. package/dist/modules/collector/CodeCollector.js +796 -0
  40. package/dist/modules/collector/CodeCollector.js.map +1 -0
  41. package/dist/modules/collector/CodeCompressor.d.ts +65 -0
  42. package/dist/modules/collector/CodeCompressor.d.ts.map +1 -0
  43. package/dist/modules/collector/CodeCompressor.js +245 -0
  44. package/dist/modules/collector/CodeCompressor.js.map +1 -0
  45. package/dist/modules/collector/DOMInspector.d.ts +51 -0
  46. package/dist/modules/collector/DOMInspector.d.ts.map +1 -0
  47. package/dist/modules/collector/DOMInspector.js +437 -0
  48. package/dist/modules/collector/DOMInspector.js.map +1 -0
  49. package/dist/modules/collector/PageController.d.ts +79 -0
  50. package/dist/modules/collector/PageController.d.ts.map +1 -0
  51. package/dist/modules/collector/PageController.js +287 -0
  52. package/dist/modules/collector/PageController.js.map +1 -0
  53. package/dist/modules/collector/SmartCodeCollector.d.ts +38 -0
  54. package/dist/modules/collector/SmartCodeCollector.d.ts.map +1 -0
  55. package/dist/modules/collector/SmartCodeCollector.js +208 -0
  56. package/dist/modules/collector/SmartCodeCollector.js.map +1 -0
  57. package/dist/modules/collector/StreamingCollector.d.ts +46 -0
  58. package/dist/modules/collector/StreamingCollector.d.ts.map +1 -0
  59. package/dist/modules/collector/StreamingCollector.js +127 -0
  60. package/dist/modules/collector/StreamingCollector.js.map +1 -0
  61. package/dist/modules/crypto/CryptoDetector.d.ts +22 -0
  62. package/dist/modules/crypto/CryptoDetector.d.ts.map +1 -0
  63. package/dist/modules/crypto/CryptoDetector.js +168 -0
  64. package/dist/modules/crypto/CryptoDetector.js.map +1 -0
  65. package/dist/modules/crypto/CryptoDetectorEnhanced.d.ts +31 -0
  66. package/dist/modules/crypto/CryptoDetectorEnhanced.d.ts.map +1 -0
  67. package/dist/modules/crypto/CryptoDetectorEnhanced.js +269 -0
  68. package/dist/modules/crypto/CryptoDetectorEnhanced.js.map +1 -0
  69. package/dist/modules/crypto/CryptoRules.d.ts +59 -0
  70. package/dist/modules/crypto/CryptoRules.d.ts.map +1 -0
  71. package/dist/modules/crypto/CryptoRules.js +234 -0
  72. package/dist/modules/crypto/CryptoRules.js.map +1 -0
  73. package/dist/modules/debugger/BlackboxManager.d.ts +14 -0
  74. package/dist/modules/debugger/BlackboxManager.d.ts.map +1 -0
  75. package/dist/modules/debugger/BlackboxManager.js +98 -0
  76. package/dist/modules/debugger/BlackboxManager.js.map +1 -0
  77. package/dist/modules/debugger/DebuggerManager.d.ts +138 -0
  78. package/dist/modules/debugger/DebuggerManager.d.ts.map +1 -0
  79. package/dist/modules/debugger/DebuggerManager.js +777 -0
  80. package/dist/modules/debugger/DebuggerManager.js.map +1 -0
  81. package/dist/modules/debugger/EventBreakpointManager.d.ts +30 -0
  82. package/dist/modules/debugger/EventBreakpointManager.d.ts.map +1 -0
  83. package/dist/modules/debugger/EventBreakpointManager.js +125 -0
  84. package/dist/modules/debugger/EventBreakpointManager.js.map +1 -0
  85. package/dist/modules/debugger/RuntimeInspector.d.ts +54 -0
  86. package/dist/modules/debugger/RuntimeInspector.d.ts.map +1 -0
  87. package/dist/modules/debugger/RuntimeInspector.js +277 -0
  88. package/dist/modules/debugger/RuntimeInspector.js.map +1 -0
  89. package/dist/modules/debugger/ScriptManager.d.ts +94 -0
  90. package/dist/modules/debugger/ScriptManager.d.ts.map +1 -0
  91. package/dist/modules/debugger/ScriptManager.js +433 -0
  92. package/dist/modules/debugger/ScriptManager.js.map +1 -0
  93. package/dist/modules/debugger/WatchExpressionManager.d.ts +52 -0
  94. package/dist/modules/debugger/WatchExpressionManager.d.ts.map +1 -0
  95. package/dist/modules/debugger/WatchExpressionManager.js +136 -0
  96. package/dist/modules/debugger/WatchExpressionManager.js.map +1 -0
  97. package/dist/modules/debugger/XHRBreakpointManager.d.ts +21 -0
  98. package/dist/modules/debugger/XHRBreakpointManager.d.ts.map +1 -0
  99. package/dist/modules/debugger/XHRBreakpointManager.js +81 -0
  100. package/dist/modules/debugger/XHRBreakpointManager.js.map +1 -0
  101. package/dist/modules/deobfuscator/ASTOptimizer.d.ts +12 -0
  102. package/dist/modules/deobfuscator/ASTOptimizer.d.ts.map +1 -0
  103. package/dist/modules/deobfuscator/ASTOptimizer.js +234 -0
  104. package/dist/modules/deobfuscator/ASTOptimizer.js.map +1 -0
  105. package/dist/modules/deobfuscator/AdvancedDeobfuscator.d.ts +52 -0
  106. package/dist/modules/deobfuscator/AdvancedDeobfuscator.d.ts.map +1 -0
  107. package/dist/modules/deobfuscator/AdvancedDeobfuscator.js +985 -0
  108. package/dist/modules/deobfuscator/AdvancedDeobfuscator.js.map +1 -0
  109. package/dist/modules/deobfuscator/Deobfuscator.d.ts +23 -0
  110. package/dist/modules/deobfuscator/Deobfuscator.d.ts.map +1 -0
  111. package/dist/modules/deobfuscator/Deobfuscator.js +487 -0
  112. package/dist/modules/deobfuscator/Deobfuscator.js.map +1 -0
  113. package/dist/modules/deobfuscator/JSVMPDeobfuscator.d.ts +19 -0
  114. package/dist/modules/deobfuscator/JSVMPDeobfuscator.d.ts.map +1 -0
  115. package/dist/modules/deobfuscator/JSVMPDeobfuscator.js +594 -0
  116. package/dist/modules/deobfuscator/JSVMPDeobfuscator.js.map +1 -0
  117. package/dist/modules/deobfuscator/JScramberDeobfuscator.d.ts +28 -0
  118. package/dist/modules/deobfuscator/JScramberDeobfuscator.d.ts.map +1 -0
  119. package/dist/modules/deobfuscator/JScramberDeobfuscator.js +239 -0
  120. package/dist/modules/deobfuscator/JScramberDeobfuscator.js.map +1 -0
  121. package/dist/modules/deobfuscator/PackerDeobfuscator.d.ts +38 -0
  122. package/dist/modules/deobfuscator/PackerDeobfuscator.d.ts.map +1 -0
  123. package/dist/modules/deobfuscator/PackerDeobfuscator.js +191 -0
  124. package/dist/modules/deobfuscator/PackerDeobfuscator.js.map +1 -0
  125. package/dist/modules/detector/ObfuscationDetector.d.ts +35 -0
  126. package/dist/modules/detector/ObfuscationDetector.d.ts.map +1 -0
  127. package/dist/modules/detector/ObfuscationDetector.js +278 -0
  128. package/dist/modules/detector/ObfuscationDetector.js.map +1 -0
  129. package/dist/modules/emulator/AIEnvironmentAnalyzer.d.ts +32 -0
  130. package/dist/modules/emulator/AIEnvironmentAnalyzer.d.ts.map +1 -0
  131. package/dist/modules/emulator/AIEnvironmentAnalyzer.js +548 -0
  132. package/dist/modules/emulator/AIEnvironmentAnalyzer.js.map +1 -0
  133. package/dist/modules/emulator/BrowserAPIDatabase.d.ts +34 -0
  134. package/dist/modules/emulator/BrowserAPIDatabase.d.ts.map +1 -0
  135. package/dist/modules/emulator/BrowserAPIDatabase.js +326 -0
  136. package/dist/modules/emulator/BrowserAPIDatabase.js.map +1 -0
  137. package/dist/modules/emulator/BrowserEnvironmentRules.d.ts +47 -0
  138. package/dist/modules/emulator/BrowserEnvironmentRules.d.ts.map +1 -0
  139. package/dist/modules/emulator/BrowserEnvironmentRules.js +493 -0
  140. package/dist/modules/emulator/BrowserEnvironmentRules.js.map +1 -0
  141. package/dist/modules/emulator/EnvironmentEmulator.d.ts +27 -0
  142. package/dist/modules/emulator/EnvironmentEmulator.d.ts.map +1 -0
  143. package/dist/modules/emulator/EnvironmentEmulator.js +1113 -0
  144. package/dist/modules/emulator/EnvironmentEmulator.js.map +1 -0
  145. package/dist/modules/emulator/EnvironmentEmulatorEnhanced.d.ts +26 -0
  146. package/dist/modules/emulator/EnvironmentEmulatorEnhanced.d.ts.map +1 -0
  147. package/dist/modules/emulator/EnvironmentEmulatorEnhanced.js +493 -0
  148. package/dist/modules/emulator/EnvironmentEmulatorEnhanced.js.map +1 -0
  149. package/dist/modules/emulator/templates/chrome-env.d.ts +260 -0
  150. package/dist/modules/emulator/templates/chrome-env.d.ts.map +1 -0
  151. package/dist/modules/emulator/templates/chrome-env.js +253 -0
  152. package/dist/modules/emulator/templates/chrome-env.js.map +1 -0
  153. package/dist/modules/hook/AIHookGenerator.d.ts +53 -0
  154. package/dist/modules/hook/AIHookGenerator.d.ts.map +1 -0
  155. package/dist/modules/hook/AIHookGenerator.js +353 -0
  156. package/dist/modules/hook/AIHookGenerator.js.map +1 -0
  157. package/dist/modules/hook/HookManager.d.ts +67 -0
  158. package/dist/modules/hook/HookManager.d.ts.map +1 -0
  159. package/dist/modules/hook/HookManager.js +1225 -0
  160. package/dist/modules/hook/HookManager.js.map +1 -0
  161. package/dist/modules/monitor/ConsoleMonitor.d.ts +140 -0
  162. package/dist/modules/monitor/ConsoleMonitor.d.ts.map +1 -0
  163. package/dist/modules/monitor/ConsoleMonitor.js +834 -0
  164. package/dist/modules/monitor/ConsoleMonitor.js.map +1 -0
  165. package/dist/modules/monitor/PerformanceMonitor.d.ts +65 -0
  166. package/dist/modules/monitor/PerformanceMonitor.d.ts.map +1 -0
  167. package/dist/modules/monitor/PerformanceMonitor.js +175 -0
  168. package/dist/modules/monitor/PerformanceMonitor.js.map +1 -0
  169. package/dist/modules/stealth/StealthScripts2025.d.ts +17 -0
  170. package/dist/modules/stealth/StealthScripts2025.d.ts.map +1 -0
  171. package/dist/modules/stealth/StealthScripts2025.js +274 -0
  172. package/dist/modules/stealth/StealthScripts2025.js.map +1 -0
  173. package/dist/modules/symbolic/JSVMPSymbolicExecutor.d.ts +69 -0
  174. package/dist/modules/symbolic/JSVMPSymbolicExecutor.d.ts.map +1 -0
  175. package/dist/modules/symbolic/JSVMPSymbolicExecutor.js +232 -0
  176. package/dist/modules/symbolic/JSVMPSymbolicExecutor.js.map +1 -0
  177. package/dist/modules/symbolic/SymbolicExecutor.d.ts +69 -0
  178. package/dist/modules/symbolic/SymbolicExecutor.d.ts.map +1 -0
  179. package/dist/modules/symbolic/SymbolicExecutor.js +346 -0
  180. package/dist/modules/symbolic/SymbolicExecutor.js.map +1 -0
  181. package/dist/server/AIHookToolDefinitions.d.ts +3 -0
  182. package/dist/server/AIHookToolDefinitions.d.ts.map +1 -0
  183. package/dist/server/AIHookToolDefinitions.js +284 -0
  184. package/dist/server/AIHookToolDefinitions.js.map +1 -0
  185. package/dist/server/AIHookToolHandlers.d.ts +50 -0
  186. package/dist/server/AIHookToolHandlers.d.ts.map +1 -0
  187. package/dist/server/AIHookToolHandlers.js +311 -0
  188. package/dist/server/AIHookToolHandlers.js.map +1 -0
  189. package/dist/server/AdvancedToolDefinitions.d.ts +3 -0
  190. package/dist/server/AdvancedToolDefinitions.d.ts.map +1 -0
  191. package/dist/server/AdvancedToolDefinitions.js +218 -0
  192. package/dist/server/AdvancedToolDefinitions.js.map +1 -0
  193. package/dist/server/AdvancedToolHandlers.d.ts +85 -0
  194. package/dist/server/AdvancedToolHandlers.d.ts.map +1 -0
  195. package/dist/server/AdvancedToolHandlers.js +431 -0
  196. package/dist/server/AdvancedToolHandlers.js.map +1 -0
  197. package/dist/server/BrowserToolDefinitions.d.ts +3 -0
  198. package/dist/server/BrowserToolDefinitions.d.ts.map +1 -0
  199. package/dist/server/BrowserToolDefinitions.js +841 -0
  200. package/dist/server/BrowserToolDefinitions.js.map +1 -0
  201. package/dist/server/BrowserToolHandlers.d.ts +290 -0
  202. package/dist/server/BrowserToolHandlers.d.ts.map +1 -0
  203. package/dist/server/BrowserToolHandlers.js +784 -0
  204. package/dist/server/BrowserToolHandlers.js.map +1 -0
  205. package/dist/server/CacheToolDefinitions.d.ts +3 -0
  206. package/dist/server/CacheToolDefinitions.d.ts.map +1 -0
  207. package/dist/server/CacheToolDefinitions.js +166 -0
  208. package/dist/server/CacheToolDefinitions.js.map +1 -0
  209. package/dist/server/DebuggerToolDefinitions.d.ts +3 -0
  210. package/dist/server/DebuggerToolDefinitions.d.ts.map +1 -0
  211. package/dist/server/DebuggerToolDefinitions.js +600 -0
  212. package/dist/server/DebuggerToolDefinitions.js.map +1 -0
  213. package/dist/server/DebuggerToolHandlers.d.ts +230 -0
  214. package/dist/server/DebuggerToolHandlers.d.ts.map +1 -0
  215. package/dist/server/DebuggerToolHandlers.js +935 -0
  216. package/dist/server/DebuggerToolHandlers.js.map +1 -0
  217. package/dist/server/MCPServer.d.ts +55 -0
  218. package/dist/server/MCPServer.d.ts.map +1 -0
  219. package/dist/server/MCPServer.js +1344 -0
  220. package/dist/server/MCPServer.js.map +1 -0
  221. package/dist/server/TokenBudgetToolDefinitions.d.ts +3 -0
  222. package/dist/server/TokenBudgetToolDefinitions.d.ts.map +1 -0
  223. package/dist/server/TokenBudgetToolDefinitions.js +114 -0
  224. package/dist/server/TokenBudgetToolDefinitions.js.map +1 -0
  225. package/dist/services/LLMService.d.ts +41 -0
  226. package/dist/services/LLMService.d.ts.map +1 -0
  227. package/dist/services/LLMService.js +792 -0
  228. package/dist/services/LLMService.js.map +1 -0
  229. package/dist/types/index.d.ts +527 -0
  230. package/dist/types/index.d.ts.map +1 -0
  231. package/dist/types/index.js +2 -0
  232. package/dist/types/index.js.map +1 -0
  233. package/dist/utils/AdaptiveDataSerializer.d.ts +27 -0
  234. package/dist/utils/AdaptiveDataSerializer.d.ts.map +1 -0
  235. package/dist/utils/AdaptiveDataSerializer.js +215 -0
  236. package/dist/utils/AdaptiveDataSerializer.js.map +1 -0
  237. package/dist/utils/CacheAdapters.d.ts +30 -0
  238. package/dist/utils/CacheAdapters.d.ts.map +1 -0
  239. package/dist/utils/CacheAdapters.js +83 -0
  240. package/dist/utils/CacheAdapters.js.map +1 -0
  241. package/dist/utils/TokenBudgetManager.d.ts +52 -0
  242. package/dist/utils/TokenBudgetManager.d.ts.map +1 -0
  243. package/dist/utils/TokenBudgetManager.js +190 -0
  244. package/dist/utils/TokenBudgetManager.js.map +1 -0
  245. package/dist/utils/UnifiedCacheManager.d.ts +55 -0
  246. package/dist/utils/UnifiedCacheManager.d.ts.map +1 -0
  247. package/dist/utils/UnifiedCacheManager.js +207 -0
  248. package/dist/utils/UnifiedCacheManager.js.map +1 -0
  249. package/dist/utils/cache.d.ts +13 -0
  250. package/dist/utils/cache.d.ts.map +1 -0
  251. package/dist/utils/cache.js +92 -0
  252. package/dist/utils/cache.js.map +1 -0
  253. package/dist/utils/config.d.ts +7 -0
  254. package/dist/utils/config.d.ts.map +1 -0
  255. package/dist/utils/config.js +93 -0
  256. package/dist/utils/config.js.map +1 -0
  257. package/dist/utils/detailedDataManager.d.ts +60 -0
  258. package/dist/utils/detailedDataManager.d.ts.map +1 -0
  259. package/dist/utils/detailedDataManager.js +204 -0
  260. package/dist/utils/detailedDataManager.js.map +1 -0
  261. package/dist/utils/logger.d.ts +16 -0
  262. package/dist/utils/logger.d.ts.map +1 -0
  263. package/dist/utils/logger.js +47 -0
  264. package/dist/utils/logger.js.map +1 -0
  265. package/dist/utils/parallel.d.ts +40 -0
  266. package/dist/utils/parallel.d.ts.map +1 -0
  267. package/dist/utils/parallel.js +148 -0
  268. package/dist/utils/parallel.js.map +1 -0
  269. package/package.json +94 -0
  270. package/server.json +39 -0
  271. package/tsconfig.dev.json +14 -0
@@ -0,0 +1,792 @@
1
+ import OpenAI from 'openai';
2
+ import Anthropic from '@anthropic-ai/sdk';
3
+ import { readFile } from 'fs/promises';
4
+ import { logger } from '../utils/logger.js';
5
+ export class LLMService {
6
+ config;
7
+ openai;
8
+ anthropic;
9
+ retryOptions = {
10
+ maxRetries: 3,
11
+ initialDelay: 1000,
12
+ maxDelay: 10000,
13
+ backoffMultiplier: 2,
14
+ };
15
+ constructor(config, retryOptions) {
16
+ this.config = config;
17
+ if (retryOptions) {
18
+ this.retryOptions = { ...this.retryOptions, ...retryOptions };
19
+ }
20
+ this.initClients();
21
+ }
22
+ initClients() {
23
+ if (this.config.provider === 'openai' && this.config.openai?.apiKey) {
24
+ this.openai = new OpenAI({
25
+ apiKey: this.config.openai.apiKey,
26
+ baseURL: this.config.openai.baseURL,
27
+ defaultHeaders: this.config.openai.headers,
28
+ });
29
+ logger.info('OpenAI client initialized');
30
+ }
31
+ if (this.config.provider === 'anthropic' && this.config.anthropic?.apiKey) {
32
+ this.anthropic = new Anthropic({
33
+ apiKey: this.config.anthropic.apiKey,
34
+ });
35
+ logger.info('Anthropic client initialized');
36
+ }
37
+ }
38
+ async chat(messages, options) {
39
+ return this.withRetry(async () => {
40
+ const startTime = Date.now();
41
+ try {
42
+ if (this.config.provider === 'openai') {
43
+ return await this.chatOpenAI(messages, options);
44
+ }
45
+ else if (this.config.provider === 'anthropic') {
46
+ return await this.chatAnthropic(messages, options);
47
+ }
48
+ else {
49
+ throw new Error(`Unsupported LLM provider: ${this.config.provider}`);
50
+ }
51
+ }
52
+ finally {
53
+ const duration = Date.now() - startTime;
54
+ logger.debug(`LLM call completed in ${duration}ms`);
55
+ }
56
+ });
57
+ }
58
+ async analyzeImage(imageInput, prompt, isFilePath = false) {
59
+ return this.withRetry(async () => {
60
+ const startTime = Date.now();
61
+ try {
62
+ let imageBase64;
63
+ if (isFilePath) {
64
+ logger.info(`📂 读取图片文件: ${imageInput}`);
65
+ const imageBuffer = await readFile(imageInput);
66
+ imageBase64 = imageBuffer.toString('base64');
67
+ logger.info(`✅ 图片文件已读取 (${(imageBuffer.length / 1024).toFixed(2)} KB)`);
68
+ }
69
+ else {
70
+ imageBase64 = imageInput;
71
+ }
72
+ if (this.config.provider === 'openai') {
73
+ if (!this.openai) {
74
+ throw new Error('OpenAI client not initialized');
75
+ }
76
+ const model = this.config.openai?.model || 'gpt-4-vision-preview';
77
+ const isVisionModel = model.includes('vision') || model.includes('gpt-4o') || model.includes('gpt-4-turbo');
78
+ if (!isVisionModel) {
79
+ logger.warn(`⚠️ 当前模型 ${model} 不支持图片分析,建议使用 gpt-4-vision-preview 或 gpt-4o`);
80
+ throw new Error(`Model ${model} does not support image analysis. ` +
81
+ `Please use gpt-4-vision-preview, gpt-4o, or gpt-4-turbo. ` +
82
+ `Current config: OPENAI_MODEL=${model}, OPENAI_BASE_URL=${this.config.openai?.baseURL || 'default'}`);
83
+ }
84
+ logger.info(`🖼️ Using OpenAI Vision model: ${model}`);
85
+ const response = await this.openai.chat.completions.create({
86
+ model,
87
+ messages: [
88
+ {
89
+ role: 'user',
90
+ content: [
91
+ { type: 'text', text: prompt },
92
+ {
93
+ type: 'image_url',
94
+ image_url: {
95
+ url: `data:image/png;base64,${imageBase64}`,
96
+ },
97
+ },
98
+ ],
99
+ },
100
+ ],
101
+ max_tokens: 1000,
102
+ });
103
+ return response.choices[0]?.message?.content || '';
104
+ }
105
+ else if (this.config.provider === 'anthropic') {
106
+ if (!this.anthropic) {
107
+ throw new Error('Anthropic client not initialized');
108
+ }
109
+ const model = this.config.anthropic?.model || 'claude-3-opus-20240229';
110
+ const isVisionModel = model.includes('claude-3') || model.includes('claude-2.1');
111
+ if (!isVisionModel) {
112
+ logger.warn(`⚠️ 当前模型 ${model} 可能不支持图片分析,建议使用 claude-3-opus 或 claude-3-sonnet`);
113
+ }
114
+ logger.info(`🖼️ Using Anthropic Vision model: ${model}`);
115
+ const response = await this.anthropic.messages.create({
116
+ model,
117
+ max_tokens: 1000,
118
+ messages: [
119
+ {
120
+ role: 'user',
121
+ content: [
122
+ {
123
+ type: 'image',
124
+ source: {
125
+ type: 'base64',
126
+ media_type: 'image/png',
127
+ data: imageBase64,
128
+ },
129
+ },
130
+ {
131
+ type: 'text',
132
+ text: prompt,
133
+ },
134
+ ],
135
+ },
136
+ ],
137
+ });
138
+ const textContent = response.content.find((c) => c.type === 'text');
139
+ return textContent?.text || '';
140
+ }
141
+ else {
142
+ throw new Error(`Unsupported LLM provider for image analysis: ${this.config.provider}`);
143
+ }
144
+ }
145
+ catch (error) {
146
+ const errorMessage = error instanceof Error ? error.message : String(error);
147
+ logger.error('❌ Image analysis failed:', errorMessage);
148
+ if (errorMessage.includes('does not support image analysis')) {
149
+ logger.error('💡 解决方案:');
150
+ logger.error(' 1. 修改 .env 文件中的 OPENAI_MODEL 为 gpt-4-vision-preview 或 gpt-4o');
151
+ logger.error(' 2. 或者切换到 Anthropic: DEFAULT_LLM_PROVIDER=anthropic');
152
+ logger.error(' 3. 当前配置不支持AI验证码检测,将使用降级方案');
153
+ }
154
+ throw error;
155
+ }
156
+ finally {
157
+ const duration = Date.now() - startTime;
158
+ logger.debug(`Image analysis completed in ${duration}ms`);
159
+ }
160
+ });
161
+ }
162
+ async withRetry(fn) {
163
+ let lastError;
164
+ let delay = this.retryOptions.initialDelay;
165
+ for (let attempt = 0; attempt <= this.retryOptions.maxRetries; attempt++) {
166
+ try {
167
+ return await fn();
168
+ }
169
+ catch (error) {
170
+ lastError = error instanceof Error ? error : new Error(String(error));
171
+ if (!this.shouldRetry(lastError) || attempt === this.retryOptions.maxRetries) {
172
+ throw lastError;
173
+ }
174
+ logger.warn(`LLM call failed (attempt ${attempt + 1}/${this.retryOptions.maxRetries + 1}): ${lastError.message}`);
175
+ logger.debug(`Retrying in ${delay}ms...`);
176
+ await new Promise((resolve) => setTimeout(resolve, delay));
177
+ delay = Math.min(delay * this.retryOptions.backoffMultiplier, this.retryOptions.maxDelay);
178
+ }
179
+ }
180
+ throw lastError || new Error('Unknown error');
181
+ }
182
+ shouldRetry(error) {
183
+ const message = error.message.toLowerCase();
184
+ const retryableErrors = [
185
+ 'rate limit',
186
+ 'timeout',
187
+ 'network',
188
+ 'econnreset',
189
+ 'enotfound',
190
+ 'etimedout',
191
+ '429',
192
+ '500',
193
+ '502',
194
+ '503',
195
+ '504',
196
+ ];
197
+ return retryableErrors.some((pattern) => message.includes(pattern));
198
+ }
199
+ async chatOpenAI(messages, options) {
200
+ if (!this.openai) {
201
+ throw new Error('OpenAI client not initialized');
202
+ }
203
+ const response = await this.openai.chat.completions.create({
204
+ model: this.config.openai?.model || 'gpt-4-turbo-preview',
205
+ messages: messages.map((msg) => ({
206
+ role: msg.role,
207
+ content: msg.content,
208
+ })),
209
+ temperature: options?.temperature ?? 0.7,
210
+ max_tokens: options?.maxTokens ?? 4000,
211
+ });
212
+ const choice = response.choices[0];
213
+ if (!choice?.message?.content) {
214
+ throw new Error('No response from OpenAI');
215
+ }
216
+ return {
217
+ content: choice.message.content,
218
+ usage: response.usage
219
+ ? {
220
+ promptTokens: response.usage.prompt_tokens,
221
+ completionTokens: response.usage.completion_tokens,
222
+ totalTokens: response.usage.total_tokens,
223
+ }
224
+ : undefined,
225
+ };
226
+ }
227
+ async chatAnthropic(messages, options) {
228
+ if (!this.anthropic) {
229
+ throw new Error('Anthropic client not initialized');
230
+ }
231
+ const systemMessage = messages.find((msg) => msg.role === 'system');
232
+ const userMessages = messages.filter((msg) => msg.role !== 'system');
233
+ const response = await this.anthropic.messages.create({
234
+ model: this.config.anthropic?.model || 'claude-3-5-sonnet-20241022',
235
+ max_tokens: options?.maxTokens ?? 4000,
236
+ temperature: options?.temperature ?? 0.7,
237
+ system: systemMessage?.content,
238
+ messages: userMessages.map((msg) => ({
239
+ role: msg.role === 'assistant' ? 'assistant' : 'user',
240
+ content: msg.content,
241
+ })),
242
+ });
243
+ const content = response.content[0];
244
+ if (!content || content.type !== 'text') {
245
+ throw new Error('Unexpected response type from Anthropic');
246
+ }
247
+ return {
248
+ content: content.text,
249
+ usage: {
250
+ promptTokens: response.usage.input_tokens,
251
+ completionTokens: response.usage.output_tokens,
252
+ totalTokens: response.usage.input_tokens + response.usage.output_tokens,
253
+ },
254
+ };
255
+ }
256
+ generateCodeAnalysisPrompt(code, focus) {
257
+ const systemPrompt = `# Role
258
+ You are an expert JavaScript/TypeScript reverse engineer and code analyst with 10+ years of experience in:
259
+ - Static code analysis and AST manipulation
260
+ - Security vulnerability detection (OWASP Top 10)
261
+ - Framework and library identification (React, Vue, Angular, etc.)
262
+ - Code obfuscation and deobfuscation techniques
263
+ - Software architecture and design patterns
264
+
265
+ # Task
266
+ Perform deep static analysis on the provided JavaScript code to extract:
267
+ 1. Technical stack (frameworks, bundlers, libraries)
268
+ 2. Code structure (functions, classes, modules)
269
+ 3. Business logic and data flow
270
+ 4. Security vulnerabilities and risks
271
+ 5. Code quality metrics
272
+
273
+ # Output Requirements
274
+ - Return ONLY valid JSON (no markdown, no explanations outside JSON)
275
+ - Follow the exact schema provided in the user message
276
+ - Use confidence scores (0.0-1.0) for uncertain detections
277
+ - Provide specific line numbers for security risks when possible
278
+ - Be precise and avoid hallucination
279
+
280
+ # Analysis Methodology
281
+ 1. First, identify the code's purpose and main functionality
282
+ 2. Then, detect frameworks and libraries by analyzing imports and API usage
283
+ 3. Next, map out the code structure and call graph
284
+ 4. Finally, perform security analysis using OWASP guidelines`;
285
+ const userPrompt = `# Analysis Focus
286
+ Primary focus: ${focus}
287
+
288
+ # Code to Analyze
289
+ \`\`\`javascript
290
+ ${code.length > 5000 ? code.substring(0, 5000) + '\n\n// ... (code truncated for analysis)' : code}
291
+ \`\`\`
292
+
293
+ # Required Output Schema
294
+ Return a JSON object with this EXACT structure (all fields are required):
295
+
296
+ \`\`\`json
297
+ {
298
+ "techStack": {
299
+ "framework": "string | null (e.g., 'React 18.x', 'Vue 3.x', 'Angular 15.x')",
300
+ "bundler": "string | null (e.g., 'Webpack 5', 'Vite', 'Rollup')",
301
+ "libraries": ["array of library names with versions if detectable"],
302
+ "confidence": 0.95
303
+ },
304
+ "structure": {
305
+ "functions": [
306
+ {
307
+ "name": "function name",
308
+ "type": "arrow | declaration | expression | async",
309
+ "purpose": "brief description of what it does",
310
+ "complexity": "low | medium | high",
311
+ "lineNumber": 42
312
+ }
313
+ ],
314
+ "classes": [
315
+ {
316
+ "name": "class name",
317
+ "purpose": "brief description",
318
+ "methods": ["method1", "method2"],
319
+ "lineNumber": 100
320
+ }
321
+ ],
322
+ "imports": ["list of imported modules"],
323
+ "exports": ["list of exported symbols"]
324
+ },
325
+ "businessLogic": {
326
+ "mainFeatures": ["feature 1", "feature 2"],
327
+ "dataFlow": "description of how data flows through the code",
328
+ "apiEndpoints": ["list of API endpoints if any"],
329
+ "stateManagement": "Redux | Vuex | Context API | none | unknown"
330
+ },
331
+ "securityRisks": [
332
+ {
333
+ "type": "XSS | SQL Injection | CSRF | Insecure Deserialization | etc.",
334
+ "severity": "critical | high | medium | low",
335
+ "description": "detailed description of the vulnerability",
336
+ "location": "line 123 or function name",
337
+ "cwe": "CWE-79",
338
+ "recommendation": "how to fix it"
339
+ }
340
+ ],
341
+ "qualityScore": 85,
342
+ "qualityMetrics": {
343
+ "maintainability": 80,
344
+ "readability": 75,
345
+ "testability": 70,
346
+ "performance": 90
347
+ },
348
+ "summary": "2-3 sentence summary of the code's purpose and quality"
349
+ }
350
+ \`\`\`
351
+
352
+ # Example Output (for reference)
353
+ \`\`\`json
354
+ {
355
+ "techStack": {
356
+ "framework": "React 18.2",
357
+ "bundler": "Webpack 5",
358
+ "libraries": ["axios@1.4.0", "lodash@4.17.21"],
359
+ "confidence": 0.92
360
+ },
361
+ "structure": {
362
+ "functions": [
363
+ {"name": "fetchUserData", "type": "async", "purpose": "Fetches user data from API", "complexity": "medium", "lineNumber": 15}
364
+ ],
365
+ "classes": [],
366
+ "imports": ["react", "axios"],
367
+ "exports": ["UserComponent"]
368
+ },
369
+ "businessLogic": {
370
+ "mainFeatures": ["User authentication", "Data fetching"],
371
+ "dataFlow": "User input -> API call -> State update -> UI render",
372
+ "apiEndpoints": ["/api/users", "/api/auth"],
373
+ "stateManagement": "React Hooks (useState, useEffect)"
374
+ },
375
+ "securityRisks": [
376
+ {
377
+ "type": "XSS",
378
+ "severity": "high",
379
+ "description": "User input directly inserted into innerHTML without sanitization",
380
+ "location": "line 45",
381
+ "cwe": "CWE-79",
382
+ "recommendation": "Use textContent or DOMPurify.sanitize()"
383
+ }
384
+ ],
385
+ "qualityScore": 72,
386
+ "qualityMetrics": {
387
+ "maintainability": 75,
388
+ "readability": 80,
389
+ "testability": 65,
390
+ "performance": 70
391
+ },
392
+ "summary": "React component for user management with API integration. Contains XSS vulnerability and lacks error handling."
393
+ }
394
+ \`\`\`
395
+
396
+ Now analyze the provided code and return ONLY the JSON output (no additional text).`;
397
+ return [
398
+ { role: 'system', content: systemPrompt },
399
+ { role: 'user', content: userPrompt },
400
+ ];
401
+ }
402
+ generateCryptoDetectionPrompt(code) {
403
+ const systemPrompt = `# Role
404
+ You are a cryptography and security expert specializing in:
405
+ - Cryptographic algorithm identification (AES, RSA, DES, 3DES, Blowfish, etc.)
406
+ - JavaScript crypto library analysis (CryptoJS, JSEncrypt, Web Crypto API, crypto-js, forge, etc.)
407
+ - Security assessment based on NIST and OWASP standards
408
+ - Cryptographic parameter extraction (keys, IVs, modes, padding)
409
+ - Vulnerability detection in crypto implementations
410
+
411
+ # Expertise Areas
412
+ - Symmetric encryption: AES, DES, 3DES, Blowfish, ChaCha20
413
+ - Asymmetric encryption: RSA, ECC, ElGamal
414
+ - Hash functions: MD5, SHA-1, SHA-256, SHA-512, BLAKE2
415
+ - Encoding: Base64, Hex, URL encoding
416
+ - Key derivation: PBKDF2, scrypt, bcrypt
417
+ - Message authentication: HMAC, CMAC
418
+
419
+ # Task
420
+ Analyze the provided JavaScript code to:
421
+ 1. Identify ALL cryptographic algorithms and their variants
422
+ 2. Detect crypto libraries and their versions
423
+ 3. Extract cryptographic parameters (keys, IVs, salts, modes, padding)
424
+ 4. Assess security strength and identify vulnerabilities
425
+ 5. Provide actionable security recommendations
426
+
427
+ # Analysis Standards
428
+ - Use NIST SP 800-175B for algorithm strength assessment
429
+ - Follow OWASP Cryptographic Storage Cheat Sheet
430
+ - Identify deprecated/weak algorithms (MD5, SHA-1, DES, RC4)
431
+ - Check for hardcoded keys and weak key generation`;
432
+ const userPrompt = `# Code to Analyze
433
+ \`\`\`javascript
434
+ ${code.length > 4000 ? code.substring(0, 4000) + '\n\n// ... (code truncated)' : code}
435
+ \`\`\`
436
+
437
+ # Required Output Schema
438
+ Return ONLY valid JSON with this exact structure:
439
+
440
+ \`\`\`json
441
+ {
442
+ "algorithms": [
443
+ {
444
+ "name": "string (e.g., 'AES-256-CBC', 'RSA-2048', 'SHA-256')",
445
+ "type": "symmetric | asymmetric | hash | encoding | kdf | mac",
446
+ "variant": "string (e.g., 'CBC', 'GCM', 'PKCS1', 'OAEP')",
447
+ "confidence": 0.95,
448
+ "location": {
449
+ "line": 42,
450
+ "function": "encryptData",
451
+ "codeSnippet": "CryptoJS.AES.encrypt(...)"
452
+ },
453
+ "parameters": {
454
+ "keySize": "128 | 192 | 256 | 1024 | 2048 | 4096 | null",
455
+ "key": "hardcoded | derived | imported | unknown",
456
+ "keyValue": "actual key if hardcoded (first 20 chars) or null",
457
+ "iv": "present | absent | hardcoded | random",
458
+ "mode": "CBC | GCM | ECB | CTR | CFB | OFB | null",
459
+ "padding": "PKCS7 | PKCS5 | NoPadding | OAEP | PSS | null",
460
+ "salt": "present | absent",
461
+ "iterations": 10000
462
+ },
463
+ "usage": "encryption | decryption | hashing | signing | verification",
464
+ "securityIssues": ["issue 1", "issue 2"]
465
+ }
466
+ ],
467
+ "libraries": [
468
+ {
469
+ "name": "CryptoJS | crypto-js | JSEncrypt | forge | sjcl | Web Crypto API | node:crypto",
470
+ "version": "4.1.1 | unknown",
471
+ "confidence": 0.92,
472
+ "detectionMethod": "import statement | CDN link | global object | API usage"
473
+ }
474
+ ],
475
+ "securityAssessment": {
476
+ "overallStrength": "strong | medium | weak | critical",
477
+ "score": 75,
478
+ "weakAlgorithms": [
479
+ {
480
+ "algorithm": "MD5",
481
+ "reason": "Cryptographically broken, vulnerable to collision attacks",
482
+ "severity": "critical | high | medium | low",
483
+ "cwe": "CWE-327"
484
+ }
485
+ ],
486
+ "hardcodedSecrets": [
487
+ {
488
+ "type": "encryption key | API key | password",
489
+ "location": "line 15",
490
+ "value": "first 10 chars...",
491
+ "severity": "critical"
492
+ }
493
+ ],
494
+ "vulnerabilities": [
495
+ {
496
+ "type": "ECB mode usage | Weak key | No IV | Predictable IV | etc.",
497
+ "description": "detailed description",
498
+ "impact": "data leakage | authentication bypass | etc.",
499
+ "cvss": 7.5,
500
+ "cwe": "CWE-326"
501
+ }
502
+ ],
503
+ "recommendations": [
504
+ {
505
+ "priority": "critical | high | medium | low",
506
+ "issue": "what's wrong",
507
+ "solution": "how to fix it",
508
+ "example": "code example if applicable"
509
+ }
510
+ ]
511
+ },
512
+ "summary": "Brief summary of crypto usage and main security concerns"
513
+ }
514
+ \`\`\`
515
+
516
+ # Example Output
517
+ \`\`\`json
518
+ {
519
+ "algorithms": [
520
+ {
521
+ "name": "AES-256-CBC",
522
+ "type": "symmetric",
523
+ "variant": "CBC",
524
+ "confidence": 0.98,
525
+ "location": {"line": 23, "function": "encryptPassword", "codeSnippet": "CryptoJS.AES.encrypt(data, key)"},
526
+ "parameters": {
527
+ "keySize": "256",
528
+ "key": "hardcoded",
529
+ "keyValue": "mySecretKey12345...",
530
+ "iv": "absent",
531
+ "mode": "CBC",
532
+ "padding": "PKCS7",
533
+ "salt": "absent",
534
+ "iterations": null
535
+ },
536
+ "usage": "encryption",
537
+ "securityIssues": ["Hardcoded key", "No IV specified (using default)"]
538
+ }
539
+ ],
540
+ "libraries": [
541
+ {"name": "CryptoJS", "version": "4.1.1", "confidence": 0.95, "detectionMethod": "CDN link"}
542
+ ],
543
+ "securityAssessment": {
544
+ "overallStrength": "weak",
545
+ "score": 35,
546
+ "weakAlgorithms": [],
547
+ "hardcodedSecrets": [
548
+ {"type": "encryption key", "location": "line 10", "value": "mySecretKe...", "severity": "critical"}
549
+ ],
550
+ "vulnerabilities": [
551
+ {
552
+ "type": "Hardcoded encryption key",
553
+ "description": "Encryption key is hardcoded in source code",
554
+ "impact": "Anyone with access to code can decrypt all data",
555
+ "cvss": 9.1,
556
+ "cwe": "CWE-321"
557
+ }
558
+ ],
559
+ "recommendations": [
560
+ {
561
+ "priority": "critical",
562
+ "issue": "Hardcoded encryption key",
563
+ "solution": "Use environment variables or secure key management service (KMS)",
564
+ "example": "const key = process.env.ENCRYPTION_KEY;"
565
+ }
566
+ ]
567
+ },
568
+ "summary": "Uses AES-256-CBC with CryptoJS but has critical security flaw: hardcoded encryption key. Immediate remediation required."
569
+ }
570
+ \`\`\`
571
+
572
+ Now analyze the code and return ONLY the JSON output.`;
573
+ return [
574
+ { role: 'system', content: systemPrompt },
575
+ { role: 'user', content: userPrompt },
576
+ ];
577
+ }
578
+ generateDeobfuscationPrompt(code) {
579
+ const systemPrompt = `# Role
580
+ You are an expert JavaScript reverse engineer specializing in:
581
+ - Code deobfuscation and obfuscation pattern recognition
582
+ - Obfuscator tool identification (javascript-obfuscator, UglifyJS, Terser, Webpack, etc.)
583
+ - Control flow analysis and simplification
584
+ - Semantic code understanding and variable naming
585
+ - AST manipulation and code transformation
586
+
587
+ # Known Obfuscation Techniques
588
+ 1. **String Array Obfuscation**: Strings stored in arrays with index-based access
589
+ 2. **Control Flow Flattening**: Switch-case state machines replacing normal control flow
590
+ 3. **Dead Code Injection**: Unreachable code blocks (if(false){...})
591
+ 4. **Opaque Predicates**: Always-true/false conditions (if(5>3){...})
592
+ 5. **Variable Name Mangling**: _0x1234, _0xabcd style names
593
+ 6. **Function Inlining/Outlining**: Moving code between functions
594
+ 7. **Encoding**: Hex, Unicode, Base64 encoded strings
595
+ 8. **VM Protection**: Custom virtual machine interpreters
596
+ 9. **Self-Defending**: Anti-debugging and anti-tampering code
597
+
598
+ # Task
599
+ Analyze the obfuscated code to:
600
+ 1. Identify the obfuscation type and tool used
601
+ 2. Understand the actual program logic
602
+ 3. Suggest meaningful variable and function names
603
+ 4. Provide deobfuscated code if possible
604
+ 5. Explain the deobfuscation process step-by-step
605
+
606
+ # Constraints
607
+ - Preserve exact program functionality
608
+ - Do NOT guess or hallucinate functionality
609
+ - If uncertain, mark with confidence scores
610
+ - Provide partial results if full deobfuscation is not possible`;
611
+ const userPrompt = `# Obfuscated Code
612
+ \`\`\`javascript
613
+ ${code.length > 3000 ? code.substring(0, 3000) + '\n\n// ... (code truncated)' : code}
614
+ \`\`\`
615
+
616
+ # Required Output Schema
617
+ Return ONLY valid JSON:
618
+
619
+ \`\`\`json
620
+ {
621
+ "obfuscationType": {
622
+ "primary": "string-array | control-flow-flattening | vm-protection | mixed | unknown",
623
+ "techniques": ["technique 1", "technique 2"],
624
+ "tool": "javascript-obfuscator | webpack | uglify | terser | custom | unknown",
625
+ "toolVersion": "string or null",
626
+ "confidence": 0.85
627
+ },
628
+ "analysis": {
629
+ "codeStructure": "description of overall structure",
630
+ "mainLogic": "what the code actually does",
631
+ "keyFunctions": [
632
+ {
633
+ "obfuscatedName": "_0x1234",
634
+ "purpose": "what it does",
635
+ "confidence": 0.9
636
+ }
637
+ ],
638
+ "dataFlow": "how data flows through the code",
639
+ "externalDependencies": ["list of external APIs or libraries used"]
640
+ },
641
+ "suggestions": {
642
+ "variableRenames": {
643
+ "_0x1234": {"suggested": "userId", "reason": "stores user ID from API", "confidence": 0.95},
644
+ "_0x5678": {"suggested": "apiKey", "reason": "used in authentication header", "confidence": 0.88}
645
+ },
646
+ "functionRenames": {
647
+ "_0xabcd": {"suggested": "encryptPassword", "reason": "calls CryptoJS.AES.encrypt", "confidence": 0.92}
648
+ },
649
+ "simplifications": [
650
+ {
651
+ "type": "remove dead code | unflatten control flow | decode strings",
652
+ "description": "what to simplify",
653
+ "impact": "high | medium | low"
654
+ }
655
+ ]
656
+ },
657
+ "deobfuscationSteps": [
658
+ "Step 1: Extract string array at line 1-5",
659
+ "Step 2: Replace string array calls with actual strings",
660
+ "Step 3: Simplify control flow in function _0x1234",
661
+ "Step 4: Rename variables based on usage context"
662
+ ],
663
+ "deobfuscatedCode": "string or null (full deobfuscated code if possible)",
664
+ "partialResults": {
665
+ "stringArrayDecoded": {"_0x0": "hello", "_0x1": "world"},
666
+ "decodedFunctions": [
667
+ {
668
+ "original": "function _0x1234(){...}",
669
+ "deobfuscated": "function getUserData(){...}",
670
+ "confidence": 0.85
671
+ }
672
+ ]
673
+ },
674
+ "limitations": ["what couldn't be deobfuscated and why"],
675
+ "summary": "Brief summary of obfuscation and deobfuscation results"
676
+ }
677
+ \`\`\`
678
+
679
+ # Example Output
680
+ \`\`\`json
681
+ {
682
+ "obfuscationType": {
683
+ "primary": "string-array",
684
+ "techniques": ["string-array", "variable-mangling", "dead-code-injection"],
685
+ "tool": "javascript-obfuscator",
686
+ "toolVersion": "4.0.0",
687
+ "confidence": 0.92
688
+ },
689
+ "analysis": {
690
+ "codeStructure": "IIFE with string array at top, followed by main logic",
691
+ "mainLogic": "Fetches user data from API and encrypts password before sending",
692
+ "keyFunctions": [
693
+ {"obfuscatedName": "_0x1a2b", "purpose": "Decodes strings from array", "confidence": 0.98},
694
+ {"obfuscatedName": "_0x3c4d", "purpose": "Makes API request", "confidence": 0.95}
695
+ ],
696
+ "dataFlow": "User input -> validation -> encryption -> API call -> response handling",
697
+ "externalDependencies": ["fetch API", "CryptoJS"]
698
+ },
699
+ "suggestions": {
700
+ "variableRenames": {
701
+ "_0x1a2b": {"suggested": "decodeString", "reason": "accesses string array with index", "confidence": 0.98},
702
+ "_0x3c4d": {"suggested": "fetchUserData", "reason": "calls fetch() with /api/users", "confidence": 0.95}
703
+ },
704
+ "functionRenames": {
705
+ "_0x5e6f": {"suggested": "encryptPassword", "reason": "uses CryptoJS.AES.encrypt", "confidence": 0.92}
706
+ },
707
+ "simplifications": [
708
+ {"type": "decode strings", "description": "Replace all string array calls with actual strings", "impact": "high"},
709
+ {"type": "remove dead code", "description": "Remove if(false) blocks at lines 45-60", "impact": "medium"}
710
+ ]
711
+ },
712
+ "deobfuscationSteps": [
713
+ "Step 1: Identified string array: ['hello', 'world', 'api', 'user']",
714
+ "Step 2: Replaced _0x1a2b(0) with 'hello', _0x1a2b(1) with 'world'",
715
+ "Step 3: Removed dead code blocks",
716
+ "Step 4: Renamed functions based on their actual purpose"
717
+ ],
718
+ "deobfuscatedCode": "// Partially deobfuscated\nfunction fetchUserData(userId) {\n const apiUrl = 'https://api.example.com/users/' + userId;\n return fetch(apiUrl);\n}",
719
+ "partialResults": {
720
+ "stringArrayDecoded": {"_0x0": "hello", "_0x1": "world", "_0x2": "api"},
721
+ "decodedFunctions": [
722
+ {"original": "function _0x3c4d(_0x1){...}", "deobfuscated": "function fetchUserData(userId){...}", "confidence": 0.95}
723
+ ]
724
+ },
725
+ "limitations": ["VM-protected section at lines 100-200 could not be fully deobfuscated", "Some variable names are uncertain due to lack of context"],
726
+ "summary": "Code uses javascript-obfuscator with string array and dead code injection. Successfully decoded 80% of the code. Main functionality is user data fetching with password encryption."
727
+ }
728
+ \`\`\`
729
+
730
+ Now analyze the obfuscated code and return ONLY the JSON output.`;
731
+ return [
732
+ { role: 'system', content: systemPrompt },
733
+ { role: 'user', content: userPrompt },
734
+ ];
735
+ }
736
+ generateTaintAnalysisPrompt(code, sources, sinks) {
737
+ const systemPrompt = `# Role
738
+ You are a security researcher specializing in:
739
+ - Taint analysis and data flow tracking
740
+ - OWASP Top 10 vulnerability detection
741
+ - Source-Sink-Sanitizer analysis
742
+ - XSS, SQL Injection, Command Injection detection
743
+ - Secure coding practices
744
+
745
+ # Task
746
+ Analyze data flow from sources (user input) to sinks (dangerous operations) to identify security vulnerabilities.
747
+
748
+ # Methodology
749
+ 1. Identify all data sources (user input, network, storage)
750
+ 2. Track data flow through variables, functions, and operations
751
+ 3. Identify sanitizers (validation, encoding, escaping)
752
+ 4. Detect dangerous sinks (eval, innerHTML, SQL queries)
753
+ 5. Report vulnerable paths where tainted data reaches sinks without sanitization`;
754
+ const userPrompt = `# Code to Analyze
755
+ \`\`\`javascript
756
+ ${code.length > 4000 ? code.substring(0, 4000) + '\n\n// ... (truncated)' : code}
757
+ \`\`\`
758
+
759
+ # Detected Sources
760
+ ${sources.map(s => `- ${s}`).join('\n')}
761
+
762
+ # Detected Sinks
763
+ ${sinks.map(s => `- ${s}`).join('\n')}
764
+
765
+ # Required Output
766
+ Return JSON with taint paths and vulnerabilities:
767
+
768
+ \`\`\`json
769
+ {
770
+ "taintPaths": [
771
+ {
772
+ "source": {"type": "user_input", "location": "line 10", "variable": "userInput"},
773
+ "sink": {"type": "eval", "location": "line 50", "variable": "code"},
774
+ "path": ["userInput -> processData -> sanitize? -> code -> eval"],
775
+ "sanitized": false,
776
+ "vulnerability": "Code Injection",
777
+ "severity": "critical",
778
+ "cwe": "CWE-94"
779
+ }
780
+ ],
781
+ "summary": "Found X vulnerable paths"
782
+ }
783
+ \`\`\`
784
+
785
+ Return ONLY the JSON output.`;
786
+ return [
787
+ { role: 'system', content: systemPrompt },
788
+ { role: 'user', content: userPrompt },
789
+ ];
790
+ }
791
+ }
792
+ //# sourceMappingURL=LLMService.js.map