@jshookmcp/jshook 0.2.3 → 0.2.5
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.
- package/README.md +14 -5
- package/README.zh.md +18 -3
- package/dist/packages/extension-sdk/src/bridges/shared.js +2 -2
- package/dist/packages/extension-sdk/src/plugin.d.ts +5 -0
- package/dist/packages/extension-sdk/src/plugin.js +119 -33
- package/dist/packages/extension-sdk/src/workflow.d.ts +156 -0
- package/dist/packages/extension-sdk/src/workflow.js +236 -0
- package/dist/src/config/search-defaults.js +161 -0
- package/dist/src/constants.d.ts +3 -0
- package/dist/src/constants.js +4 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +13 -17
- package/dist/src/modules/analyzer/CodeAnalyzer.d.ts +1 -3
- package/dist/src/modules/analyzer/CodeAnalyzer.js +16 -28
- package/dist/src/modules/analyzer/CodeAnalyzerDataFlow.d.ts +1 -2
- package/dist/src/modules/analyzer/CodeAnalyzerDataFlow.js +1 -45
- package/dist/src/modules/analyzer/IntelligentAnalyzer.d.ts +1 -37
- package/dist/src/modules/analyzer/IntelligentAnalyzer.js +9 -142
- package/dist/src/modules/analyzer/PatternDetector.js +3 -3
- package/dist/src/modules/analyzer/PatternDetectorAuthPatterns.js +1 -1
- package/dist/src/modules/browser/BrowserDiscovery.js +2 -2
- package/dist/src/modules/browser/BrowserModeManager.js +11 -10
- package/dist/src/modules/browser/TabRegistry.js +2 -2
- package/dist/src/modules/browser/UnifiedBrowserManager.d.ts +1 -0
- package/dist/src/modules/browser/UnifiedBrowserManager.js +18 -3
- package/dist/src/modules/captcha/AICaptchaDetector.d.ts +1 -10
- package/dist/src/modules/captcha/AICaptchaDetector.js +7 -201
- package/dist/src/modules/collector/CodeCollector.js +4 -5
- package/dist/src/modules/collector/DOMInspector.js +48 -58
- package/dist/src/modules/collector/PageController.d.ts +17 -4
- package/dist/src/modules/collector/PageController.js +2 -5
- package/dist/src/modules/collector/PageScriptCollectors.js +3 -3
- package/dist/src/modules/crypto/CryptoDetector.d.ts +1 -4
- package/dist/src/modules/crypto/CryptoDetector.js +2 -42
- package/dist/src/modules/crypto/CryptoRules.js +1 -1
- package/dist/src/modules/debugger/BlackboxManager.js +1 -1
- package/dist/src/modules/debugger/DebuggerManager.impl.core.scope.js +1 -1
- package/dist/src/modules/debugger/ScriptManager.impl.extract-function-tree.js +4 -2
- package/dist/src/modules/debugger/WatchExpressionManager.js +1 -1
- package/dist/src/modules/deobfuscator/Deobfuscator.d.ts +1 -4
- package/dist/src/modules/deobfuscator/Deobfuscator.js +4 -39
- package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.d.ts +0 -3
- package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.js +2 -8
- package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.d.ts +1 -2
- package/dist/src/modules/deobfuscator/JSVMPDeobfuscator.restore.js +3 -55
- package/dist/src/modules/deobfuscator/JScramblerDeobfuscator.js +3 -4
- package/dist/src/modules/deobfuscator/VMDeobfuscator.d.ts +2 -10
- package/dist/src/modules/deobfuscator/VMDeobfuscator.js +3 -128
- package/dist/src/modules/deobfuscator/webcrack.js +15 -2
- package/dist/src/modules/emulator/AIEnvironmentAnalyzer.d.ts +5 -8
- package/dist/src/modules/emulator/AIEnvironmentAnalyzer.js +10 -102
- package/dist/src/modules/emulator/EnvironmentEmulator.d.ts +1 -5
- package/dist/src/modules/emulator/EnvironmentEmulator.js +7 -91
- package/dist/src/modules/emulator/EnvironmentEmulatorFetch.js +58 -61
- package/dist/src/modules/emulator/templates/chrome-env.d.ts +17 -7
- package/dist/src/modules/emulator/templates/chrome-env.js +14 -7
- package/dist/src/modules/external/ExternalToolRunner.js +25 -22
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.compose.js +5 -5
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.network.js +311 -311
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.runtime.js +410 -410
- package/dist/src/modules/hook/HookGeneratorBuilders.core.generators.storage.js +122 -122
- package/dist/src/modules/monitor/ConsoleMonitor.impl.core.class.d.ts +13 -0
- package/dist/src/modules/monitor/ConsoleMonitor.impl.core.class.js +42 -0
- package/dist/src/modules/monitor/ConsoleMonitor.impl.core.dynamic.js +194 -194
- package/dist/src/modules/monitor/FetchInterceptor.d.ts +46 -0
- package/dist/src/modules/monitor/FetchInterceptor.js +191 -0
- package/dist/src/modules/monitor/PerformanceMonitor.js +8 -7
- package/dist/src/modules/monitor/PlaywrightNetworkMonitor.js +62 -62
- package/dist/src/modules/process/BaseMemoryManager.d.ts +1 -1
- package/dist/src/modules/process/LinuxProcessManager.js +2 -0
- package/dist/src/modules/process/MacProcessManager.js +25 -25
- package/dist/src/modules/process/MemoryManager.d.ts +1 -1
- package/dist/src/modules/process/MemoryManager.js +2 -2
- package/dist/src/modules/process/memory/AuditTrail.js +1 -1
- package/dist/src/modules/process/memory/availability.js +49 -49
- package/dist/src/modules/process/memory/injector.js +185 -185
- package/dist/src/modules/process/memory/reader.js +85 -53
- package/dist/src/modules/process/memory/regions.dump.js +51 -51
- package/dist/src/modules/process/memory/regions.enumerate.js +108 -108
- package/dist/src/modules/process/memory/regions.modules.js +80 -80
- package/dist/src/modules/process/memory/regions.protection.js +148 -115
- package/dist/src/modules/process/memory/scanner.d.ts +5 -1
- package/dist/src/modules/process/memory/scanner.darwin.js +98 -41
- package/dist/src/modules/process/memory/scanner.js +88 -4
- package/dist/src/modules/process/memory/scanner.windows.js +124 -124
- package/dist/src/modules/process/memory/writer.js +98 -58
- package/dist/src/modules/security/ExecutionSandbox.js +51 -52
- package/dist/src/modules/stealth/FingerprintManager.js +1 -1
- package/dist/src/modules/stealth/StealthScripts.d.ts +1 -0
- package/dist/src/modules/stealth/StealthScripts.js +18 -13
- package/dist/src/modules/stealth/StealthVerifier.js +1 -3
- package/dist/src/modules/symbolic/JSVMPSymbolicExecutor.d.ts +14 -0
- package/dist/src/modules/symbolic/JSVMPSymbolicExecutor.js +181 -2
- package/dist/src/modules/trace/TraceDB.js +75 -69
- package/dist/src/modules/trace/TraceRecorder.js +1 -5
- package/dist/src/native/AntiCheatDetector.js +67 -16
- package/dist/src/native/CodeInjector.js +3 -3
- package/dist/src/native/HardwareBreakpoint.js +24 -15
- package/dist/src/native/HeapAnalyzer.js +2 -2
- package/dist/src/native/MemoryController.js +1 -1
- package/dist/src/native/MemoryScanSession.js +2 -2
- package/dist/src/native/MemoryScanner.js +4 -8
- package/dist/src/native/NativeMemoryManager.impl.js +2 -2
- package/dist/src/native/PEAnalyzer.js +14 -15
- package/dist/src/native/PointerChainEngine.js +2 -4
- package/dist/src/native/ScriptLoader.js +4 -9
- package/dist/src/native/Speedhack.js +1 -1
- package/dist/src/native/StructureAnalyzer.js +52 -33
- package/dist/src/native/Win32API.d.ts +1 -0
- package/dist/src/native/Win32API.js +13 -0
- package/dist/src/native/Win32Debug.js +19 -19
- package/dist/src/native/platform/darwin/DarwinAPI.d.ts +2 -0
- package/dist/src/native/platform/darwin/DarwinAPI.js +8 -0
- package/dist/src/native/platform/darwin/DarwinMemoryProvider.js +6 -1
- package/dist/src/server/MCPServer.context.d.ts +2 -1
- package/dist/src/server/MCPServer.d.ts +2 -1
- package/dist/src/server/MCPServer.domain.d.ts +1 -1
- package/dist/src/server/MCPServer.domain.js +81 -16
- package/dist/src/server/MCPServer.js +41 -14
- package/dist/src/server/MCPServer.resources.d.ts +2 -0
- package/dist/src/server/MCPServer.resources.js +91 -0
- package/dist/src/server/MCPServer.search.handlers.call.js +2 -1
- package/dist/src/server/MCPServer.search.helpers.js +1 -1
- package/dist/src/server/MCPServer.transport.js +12 -0
- package/dist/src/server/ToolCallContextGuard.js +8 -0
- package/dist/src/server/ToolRouter.d.ts +25 -9
- package/dist/src/server/ToolRouter.intent.d.ts +26 -0
- package/dist/src/server/ToolRouter.intent.js +77 -0
- package/dist/src/server/ToolRouter.js +103 -284
- package/dist/src/server/ToolRouter.policy.d.ts +22 -0
- package/dist/src/server/ToolRouter.policy.js +163 -0
- package/dist/src/server/ToolRouter.probe.d.ts +17 -0
- package/dist/src/server/ToolRouter.probe.js +103 -0
- package/dist/src/server/ToolRouter.renderer.d.ts +9 -0
- package/dist/src/server/ToolRouter.renderer.js +52 -0
- package/dist/src/server/activation/ActivationController.js +15 -12
- package/dist/src/server/activation/CompoundConditionEngine.js +1 -1
- package/dist/src/server/activation/PredictiveBooster.js +1 -3
- package/dist/src/server/domains/analysis/definitions.js +155 -655
- package/dist/src/server/domains/analysis/handlers.impl.js +26 -20
- package/dist/src/server/domains/analysis/handlers.web-tools.js +2 -1
- package/dist/src/server/domains/analysis/manifest.js +6 -4
- package/dist/src/server/domains/antidebug/definitions.js +25 -111
- package/dist/src/server/domains/browser/definitions.tools.advanced.js +59 -88
- package/dist/src/server/domains/browser/definitions.tools.behavior.js +120 -227
- package/dist/src/server/domains/browser/definitions.tools.page-core.js +210 -439
- package/dist/src/server/domains/browser/definitions.tools.page-system.js +108 -250
- package/dist/src/server/domains/browser/definitions.tools.runtime.js +98 -211
- package/dist/src/server/domains/browser/definitions.tools.security.js +194 -339
- package/dist/src/server/domains/browser/handlers/camoufox-browser.js +3 -2
- package/dist/src/server/domains/browser/handlers/captcha-solver.js +3 -3
- package/dist/src/server/domains/browser/handlers/dom-query.js +2 -1
- package/dist/src/server/domains/browser/handlers/framework-state.js +27 -9
- package/dist/src/server/domains/browser/handlers/indexeddb-dump.js +21 -20
- package/dist/src/server/domains/browser/handlers/script-management.js +1 -1
- package/dist/src/server/domains/browser/handlers.impl.d.ts +1 -2
- package/dist/src/server/domains/browser/handlers.impl.js +2 -3
- package/dist/src/server/domains/browser/manifest.js +37 -13
- package/dist/src/server/domains/coordination/definitions.js +50 -216
- package/dist/src/server/domains/coordination/index.d.ts +2 -1
- package/dist/src/server/domains/coordination/index.js +1 -0
- package/dist/src/server/domains/debugger/definitions.tools.advanced.js +72 -189
- package/dist/src/server/domains/debugger/definitions.tools.core.js +114 -288
- package/dist/src/server/domains/debugger/manifest.js +9 -2
- package/dist/src/server/domains/encoding/definitions.js +43 -153
- package/dist/src/server/domains/encoding/handlers.base.js +2 -2
- package/dist/src/server/domains/evidence/definitions.d.ts +2 -0
- package/dist/src/server/domains/evidence/definitions.js +42 -0
- package/dist/src/server/domains/evidence/handlers.d.ts +582 -0
- package/dist/src/server/domains/evidence/handlers.js +60 -0
- package/dist/src/server/domains/evidence/index.d.ts +2 -0
- package/dist/src/server/domains/evidence/index.js +2 -0
- package/dist/src/server/domains/evidence/manifest.d.ts +63 -0
- package/dist/src/server/domains/evidence/manifest.js +78 -0
- package/dist/src/server/domains/graphql/definitions.js +53 -141
- package/dist/src/server/domains/graphql/handlers.impl.core.runtime.replay.js +92 -114
- package/dist/src/server/domains/graphql/handlers.impl.core.runtime.shared.js +77 -77
- package/dist/src/server/domains/hooks/ai-handlers.d.ts +0 -7
- package/dist/src/server/domains/hooks/ai-handlers.js +1 -67
- package/dist/src/server/domains/hooks/definitions.js +69 -335
- package/dist/src/server/domains/hooks/manifest.d.ts +1 -1
- package/dist/src/server/domains/hooks/manifest.js +1 -2
- package/dist/src/server/domains/instrumentation/definitions.d.ts +2 -0
- package/dist/src/server/domains/instrumentation/definitions.js +99 -0
- package/dist/src/server/domains/instrumentation/handlers.d.ts +78 -0
- package/dist/src/server/domains/instrumentation/handlers.js +206 -0
- package/dist/src/server/domains/instrumentation/index.d.ts +2 -0
- package/dist/src/server/domains/instrumentation/index.js +2 -0
- package/dist/src/server/domains/instrumentation/manifest.d.ts +63 -0
- package/dist/src/server/domains/instrumentation/manifest.js +114 -0
- package/dist/src/server/domains/macro/definitions.js +16 -43
- package/dist/src/server/domains/maintenance/definitions.js +60 -219
- package/dist/src/server/domains/maintenance/handlers.extensions.js +78 -20
- package/dist/src/server/domains/memory/definitions.js +387 -559
- package/dist/src/server/domains/memory/handlers/hooks.d.ts +55 -0
- package/dist/src/server/domains/memory/handlers/hooks.js +115 -0
- package/dist/src/server/domains/memory/handlers/integrity.d.ts +77 -0
- package/dist/src/server/domains/memory/handlers/integrity.js +180 -0
- package/dist/src/server/domains/memory/handlers/pointer-chain.d.ts +29 -0
- package/dist/src/server/domains/memory/handlers/pointer-chain.js +82 -0
- package/dist/src/server/domains/memory/handlers/readwrite.d.ts +41 -0
- package/dist/src/server/domains/memory/handlers/readwrite.js +78 -0
- package/dist/src/server/domains/memory/handlers/scan.d.ts +35 -0
- package/dist/src/server/domains/memory/handlers/scan.js +97 -0
- package/dist/src/server/domains/memory/handlers/session.d.ts +23 -0
- package/dist/src/server/domains/memory/handlers/session.js +49 -0
- package/dist/src/server/domains/memory/handlers/structure.d.ts +29 -0
- package/dist/src/server/domains/memory/handlers/structure.js +74 -0
- package/dist/src/server/domains/memory/handlers.impl.d.ts +49 -54
- package/dist/src/server/domains/memory/handlers.impl.js +63 -494
- package/dist/src/server/domains/memory/manifest.js +236 -64
- package/dist/src/server/domains/native-bridge/definitions.js +54 -192
- package/dist/src/server/domains/native-bridge/index.d.ts +1 -0
- package/dist/src/server/domains/native-bridge/index.js +2 -1
- package/dist/src/server/domains/network/auth-extractor.js +1 -1
- package/dist/src/server/domains/network/definitions.js +175 -578
- package/dist/src/server/domains/network/handlers.base.core.d.ts +64 -0
- package/dist/src/server/domains/network/handlers.base.core.js +623 -0
- package/dist/src/server/domains/network/handlers.base.d.ts +2 -124
- package/dist/src/server/domains/network/handlers.base.js +3 -878
- package/dist/src/server/domains/network/handlers.base.performance.d.ts +63 -0
- package/dist/src/server/domains/network/handlers.base.performance.js +193 -0
- package/dist/src/server/domains/network/handlers.base.types.d.ts +42 -0
- package/dist/src/server/domains/network/handlers.base.types.js +89 -0
- package/dist/src/server/domains/network/handlers.impl.core.runtime.d.ts +1 -1
- package/dist/src/server/domains/network/handlers.impl.core.runtime.intercept.d.ts +21 -0
- package/dist/src/server/domains/network/handlers.impl.core.runtime.intercept.js +186 -0
- package/dist/src/server/domains/network/handlers.impl.core.runtime.js +1 -1
- package/dist/src/server/domains/network/manifest.js +15 -0
- package/dist/src/server/domains/network/replay.js +1 -4
- package/dist/src/server/domains/platform/definitions.js +121 -112
- package/dist/src/server/domains/platform/handlers/bridge-handlers.d.ts +4 -0
- package/dist/src/server/domains/platform/handlers/bridge-handlers.js +193 -4
- package/dist/src/server/domains/platform/handlers/electron-asar-helpers.js +26 -6
- package/dist/src/server/domains/platform/handlers/electron-dual-cdp.d.ts +3 -0
- package/dist/src/server/domains/platform/handlers/electron-dual-cdp.js +170 -0
- package/dist/src/server/domains/platform/handlers/electron-fuse-handler.d.ts +3 -0
- package/dist/src/server/domains/platform/handlers/electron-fuse-handler.js +193 -0
- package/dist/src/server/domains/platform/handlers/electron-handlers.d.ts +6 -0
- package/dist/src/server/domains/platform/handlers/electron-handlers.js +95 -2
- package/dist/src/server/domains/platform/handlers/electron-ipc-sniffer.d.ts +2 -0
- package/dist/src/server/domains/platform/handlers/electron-ipc-sniffer.js +370 -0
- package/dist/src/server/domains/platform/handlers/electron-userdata-handler.d.ts +2 -0
- package/dist/src/server/domains/platform/handlers/electron-userdata-handler.js +78 -0
- package/dist/src/server/domains/platform/handlers/miniapp-handlers.js +3 -3
- package/dist/src/server/domains/platform/handlers/v8-bytecode-handler.d.ts +2 -0
- package/dist/src/server/domains/platform/handlers/v8-bytecode-handler.js +207 -0
- package/dist/src/server/domains/platform/handlers.d.ts +48 -0
- package/dist/src/server/domains/platform/handlers.js +29 -0
- package/dist/src/server/domains/platform/manifest.js +38 -0
- package/dist/src/server/domains/process/definitions.js +163 -647
- package/dist/src/server/domains/process/handlers.base.d.ts +3 -95
- package/dist/src/server/domains/process/handlers.base.js +7 -462
- package/dist/src/server/domains/process/handlers.base.process.d.ts +61 -0
- package/dist/src/server/domains/process/handlers.base.process.js +417 -0
- package/dist/src/server/domains/process/handlers.base.types.d.ts +57 -0
- package/dist/src/server/domains/process/handlers.base.types.js +50 -0
- package/dist/src/server/domains/process/handlers.impl.core.runtime.inject.js +18 -16
- package/dist/src/server/domains/process/manifest.js +6 -1
- package/dist/src/server/domains/sandbox/definitions.js +11 -33
- package/dist/src/server/domains/sandbox/handlers.js +8 -3
- package/dist/src/server/domains/shared/ResponseBuilder.d.ts +209 -0
- package/dist/src/server/domains/shared/ResponseBuilder.js +48 -0
- package/dist/src/server/domains/shared/modules.d.ts +0 -2
- package/dist/src/server/domains/shared/modules.js +0 -1
- package/dist/src/server/domains/sourcemap/definitions.js +27 -111
- package/dist/src/server/domains/sourcemap/handlers.impl.sourcemap-common.js +7 -2
- package/dist/src/server/domains/sourcemap/handlers.impl.sourcemap-main.js +1 -1
- package/dist/src/server/domains/sourcemap/handlers.impl.sourcemap-parse-base.js +1 -1
- package/dist/src/server/domains/sourcemap/manifest.d.ts +1 -1
- package/dist/src/server/domains/sourcemap/manifest.js +1 -1
- package/dist/src/server/domains/streaming/definitions.js +36 -148
- package/dist/src/server/domains/streaming/handlers.impl.streaming-sse.js +163 -164
- package/dist/src/server/domains/streaming/handlers.impl.streaming-ws.js +1 -1
- package/dist/src/server/domains/trace/TraceSummarizer.js +8 -5
- package/dist/src/server/domains/trace/definitions.tools.js +51 -206
- package/dist/src/server/domains/trace/handlers.js +10 -12
- package/dist/src/server/domains/trace/index.d.ts +2 -1
- package/dist/src/server/domains/trace/index.js +2 -1
- package/dist/src/server/domains/trace/manifest.js +15 -3
- package/dist/src/server/domains/transform/definitions.js +50 -210
- package/dist/src/server/domains/transform/handlers.impl.transform-base.js +108 -108
- package/dist/src/server/domains/transform/handlers.impl.transform-crypto.js +18 -19
- package/dist/src/server/domains/transform/manifest.d.ts +1 -1
- package/dist/src/server/domains/transform/manifest.js +1 -1
- package/dist/src/server/domains/wasm/definitions.js +55 -232
- package/dist/src/server/domains/wasm/handlers.js +1 -1
- package/dist/src/server/domains/workflow/definitions.js +144 -414
- package/dist/src/server/domains/workflow/handlers.impl.workflow-account-bundle.js +1 -1
- package/dist/src/server/domains/workflow/handlers.impl.workflow-api.js +51 -51
- package/dist/src/server/domains/workflow/handlers.impl.workflow-base.d.ts +2 -0
- package/dist/src/server/domains/workflow/handlers.impl.workflow-base.js +126 -87
- package/dist/src/server/domains/workflow/handlers.impl.workflow-batch.js +5 -5
- package/dist/src/server/evidence/ReverseEvidenceGraph.d.ts +20 -0
- package/dist/src/server/evidence/ReverseEvidenceGraph.js +208 -0
- package/dist/src/server/evidence/index.d.ts +2 -0
- package/dist/src/server/evidence/index.js +1 -0
- package/dist/src/server/evidence/types.d.ts +22 -0
- package/dist/src/server/evidence/types.js +1 -0
- package/dist/src/server/extensions/ExtensionManager.d.ts +1 -0
- package/dist/src/server/extensions/ExtensionManager.discovery.js +72 -9
- package/dist/src/server/extensions/ExtensionManager.integrity.js +1 -1
- package/dist/src/server/extensions/ExtensionManager.js +193 -40
- package/dist/src/server/extensions/ExtensionManager.roots.d.ts +1 -1
- package/dist/src/server/extensions/ExtensionManager.roots.js +4 -4
- package/dist/src/server/extensions/plugin-config.js +1 -1
- package/dist/src/server/extensions/plugin-env.d.ts +1 -1
- package/dist/src/server/extensions/plugin-env.js +10 -4
- package/dist/src/server/extensions/types.d.ts +17 -0
- package/dist/src/server/extensions/types.js +1 -1
- package/dist/src/server/instrumentation/EvidenceGraphBridge.d.ts +13 -0
- package/dist/src/server/instrumentation/EvidenceGraphBridge.js +150 -0
- package/dist/src/server/instrumentation/InstrumentationSession.d.ts +60 -0
- package/dist/src/server/instrumentation/InstrumentationSession.js +269 -0
- package/dist/src/server/instrumentation/index.d.ts +2 -0
- package/dist/src/server/instrumentation/index.js +2 -0
- package/dist/src/server/instrumentation/types.d.ts +62 -0
- package/dist/src/server/instrumentation/types.js +7 -0
- package/dist/src/server/macros/MacroConfigLoader.d.ts +6 -5
- package/dist/src/server/macros/MacroConfigLoader.js +61 -59
- package/dist/src/server/macros/MacroRunner.js +6 -2
- package/dist/src/server/macros/builtins/index.d.ts +2 -3
- package/dist/src/server/macros/builtins/index.js +51 -7
- package/dist/src/server/plugins/PluginContract.d.ts +1 -1
- package/dist/src/server/registry/contracts.d.ts +1 -1
- package/dist/src/server/registry/discovery.js +5 -4
- package/dist/src/server/registry/ensure-browser-core.js +0 -3
- package/dist/src/server/registry/index.js +4 -4
- package/dist/src/server/registry/tool-builder.d.ts +46 -0
- package/dist/src/server/registry/tool-builder.js +105 -0
- package/dist/src/server/sandbox/QuickJSSandbox.js +16 -5
- package/dist/src/server/sandbox/SandboxHelpers.js +250 -250
- package/dist/src/server/search/EmbeddingWorker.js +5 -3
- package/dist/src/server/search/FeedbackTracker.d.ts +9 -0
- package/dist/src/server/search/FeedbackTracker.js +26 -0
- package/dist/src/server/search/QueryNormalizer.d.ts +6 -0
- package/dist/src/server/search/QueryNormalizer.js +94 -0
- package/dist/src/server/search/ToolSearchEngineImpl.d.ts +2 -3
- package/dist/src/server/search/ToolSearchEngineImpl.js +38 -88
- package/dist/src/server/workflows/WorkflowContract.d.ts +24 -0
- package/dist/src/server/workflows/WorkflowContract.js +12 -0
- package/dist/src/server/workflows/WorkflowEngine.d.ts +1 -0
- package/dist/src/server/workflows/WorkflowEngine.js +136 -3
- package/dist/src/types/config.d.ts +0 -14
- package/dist/src/types/deobfuscator.d.ts +0 -1
- package/dist/src/types/index.d.ts +1 -1
- package/dist/src/utils/DetailedDataManager.js +2 -0
- package/dist/src/utils/RingBuffer.js +5 -5
- package/dist/src/utils/TokenBudgetManager.js +1 -1
- package/dist/src/utils/UnifiedCacheManager.js +1 -1
- package/dist/src/utils/artifactRetention.js +2 -2
- package/dist/src/utils/betterSqlite3.d.ts +11 -0
- package/dist/src/utils/betterSqlite3.js +88 -0
- package/dist/src/utils/browserExecutable.js +2 -2
- package/dist/src/utils/cliFastPath.js +5 -8
- package/dist/src/utils/config.js +4 -26
- package/dist/src/utils/environmentDoctor.js +138 -11
- package/dist/src/utils/outputPaths.js +16 -9
- package/dist/src/utils/parallel.js +1 -3
- package/package.json +74 -72
- package/workflows/.gitkeep +0 -0
- package/dist/src/modules/analyzer/AISummarizer.d.ts +0 -39
- package/dist/src/modules/analyzer/AISummarizer.js +0 -122
- package/dist/src/modules/hook/AIHookGenerator.d.ts +0 -52
- package/dist/src/modules/hook/AIHookGenerator.js +0 -360
- package/dist/src/modules/hook/AIHookGeneratorTemplates.d.ts +0 -9
- package/dist/src/modules/hook/AIHookGeneratorTemplates.js +0 -157
- package/dist/src/server/macros/builtins/deobfuscate-ast-flow.d.ts +0 -2
- package/dist/src/server/macros/builtins/deobfuscate-ast-flow.js +0 -25
- package/dist/src/server/macros/builtins/unpacker-flow.d.ts +0 -2
- package/dist/src/server/macros/builtins/unpacker-flow.js +0 -25
- package/dist/src/services/LLMService.d.ts +0 -37
- package/dist/src/services/LLMService.js +0 -233
- package/dist/src/services/prompts/analysis.d.ts +0 -9
- package/dist/src/services/prompts/analysis.js +0 -158
- package/dist/src/services/prompts/crypto.d.ts +0 -2
- package/dist/src/services/prompts/crypto.js +0 -108
- package/dist/src/services/prompts/deobfuscation.d.ts +0 -6
- package/dist/src/services/prompts/deobfuscation.js +0 -300
- package/dist/src/services/prompts/environment.d.ts +0 -16
- package/dist/src/services/prompts/environment.js +0 -372
- package/dist/src/services/prompts/intelligence.d.ts +0 -4
- package/dist/src/services/prompts/intelligence.js +0 -250
- package/dist/src/services/prompts/taint.d.ts +0 -2
- package/dist/src/services/prompts/taint.js +0 -54
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
import { toTextResponse, toErrorResponse, parseStringArg, } from '../../../domains/platform/handlers/platform-utils.js';
|
|
2
|
+
const ipcSessions = new Map();
|
|
3
|
+
const IPC_HOOK_PAYLOAD = `
|
|
4
|
+
(function() {
|
|
5
|
+
if (window.__ipcSnifferInstalled) return 'already_installed';
|
|
6
|
+
|
|
7
|
+
const captured = [];
|
|
8
|
+
window.__ipcSnifferCaptured = captured;
|
|
9
|
+
window.__ipcSnifferInstalled = true;
|
|
10
|
+
|
|
11
|
+
// Try to access ipcRenderer from contextBridge-exposed API or require
|
|
12
|
+
let ipcRenderer = null;
|
|
13
|
+
|
|
14
|
+
// Method 1: Direct require (works if nodeIntegration is enabled)
|
|
15
|
+
try {
|
|
16
|
+
ipcRenderer = require('electron').ipcRenderer;
|
|
17
|
+
} catch(e) {}
|
|
18
|
+
|
|
19
|
+
// Method 2: window.electron (common contextBridge pattern)
|
|
20
|
+
if (!ipcRenderer && window.electron && window.electron.ipcRenderer) {
|
|
21
|
+
ipcRenderer = window.electron.ipcRenderer;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if (!ipcRenderer) {
|
|
25
|
+
return 'ipcRenderer_not_accessible';
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// Hook invoke
|
|
29
|
+
const origInvoke = ipcRenderer.invoke.bind(ipcRenderer);
|
|
30
|
+
ipcRenderer.invoke = function(channel, ...args) {
|
|
31
|
+
captured.push({
|
|
32
|
+
timestamp: Date.now(),
|
|
33
|
+
method: 'invoke',
|
|
34
|
+
channel: channel,
|
|
35
|
+
args: args.map(a => {
|
|
36
|
+
try { return JSON.parse(JSON.stringify(a)); }
|
|
37
|
+
catch { return String(a); }
|
|
38
|
+
})
|
|
39
|
+
});
|
|
40
|
+
return origInvoke(channel, ...args);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
// Hook send
|
|
44
|
+
const origSend = ipcRenderer.send.bind(ipcRenderer);
|
|
45
|
+
ipcRenderer.send = function(channel, ...args) {
|
|
46
|
+
captured.push({
|
|
47
|
+
timestamp: Date.now(),
|
|
48
|
+
method: 'send',
|
|
49
|
+
channel: channel,
|
|
50
|
+
args: args.map(a => {
|
|
51
|
+
try { return JSON.parse(JSON.stringify(a)); }
|
|
52
|
+
catch { return String(a); }
|
|
53
|
+
})
|
|
54
|
+
});
|
|
55
|
+
return origSend(channel, ...args);
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
// Hook sendSync
|
|
59
|
+
if (ipcRenderer.sendSync) {
|
|
60
|
+
const origSendSync = ipcRenderer.sendSync.bind(ipcRenderer);
|
|
61
|
+
ipcRenderer.sendSync = function(channel, ...args) {
|
|
62
|
+
captured.push({
|
|
63
|
+
timestamp: Date.now(),
|
|
64
|
+
method: 'sendSync',
|
|
65
|
+
channel: channel,
|
|
66
|
+
args: args.map(a => {
|
|
67
|
+
try { return JSON.parse(JSON.stringify(a)); }
|
|
68
|
+
catch { return String(a); }
|
|
69
|
+
})
|
|
70
|
+
});
|
|
71
|
+
return origSendSync(channel, ...args);
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
return 'hooks_installed';
|
|
76
|
+
})();
|
|
77
|
+
`;
|
|
78
|
+
const IPC_DUMP_PAYLOAD = `
|
|
79
|
+
(function() {
|
|
80
|
+
const captured = window.__ipcSnifferCaptured || [];
|
|
81
|
+
const result = JSON.stringify(captured);
|
|
82
|
+
return result;
|
|
83
|
+
})();
|
|
84
|
+
`;
|
|
85
|
+
const IPC_CLEAR_PAYLOAD = `
|
|
86
|
+
(function() {
|
|
87
|
+
if (window.__ipcSnifferCaptured) {
|
|
88
|
+
const count = window.__ipcSnifferCaptured.length;
|
|
89
|
+
window.__ipcSnifferCaptured.length = 0;
|
|
90
|
+
return String(count);
|
|
91
|
+
}
|
|
92
|
+
return '0';
|
|
93
|
+
})();
|
|
94
|
+
`;
|
|
95
|
+
async function cdpEvaluate(wsDebuggerUrl, expression) {
|
|
96
|
+
const match = wsDebuggerUrl.match(/ws:\/\/([\d.]+:\d+)\//);
|
|
97
|
+
if (!match?.[1]) {
|
|
98
|
+
return { ok: false, error: `Invalid wsDebuggerUrl: ${wsDebuggerUrl}` };
|
|
99
|
+
}
|
|
100
|
+
const hostPort = match[1];
|
|
101
|
+
try {
|
|
102
|
+
const listRes = await fetch(`http://${hostPort}/json`, {
|
|
103
|
+
signal: AbortSignal.timeout(5000),
|
|
104
|
+
});
|
|
105
|
+
const targets = (await listRes.json());
|
|
106
|
+
const page = targets.find((t) => t.type === 'page');
|
|
107
|
+
if (!page) {
|
|
108
|
+
return { ok: false, error: 'No page target found' };
|
|
109
|
+
}
|
|
110
|
+
const pageWsUrl = page.webSocketDebuggerUrl;
|
|
111
|
+
if (!pageWsUrl) {
|
|
112
|
+
return { ok: false, error: 'Page target has no WebSocket debugger URL' };
|
|
113
|
+
}
|
|
114
|
+
return await cdpEvalViaWs(pageWsUrl, expression);
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
return {
|
|
118
|
+
ok: false,
|
|
119
|
+
error: error instanceof Error ? error.message : String(error),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function cdpEvalViaWs(wsUrl, expression) {
|
|
124
|
+
return new Promise((resolve) => {
|
|
125
|
+
try {
|
|
126
|
+
const WS = globalThis.WebSocket;
|
|
127
|
+
if (!WS) {
|
|
128
|
+
resolve({
|
|
129
|
+
ok: false,
|
|
130
|
+
error: 'WebSocket not available. Requires Node.js 21+ or ws package.',
|
|
131
|
+
});
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const ws = new WS(wsUrl);
|
|
135
|
+
const timeout = setTimeout(() => {
|
|
136
|
+
try {
|
|
137
|
+
ws.close();
|
|
138
|
+
}
|
|
139
|
+
catch {
|
|
140
|
+
}
|
|
141
|
+
resolve({ ok: false, error: 'CDP WebSocket timeout (10s)' });
|
|
142
|
+
}, 10_000);
|
|
143
|
+
ws.addEventListener('open', () => {
|
|
144
|
+
ws.send(JSON.stringify({
|
|
145
|
+
id: 1,
|
|
146
|
+
method: 'Runtime.evaluate',
|
|
147
|
+
params: {
|
|
148
|
+
expression,
|
|
149
|
+
returnByValue: true,
|
|
150
|
+
awaitPromise: false,
|
|
151
|
+
},
|
|
152
|
+
}));
|
|
153
|
+
});
|
|
154
|
+
ws.addEventListener('message', (event) => {
|
|
155
|
+
clearTimeout(timeout);
|
|
156
|
+
try {
|
|
157
|
+
const data = JSON.parse(String(event.data));
|
|
158
|
+
if (data.result?.exceptionDetails) {
|
|
159
|
+
resolve({ ok: false, error: data.result.exceptionDetails.text });
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
resolve({ ok: true, result: String(data.result?.result?.value ?? '') });
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
catch (e) {
|
|
166
|
+
resolve({ ok: false, error: `Parse error: ${e}` });
|
|
167
|
+
}
|
|
168
|
+
try {
|
|
169
|
+
ws.close();
|
|
170
|
+
}
|
|
171
|
+
catch {
|
|
172
|
+
}
|
|
173
|
+
});
|
|
174
|
+
ws.addEventListener('error', (err) => {
|
|
175
|
+
clearTimeout(timeout);
|
|
176
|
+
resolve({ ok: false, error: `WebSocket error: ${err}` });
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
resolve({
|
|
181
|
+
ok: false,
|
|
182
|
+
error: error instanceof Error ? error.message : String(error),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
export async function handleElectronIPCSniff(args) {
|
|
188
|
+
try {
|
|
189
|
+
const action = parseStringArg(args, 'action') ?? 'guide';
|
|
190
|
+
if (action === 'start') {
|
|
191
|
+
const port = args.port ?? 9222;
|
|
192
|
+
const sessionId = `ipc-sniff-${port}-${Date.now()}`;
|
|
193
|
+
let wsUrl;
|
|
194
|
+
try {
|
|
195
|
+
const res = await fetch(`http://127.0.0.1:${port}/json/version`, {
|
|
196
|
+
signal: AbortSignal.timeout(5000),
|
|
197
|
+
});
|
|
198
|
+
const info = (await res.json());
|
|
199
|
+
wsUrl = info.webSocketDebuggerUrl ?? `ws://127.0.0.1:${port}/devtools/browser`;
|
|
200
|
+
}
|
|
201
|
+
catch {
|
|
202
|
+
return toTextResponse({
|
|
203
|
+
success: false,
|
|
204
|
+
tool: 'electron_ipc_sniff',
|
|
205
|
+
error: `Cannot connect to CDP at port ${port}. Ensure Electron is launched with --remote-debugging-port=${port}.`,
|
|
206
|
+
hint: 'Use electron_launch_debug to start the app with CDP enabled.',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
const injectResult = await cdpEvaluate(wsUrl, IPC_HOOK_PAYLOAD);
|
|
210
|
+
if (!injectResult.ok) {
|
|
211
|
+
return toTextResponse({
|
|
212
|
+
success: false,
|
|
213
|
+
tool: 'electron_ipc_sniff',
|
|
214
|
+
error: `Failed to inject IPC hooks: ${injectResult.error}`,
|
|
215
|
+
hint: 'The renderer may have contextIsolation enabled. Try injecting via main process CDP instead.',
|
|
216
|
+
});
|
|
217
|
+
}
|
|
218
|
+
const session = {
|
|
219
|
+
id: sessionId,
|
|
220
|
+
port,
|
|
221
|
+
wsUrl,
|
|
222
|
+
messages: [],
|
|
223
|
+
startedAt: Date.now(),
|
|
224
|
+
active: true,
|
|
225
|
+
};
|
|
226
|
+
ipcSessions.set(sessionId, session);
|
|
227
|
+
return toTextResponse({
|
|
228
|
+
success: true,
|
|
229
|
+
tool: 'electron_ipc_sniff',
|
|
230
|
+
action: 'start',
|
|
231
|
+
sessionId,
|
|
232
|
+
port,
|
|
233
|
+
hookStatus: injectResult.result,
|
|
234
|
+
usage: {
|
|
235
|
+
dump: `electron_ipc_sniff(action="dump", sessionId="${sessionId}")`,
|
|
236
|
+
stop: `electron_ipc_sniff(action="stop", sessionId="${sessionId}")`,
|
|
237
|
+
},
|
|
238
|
+
note: injectResult.result === 'ipcRenderer_not_accessible'
|
|
239
|
+
? 'ipcRenderer not accessible — contextIsolation may be enabled. IPC hooking requires nodeIntegration or a custom preload.'
|
|
240
|
+
: 'IPC hooks installed. Interact with the app, then use dump to retrieve captured messages.',
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
if (action === 'dump') {
|
|
244
|
+
const sessionId = parseStringArg(args, 'sessionId');
|
|
245
|
+
const port = args.port;
|
|
246
|
+
const clear = args.clear !== false;
|
|
247
|
+
let session;
|
|
248
|
+
if (sessionId) {
|
|
249
|
+
session = ipcSessions.get(sessionId);
|
|
250
|
+
}
|
|
251
|
+
else if (port) {
|
|
252
|
+
session = Array.from(ipcSessions.values()).find((s) => s.port === port);
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
const sessions = Array.from(ipcSessions.values());
|
|
256
|
+
session = sessions[sessions.length - 1];
|
|
257
|
+
}
|
|
258
|
+
if (!session) {
|
|
259
|
+
return toTextResponse({
|
|
260
|
+
success: false,
|
|
261
|
+
tool: 'electron_ipc_sniff',
|
|
262
|
+
error: 'No active IPC sniff session found.',
|
|
263
|
+
activeSessions: Array.from(ipcSessions.keys()),
|
|
264
|
+
hint: 'Start a session first: electron_ipc_sniff(action="start", port=9222)',
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
const dumpResult = await cdpEvaluate(session.wsUrl, IPC_DUMP_PAYLOAD);
|
|
268
|
+
if (!dumpResult.ok) {
|
|
269
|
+
return toTextResponse({
|
|
270
|
+
success: false,
|
|
271
|
+
tool: 'electron_ipc_sniff',
|
|
272
|
+
error: `Failed to dump IPC messages: ${dumpResult.error}`,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
let messages = [];
|
|
276
|
+
try {
|
|
277
|
+
messages = JSON.parse(dumpResult.result ?? '[]');
|
|
278
|
+
}
|
|
279
|
+
catch {
|
|
280
|
+
messages = [];
|
|
281
|
+
}
|
|
282
|
+
if (clear && messages.length > 0) {
|
|
283
|
+
await cdpEvaluate(session.wsUrl, IPC_CLEAR_PAYLOAD);
|
|
284
|
+
}
|
|
285
|
+
const channelSummary = {};
|
|
286
|
+
for (const msg of messages) {
|
|
287
|
+
channelSummary[msg.channel] = (channelSummary[msg.channel] ?? 0) + 1;
|
|
288
|
+
}
|
|
289
|
+
return toTextResponse({
|
|
290
|
+
success: true,
|
|
291
|
+
tool: 'electron_ipc_sniff',
|
|
292
|
+
action: 'dump',
|
|
293
|
+
sessionId: session.id,
|
|
294
|
+
messageCount: messages.length,
|
|
295
|
+
channelSummary,
|
|
296
|
+
messages: messages.slice(0, 200),
|
|
297
|
+
cleared: clear,
|
|
298
|
+
note: messages.length > 200
|
|
299
|
+
? `Showing first 200 of ${messages.length} messages. Use dump repeatedly for ongoing capture.`
|
|
300
|
+
: undefined,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
if (action === 'stop') {
|
|
304
|
+
const sessionId = parseStringArg(args, 'sessionId');
|
|
305
|
+
if (!sessionId) {
|
|
306
|
+
return toTextResponse({
|
|
307
|
+
success: false,
|
|
308
|
+
tool: 'electron_ipc_sniff',
|
|
309
|
+
error: 'sessionId is required for stop.',
|
|
310
|
+
activeSessions: Array.from(ipcSessions.keys()),
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
const session = ipcSessions.get(sessionId);
|
|
314
|
+
if (!session) {
|
|
315
|
+
return toTextResponse({
|
|
316
|
+
success: false,
|
|
317
|
+
tool: 'electron_ipc_sniff',
|
|
318
|
+
error: `Session not found: ${sessionId}`,
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
session.active = false;
|
|
322
|
+
ipcSessions.delete(sessionId);
|
|
323
|
+
return toTextResponse({
|
|
324
|
+
success: true,
|
|
325
|
+
tool: 'electron_ipc_sniff',
|
|
326
|
+
action: 'stop',
|
|
327
|
+
sessionId,
|
|
328
|
+
message: 'IPC sniff session stopped.',
|
|
329
|
+
uptime: Math.round((Date.now() - session.startedAt) / 1000),
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
if (action === 'list') {
|
|
333
|
+
const sessions = Array.from(ipcSessions.entries()).map(([id, s]) => ({
|
|
334
|
+
sessionId: id,
|
|
335
|
+
port: s.port,
|
|
336
|
+
active: s.active,
|
|
337
|
+
uptime: Math.round((Date.now() - s.startedAt) / 1000),
|
|
338
|
+
}));
|
|
339
|
+
return toTextResponse({
|
|
340
|
+
success: true,
|
|
341
|
+
tool: 'electron_ipc_sniff',
|
|
342
|
+
action: 'list',
|
|
343
|
+
sessions,
|
|
344
|
+
count: sessions.length,
|
|
345
|
+
});
|
|
346
|
+
}
|
|
347
|
+
return toTextResponse({
|
|
348
|
+
success: true,
|
|
349
|
+
guide: {
|
|
350
|
+
what: 'Electron IPC sniffer — intercepts ipcRenderer.invoke/send/sendSync messages via CDP injection.',
|
|
351
|
+
workflow: [
|
|
352
|
+
'1. Launch Electron with: electron_launch_debug(exePath="...")',
|
|
353
|
+
'2. Start sniffing: electron_ipc_sniff(action="start", port=9222)',
|
|
354
|
+
'3. Interact with the app to trigger IPC messages',
|
|
355
|
+
'4. Dump captured: electron_ipc_sniff(action="dump", sessionId="...")',
|
|
356
|
+
'5. Stop when done: electron_ipc_sniff(action="stop", sessionId="...")',
|
|
357
|
+
],
|
|
358
|
+
actions: ['start', 'dump', 'stop', 'list', 'guide'],
|
|
359
|
+
limitations: [
|
|
360
|
+
'Requires renderer CDP port (--remote-debugging-port)',
|
|
361
|
+
'contextIsolation=true may block direct ipcRenderer access',
|
|
362
|
+
'Main process IPC (ipcMain) is captured indirectly through renderer-side hooks',
|
|
363
|
+
],
|
|
364
|
+
},
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
catch (error) {
|
|
368
|
+
return toErrorResponse('electron_ipc_sniff', error);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { readdir, readFile, stat } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
import { toTextResponse, toErrorResponse, parseStringArg, pathExists, } from '../../../domains/platform/handlers/platform-utils.js';
|
|
4
|
+
export async function handleElectronScanUserdata(args) {
|
|
5
|
+
try {
|
|
6
|
+
const dirPath = parseStringArg(args, 'dirPath', true);
|
|
7
|
+
if (!dirPath) {
|
|
8
|
+
throw new Error('dirPath is required');
|
|
9
|
+
}
|
|
10
|
+
const maxFiles = typeof args.maxFiles === 'number' && args.maxFiles > 0 ? args.maxFiles : 20;
|
|
11
|
+
const maxFileSizeKB = typeof args.maxFileSizeKB === 'number' && args.maxFileSizeKB > 0 ? args.maxFileSizeKB : 1024;
|
|
12
|
+
const maxFileSize = maxFileSizeKB * 1024;
|
|
13
|
+
if (!(await pathExists(dirPath))) {
|
|
14
|
+
return toTextResponse({
|
|
15
|
+
success: false,
|
|
16
|
+
tool: 'electron_scan_userdata',
|
|
17
|
+
error: `Directory does not exist: ${dirPath}`,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
const dirStat = await stat(dirPath);
|
|
21
|
+
if (!dirStat.isDirectory()) {
|
|
22
|
+
return toTextResponse({
|
|
23
|
+
success: false,
|
|
24
|
+
tool: 'electron_scan_userdata',
|
|
25
|
+
error: `Path is not a directory: ${dirPath}`,
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
let dirEntries;
|
|
29
|
+
try {
|
|
30
|
+
dirEntries = await readdir(dirPath);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return toTextResponse({
|
|
34
|
+
success: false,
|
|
35
|
+
tool: 'electron_scan_userdata',
|
|
36
|
+
error: `Cannot read directory: ${dirPath}`,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
const jsonFiles = dirEntries.filter((name) => name.endsWith('.json')).slice(0, maxFiles);
|
|
40
|
+
const files = [];
|
|
41
|
+
const skipped = [];
|
|
42
|
+
for (const fileName of jsonFiles) {
|
|
43
|
+
const filePath = join(dirPath, fileName);
|
|
44
|
+
try {
|
|
45
|
+
const fileStat = await stat(filePath);
|
|
46
|
+
if (!fileStat.isFile()) {
|
|
47
|
+
skipped.push({ name: fileName, reason: 'not a file' });
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (fileStat.size > maxFileSize) {
|
|
51
|
+
skipped.push({ name: fileName, reason: 'exceeds maxFileSizeKB' });
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
const raw = await readFile(filePath, 'utf-8');
|
|
55
|
+
const parsed = JSON.parse(raw);
|
|
56
|
+
files.push({
|
|
57
|
+
name: fileName,
|
|
58
|
+
sizeBytes: fileStat.size,
|
|
59
|
+
content: parsed,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
skipped.push({ name: fileName, reason: 'read or parse error' });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return toTextResponse({
|
|
67
|
+
success: true,
|
|
68
|
+
tool: 'electron_scan_userdata',
|
|
69
|
+
files,
|
|
70
|
+
skipped,
|
|
71
|
+
totalScanned: jsonFiles.length,
|
|
72
|
+
directory: dirPath,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
catch (error) {
|
|
76
|
+
return toErrorResponse('electron_scan_userdata', error);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
@@ -368,10 +368,10 @@ export class MiniappHandlers {
|
|
|
368
368
|
return toTextResponse({
|
|
369
369
|
success: true,
|
|
370
370
|
unpackedDir: absoluteUnpackedDir.replace(/\\/g, '/'),
|
|
371
|
-
pages: Array.from(pages).
|
|
371
|
+
pages: Array.from(pages).toSorted(),
|
|
372
372
|
subPackages,
|
|
373
|
-
components: Array.from(components).
|
|
374
|
-
jsFiles: jsFiles.
|
|
373
|
+
components: Array.from(components).toSorted(),
|
|
374
|
+
jsFiles: jsFiles.toSorted(),
|
|
375
375
|
totalSize,
|
|
376
376
|
appId,
|
|
377
377
|
discovered: {
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
import { readFile, stat } from 'node:fs/promises';
|
|
2
|
+
import { execFile } from 'node:child_process';
|
|
3
|
+
import { promisify } from 'node:util';
|
|
4
|
+
import { extname } from 'node:path';
|
|
5
|
+
import { toTextResponse, toErrorResponse, parseStringArg, pathExists, } from '../../../domains/platform/handlers/platform-utils.js';
|
|
6
|
+
const execFileAsync = promisify(execFile);
|
|
7
|
+
const V8_MAGIC = Buffer.from([0xc0, 0xde]);
|
|
8
|
+
const BYTENODE_MAGIC = Buffer.from('BYTN');
|
|
9
|
+
const JSC_EXTENSIONS = new Set(['.jsc', '.bin']);
|
|
10
|
+
function detectFormat(buffer, filePath) {
|
|
11
|
+
const ext = extname(filePath).toLowerCase();
|
|
12
|
+
if (buffer.length >= 4 && buffer.subarray(0, 4).equals(BYTENODE_MAGIC)) {
|
|
13
|
+
return 'bytenode';
|
|
14
|
+
}
|
|
15
|
+
if (buffer.length >= 2 && buffer.subarray(0, 2).equals(V8_MAGIC)) {
|
|
16
|
+
return 'v8-raw';
|
|
17
|
+
}
|
|
18
|
+
if (JSC_EXTENSIONS.has(ext)) {
|
|
19
|
+
return 'jsc-extension';
|
|
20
|
+
}
|
|
21
|
+
const v8Markers = [
|
|
22
|
+
Buffer.from('Ldar'),
|
|
23
|
+
Buffer.from('Star'),
|
|
24
|
+
Buffer.from('LdaSmi'),
|
|
25
|
+
Buffer.from('CallRuntime'),
|
|
26
|
+
];
|
|
27
|
+
for (const marker of v8Markers) {
|
|
28
|
+
if (buffer.indexOf(marker) !== -1) {
|
|
29
|
+
return 'v8-heuristic';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
async function tryView8(filePath) {
|
|
35
|
+
try {
|
|
36
|
+
const { stdout, stderr } = await execFileAsync('python', ['-m', 'view8', filePath], {
|
|
37
|
+
timeout: 60_000,
|
|
38
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
39
|
+
});
|
|
40
|
+
if (stdout && stdout.trim().length > 0) {
|
|
41
|
+
return { ok: true, output: stdout };
|
|
42
|
+
}
|
|
43
|
+
return { ok: false, error: stderr || 'Empty output from view8' };
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
try {
|
|
47
|
+
const { stdout } = await execFileAsync('python3', ['-m', 'view8', filePath], {
|
|
48
|
+
timeout: 60_000,
|
|
49
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
50
|
+
});
|
|
51
|
+
if (stdout && stdout.trim().length > 0) {
|
|
52
|
+
return { ok: true, output: stdout };
|
|
53
|
+
}
|
|
54
|
+
return { ok: false, error: 'Empty output from view8' };
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
return { ok: false, error: 'view8 not available. Install with: pip install view8' };
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function extractConstantPool(buffer) {
|
|
62
|
+
const strings = [];
|
|
63
|
+
const numbers = [];
|
|
64
|
+
const seen = new Set();
|
|
65
|
+
const MIN_STRING_LEN = 4;
|
|
66
|
+
const MAX_STRING_LEN = 2000;
|
|
67
|
+
let currentString = '';
|
|
68
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
69
|
+
const byte = buffer[i];
|
|
70
|
+
if (byte >= 0x20 && byte <= 0x7e) {
|
|
71
|
+
currentString += String.fromCharCode(byte);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
if (currentString.length >= MIN_STRING_LEN && currentString.length <= MAX_STRING_LEN) {
|
|
75
|
+
if (isLikelyCodeString(currentString) && !seen.has(currentString)) {
|
|
76
|
+
seen.add(currentString);
|
|
77
|
+
strings.push(currentString);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
currentString = '';
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
for (let i = 0; i < buffer.length - 3; i++) {
|
|
84
|
+
if (buffer[i + 1] === 0x00 && buffer[i] >= 0x20 && buffer[i] <= 0x7e) {
|
|
85
|
+
let utf16str = '';
|
|
86
|
+
let j = i;
|
|
87
|
+
while (j < buffer.length - 1 &&
|
|
88
|
+
buffer[j] >= 0x20 &&
|
|
89
|
+
buffer[j] <= 0x7e &&
|
|
90
|
+
buffer[j + 1] === 0x00) {
|
|
91
|
+
utf16str += String.fromCharCode(buffer[j]);
|
|
92
|
+
j += 2;
|
|
93
|
+
}
|
|
94
|
+
if (utf16str.length >= MIN_STRING_LEN && utf16str.length <= MAX_STRING_LEN) {
|
|
95
|
+
if (isLikelyCodeString(utf16str) && !seen.has(utf16str)) {
|
|
96
|
+
seen.add(utf16str);
|
|
97
|
+
strings.push(utf16str);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return { strings, numbers };
|
|
103
|
+
}
|
|
104
|
+
function isLikelyCodeString(s) {
|
|
105
|
+
if (new Set(s).size <= 2)
|
|
106
|
+
return false;
|
|
107
|
+
const specialRatio = (s.match(/[^a-zA-Z0-9_\-.\s/\\:;=+*&|!?,'"(){}[\]<>@#$%^~`]/g) ?? []).length / s.length;
|
|
108
|
+
if (specialRatio > 0.3)
|
|
109
|
+
return false;
|
|
110
|
+
const codePatterns = [
|
|
111
|
+
/[a-zA-Z_$][a-zA-Z0-9_$]*/,
|
|
112
|
+
/function\s/,
|
|
113
|
+
/return\s/,
|
|
114
|
+
/const\s/,
|
|
115
|
+
/let\s/,
|
|
116
|
+
/var\s/,
|
|
117
|
+
/require\(/,
|
|
118
|
+
/module\.exports/,
|
|
119
|
+
/import\s/,
|
|
120
|
+
/\.prototype\./,
|
|
121
|
+
/\.call\(/,
|
|
122
|
+
/\.apply\(/,
|
|
123
|
+
/async\s/,
|
|
124
|
+
/await\s/,
|
|
125
|
+
/Promise/,
|
|
126
|
+
/https?:\/\//,
|
|
127
|
+
/[a-zA-Z]+Error/,
|
|
128
|
+
];
|
|
129
|
+
return codePatterns.some((p) => p.test(s));
|
|
130
|
+
}
|
|
131
|
+
export async function handleV8BytecodeDecompile(args) {
|
|
132
|
+
try {
|
|
133
|
+
const filePath = parseStringArg(args, 'filePath', true);
|
|
134
|
+
if (!filePath) {
|
|
135
|
+
throw new Error('filePath is required — path to a .jsc or V8 bytecode file');
|
|
136
|
+
}
|
|
137
|
+
if (!(await pathExists(filePath))) {
|
|
138
|
+
return toTextResponse({
|
|
139
|
+
success: false,
|
|
140
|
+
tool: 'v8_bytecode_decompile',
|
|
141
|
+
error: `File does not exist: ${filePath}`,
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
const fileStat = await stat(filePath);
|
|
145
|
+
if (fileStat.size > 50 * 1024 * 1024) {
|
|
146
|
+
return toTextResponse({
|
|
147
|
+
success: false,
|
|
148
|
+
tool: 'v8_bytecode_decompile',
|
|
149
|
+
error: `File too large (${(fileStat.size / 1024 / 1024).toFixed(1)}MB). Maximum: 50MB.`,
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
const buffer = await readFile(filePath);
|
|
153
|
+
const format = detectFormat(buffer, filePath);
|
|
154
|
+
if (!format) {
|
|
155
|
+
return toTextResponse({
|
|
156
|
+
success: false,
|
|
157
|
+
tool: 'v8_bytecode_decompile',
|
|
158
|
+
filePath,
|
|
159
|
+
fileSize: fileStat.size,
|
|
160
|
+
error: 'Not a recognized V8 bytecode format. Expected .jsc, bytenode, or V8 serialized bytecode.',
|
|
161
|
+
hint: 'Ensure the file is a V8 compiled bytecode file (created by bytenode or v8.serialize).',
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
const result = {
|
|
165
|
+
success: false,
|
|
166
|
+
tool: 'v8_bytecode_decompile',
|
|
167
|
+
filePath,
|
|
168
|
+
fileSize: fileStat.size,
|
|
169
|
+
detectedFormat: format,
|
|
170
|
+
strategy: 'pending',
|
|
171
|
+
};
|
|
172
|
+
const view8Result = await tryView8(filePath);
|
|
173
|
+
if (view8Result.ok && view8Result.output) {
|
|
174
|
+
result.success = true;
|
|
175
|
+
result.strategy = 'view8';
|
|
176
|
+
result.pseudocode =
|
|
177
|
+
view8Result.output.length > 50_000
|
|
178
|
+
? view8Result.output.slice(0, 50_000) +
|
|
179
|
+
'\n\n... [truncated, total ' +
|
|
180
|
+
view8Result.output.length +
|
|
181
|
+
' chars]'
|
|
182
|
+
: view8Result.output;
|
|
183
|
+
return toTextResponse(result);
|
|
184
|
+
}
|
|
185
|
+
const { strings } = extractConstantPool(buffer);
|
|
186
|
+
if (strings.length > 0) {
|
|
187
|
+
result.success = true;
|
|
188
|
+
result.strategy = 'constant-pool-extraction';
|
|
189
|
+
result.strings = strings.slice(0, 500);
|
|
190
|
+
result.note = [
|
|
191
|
+
`view8 unavailable (${view8Result.error}). Used built-in constant pool extraction.`,
|
|
192
|
+
`Found ${strings.length} code-relevant strings. These include function names, identifiers, URLs, and string literals from the original source.`,
|
|
193
|
+
`For full decompilation, install view8: pip install view8`,
|
|
194
|
+
].join(' ');
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
result.success = false;
|
|
198
|
+
result.strategy = 'none';
|
|
199
|
+
result.error = `Could not decompile. view8: ${view8Result.error}. Built-in extraction found no code strings.`;
|
|
200
|
+
result.note = 'The bytecode may be heavily optimized or use an unsupported V8 version.';
|
|
201
|
+
}
|
|
202
|
+
return toTextResponse(result);
|
|
203
|
+
}
|
|
204
|
+
catch (error) {
|
|
205
|
+
return toErrorResponse('v8_bytecode_decompile', error);
|
|
206
|
+
}
|
|
207
|
+
}
|