@jshookmcp/jshook 0.3.2 → 0.3.4
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 +19 -4
- package/README.zh.md +19 -4
- package/dist/AntiCheatDetector-B-mz4DK_.mjs +1 -0
- package/dist/{BrowserSessionCoordinator-BJ-HOxo0.mjs → BrowserSessionCoordinator-Cdic8FsH.mjs} +1 -1
- package/dist/CodeAnalyzerDataFlow-a-NkwcaG.mjs +2 -0
- package/dist/CodeInjector-B099WO6x.mjs +1 -0
- package/dist/ConsoleMonitor-BZRqrBH-.mjs +306 -0
- package/dist/CpuEngine-BC8jayy9.mjs +1 -0
- package/dist/DartAotExecutor-B7WVTKsd.mjs +1 -0
- package/dist/DartAotLoader-BxdhW-K2.mjs +2 -0
- package/dist/DarwinAPI-DzojdfjF.mjs +1 -0
- package/dist/DetailedDataManager-Dgh402Gp.mjs +5 -0
- package/dist/ExecutionSandbox-QbWQmzuC.mjs +45 -0
- package/dist/ExtensionManager.tools-D3h818Xs.mjs +1 -0
- package/dist/FingerprintManager-D9Zlr6be.mjs +1 -0
- package/dist/HardwareBreakpoint-C_lJ22bj.mjs +1 -0
- package/dist/HeapAnalyzer-bJbLvzp6.mjs +1 -0
- package/dist/HookPatternScanner-yx4vJ9sd.mjs +1 -0
- package/dist/InstrumentationSession-Cv1wikLA.mjs +1 -0
- package/dist/IntegrityScanner-BB7sw-SA.mjs +1 -0
- package/dist/JScramblerDeobfuscator-NVR5VatT.mjs +1 -0
- package/dist/MCPServer.activation.ttl-C2wOCMLV.mjs +1 -0
- package/dist/MCPServer.search.helpers-DlassAew.mjs +2 -0
- package/dist/MCPServer.search.validation-DnifPCCv.mjs +1 -0
- package/dist/MemoryController-CCsGuGJS.mjs +2 -0
- package/dist/{MemoryScanSession-DG_F-PjE.mjs → MemoryScanSession-BZ2A9Ph1.mjs} +1 -1
- package/dist/MemoryScanner-DAxsq7Sx.mjs +1 -0
- package/dist/NativeMemoryManager.impl-BIJzXMqH.mjs +1 -0
- package/dist/{NativeMemoryManager.utils-BHy1P_jM.mjs → NativeMemoryManager.utils-CMoul2an.mjs} +1 -1
- package/dist/PEAnalyzer-CB_kaTis.mjs +1 -0
- package/dist/PackerDeobfuscator-BpwGjxDL.mjs +7 -0
- package/dist/PointerChainEngine-B6SYv6ZM.mjs +1 -0
- package/dist/ProcessRegistry-C5W1Tkn9.mjs +1 -0
- package/dist/{handlers-mPFiNPe8.mjs → QuickJSSandbox-CIde-jzG.mjs} +2 -5
- package/dist/{ResponseBuilder-BfWP-uaT.mjs → ResponseBuilder-BLicSCjn.mjs} +1 -1
- package/dist/ReverseEvidenceGraph-DJzk0GQz.mjs +2 -0
- package/dist/ServerRuntimeState-DGXNv8Ji.mjs +1 -0
- package/dist/Speedhack-MGoeq1ZS.mjs +1 -0
- package/dist/StructureAnalyzer-CCTWAXR3.mjs +2 -0
- package/dist/ToolHandlerMap-C40EmuLT.mjs +1 -0
- package/dist/{ToolProbe-C7ZU2x7M.mjs → ToolProbe-B02GC3ZY.mjs} +1 -1
- package/dist/ToolRegistry-CzqQxFqf.mjs +1 -0
- package/dist/ToolRouter.policy-Bgb3S8jc.mjs +4 -0
- package/dist/TraceRecorder-BfeCTQUj.mjs +407 -0
- package/dist/VMDeobfuscator-BHtkV850.mjs +1 -0
- package/dist/Win32API-G7QPyckq.mjs +1 -0
- package/dist/{Win32Debug-CYrIQBvr.mjs → Win32Debug-6yzmtv5b.mjs} +1 -1
- package/dist/allocation-track-CiI-CnaI.mjs +1 -0
- package/dist/analysis-CojUzwX-.mjs +27 -0
- package/dist/antidebug-CgU84TE1.mjs +1 -0
- package/dist/apk-DrPBsOq8.mjs +1 -0
- package/dist/artifactRetention-Bk6fW2uF.mjs +1 -0
- package/dist/artifacts-Bx9GLx4J.mjs +1 -0
- package/dist/ast-bridge-BlOrmVAv.mjs +1 -0
- package/dist/ast-utils-B9E5k_v1.mjs +1 -0
- package/dist/{betterSqlite3-Brtq-SIQ.mjs → betterSqlite3-Bdo_ifuJ.mjs} +1 -1
- package/dist/binary-instrument-DiE1BP0x.mjs +12 -0
- package/dist/boringssl-inspector-C6M3sOga.mjs +2 -0
- package/dist/browser-QDUu5ML9.mjs +29 -0
- package/dist/{handlers-yo_xYzT8.mjs → canvas-g5kmLdY-.mjs} +1098 -24
- package/dist/{capabilities-CyXuKUl1.mjs → capabilities-DwzyxL2w.mjs} +1 -1
- package/dist/cdp-session-Dy4OwMOP.mjs +1 -0
- package/dist/collector-Cld4i-E4.mjs +1 -0
- package/dist/config-5ODJ3Aj0.mjs +3 -0
- package/dist/constants-nvsLpSri.mjs +1 -0
- package/dist/coordination-C6y2gM9O.mjs +98 -0
- package/dist/coverage-and-block--cWjjEe5.mjs +1 -0
- package/dist/dart-inspector-D4IKxZ6u.mjs +0 -0
- package/dist/debugger-C2SpiXoO.mjs +1 -0
- package/dist/definitions-0mtilYzG.mjs +1 -0
- package/dist/definitions-9csunmeX.mjs +1 -0
- package/dist/definitions-B11MudW_.mjs +1 -0
- package/dist/definitions-BKpRDjcI.mjs +1 -0
- package/dist/definitions-BXE3H4re.mjs +1 -0
- package/dist/definitions-BlPHe5DX.mjs +1 -0
- package/dist/definitions-Bob4XMxI.mjs +27 -0
- package/dist/definitions-BpIQN2nm.mjs +1 -0
- package/dist/definitions-BvolWeSu.mjs +1 -0
- package/dist/definitions-C-6j3Ejl.mjs +1 -0
- package/dist/definitions-C-AdFfFu.mjs +1 -0
- package/dist/definitions-CArdw_9T.mjs +1 -0
- package/dist/definitions-CCvIcRrT.mjs +1 -0
- package/dist/definitions-CJPE5PIl.mjs +1 -0
- package/dist/definitions-CbqeW06u.mjs +1 -0
- package/dist/definitions-Cexmkypg.mjs +1 -0
- package/dist/definitions-D1dxl8qt.mjs +1 -0
- package/dist/definitions-D3uT-ZbU.mjs +1 -0
- package/dist/definitions-DtOY5iUc.mjs +1 -0
- package/dist/{definitions-DxFNRQNK2.mjs → definitions-DvrYdDCJ2.mjs} +1 -1
- package/dist/{definitions-Cenu6mxo.mjs → definitions-aeRd5DAR.mjs} +1 -1
- package/dist/definitions-ihxOqOC4.mjs +1 -0
- package/dist/deopt-trace-qnAcC931.mjs +17 -0
- package/dist/disasm-DoxSucGp.mjs +1 -0
- package/dist/dumpsys-parser-Du-5ruEe.mjs +2 -0
- package/dist/encoding-UMtwgy4M.mjs +2 -0
- package/dist/ensure-browser-core-BP70x0TB.mjs +285 -0
- package/dist/factory-BeND77hf.mjs +2 -0
- package/dist/graphql-CF7QKJME.mjs +68 -0
- package/dist/grpc-raw-Dp7ps2sv.mjs +1 -0
- package/dist/handlers--qCl9vNv.mjs +1 -0
- package/dist/handlers-BHIu1LqA.mjs +1 -0
- package/dist/{antidebug-7L3ygj_9.mjs → handlers-BQ4K8Jbr.mjs} +2 -2
- package/dist/handlers-BxQv-wtf.mjs +8 -0
- package/dist/handlers-ByYG27-5.mjs +1 -0
- package/dist/handlers-C0I9-BtX.mjs +5 -0
- package/dist/handlers-CL0Iokmw.mjs +1 -0
- package/dist/handlers-CNbhIdSK.mjs +4 -0
- package/dist/handlers-CnTTSJFs.mjs +109 -0
- package/dist/handlers-CoDx6akJ2.mjs +49 -0
- package/dist/{handlers-0yKLRIfo.mjs → handlers-DASJI0Pn.mjs} +1 -1
- package/dist/handlers-DRKMaA-_.mjs +74 -0
- package/dist/handlers-Dalu0olz.mjs +2 -0
- package/dist/handlers-KY0g31ny.mjs +9 -0
- package/dist/handlers-oGo60aVv.mjs +1 -0
- package/dist/handlers.impl-BTXLw6Qc.mjs +1 -0
- package/dist/heap-sampling-BqdiU-5j.mjs +1 -0
- package/dist/{hooks-D4XLfgtV.mjs → hooks-COK3t5rT.mjs} +52 -33
- package/dist/index.mjs +11 -11
- package/dist/logger-BGCcd-jJ.mjs +1 -0
- package/dist/macro-nUYUjKNZ.mjs +2 -0
- package/dist/maintenance-CfnE7ZKU.mjs +4 -0
- package/dist/manifest-7EOTUc0D.mjs +1 -0
- package/dist/manifest-B5ujuQmf.mjs +1 -0
- package/dist/manifest-BErXl3zn.mjs +1 -0
- package/dist/manifest-BKA-mD3J.mjs +1 -0
- package/dist/manifest-BUXj23bX.mjs +1 -0
- package/dist/manifest-BfXt9cau.mjs +1 -0
- package/dist/manifest-Bx-tpURK.mjs +1 -0
- package/dist/manifest-C0owVAdq.mjs +1 -0
- package/dist/manifest-C5XqYc9o.mjs +1 -0
- package/dist/manifest-CVKzLjsA.mjs +1 -0
- package/dist/manifest-CaeFjdhj.mjs +1 -0
- package/dist/manifest-CegBgip0.mjs +1 -0
- package/dist/manifest-CoJHqlgS.mjs +1 -0
- package/dist/manifest-D0dbtDqd.mjs +1 -0
- package/dist/manifest-D5Gr8ujd.mjs +12 -0
- package/dist/manifest-D82z-5og.mjs +1 -0
- package/dist/manifest-DA2afIwh.mjs +1 -0
- package/dist/manifest-DAbiFP5o.mjs +1 -0
- package/dist/manifest-DEY0s1O72.mjs +1 -0
- package/dist/manifest-DTOqNqiA.mjs +1 -0
- package/dist/manifest-DZ6ELNgX.mjs +1 -0
- package/dist/manifest-DjHkjddT.mjs +1 -0
- package/dist/manifest-DocA_itf2.mjs +1 -0
- package/dist/manifest-Dpnhvfq0.mjs +1 -0
- package/dist/manifest-DucPMG_a.mjs +1 -0
- package/dist/manifest-Dw5yYEac.mjs +1 -0
- package/dist/manifest-Ic_Cg66S.mjs +1 -0
- package/dist/manifest-JHaG6GMN.mjs +1 -0
- package/dist/manifest-QdkIzmYM.mjs +1 -0
- package/dist/manifest-YZqaCe25.mjs +1 -0
- package/dist/manifest-f0lUeXwq.mjs +1 -0
- package/dist/manifest-h-Ebisf8.mjs +1 -0
- package/dist/manifest-oOfTymBS.mjs +1 -0
- package/dist/manifest-qXqrO6KC.mjs +2 -0
- package/dist/mapsParser-DrJoeC0c.mjs +1 -0
- package/dist/modules-CC_ADmwi.mjs +333 -0
- package/dist/mojo-ipc-kVztXYw-.mjs +140 -0
- package/dist/native-D9ouskXO.mjs +961 -0
- package/dist/native-bridge-Dzd7hYoq.mjs +1 -0
- package/dist/network-C5Y-S87J.mjs +7 -0
- package/dist/one-gadget-CiWFE17F.mjs +1 -0
- package/dist/outputPaths-CHtELDyi.mjs +1 -0
- package/dist/parse-args-B6dwWc9k.mjs +1 -0
- package/dist/platform-BIXgJaM3.mjs +94 -0
- package/dist/process-aDIfLC0v.mjs +6 -0
- package/dist/proxy-DsHsQ1I4.mjs +2 -0
- package/dist/registry-7h8jJ9y9.mjs +1 -0
- package/dist/{registry-DH4sc1dt.mjs → registry-DJDnkQW2.mjs} +1 -1
- package/dist/response-R8ghbZSb.mjs +1 -0
- package/dist/retry-policy-DtYv0kDi.mjs +1 -0
- package/dist/reverseEngineeringConfig-BhZLOa3C.mjs +1 -0
- package/dist/safeOutput-Dt4mfjXA.mjs +1 -0
- package/dist/search-defaults-BBRJNAzC.mjs +1 -0
- package/dist/server/plugin-api.mjs +1 -1
- package/dist/server/search/EmbeddingWorker.d.mts +1 -0
- package/dist/server/search/EmbeddingWorker.mjs +1 -0
- package/dist/shared-BKtWZDGN.mjs +1 -0
- package/dist/sourcemap-2VIeVeKw.mjs +3 -0
- package/dist/streaming-DkpE3GGU.mjs +15 -0
- package/dist/syscall-DGZoYM_U.mjs +1 -0
- package/dist/transform-BJqsBC_-.mjs +105 -0
- package/dist/turbofan-graph-CbGHNVtl.mjs +1 -0
- package/dist/turbofan-inspect--NdCuYXi.mjs +23 -0
- package/dist/types-CWSvzmIh.mjs +1 -0
- package/dist/v8-inspector-CTJo08-K.mjs +297 -0
- package/dist/wasm-DX4Qm2Vs.mjs +235 -0
- package/dist/weakrefs-inspect-CnhaF-rN.mjs +57 -0
- package/dist/webgpu-D4-DxbxZ.mjs +6 -0
- package/dist/workflow-DHktRNF2.mjs +108 -0
- package/package.json +33 -27
- package/dist/AntiCheatDetector-B6d4Qe9D.mjs +0 -1
- package/dist/CodeInjector-Cll_7bLJ.mjs +0 -1
- package/dist/ConsoleMonitor-CxDJV15E.mjs +0 -306
- package/dist/DOMInspector-C19J4zeq.mjs +0 -95
- package/dist/DarwinAPI-ZfQdpLNI.mjs +0 -1
- package/dist/DetailedDataManager-DmQ1LT-W.mjs +0 -1
- package/dist/ExtensionManager-BD724zkO.mjs +0 -1
- package/dist/ExtensionManager.tools-oVMJgPcN.mjs +0 -1
- package/dist/FingerprintManager-DT0EAUEo.mjs +0 -1
- package/dist/HardwareBreakpoint-BUfPdp0f.mjs +0 -1
- package/dist/HeapAnalyzer-B_aqY8oj.mjs +0 -1
- package/dist/InstrumentationSession-D_G1ZPyd.mjs +0 -1
- package/dist/MCPServer.search.handlers.domain-BbS-6LnX.mjs +0 -1
- package/dist/MemoryController-X1XNSn1n.mjs +0 -2
- package/dist/MemoryScanner-g1_L1ub5.mjs +0 -1
- package/dist/NativeMemoryManager.impl-DniBe2wf.mjs +0 -1
- package/dist/NetworkMonitor-B_-au6aV.mjs +0 -185
- package/dist/PEAnalyzer-yWQaGrcx.mjs +0 -1
- package/dist/PageController-Dfsm1_o7.mjs +0 -1
- package/dist/PointerChainEngine-BhCUkmxY.mjs +0 -1
- package/dist/PrerequisiteError-BjCQA-gK.mjs +0 -1
- package/dist/ProcessRegistry-C-bN48oR.mjs +0 -1
- package/dist/ReverseEvidenceGraph-BhSYYdiI.mjs +0 -2
- package/dist/ScriptManager-LWGPTdvD.mjs +0 -7
- package/dist/ServerRuntimeState-D2bWHqEE.mjs +0 -1
- package/dist/Speedhack-yseDPSZ9.mjs +0 -1
- package/dist/StructureAnalyzer-C5lpuZkg.mjs +0 -2
- package/dist/ToolCatalog-CYdD9F5f.mjs +0 -1
- package/dist/ToolRegistry-C5oB8KP8.mjs +0 -1
- package/dist/ToolRouter.policy-CfhJczkt.mjs +0 -4
- package/dist/TraceRecorder-BiJWBXHX.mjs +0 -272
- package/dist/VersionDetector-CHT36Az0.mjs +0 -9
- package/dist/Win32API-eUCF57l_.mjs +0 -1
- package/dist/WorkflowEngine-D876meOO.mjs +0 -1
- package/dist/analysis-D4swdMvq.mjs +0 -6
- package/dist/apk-packer-BqXcInnX.mjs +0 -1
- package/dist/artifactRetention-BCPQASm7.mjs +0 -1
- package/dist/artifacts-CkodUM4j.mjs +0 -1
- package/dist/binary-instrument-DU7V6TUM.mjs +0 -7
- package/dist/binary-secrets-PdMVoyt0.mjs +0 -1
- package/dist/boringssl-inspector-BBaJwwkU.mjs +0 -2
- package/dist/browser-Qqco2rOT.mjs +0 -11
- package/dist/collector-Bpl6qy2L.mjs +0 -1
- package/dist/constants-BYj8Xek8.mjs +0 -1
- package/dist/coordination-CWXW1o8K.mjs +0 -1
- package/dist/dart-inspector-7AkPeZ_Q.mjs +0 -0
- package/dist/debugger-DyALjYMk.mjs +0 -1
- package/dist/definitions-BWxBke3r.mjs +0 -1
- package/dist/definitions-BYwATKc-.mjs +0 -1
- package/dist/definitions-B_83XfNQ.mjs +0 -1
- package/dist/definitions-Bf3H1EwV.mjs +0 -1
- package/dist/definitions-BftdXgXI.mjs +0 -1
- package/dist/definitions-Bio5XJYy.mjs +0 -1
- package/dist/definitions-C3qNgSn1.mjs +0 -1
- package/dist/definitions-CB6vmOer.mjs +0 -1
- package/dist/definitions-CMZRSy3k.mjs +0 -1
- package/dist/definitions-CQd7yCQH.mjs +0 -1
- package/dist/definitions-CT8ln6GQ.mjs +0 -1
- package/dist/definitions-D4g-MS10.mjs +0 -1
- package/dist/definitions-D5wl_8HN.mjs +0 -1
- package/dist/definitions-DAQm1Xar.mjs +0 -1
- package/dist/definitions-DP1vgxEY.mjs +0 -1
- package/dist/definitions-Ibci7e_L.mjs +0 -1
- package/dist/definitions-OeLvmlQy.mjs +0 -1
- package/dist/definitions-RZYGD_Ey.mjs +0 -1
- package/dist/definitions-Tls8c0A0.mjs +0 -1
- package/dist/definitions-bybDvnG0.mjs +0 -26
- package/dist/definitions-l7TjdE6V.mjs +0 -1
- package/dist/encoding-ycOaz8Vr.mjs +0 -2
- package/dist/ensure-browser-core-DxWC-NTp.mjs +0 -1
- package/dist/factory-CKr4fAE1.mjs +0 -1
- package/dist/flat-target-session-DvcQX7J5.mjs +0 -1
- package/dist/graphql-B2TiPEow.mjs +0 -62
- package/dist/handlers-8zN_vBIz.mjs +0 -1
- package/dist/handlers-B62K4FTc.mjs +0 -1
- package/dist/handlers-BpDlVVVU.mjs +0 -1
- package/dist/handlers-CMJK7m1c.mjs +0 -31
- package/dist/handlers-D2ZOul9p.mjs +0 -54
- package/dist/handlers-D5E40ssn.mjs +0 -5
- package/dist/handlers-DGbdQAgD.mjs +0 -4
- package/dist/handlers-DHO3rjsW.mjs +0 -1
- package/dist/handlers-FJ80VzUI.mjs +0 -2
- package/dist/handlers-VHWrxbM_.mjs +0 -1
- package/dist/handlers-l8QIKqBj.mjs +0 -2
- package/dist/handlers.impl-D9Hh8Bgl.mjs +0 -1
- package/dist/jadx-search-B_Yse0Zh.mjs +0 -5
- package/dist/logger-sBC6IdRT.mjs +0 -1
- package/dist/maintenance-BUpIukhg.mjs +0 -1
- package/dist/manifest-0Jpt_AQa.mjs +0 -1
- package/dist/manifest-B3fZbSWR.mjs +0 -1
- package/dist/manifest-B7NB2rh2.mjs +0 -1
- package/dist/manifest-BDi4nbH1.mjs +0 -1
- package/dist/manifest-BLDfkE7n.mjs +0 -1
- package/dist/manifest-BcXbB4gf.mjs +0 -1
- package/dist/manifest-Bdnc_vrc.mjs +0 -1
- package/dist/manifest-BuYKgCnp.mjs +0 -1
- package/dist/manifest-CBfNnGPV.mjs +0 -1
- package/dist/manifest-CPS1Xv69.mjs +0 -1
- package/dist/manifest-CQH9FhwI.mjs +0 -1
- package/dist/manifest-CRryuZF4.mjs +0 -1
- package/dist/manifest-CctIumog.mjs +0 -1
- package/dist/manifest-CvTe5ZGV2.mjs +0 -1
- package/dist/manifest-D-5GH0DV.mjs +0 -1
- package/dist/manifest-D3Ssf3IC.mjs +0 -1
- package/dist/manifest-D5ck3NvC.mjs +0 -1
- package/dist/manifest-D9jUUJAu.mjs +0 -1
- package/dist/manifest-DCx6w2XV.mjs +0 -1
- package/dist/manifest-DG19q-Ld.mjs +0 -1
- package/dist/manifest-DLMlD0Zc.mjs +0 -1
- package/dist/manifest-DYpn8w_h.mjs +0 -1
- package/dist/manifest-DYzWI8Xs.mjs +0 -1
- package/dist/manifest-D_obs5F4.mjs +0 -1
- package/dist/manifest-DujQqEQR.mjs +0 -2
- package/dist/manifest-DwL2ik8P.mjs +0 -1
- package/dist/manifest-ItF5P8A12.mjs +0 -1
- package/dist/manifest-KZphqIyX.mjs +0 -1
- package/dist/manifest-LG42zPLY2.mjs +0 -1
- package/dist/manifest-LLdI5m4T.mjs +0 -1
- package/dist/manifest-QYbQXJn0.mjs +0 -1
- package/dist/manifest-RcpX_MyZ.mjs +0 -123
- package/dist/manifest-YgVd8Sgz.mjs +0 -1
- package/dist/manifest-Zy7Odg5J.mjs +0 -1
- package/dist/manifest-ff1H7Pdp.mjs +0 -1
- package/dist/manifest-iuhF6pTL2.mjs +0 -1
- package/dist/manifest-nXHmtMSp2.mjs +0 -1
- package/dist/manifest-xWfu6iLo.mjs +0 -1
- package/dist/manifest-yC16OhL2.mjs +0 -1
- package/dist/manifest-ztWJoXy4.mjs +0 -1
- package/dist/matchesWildcardPattern-BAG6LvX5.mjs +0 -1
- package/dist/modules-BPBcSaM-.mjs +0 -333
- package/dist/mojo-ipc-BhwsdVUW.mjs +0 -9
- package/dist/native-j8l473zn.mjs +0 -961
- package/dist/network-T0VRwNPd.mjs +0 -7
- package/dist/outputPaths-B4Ic4RZh.mjs +0 -2
- package/dist/parse-args-Bw413PlW.mjs +0 -1
- package/dist/platform-CzaQtISh.mjs +0 -93
- package/dist/playwright-cdp-fallback-DqFdx9-s.mjs +0 -1
- package/dist/process-CWhsCWrf.mjs +0 -2
- package/dist/proxy-DZFlDsG3.mjs +0 -2
- package/dist/renderer-pid-9tJnZ_9N.mjs +0 -1
- package/dist/response-C7rKQst4.mjs +0 -1
- package/dist/search-defaults-lYBVn_3L.mjs +0 -1
- package/dist/shared-state-board-BSjXLUV1.mjs +0 -1
- package/dist/sourcemap-Dh3Ai_ur.mjs +0 -1
- package/dist/streaming-BcJ0B6ao.mjs +0 -1
- package/dist/transform-DOxzeWPB.mjs +0 -103
- package/dist/types-D9EiE5o9.mjs +0 -1
- package/dist/wasm-CZ_HTfKR.mjs +0 -174
- package/dist/webcrack-C1iYG_EX.mjs +0 -46
- package/dist/workflow-BdwQmARn.mjs +0 -101
- /package/dist/{CacheAdapters-CsNtQIR8.mjs → CacheAdapters-BlDrQg8f.mjs} +0 -0
- /package/dist/{EventBus-DL8iLA09.mjs → EventBus-Cm-t-B65.mjs} +0 -0
- /package/dist/{EvidenceGraphBridge-BtbwXsLC.mjs → EvidenceGraphBridge-DBDc0wUA.mjs} +0 -0
- /package/dist/{HookGeneratorBuilders.core.generators.storage-DzD6dIJd.mjs → HookGeneratorBuilders.core.generators.storage-CWaWpOHa.mjs} +0 -0
- /package/dist/{RingBuffer-Dm54ELKT.mjs → RingBuffer-B6RTHmij.mjs} +0 -0
- /package/dist/{StealthVerifier-BmcxfwSF.mjs → StealthVerifier-DMBrtkhN.mjs} +0 -0
- /package/dist/{ToolError-DWU_z7gp.mjs → ToolError-g3rjWzhx.mjs} +0 -0
- /package/dist/{authorization-schema-BOFwSXUN.mjs → authorization-schema-Jtikc5Yt.mjs} +0 -0
- /package/dist/{bind-helpers-m2U8glkF.mjs → bind-helpers-D0mGAOof.mjs} +0 -0
- /package/dist/{concurrency-DCr8WQ2M.mjs → concurrency-Dehnw4JC.mjs} +0 -0
- /package/dist/{evidence-graph-bridge-CV_UdYqj.mjs → evidence-graph-bridge-eT9icP6a.mjs} +0 -0
- /package/dist/{formatAddress-vLA_hOJt.mjs → formatAddress-DAcw4Ckg.mjs} +0 -0
- /package/dist/{chunk-C_pMuVsO.mjs → rolldown-runtime-88NL7fhV.mjs} +0 -0
- /package/dist/{ssrf-policy-CsIJGkpd.mjs → ssrf-policy-B72vdy23.mjs} +0 -0
- /package/dist/{tool-builder-qif8M9-K.mjs → tool-builder-CpLh-UQd.mjs} +0 -0
- /package/dist/{types-Fz69RzbZ.mjs → types-BzPBzmVB.mjs} +0 -0
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import{Jr as e,Yr as t,qr as n}from"./constants-BYj8Xek8.mjs";const r=[`etw`,`strace`,`dtrace`],i=3e3,a={etw:[{syscall:`NtCreateFile`,args:[`C:\\Windows\\Temp\\jshookmcp.log`,`GENERIC_READ`],returnValue:0,duration:.7},{syscall:`NtReadFile`,args:[`handle=0x90`,`buffer=4096`],returnValue:512,duration:.2},{syscall:`NtWriteFile`,args:[`handle=0x90`,`buffer=128`],returnValue:128,duration:.3},{syscall:`NtDeviceIoControlFile`,args:[`handle=0x44`,`code=0x222004`],returnValue:0,duration:1.1}],strace:[{syscall:`openat`,args:[`/tmp/jshookmcp.log`,`O_RDONLY`],returnValue:3,duration:.4},{syscall:`read`,args:[`fd=3`,`count=4096`],returnValue:256,duration:.1},{syscall:`write`,args:[`fd=3`,`count=128`],returnValue:128,duration:.2},{syscall:`connect`,args:[`fd=18`,`127.0.0.1:9222`],returnValue:0,duration:1.4}],dtrace:[{syscall:`open_nocancel`,args:[`/private/tmp/jshookmcp.log`,`O_RDONLY`],returnValue:3,duration:.5},{syscall:`read_nocancel`,args:[`fd=3`,`count=4096`],returnValue:320,duration:.1},{syscall:`write_nocancel`,args:[`fd=3`,`count=128`],returnValue:128,duration:.2},{syscall:`connect`,args:[`fd=21`,`127.0.0.1:9222`],returnValue:0,duration:1.3}]};function o(e){return e===`etw`?process.platform===`win32`:e===`strace`?process.platform===`linux`:e===`dtrace`?process.platform===`darwin`:!1}function s(){return process.platform===`win32`?`etw`:process.platform===`linux`?`strace`:process.platform===`darwin`?`dtrace`:`etw`}function c(e){return{timestamp:e.timestamp,pid:e.pid,syscall:e.syscall,args:[...e.args],returnValue:e.returnValue,duration:e.duration}}function l(e,t,n,r){let a=!1,o=setTimeout(()=>{if(!a){a=!0;try{r?.()}catch{}n(Error(`${e} did not signal readiness within ${i}ms`))}},i);return{resolveReady(e){a||(a=!0,clearTimeout(o),t(e))},rejectReady(e){a||(a=!0,clearTimeout(o),n(e))}}}function u(e,t){return t?!(t.pid!==void 0&&e.pid!==t.pid||t.name&&t.name.length>0&&!t.name.includes(e.syscall)):!0}function d(e,t,n){let r=/^(\d+)\s+([\d:.]+)\s+(\w+)\(([^)]*)\)\s*=\s*(-?\d+)(?:\s+<([\d.]+)>)?$/u.exec(e.trim());if(!r)return null;let i=r[3]??`unknown`,a=r[4]??``,o=Number(r[5]),s=r[6]?Number(r[6]):void 0,c=a.split(`,`).map(e=>e.trim()).filter(e=>e.length>0);return{timestamp:Date.now()-n,pid:t,syscall:i,args:c,returnValue:Number.isFinite(o)?o:void 0,duration:s!==void 0&&Number.isFinite(s)?s*1e3:void 0}}function f(e,t,n){let r=/^\[([^\]]+)\]\s+PID=(\d+)\s+(\w+)\s+(.*)$/u.exec(e.trim());if(!r)return null;let i=r[3]??`unknown`,a=r[4]??``,o=Number(r[2]),s=a.split(/\s+/u).filter(e=>e.length>0);return{timestamp:Date.now()-n,pid:Number.isFinite(o)?o:t,syscall:i,args:s}}function p(e,t,n){let r=/^\s*(\d+)\s+\d+\s+(\d+)\s+(\w+):\w+\s+(.*)$/u.exec(e.trim());if(!r)return null;let i=r[3]??`unknown`,a=r[4]??``,o=Number(r[2]),s=a.split(/\s+/u).filter(e=>e.length>0);return{timestamp:Date.now()-n,pid:Number.isFinite(o)?o:t,syscall:i,args:s}}var m=class{activeState;capturedEvents=[];lastBackend=s();subprocessError;async start(e){let t=e?.backend??s(),n=Date.now();if(!o(t))throw Error(`Backend "${t}" is not available on platform "${process.platform}"`);if(e?.simulate??process.env.JSHOOK_SIMULATE===`1`){this.activeState={backend:t,pid:e?.pid,startedAt:n,generatedEvents:0},this.lastBackend=t,this.capturedEvents.length=0,this.generateSyntheticEvents();return}let r=e?.pid??process.pid,i;try{t===`strace`?i=await this.captureWithStrace(r,n):t===`etw`?i=await this.captureWithETW(r,n):t===`dtrace`&&(i=await this.captureWithDTrace(r,n))}catch(r){this.subprocessError=r instanceof Error?r.message:String(r),this.activeState={backend:t,pid:e?.pid,startedAt:n,generatedEvents:0},this.lastBackend=t,this.capturedEvents.length=0,this.generateSyntheticEvents();return}this.activeState={backend:t,pid:e?.pid,startedAt:n,generatedEvents:0,subprocess:i},this.lastBackend=t,this.capturedEvents.length=0,this.subprocessError=void 0}async stop(){this.activeState?.subprocess&&(this.activeState.subprocess.kill(`SIGTERM`),this.activeState.subprocess=void 0),this.activeState=void 0}async captureEvents(e){return this.activeState&&!this.activeState.subprocess&&this.generateSyntheticEvents(),this.capturedEvents.filter(t=>u(t,e)).map(c)}getStats(){let e=this.activeState?.backend??this.lastBackend,t=this.activeState?Date.now()-this.activeState.startedAt:0;return{eventsCaptured:this.capturedEvents.length,uptime:t,backend:e,subprocessActive:!!this.activeState?.subprocess,subprocessError:this.subprocessError}}getSupportedBackends(){return r.filter(e=>o(e))}isRunning(){return this.activeState!==void 0}async captureWithStrace(e,t=this.activeState?.startedAt??Date.now()){let{spawn:n}=await import(`node:child_process`);return new Promise((r,i)=>{let a=n(`strace`,[`-p`,String(e),`-f`,`-e`,`trace=all`,`-t`],{stdio:[`ignore`,`pipe`,`pipe`]}),o=l(`strace process`,r,i,()=>a.kill(`SIGTERM`)),s=``,c=``;a.stdout?.on(`data`,t=>{c+=t.toString(),this.processLineBuffer(c,e,`strace`)}),a.stderr?.on(`data`,n=>{s+=n.toString();let r=s.split(/\r?\n/u);s=r.pop()??``;for(let n of r)if(n.length>0){let r=d(n,e,t);r&&this.capturedEvents.push(r)}}),a.on(`error`,e=>{o.rejectReady(Error(`strace process error: ${e.message}. Is strace installed?`))}),a.on(`spawn`,()=>{o.resolveReady(a)})})}async captureWithETW(e,t=this.activeState?.startedAt??Date.now()){let{spawn:n}=await import(`node:child_process`);return new Promise((r,i)=>{let a=n(`logman`,[`create`,`trace`,`JSHookETW_${e}`,`-p`,`NT Kernel Logger`,`0x10000`,`-o`,`jshook_etw_${e}.etl`,`-ets`],{stdio:[`ignore`,`pipe`,`pipe`],windowsHide:!0}),o=l(`ETW trace session`,r,i,()=>a.kill(`SIGTERM`)),s=``;a.stdout?.on(`data`,n=>{s+=n.toString();let r=s.split(/\r?\n/u);s=r.pop()??``;for(let n of r){let r=f(n,e,t);r&&this.capturedEvents.push(r)}}),a.stderr?.on(`data`,e=>{let t=e.toString().trim();t.length>0&&t.startsWith(`The command completed successfully`)}),a.on(`error`,e=>{o.rejectReady(Error(`ETW trace error: ${e.message}. Run as Administrator.`))}),a.on(`exit`,e=>{e!==0&&e!==void 0&&o.rejectReady(Error(`ETW trace session ended (code ${e}). Check permissions.`))}),a.on(`spawn`,()=>{o.resolveReady(a)})})}async captureWithDTrace(e,t=this.activeState?.startedAt??Date.now()){let{spawn:n}=await import(`node:child_process`);return new Promise((r,i)=>{let a=n(`dtrace`,[`-n`,`
|
|
2
|
-
syscall:::entry
|
|
3
|
-
/pid == ${e}/
|
|
4
|
-
{
|
|
5
|
-
printf("%d %d %s:entry %s", pid, probeproc, probefunc, copyinstr(arg0));
|
|
6
|
-
}
|
|
7
|
-
`],{stdio:[`ignore`,`pipe`,`pipe`]}),o=l(`dtrace process`,r,i,()=>a.kill(`SIGTERM`)),s=``;a.stdout?.on(`data`,n=>{s+=n.toString();let r=s.split(/\r?\n/u);s=r.pop()??``;for(let n of r){let r=p(n,e,t);r&&this.capturedEvents.push(r)}}),a.stderr?.on(`data`,()=>{}),a.on(`error`,e=>{o.rejectReady(Error(`dtrace error: ${e.message}. Run with sudo.`))}),a.on(`spawn`,()=>{o.resolveReady(a)})})}generateSyntheticEvents(){if(!this.activeState)return;let e=a[this.activeState.backend];if(!e)return;let t=Date.now()-this.activeState.startedAt,n=Math.max(1,Math.min(e.length*3,Math.floor(t/150)+1)),r=this.activeState.pid??process.pid;for(;this.activeState.generatedEvents<n;){let t=e[this.activeState.generatedEvents%e.length];if(!t)break;let n=this.activeState.generatedEvents*75;this.capturedEvents.push({timestamp:n,pid:r,syscall:t.syscall,args:[...t.args],returnValue:t.returnValue,duration:t.duration}),this.activeState.generatedEvents+=1}}processLineBuffer(e,t,n){}};const h=[{syscallNames:[`NtCreateFile`,`openat`,`open_nocancel`],jsFunction:`fs.open`,baseConfidence:.8,explanation:`File open syscalls commonly originate from Node.js file-system entry points.`},{syscallNames:[`NtReadFile`,`read`,`read_nocancel`],jsFunction:`fs.readFile`,baseConfidence:.78,explanation:`Read-oriented syscalls usually map back to file or stream reads in JavaScript.`},{syscallNames:[`NtWriteFile`,`write`,`write_nocancel`],jsFunction:`fs.writeFile`,baseConfidence:.78,explanation:`Write-oriented syscalls are strongly associated with Node.js file writes.`},{syscallNames:[`NtDeviceIoControlFile`,`ioctl`],jsFunction:`child_process.spawn`,baseConfidence:.55,explanation:`Device and control syscalls are often triggered by child processes or native helpers.`},{syscallNames:[`connect`,`sendto`,`recvfrom`],jsFunction:`fetch`,baseConfidence:.7,explanation:`Socket syscalls generally indicate outbound network activity from fetch-like APIs.`}];function g(e){return h.find(t=>t.syscallNames.includes(e))}function _(e){return e<0?0:e>1?1:e}function v(e,t){return e.some(e=>t.some(t=>e.toLowerCase().includes(t)))}var y=class{map(e){let t=this.findJSFunction(e.syscall);if(!t)return null;let n=g(e.syscall);if(!n)return null;let r=n.baseConfidence;return t.startsWith(`fs.`)&&v(e.args,[`.js`,`.json`,`.node`])&&(r+=.08),t===`fetch`&&v(e.args,[`80`,`443`,`http`,`https`])&&(r+=.1),{syscall:{timestamp:e.timestamp,pid:e.pid,syscall:e.syscall,args:[...e.args],returnValue:e.returnValue,duration:e.duration},jsFunction:t,confidence:_(r),reasoning:this.getCorrelationReason(e,t)}}findJSFunction(e){let t=g(e);return t?t.jsFunction:null}getCorrelationReason(e,t){let n=g(e.syscall),r=[];return n&&r.push(n.explanation),t.startsWith(`fs.`)&&v(e.args,[`.js`,`.json`,`.node`])&&r.push(`The syscall arguments reference module-like file extensions, which strengthens the fs correlation.`),t===`fetch`&&v(e.args,[`80`,`443`,`http`,`https`])&&r.push(`The syscall arguments look like network endpoints, which aligns with fetch or low-level HTTP clients.`),r.length===0&&r.push(`Mapped ${e.syscall} to ${t} using the default syscall-to-JS heuristic table.`),r.join(` `)}};function b(e){return typeof e==`object`&&!!e}function x(e){if(typeof e==`number`&&Number.isFinite(e))return e}function S(e){if(typeof e==`boolean`)return e}function C(e){if(typeof e==`string`)return e}function w(e){if(!Array.isArray(e))return;let t=[];for(let n of e){if(typeof n!=`string`)return;t.push(n)}return t}const T=/^[a-z][a-z0-9_]*$/;function E(e){return T.test(e)&&e.length<=64}function D(e){if(e===`etw`||e===`strace`||e===`dtrace`)return e}function O(e){if(!b(e))return;let t={},n=w(e.name),r=x(e.pid);return n&&(t.name=n),r!==void 0&&(t.pid=r),t}function k(e){if(!b(e))return!1;let t=x(e.timestamp),n=x(e.pid),r=C(e.syscall),i=w(e.args),a=e.returnValue,o=e.duration,s=a===void 0||x(a)!==void 0,c=o===void 0||x(o)!==void 0;return t!==void 0&&n!==void 0&&r!==void 0&&i!==void 0&&s&&c}function A(e){return{timestamp:e.timestamp,pid:e.pid,syscall:e.syscall,args:[...e.args],returnValue:e.returnValue,duration:e.duration}}function j(e){return e instanceof Error?e.message:`Unknown syscall-hook error`}var M=class{monitor;mapper;eventBus;constructor(e,t,n){this.monitor=e,this.mapper=t,this.eventBus=n}async handleSyscallStartMonitor(e){let t=D(e.backend);if(!t)return{ok:!1,error:`backend must be one of: etw, strace, dtrace`};let n=x(e.pid),r=S(e.simulate)??!1;if(e.pid!==void 0&&e.pid!==null&&(n===void 0||!Number.isInteger(n)||n<0))return{ok:!1,error:`pid must be a non-negative integer when provided`};let i=n,a=this.ensureMonitor();try{return await a.start({backend:t,pid:i,simulate:r}),this.eventBus?.emit(`syscall:trace_started`,{backend:t,pid:i,simulate:r,timestamp:new Date().toISOString()}),{ok:!0,started:!0,backend:t,pid:i,simulate:r,stats:a.getStats()}}catch(e){return{ok:!1,error:j(e),requestedBackend:t,supportedBackends:a.getSupportedBackends()}}}async handleSyscallStopMonitor(){let e=this.ensureMonitor();try{return await e.stop(),{ok:!0,stopped:!0,stats:e.getStats()}}catch(e){return{ok:!1,error:j(e)}}}async handleSyscallCaptureEvents(e){let t=this.ensureMonitor(),n=O(e.filter),r=await t.captureEvents(n);return{ok:!0,events:r,count:r.length,stats:t.getStats()}}async handleSyscallCorrelateJs(e){let t=e.syscallEvents;if(!Array.isArray(t)||!t.every(e=>k(e)))return{ok:!1,error:`syscallEvents must be an array of valid SyscallEvent objects`};let n=this.ensureMapper(),r=[],i=[];for(let e of t){let t=A(e),a=n.map(t);a?r.push(a):i.push(t)}return{ok:!0,correlations:r,matched:r.length,unmatched:i}}async handleSyscallFilter(e){let t=w(e.names);if(e.names!==void 0&&t===void 0)return{ok:!1,error:`names must be an array of strings when provided`};let n=await this.ensureMonitor().captureEvents(t&&t.length>0?{name:t}:void 0);return{ok:!0,names:t,events:n,count:n.length}}async handleSyscallGetStats(){let e=this.ensureMonitor();return{ok:!0,...e.getStats(),running:e.isRunning(),supportedBackends:e.getSupportedBackends()}}async handleSyscallEbpfTrace(r){let i=x(r.pid),a=w(r.syscalls),o=x(r.durationSec)??n,s=S(r.simulate)??!1;if(r.pid!==void 0&&r.pid!==null&&(i===void 0||!Number.isInteger(i)||i<0))return{ok:!1,error:`pid must be a non-negative integer (0 for all processes)`};let c=i??0;if(o<t||o>e)return{ok:!1,error:`durationSec must be between ${t} and ${e}`};if(a?.length){let e=a.filter(e=>!E(e));if(e.length>0)return{ok:!1,error:`Invalid syscall names (must be lowercase alphanumeric with underscores): ${e.join(`, `)}`}}if(s){let e=[],t=a?.length?a:[`read`,`write`,`openat`,`close`,`fstat`,`mmap`,`mprotect`,`munmap`,`brk`,`ioctl`],n=o*50;for(let r=0;r<20;r++)e.push({timestamp:r*n,pid:c||1234,syscall:t[r%t.length]??`read`,args:[`fd=${r%5+3}`,`count=${(r+1)*64}`],returnValue:r%3==0?-1:(r+1)*64,duration:Math.random()*2});return{ok:!0,backend:`ebpf`,simulated:!0,pid:c,durationSec:o,events:e,count:e.length,syscallsTraced:t}}let l=a?.length?a:[`read`,`write`,`openat`,`close`,`fstat`,`mmap`,`mprotect`,`munmap`,`brk`,`ioctl`,`connect`,`sendto`,`recvfrom`,`clone`,`execve`],u=c>0?`/pid == ${c}/`:``,d=l.map(e=>`tracepoint:syscalls:sys_enter_${e}`).join(`, `),f=l.map(e=>`tracepoint:syscalls:sys_exit_${e}`).join(`, `),p=`#!/usr/bin/env bpftrace
|
|
8
|
-
// Generated by jshookmcp syscall_ebpf_trace
|
|
9
|
-
// Target PID: ${c||`all`} | Duration: ${o}s | Syscalls: ${l.join(`, `)}
|
|
10
|
-
|
|
11
|
-
BEGIN {
|
|
12
|
-
printf("=== eBPF syscall trace started (pid=${c||`all`}, duration=${o}s) ===\\n");
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
${d} ${u}
|
|
16
|
-
{
|
|
17
|
-
@enter_ts[tid] = nsecs;
|
|
18
|
-
printf("{\\"timestamp\\": %llu, \\"pid\\": %d, \\"tid\\": %d, \\"syscall\\": \\"%s\\", \\"phase\\": \\"enter\\", \\"args\\": {",
|
|
19
|
-
elapsed / 1000000, pid, tid, probe);
|
|
20
|
-
// Log key arguments based on syscall
|
|
21
|
-
if (probe == "tracepoint:syscalls:sys_enter_openat" || probe == "tracepoint:syscalls:sys_enter_open") {
|
|
22
|
-
printf("\\"pathname\\": \\"%s\\", \\"flags\\": %d, \\"mode\\": %d", args->pathname, args->flags, args->mode);
|
|
23
|
-
} else if (probe == "tracepoint:syscalls:sys_enter_read" || probe == "tracepoint:syscalls:sys_enter_write") {
|
|
24
|
-
printf("\\"fd\\": %d, \\"count\\": %d", args->fd, args->count);
|
|
25
|
-
} else if (probe == "tracepoint:syscalls:sys_enter_connect") {
|
|
26
|
-
printf("\\"fd\\": %d", args->fd);
|
|
27
|
-
} else if (probe == "tracepoint:syscalls:sys_enter_mmap") {
|
|
28
|
-
printf("\\"addr\\": %llu, \\"length\\": %llu, \\"prot\\": %d, \\"flags\\": %d, \\"fd\\": %d", args->addr, args->length, args->prot, args->flags, args->fd);
|
|
29
|
-
} else if (probe == "tracepoint:syscalls:sys_enter_execve") {
|
|
30
|
-
printf("\\"filename\\": \\"%s\\"", args->filename);
|
|
31
|
-
} else {
|
|
32
|
-
printf("\\"raw_args\\": \\"(see bpftrace -v output)\\"");
|
|
33
|
-
}
|
|
34
|
-
printf("}}\\n");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
${f} ${u}
|
|
38
|
-
{
|
|
39
|
-
$elapsed_ns = nsecs - @enter_ts[tid];
|
|
40
|
-
printf("{\\"timestamp\\": %llu, \\"pid\\": %d, \\"tid\\": %d, \\"syscall\\": \\"%s\\", \\"phase\\": \\"exit\\", \\"ret\\": %d, \\"duration_us\\": %llu}\\n",
|
|
41
|
-
elapsed / 1000000, pid, tid, probe, args->ret, $elapsed_ns / 1000);
|
|
42
|
-
delete(@enter_ts[tid]);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
interval:s:${o} {
|
|
46
|
-
printf("=== Trace duration (${o}s) elapsed, exiting ===\\n");
|
|
47
|
-
exit();
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
END {
|
|
51
|
-
printf("=== eBPF syscall trace complete ===\\n");
|
|
52
|
-
clear(@enter_ts);
|
|
53
|
-
}
|
|
54
|
-
`;return{ok:!0,backend:`ebpf`,mode:`script`,pid:c,durationSec:o,syscallCount:l.length,syscallsTraced:l,script:p,usage:`bpftrace -e '${p.replace(/'/g,`'\\''`)}'`,note:`Run the generated bpftrace script on a Linux system with bpftrace installed and CAP_BPF/root privileges.`,requiredCapabilities:[`CAP_BPF`,`root`,`bpftrace`]}}ensureMonitor(){return this.monitor||=new m,this.monitor}ensureMapper(){return this.mapper||=new y,this.mapper}};export{M as SyscallHookHandlers};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./response-C7rKQst4.mjs";import{a as t,c as n,i as r,l as i,n as a,o,r as s,s as c}from"./boringssl-inspector-BBaJwwkU.mjs";import{a as l,n as u,o as d,r as f,t as p}from"./parse-args-Bw413PlW.mjs";import{a as m,s as h}from"./ssrf-policy-CsIJGkpd.mjs";import{X509Certificate as g,createHash as _,randomBytes as v,randomUUID as y}from"node:crypto";import{readFile as b}from"node:fs/promises";import{createSocket as x}from"node:dgram";import{Socket as S,createServer as C,isIP as w}from"node:net";import{checkServerIdentity as T,connect as E}from"node:tls";const D=new Set([`TLSv1`,`TLSv1.1`,`TLSv1.2`,`TLSv1.3`]);function O(e){return e instanceof Error?e.message:String(e)}function k(e){return e.replace(/\s+/g,``).toUpperCase()}function A(e){return e.length>0&&e.length%2==0&&/^[0-9A-F]+$/i.test(e)}function j(e){return h(e)&&!m(e)?{ok:!1,error:`Blocked: target host "${e}" resolves to a private/internal address. SSRF protection applies.`}:null}function M(e){return typeof e==`string`&&e.length>0?e:null}function N(e){return typeof e==`string`&&e.length>0?e:null}function P(e,t){let n={...e};return Reflect.set(n,`rejectUnauthorized`,!t),n}async function F(e){let t=l(e,`caPem`)??null,n=l(e,`caPath`)??null;if(t&&n)return{ok:!1,error:`caPem and caPath are mutually exclusive`};if(t)return{ok:!0,ca:t,source:`inline`,path:null,bytes:Buffer.byteLength(t)};if(n)try{let e=await b(n,`utf8`);return{ok:!0,ca:e,source:`path`,path:n,bytes:Buffer.byteLength(e)}}catch(e){return{ok:!1,error:`Failed to read caPath "${n}": ${O(e)}`}}return{ok:!0,ca:void 0,source:null,path:null,bytes:null}}function I(e){return typeof e==`object`&&!!e&&Object.keys(e).length>0}function L(e){return I(e)}function R(e,t){let n=Buffer.isBuffer(e.raw)?e.raw:null,r=n?new g(n):null,i=r?.subject??null,a=r?.issuer??null;return{depth:t,subject:i,issuer:a,subjectAltName:r?.subjectAltName??e.subjectaltname??null,serialNumber:r?.serialNumber??e.serialNumber??null,validFrom:r?.validFrom??e.valid_from??null,validTo:r?.validTo??e.valid_to??null,fingerprint256:r?.fingerprint256??e.fingerprint256??null,fingerprint512:r?.fingerprint512??e.fingerprint512??null,rawLength:n?.length??null,isCA:r?.ca??e.ca??null,selfIssued:i&&a?i===a:null}}function z(e){if(!e)return[];let t=[],n=new Set,r=e,i=0;for(;r&&L(r);){let e=R(r,i),a=e.fingerprint256??`${e.subject??`unknown-subject`}:${e.serialNumber??`unknown-serial`}:${i}`;if(n.has(a)||(n.add(a),t.push(e),!(`issuerCertificate`in r)))break;let o=r.issuerCertificate;if(!o||o===r||!L(o))break;r=o,i+=1}return t}function B(e){let t=_(`sha256`).update(e).digest(`hex`).toUpperCase();try{let n=new g(e);return{subject:n.subject||void 0,issuer:n.issuer||void 0,serialNumber:n.serialNumber||void 0,validFrom:n.validFrom||void 0,validTo:n.validTo||void 0,sha256:t,length:e.length}}catch{return{sha256:t,length:e.length}}}function V(e){let t=Buffer.from(k(e),`hex`),n=[],r=0;for(;r<t.length-4;)if(t[r]===48){let e=B(t.subarray(r));n.push({sha256:e.sha256,length:e.length}),r+=e.length}else r+=1;return n.length===0&&t.length>0&&n.push({sha256:_(`sha256`).update(t).digest(`hex`).toUpperCase(),length:t.length}),n}function H(e){return`${e}_${y()}`}function U(e){return{localAddress:e.localAddress??null,localPort:e.localPort??null,remoteAddress:e.remoteAddress??null,remotePort:e.remotePort??null}}function W(e){return{bufferedBytes:e.buffer.length,remoteEnded:e.ended,socketClosed:e.closed,error:e.error}}function G(e){for(let t of e.waiters)t();e.waiters.clear()}function K(e){e.socket.on(`data`,t=>{e.buffer=Buffer.concat([e.buffer,t]),G(e)}),e.socket.on(`end`,()=>{e.ended=!0,G(e)}),e.socket.on(`close`,()=>{e.closed=!0,G(e)}),e.socket.on(`error`,t=>{e.error=t.message,G(e)})}function ee(e,t){return new Promise(n=>{let r=()=>{clearTimeout(i),e.waiters.delete(r),n(!0)},i=setTimeout(()=>{e.waiters.delete(r),n(!1)},t);e.waiters.add(r)})}function te(e,t,n,r){let i=t?t.toString(`hex`).toUpperCase():null;if(t){let r=e.buffer.indexOf(t);if(r>=0){let a=r+t.length,o=n?e.buffer.subarray(0,a):e.buffer.subarray(0,r);return e.buffer=e.buffer.subarray(a),{data:o,matchedDelimiter:!0,stopReason:`delimiter`,delimiterHex:i}}}if(typeof r==`number`&&e.buffer.length>=r){let t=e.buffer.subarray(0,r);return e.buffer=e.buffer.subarray(r),{data:t,matchedDelimiter:!1,stopReason:`maxBytes`,delimiterHex:i}}if((e.error||e.ended||e.closed)&&e.buffer.length>0){let t=e.buffer;return e.buffer=Buffer.alloc(0),{data:t,matchedDelimiter:!1,stopReason:e.error?`error`:`closed`,delimiterHex:i}}return null}function q(e){return{bufferedBytes:e.parserBuffer.length,queuedFrames:e.frames.length,remoteEnded:e.ended,socketClosed:e.closed,closeSent:e.closeSent,closeReceived:e.closeReceived,error:e.error}}function J(e){return!e||e.trim().length===0?`/`:e.startsWith(`/`)?e:`/${e}`}function ne(e){return{1:`text`,2:`binary`,8:`close`,9:`ping`,10:`pong`}[e]??null}function re(e){return _(`sha1`).update(`${e}258EAFA5-E914-47DA-95CA-C5AB0DC85B11`,`utf8`).digest(`base64`)}function Y(e,t,n,r){let i={text:1,binary:2,close:8,ping:9,pong:10},a=t;if(e===`close`)if(n!=null){let e=r?Buffer.from(r,`utf8`):Buffer.alloc(0);a=Buffer.alloc(2+e.length),a.writeUInt16BE(n,0),e.copy(a,2)}else r&&(a=Buffer.from(r,`utf8`));let o=v(4),s=a.length,c;s<126?(c=Buffer.alloc(2),c[1]=128|s):s<=65535?(c=Buffer.alloc(4),c[1]=254,c.writeUInt16BE(s,2)):(c=Buffer.alloc(10),c[1]=255,c.writeBigUInt64BE(BigInt(s),2)),c[0]=128|i[e];let l=Buffer.alloc(s);for(let e=0;e<s;e+=1)l[e]=a[e]^o[e%4];return Buffer.concat([c,o,l])}function ie(e){if(e.length<2)return null;let t=e[0],n=e[1],r=(t&128)!=0,i=t&15,a=(n&128)!=0,o=n&127,s=2;if(o===126){if(e.length<s+2)return null;o=e.readUInt16BE(s),s+=2}else if(o===127){if(e.length<s+8)return null;let t=e.readBigUInt64BE(s);if(t>BigInt(2**53-1))throw Error(`WebSocket frame payload length exceeds supported limits`);o=Number(t),s+=8}let c=a?e.subarray(s,s+4):null;if(a){if(e.length<s+4)return null;s+=4}if(e.length<s+o)return null;let l=e.subarray(s,s+o),u=Buffer.alloc(l.length);if(a&&c)for(let e=0;e<l.length;e+=1)u[e]=l[e]^c[e%4];else l.copy(u);let d=ne(i);if(!d)throw Error(`Unsupported WebSocket opcode 0x${i.toString(16)}`);let f=null,p=null;return d===`close`&&u.length>=2&&(f=u.readUInt16BE(0),p=u.subarray(2).toString(`utf8`)),{frame:{type:d,fin:r,opcode:i,masked:a,data:u,closeCode:f,closeReason:p,receivedAt:Date.now()},bytesConsumed:s+o}}function X(e){for(let t of e.waiters)t();e.waiters.clear()}function ae(e,t){return new Promise(n=>{let r=()=>{clearTimeout(i),e.waiters.delete(r),n(!0)},i=setTimeout(()=>{e.waiters.delete(r),n(!1)},t);e.waiters.add(r)})}const oe={"3:1":`TLS 1.0`,"3:2":`TLS 1.1`,"3:3":`TLS 1.2`,"3:4":`TLS 1.3`},se={20:`change_cipher_spec`,21:`alert`,22:`handshake`,23:`application_data`,24:`heartbeat`},ce={156:`TLS_RSA_WITH_AES_128_GCM_SHA256`,157:`TLS_RSA_WITH_AES_256_GCM_SHA384`,52392:`TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`,52393:`TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384`,4865:`TLS_AES_128_GCM_SHA256`,4866:`TLS_AES_256_GCM_SHA384`,4867:`TLS_CHACHA20_POLY1305_SHA256`,4868:`TLS_AES_128_CCM_SHA256`,4869:`TLS_AES_128_CCM_8_SHA256`,49195:`TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`,49196:`TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384`,49199:`TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`,49200:`TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384`},le={0:`server_name`,1:`max_fragment_length`,5:`status_request`,10:`supported_groups`,13:`signature_algorithms`,16:`application_layer_protocol_negotiation`,18:`signed_certificate_timestamp`,23:`record_size_limit`,27:`compress_certificate`,35:`session_ticket`,43:`supported_versions`,44:`cookie`,45:`psk_key_exchange_modes`,49:`post_handshake_auth`,51:`key_share`};function Z(e,t){return oe[`${e}:${t}`]??`0x${e.toString(16).padStart(2,`0`)}${t.toString(16).padStart(2,`0`)}`}function Q(e){return se[e]??`unknown`}function ue(e){let t={cipherSuites:[],extensions:[]},n=e[0]!==void 0&&e[0]<25?4:0;if(e.length<n+38)return t;let r=n+34,i=e[r]??0,a=r+1+i;if(a+2>e.length)return t;let o=e.readUInt16BE(a);a+=2;let s=a+o;for(;a+2<=s;){let n=e.readUInt16BE(a);t.cipherSuites.push(ce[n]??`0x${n.toString(16).padStart(4,`0`)}`),a+=2}if(a=s+1,a<e.length){let t=e[a];t!==void 0&&(a+=1+t)}if(a+2<=e.length){let n=e.readUInt16BE(a);a+=2;let r=a+n;for(;a+4<=r;){let n=e.readUInt16BE(a),i=e.readUInt16BE(a+2);a+=4;let o=le[n]??`unknown(0x${n.toString(16)})`;if(t.extensions.push({type:n,name:o,length:i}),n===0&&a+2<=r){let n=a+2;if(n+3<=r&&e[n]===0){let i=e.readUInt16BE(n+1),a=n+3;a+i<=r&&(t.serverName=e.subarray(a,a+i).toString(`utf8`))}}a+=i}}return t}var de=class{keyLogExtractor;extensionInvoke;eventBus;tcpSessions=new Map;tlsSessions=new Map;websocketSessions=new Map;constructor(e=new a){this.keyLogExtractor=e}setExtensionInvoke(e){this.extensionInvoke=e}setEventBus(e){this.eventBus=e}getTcpSession(e){return this.tcpSessions.get(e)??null}getTlsSession(e){return this.tlsSessions.get(e)??null}getWebSocketSession(e){return this.websocketSessions.get(e)??null}parseWritePayload(e){let t=l(e,`dataHex`),n=l(e,`dataText`);if(!t&&!n)return{ok:!1,error:`dataHex or dataText is required`};if(t&&n)return{ok:!1,error:`dataHex and dataText are mutually exclusive`};if(t){let e=k(t);return A(e)?{ok:!0,data:Buffer.from(e,`hex`),inputEncoding:`hex`}:{ok:!1,error:`dataHex must be valid even-length hexadecimal data`}}return{ok:!0,data:Buffer.from(n??``,`utf8`),inputEncoding:`utf8`}}async writeBufferedSession(e,t){if(e.socket.destroyed||e.closed)return{ok:!1,error:`Session "${e.id}" is already closed`,sessionId:e.id,kind:e.kind,state:W(e)};let n=this.parseWritePayload(t);if(!n.ok)return{ok:!1,error:n.error,sessionId:e.id,kind:e.kind};let r=f(t,`timeoutMs`)??5e3;return!Number.isFinite(r)||r<=0?{ok:!1,error:`timeoutMs must be a positive number`}:new Promise(t=>{let i=!1,a=n=>{i||(i=!0,clearTimeout(o),e.socket.off(`error`,s),t(n))},o=setTimeout(()=>{a({ok:!1,error:`write timed out`,sessionId:e.id,kind:e.kind,state:W(e)})},r),s=t=>{a({ok:!1,error:t.message,sessionId:e.id,kind:e.kind,state:W(e)})};e.socket.once(`error`,s),e.socket.write(n.data,()=>{e.kind===`tcp`?this.eventBus?.emit(`tcp:session_written`,{sessionId:e.id,byteLength:n.data.length,timestamp:new Date().toISOString()}):this.eventBus?.emit(`tls:session_written`,{sessionId:e.id,byteLength:n.data.length,timestamp:new Date().toISOString()}),a({ok:!0,sessionId:e.id,kind:e.kind,inputEncoding:n.inputEncoding,bytesWritten:n.data.length,transport:U(e.socket),state:W(e)})})})}async readBufferedSessionUntil(e,t){let n=l(t,`delimiterHex`),r=l(t,`delimiterText`);if(n&&r)return{ok:!1,error:`delimiterHex and delimiterText are mutually exclusive`};let i=null;if(n){let e=k(n);if(!A(e))return{ok:!1,error:`delimiterHex must be valid even-length hexadecimal data`};i=Buffer.from(e,`hex`)}else r!==void 0&&(i=Buffer.from(r,`utf8`));if(i&&i.length===0)return{ok:!1,error:`delimiter must not be empty`};let a=p(t,`includeDelimiter`)??!0,o=f(t,`maxBytes`),s=o===void 0?void 0:Math.trunc(o);if(s!==void 0&&(!Number.isFinite(s)||s<=0))return{ok:!1,error:`maxBytes must be a positive integer when provided`};if(!i&&s===void 0)return{ok:!1,error:`delimiterHex, delimiterText, or maxBytes is required`};let c=f(t,`timeoutMs`)??5e3;if(!Number.isFinite(c)||c<=0)return{ok:!1,error:`timeoutMs must be a positive number`};if(e.activeRead)return{ok:!1,error:`Session "${e.id}" already has a pending read`,sessionId:e.id,kind:e.kind,state:W(e)};e.activeRead=!0;let u=Date.now();try{for(;;){let t=te(e,i,a,s);if(t)return e.kind===`tcp`?this.eventBus?.emit(`tcp:session_read`,{sessionId:e.id,byteLength:t.data.length,matched:t.matchedDelimiter,timestamp:new Date().toISOString()}):this.eventBus?.emit(`tls:session_read`,{sessionId:e.id,byteLength:t.data.length,matched:t.matchedDelimiter,timestamp:new Date().toISOString()}),{ok:!0,sessionId:e.id,kind:e.kind,bytesRead:t.data.length,matchedDelimiter:t.matchedDelimiter,stopReason:t.stopReason,delimiterHex:t.delimiterHex,dataHex:t.data.toString(`hex`).toUpperCase(),dataText:t.data.toString(`utf8`),elapsedMs:Date.now()-u,state:W(e)};if(e.error)return{ok:!1,error:e.error,sessionId:e.id,kind:e.kind,state:W(e)};if(e.ended||e.closed)return{ok:!1,error:`socket closed before the requested read condition was satisfied`,sessionId:e.id,kind:e.kind,state:W(e)};let n=c-(Date.now()-u);if(n<=0||!await ee(e,n))return{ok:!1,error:`read timed out`,sessionId:e.id,kind:e.kind,state:W(e)}}}finally{e.activeRead=!1}}async closeBufferedSession(e,t,n,r){let i=t.get(e);if(!i)return{ok:!1,error:`Unknown ${n} sessionId "${e}"`};let a=p(r,`force`)??!1,o=f(r,`timeoutMs`)??1e3;if(!Number.isFinite(o)||o<=0)return{ok:!1,error:`timeoutMs must be a positive number`};let s=i.buffer.length;return i.closed||i.socket.destroyed?(t.delete(e),{ok:!0,sessionId:e,kind:n,force:a,closed:!0,bufferedBytesDiscarded:s,state:W(i)}):new Promise(r=>{let c=!1,l=o=>{c||(c=!0,clearTimeout(f),i.socket.off(`close`,u),i.socket.off(`error`,d),t.delete(e),n===`tcp`?this.eventBus?.emit(`tcp:session_closed`,{sessionId:e,reason:i.error,timestamp:new Date().toISOString()}):this.eventBus?.emit(`tls:session_closed`,{sessionId:e,reason:i.error,timestamp:new Date().toISOString()}),r({ok:!0,sessionId:e,kind:n,force:a,closed:o,bufferedBytesDiscarded:s,state:W(i)}))},u=()=>l(!0),d=()=>l(i.socket.destroyed||i.closed),f=setTimeout(()=>{i.socket.destroy(),l(i.socket.destroyed||i.closed)},o);if(i.socket.once(`close`,u),i.socket.once(`error`,d),a){i.socket.destroy();return}i.socket.end()})}},fe=class extends de{async handleTlsKeylogEnable(e){return{enabled:!0,keyLogPath:await this.keyLogExtractor.enableKeyLog(),environmentVariable:`SSLKEYLOGFILE`}}async handleTlsKeylogDisable(e){let t=l(e,`path`)??null;return t?await this.keyLogExtractor.disableKeyLog():r(),{disabled:!0,previousPath:t??o()}}async handleTlsKeylogParse(e){let t=l(e,`path`)??null,n=this.keyLogExtractor.parseKeyLog(t??void 0),r=this.keyLogExtractor.summarizeKeyLog(t??void 0);return{path:t??this.keyLogExtractor.getKeyLogFilePath(),entries:n,summary:r}}async handleTlsDecryptPayload(e){let t=l(e,`encryptedHex`)??null,n=l(e,`keyHex`)??null,r=l(e,`nonceHex`)??null,i=l(e,`algorithm`)??`aes-256-gcm`,a=l(e,`authTagHex`)??null;if(!t||!n||!r)return{ok:!1,error:`encryptedHex, keyHex, and nonceHex are required`};let o=s(t,n,r,i,a??void 0);return{ok:!0,algorithm:i,decrypted:o,isFailed:o.startsWith(`DECRYPTION_FAILED:`)}}async handleTlsKeylogSummarize(e){let t=l(e,`content`)??null;return t?i(n(t)):(this.keyLogExtractor.parseKeyLog(),this.keyLogExtractor.summarizeKeyLog())}async handleTlsKeylogLookupSecret(e){let t=l(e,`clientRandom`)??null,n=l(e,`label`)??void 0;if(!t)return{ok:!1,error:`clientRandom is required`};let r=this.keyLogExtractor.lookupSecret(t);if(r)return{ok:!0,clientRandom:k(t),secret:r};let i=c(this.keyLogExtractor.parseKeyLog(),t,n);return{ok:i!==null,clientRandom:k(t),secret:i??null}}async handleTlsCertPinBypass(e){let t=l(e,`target`)??null;return t!==`android`&&t!==`ios`&&t!==`desktop`?{error:`target must be one of android, ios, or desktop`}:{bypassStrategy:{android:`hook-trust-manager`,ios:`replace-sec-trust-evaluation`,desktop:`patch-custom-verifier`}[t],affectedDomains:[`*`],instructions:{android:[`Inject a Frida script that overrides X509TrustManager checks.`,`Re-run the target flow after SSLKEYLOGFILE capture is enabled.`],ios:[`Hook SecTrustEvaluateWithError and return success for the target session.`,`Collect TLS keys after the app resumes the failing request.`],desktop:[`Patch the custom verifier callback or disable pin comparison in the client.`,`Capture a fresh handshake after the patched build starts.`]}[t]}}async handleParseHandshake(t){let n=l(t,`rawHex`)??null,r=t.decrypt===!0;if(!n)return e({success:!1,error:`rawHex is required`});let i=k(n);if(!/^(?:[0-9a-f]{2})+$/i.test(i))return e({success:!1,error:`Invalid hex payload`});let a=Buffer.from(i,`hex`);if(a.length<5)return e({success:!1,error:`TLS record is too short`});let o=a[0],s=a[1],c=a[2],u=a.readUInt16BE(3),d=a.subarray(5),f=o===22&&d.length>0&&d[0]===1?ue(d):void 0,p=r?(()=>{let e=this.keyLogExtractor.decryptPayload(i,this.keyLogExtractor.parseKeyLog());return e?e.subarray(0,16).toString(`hex`).toUpperCase():null})():void 0;return e({success:!0,record:{contentType:o,contentTypeName:Q(o),version:Z(s,c),declaredLength:u,actualLength:d.length},handshake:{version:Z(s,c),contentType:Q(o),...f?{type:`client_hello`,serverName:f.serverName,cipherSuites:f.cipherSuites,extensions:f.extensions}:{cipherSuite:[],extensions:[]}},sni:f?.serverName?{serverName:f.serverName}:void 0,...p===void 0?{}:{decryptedPreviewHex:p}})}async handleKeyLogEnable(n){let r=l(n,`filePath`)??`/tmp/sslkeylog.log`;return t(r),this.eventBus?.emit(`tls:keylog_started`,{filePath:r,timestamp:new Date().toISOString()}),e({success:!0,filePath:r,currentFilePath:o()})}async handleCipherSuites(t){let n=l(t,`filter`)??null,r=[`TLS_AES_128_GCM_SHA256`,`TLS_AES_256_GCM_SHA384`,`TLS_CHACHA20_POLY1305_SHA256`,`TLS_AES_128_CCM_SHA256`,`TLS_AES_128_CCM_8_SHA256`,`TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256`,`TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384`,`TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256`,`TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384`,`TLS_RSA_WITH_AES_128_GCM_SHA256`,`TLS_RSA_WITH_AES_256_GCM_SHA384`],i=n?r.filter(e=>e.includes(n)):r;return e({success:!0,filter:n,total:i.length,suites:i})}async handleParseCertificate(t){let n=l(t,`rawHex`)??null;if(!n)return e({success:!1,error:`rawHex is required`});let r=V(n);return e({success:!0,certificateCount:r.length,fingerprints:r.map(e=>({sha256:e.sha256,length:e.length}))})}};const $=[`TLSv1`,`TLSv1.1`,`TLSv1.2`,`TLSv1.3`];var pe=class extends fe{async handleTlsProbeEndpoint(e){let t=l(e,`host`)?.trim()??null;if(!t)return{ok:!1,error:`host is required`};let n=f(e,`port`)??443;if(!Number.isInteger(n)||n<1||n>65535)return{ok:!1,error:`port must be an integer between 1 and 65535`};let r=f(e,`timeoutMs`)??5e3;if(!Number.isFinite(r)||r<=0)return{ok:!1,error:`timeoutMs must be a positive number`};let i=p(e,`allowInvalidCertificates`)??!1,a=p(e,`skipHostnameCheck`)??!1,o=l(e,`servername`)?.trim()??null,s=[...new Set(d(e,`alpnProtocols`).map(e=>e.trim()))].filter(e=>e.length>0),c,m;try{c=u(e,`minVersion`,D),m=u(e,`maxVersion`,D)}catch(e){return{ok:!1,error:O(e)}}if(c&&m&&$.indexOf(c)>$.indexOf(m))return{ok:!1,error:`minVersion must not be greater than maxVersion`};let h=j(t);if(h)return h;let g=await F(e);if(!g.ok)return{ok:!1,error:g.error};let _=o??t,v=o??(w(t)===0?t:void 0),y=Date.now();return new Promise(e=>{let o=!1,l=E(P({host:t,port:n,servername:v,...c?{minVersion:c}:{},...m?{maxVersion:m}:{},...s.length>0?{ALPNProtocols:s}:{},...g.ca?{ca:g.ca}:{}},i)),u=t=>{o||(o=!0,clearTimeout(d),l.removeAllListeners(),l.destroy(),e(t))},d=setTimeout(()=>{this.eventBus?.emit(`tls:probe_completed`,{host:t,port:n,success:!1,timestamp:new Date().toISOString()}),u({ok:!1,error:`TLS probe timed out`,target:{host:t,port:n,requestedServername:v??null,validationTarget:_},policy:{allowInvalidCertificates:i,skipHostnameCheck:a,timeoutMs:r,minVersion:c??null,maxVersion:m??null,alpnProtocols:s,customCa:{source:g.source,path:g.path,bytes:g.bytes}}})},r);l.once(`error`,e=>{this.eventBus?.emit(`tls:probe_completed`,{host:t,port:n,success:!1,timestamp:new Date().toISOString()}),u({ok:!1,error:e.message,errorCode:e.code??null,target:{host:t,port:n,requestedServername:v??null,validationTarget:_},policy:{allowInvalidCertificates:i,skipHostnameCheck:a,timeoutMs:r,minVersion:c??null,maxVersion:m??null,alpnProtocols:s,customCa:{source:g.source,path:g.path,bytes:g.bytes}}})}),l.once(`secureConnect`,()=>{let e=Date.now()-y,o=l.getPeerCertificate(!0),d=L(o),f=d?z(o):[],p=f[0]??null,h=a||!d?void 0:T(_,o),b={checked:!a,target:a?null:_,matched:a?null:h===void 0,error:!a&&!d?`Peer certificate was not presented by the server`:h?.message??null},x=[l.authorized?`Certificate chain validated against the active trust store.`:`Certificate chain validation failed: ${l.authorizationError??`unknown_authority`}`,a?`Hostname validation was skipped by request.`:b.matched?`Hostname validation passed.`:`Hostname validation failed: ${b.error??`unknown_error`}`,!l.authorized&&i?`Policy allowed the probe to continue despite certificate trust failure.`:null].filter(e=>!!e),S=l.getCipher();this.eventBus?.emit(`tls:probe_completed`,{host:t,port:n,success:!0,timestamp:new Date().toISOString()}),u({ok:!0,target:{host:t,port:n,requestedServername:v??null,validationTarget:_},policy:{allowInvalidCertificates:i,skipHostnameCheck:a,timeoutMs:r,minVersion:c??null,maxVersion:m??null,alpnProtocols:s,customCa:{source:g.source,path:g.path,bytes:g.bytes}},transport:{protocol:l.getProtocol()??null,alpnProtocol:N(l.alpnProtocol),cipher:{name:S.name,standardName:S.standardName,version:S.version},localAddress:l.localAddress??null,localPort:l.localPort??null,remoteAddress:l.remoteAddress??null,remotePort:l.remotePort??null,servernameSent:M(l.servername),sessionReused:l.isSessionReused()},authorization:{socketAuthorized:l.authorized,authorizationError:typeof l.authorizationError==`string`?l.authorizationError:l.authorizationError?.message??null,hostnameValidation:b,policyAllowed:(l.authorized||i)&&(a||b.matched===!0),reasons:x},certificates:{leaf:p,chain:f},timing:{handshakeMs:e}})})})}};const me=[`TLSv1`,`TLSv1.1`,`TLSv1.2`,`TLSv1.3`];var he=class extends pe{async handleTcpOpen(e){let t=l(e,`host`)??`127.0.0.1`,n=f(e,`port`);if(n===void 0||!Number.isInteger(n)||n<1||n>65535)return{ok:!1,error:`port must be an integer between 1 and 65535`};let r=f(e,`timeoutMs`)??5e3;if(!Number.isFinite(r)||r<=0)return{ok:!1,error:`timeoutMs must be a positive number`};let i=p(e,`noDelay`)??!0;return j(t)||new Promise(e=>{let a=!1,o=new S,s=t=>{a||(a=!0,clearTimeout(c),o.off(`connect`,u),o.off(`error`,l),e(t))},c=setTimeout(()=>{o.destroy(),s({ok:!1,error:`TCP connect timed out`,target:{host:t,port:n}})},r),l=e=>{s({ok:!1,error:e.message,target:{host:t,port:n}})},u=()=>{o.setNoDelay(i);let e=H(`tcp`),r={id:e,kind:`tcp`,socket:o,host:t,port:n,createdAt:Date.now(),buffer:Buffer.alloc(0),ended:!1,closed:!1,error:null,waiters:new Set,activeRead:!1};K(r),this.tcpSessions.set(e,r),this.eventBus?.emit(`tcp:session_opened`,{sessionId:e,host:t,port:n,timestamp:new Date().toISOString()}),s({ok:!0,sessionId:e,kind:`tcp`,target:{host:t,port:n},createdAt:new Date(r.createdAt).toISOString(),transport:U(o),state:W(r)})};o.once(`connect`,u),o.once(`error`,l),o.connect(n,t)})}async handleTcpWrite(e){let t=l(e,`sessionId`)?.trim()??null;if(!t)return{ok:!1,error:`sessionId is required`};let n=this.getTcpSession(t);return n?this.writeBufferedSession(n,e):{ok:!1,error:`Unknown tcp sessionId "${t}"`}}async handleTcpReadUntil(e){let t=l(e,`sessionId`)?.trim()??null;if(!t)return{ok:!1,error:`sessionId is required`};let n=this.getTcpSession(t);return n?this.readBufferedSessionUntil(n,e):{ok:!1,error:`Unknown tcp sessionId "${t}"`}}async handleTcpClose(e){let t=l(e,`sessionId`)?.trim()??null;return t?this.closeBufferedSession(t,this.tcpSessions,`tcp`,e):{ok:!1,error:`sessionId is required`}}async handleTlsOpen(e){let t=l(e,`host`)?.trim()??null;if(!t)return{ok:!1,error:`host is required`};let n=f(e,`port`)??443;if(!Number.isInteger(n)||n<1||n>65535)return{ok:!1,error:`port must be an integer between 1 and 65535`};let r=f(e,`timeoutMs`)??5e3;if(!Number.isFinite(r)||r<=0)return{ok:!1,error:`timeoutMs must be a positive number`};let i=p(e,`allowInvalidCertificates`)??!1,a=p(e,`skipHostnameCheck`)??!1,o=l(e,`servername`)?.trim()??null,s=[...new Set(d(e,`alpnProtocols`).map(e=>e.trim()))].filter(e=>e.length>0),c,m;try{c=u(e,`minVersion`,D),m=u(e,`maxVersion`,D)}catch(e){return{ok:!1,error:O(e)}}if(c&&m&&me.indexOf(c)>me.indexOf(m))return{ok:!1,error:`minVersion must not be greater than maxVersion`};let h=j(t);if(h)return h;let g=await F(e);if(!g.ok)return{ok:!1,error:g.error};let _={host:t,port:n,requestedServername:o??(w(t)===0?t:void 0)??null,validationTarget:o??t},v={allowInvalidCertificates:i,skipHostnameCheck:a,timeoutMs:r,minVersion:c??null,maxVersion:m??null,alpnProtocols:s,customCa:{source:g.source,path:g.path,bytes:g.bytes}},y=Date.now();return new Promise(e=>{let o=!1,l=E(P({host:t,port:n,servername:_.requestedServername??void 0,...c?{minVersion:c}:{},...m?{maxVersion:m}:{},...s.length>0?{ALPNProtocols:s}:{},...g.ca?{ca:g.ca}:{}},i)),u=t=>{o||(o=!0,clearTimeout(d),l.off(`error`,f),l.off(`secureConnect`,p),e(t))},d=setTimeout(()=>{l.destroy(),this.eventBus?.emit(`tls:probe_completed`,{host:t,port:n,success:!1,timestamp:new Date().toISOString()}),u({ok:!1,error:`TLS open timed out`,target:_,policy:v})},r),f=e=>{this.eventBus?.emit(`tls:probe_completed`,{host:t,port:n,success:!1,timestamp:new Date().toISOString()}),u({ok:!1,error:e.message,errorCode:e.code??null,target:_,policy:v})},p=()=>{let e=Date.now()-y,r=l.getPeerCertificate(!0),o=L(r),s=o?z(r):[],c=s[0]??null,d=a||!o?void 0:T(_.validationTarget,r),f={checked:!a,target:a?null:_.validationTarget,matched:a?null:d===void 0,error:!a&&!o?`Peer certificate was not presented by the server`:d?.message??null},p=[l.authorized?`Certificate chain validated against the active trust store.`:`Certificate chain validation failed: ${l.authorizationError??`unknown_authority`}`,a?`Hostname validation was skipped by request.`:f.matched?`Hostname validation passed.`:`Hostname validation failed: ${f.error??`unknown_error`}`,!l.authorized&&i?`Policy allowed the session to continue despite certificate trust failure.`:null].filter(e=>!!e),m=l.getCipher(),h={target:_,policy:v,transport:{protocol:l.getProtocol()??null,alpnProtocol:N(l.alpnProtocol),cipher:{name:m.name,standardName:m.standardName,version:m.version},localAddress:l.localAddress??null,localPort:l.localPort??null,remoteAddress:l.remoteAddress??null,remotePort:l.remotePort??null,servernameSent:M(l.servername),sessionReused:l.isSessionReused()},authorization:{socketAuthorized:l.authorized,authorizationError:typeof l.authorizationError==`string`?l.authorizationError:l.authorizationError?.message??null,hostnameValidation:f,policyAllowed:(l.authorized||i)&&(a||f.matched===!0),reasons:p},certificates:{leaf:c,chain:s}};if(!h.authorization.policyAllowed){l.destroy(),this.eventBus?.emit(`tls:probe_completed`,{host:t,port:n,success:!1,timestamp:new Date().toISOString()}),u({ok:!1,error:`TLS session authorization failed`,...h,timing:{handshakeMs:e}});return}let g=H(`tls`),b={id:g,kind:`tls`,socket:l,host:t,port:n,createdAt:Date.now(),buffer:Buffer.alloc(0),ended:!1,closed:!1,error:null,waiters:new Set,activeRead:!1,metadata:h};K(b),this.tlsSessions.set(g,b),this.eventBus?.emit(`tls:session_opened`,{sessionId:g,host:t,port:n,timestamp:new Date().toISOString()}),this.eventBus?.emit(`tls:probe_completed`,{host:t,port:n,success:!0,timestamp:new Date().toISOString()}),u({ok:!0,sessionId:g,kind:`tls`,...h,timing:{handshakeMs:e},state:W(b)})};l.once(`error`,f),l.once(`secureConnect`,p)})}async handleTlsWrite(e){let t=l(e,`sessionId`)?.trim()??null;if(!t)return{ok:!1,error:`sessionId is required`};let n=this.getTlsSession(t);return n?this.writeBufferedSession(n,e):{ok:!1,error:`Unknown tls sessionId "${t}"`}}async handleTlsReadUntil(e){let t=l(e,`sessionId`)?.trim()??null;if(!t)return{ok:!1,error:`sessionId is required`};let n=this.getTlsSession(t);return n?this.readBufferedSessionUntil(n,e):{ok:!1,error:`Unknown tls sessionId "${t}"`}}async handleTlsClose(e){let t=l(e,`sessionId`)?.trim()??null;return t?this.closeBufferedSession(t,this.tlsSessions,`tls`,e):{ok:!1,error:`sessionId is required`}}},ge=class extends he{emitWebSocketEvent(e,t){this.eventBus?.emit(e,t)}attachWebSocketSession(e){let t=()=>{for(;e.parserBuffer.length>0;){let t;try{t=ie(e.parserBuffer)}catch(t){e.error=O(t),e.socket.destroy();break}if(!t)break;e.parserBuffer=e.parserBuffer.subarray(t.bytesConsumed);let n=t.frame;if(e.frames.push(n),n.type===`ping`&&!e.closeSent&&!e.socket.destroyed){let t=Y(`pong`,n.data);e.socket.write(t),this.emitWebSocketEvent(`websocket:session_written`,{sessionId:e.id,frameType:`pong`,byteLength:n.data.length,automatic:!0,timestamp:new Date().toISOString()})}n.type===`close`&&(e.closeReceived=!0,!e.closeSent&&!e.socket.destroyed&&(e.closeSent=!0,e.socket.write(Y(`close`,n.data,n.closeCode,n.closeReason)),this.emitWebSocketEvent(`websocket:session_written`,{sessionId:e.id,frameType:`close`,byteLength:n.data.length,automatic:!0,timestamp:new Date().toISOString()})))}X(e)};e.socket.on(`data`,n=>{e.parserBuffer=Buffer.concat([e.parserBuffer,n]),t()}),e.socket.on(`end`,()=>{e.ended=!0,X(e)}),e.socket.on(`close`,()=>{e.closed=!0,X(e)}),e.socket.on(`error`,t=>{e.error=t.message,X(e)}),t()}async readWebSocketFrame(e,t){let n=f(t,`timeoutMs`)??5e3;if(!Number.isFinite(n)||n<=0)return{ok:!1,error:`timeoutMs must be a positive number`};if(e.activeRead)return{ok:!1,error:`Session "${e.id}" already has a pending read`,sessionId:e.id,kind:e.kind,state:q(e)};e.activeRead=!0;let r=Date.now();try{for(;;){let t=e.frames.shift();if(t)return this.emitWebSocketEvent(`websocket:frame_read`,{sessionId:e.id,frameType:t.type,byteLength:t.data.length,timestamp:new Date().toISOString()}),{ok:!0,sessionId:e.id,kind:e.kind,scheme:e.scheme,frameType:t.type,fin:t.fin,opcode:t.opcode,masked:t.masked,byteLength:t.data.length,dataHex:t.data.toString(`hex`).toUpperCase(),dataText:t.type===`binary`?null:t.data.toString(`utf8`),closeCode:t.closeCode,closeReason:t.closeReason,elapsedMs:Date.now()-r,state:q(e)};if(e.error)return{ok:!1,error:e.error,sessionId:e.id,kind:e.kind,state:q(e)};if(e.closed||e.ended)return{ok:!1,error:`socket closed before a WebSocket frame was available`,sessionId:e.id,kind:e.kind,state:q(e)};let i=n-(Date.now()-r);if(i<=0||!await ae(e,i))return{ok:!1,error:`read timed out`,sessionId:e.id,kind:e.kind,state:q(e)}}}finally{e.activeRead=!1}}async sendWebSocketFrame(e,t){if(e.closed||e.socket.destroyed)return{ok:!1,error:`Session "${e.id}" is already closed`,sessionId:e.id,kind:e.kind,state:q(e)};let n=u(t,`frameType`,new Set([`text`,`binary`,`ping`,`pong`,`close`]));if(!n)return{ok:!1,error:`frameType is required`};let r=l(t,`dataHex`),i=l(t,`dataText`);if(r&&i)return{ok:!1,error:`dataHex and dataText are mutually exclusive`};let a=f(t,`timeoutMs`)??5e3;if(!Number.isFinite(a)||a<=0)return{ok:!1,error:`timeoutMs must be a positive number`};let o=Buffer.alloc(0);if(r){let e=k(r);if(!A(e))return{ok:!1,error:`dataHex must be valid even-length hexadecimal data`};o=Buffer.from(e,`hex`)}else i!==void 0&&(o=Buffer.from(i,`utf8`));let s=null,c=null;if(n===`close`){let n=f(t,`closeCode`);if(n!==void 0){if(!Number.isInteger(n)||n<1e3||n>4999)return{ok:!1,error:`closeCode must be an integer between 1000 and 4999`};s=n}if(c=l(t,`closeReason`)??null,r||i)return{ok:!1,error:`close frames use closeCode/closeReason instead of dataHex/dataText`};e.closeSent=!0}if(n===`text`&&r)return{ok:!1,error:`text frames require UTF-8 dataText instead of dataHex`};let d=Y(n,o,s,c);return new Promise(t=>{let r=!1,i=n=>{r||(r=!0,clearTimeout(l),e.socket.off(`error`,u),t(n))},l=setTimeout(()=>{i({ok:!1,error:`write timed out`,sessionId:e.id,kind:e.kind,state:q(e)})},a),u=t=>{i({ok:!1,error:t.message,sessionId:e.id,kind:e.kind,state:q(e)})};e.socket.once(`error`,u),e.socket.write(d,()=>{this.emitWebSocketEvent(`websocket:session_written`,{sessionId:e.id,frameType:n,byteLength:n===`close`?c?Buffer.byteLength(c)+2:s?2:0:o.length,automatic:!1,timestamp:new Date().toISOString()}),i({ok:!0,sessionId:e.id,kind:e.kind,scheme:e.scheme,frameType:n,bytesWritten:d.length,payloadBytes:n===`close`?c?Buffer.byteLength(c)+2:s?2:0:o.length,state:q(e)})})})}async closeWebSocketSession(e,t){let n=this.websocketSessions.get(e);if(!n)return{ok:!1,error:`Unknown websocket sessionId "${e}"`};let r=p(t,`force`)??!1,i=f(t,`timeoutMs`)??1e3;if(!Number.isFinite(i)||i<=0)return{ok:!1,error:`timeoutMs must be a positive number`};let a=n.frames.length;if(n.closed||n.socket.destroyed)return this.websocketSessions.delete(e),{ok:!0,sessionId:e,kind:n.kind,force:r,closed:!0,queuedFramesDiscarded:a,state:q(n)};let o=null,s=f(t,`closeCode`);if(s!==void 0){if(!Number.isInteger(s)||s<1e3||s>4999)return{ok:!1,error:`closeCode must be an integer between 1000 and 4999`};o=s}let c=l(t,`closeReason`)??null;return new Promise(t=>{let s=!1,l=i=>{s||(s=!0,clearTimeout(f),n.socket.off(`close`,u),n.socket.off(`error`,d),this.websocketSessions.delete(e),this.emitWebSocketEvent(`websocket:session_closed`,{sessionId:e,reason:n.error,timestamp:new Date().toISOString()}),t({ok:!0,sessionId:e,kind:n.kind,force:r,closed:i,queuedFramesDiscarded:a,state:q(n)}))},u=()=>l(!0),d=()=>l(n.socket.destroyed||n.closed),f=setTimeout(()=>{n.socket.destroy(),l(n.socket.destroyed||n.closed)},i);if(n.socket.once(`close`,u),n.socket.once(`error`,d),r){n.socket.destroy();return}n.closeSent||(n.closeSent=!0,n.socket.write(Y(`close`,Buffer.alloc(0),o,c)),this.emitWebSocketEvent(`websocket:session_written`,{sessionId:e,frameType:`close`,byteLength:c?Buffer.byteLength(c)+2:o?2:0,automatic:!1,timestamp:new Date().toISOString()}))})}async handleWebSocketSendFrame(e){let t=l(e,`sessionId`)?.trim()??null;if(!t)return{ok:!1,error:`sessionId is required`};let n=this.getWebSocketSession(t);return n?this.sendWebSocketFrame(n,e):{ok:!1,error:`Unknown websocket sessionId "${t}"`}}async handleWebSocketReadFrame(e){let t=l(e,`sessionId`)?.trim()??null;if(!t)return{ok:!1,error:`sessionId is required`};let n=this.getWebSocketSession(t);return n?this.readWebSocketFrame(n,e):{ok:!1,error:`Unknown websocket sessionId "${t}"`}}async handleWebSocketClose(e){let t=l(e,`sessionId`)?.trim()??null;return t?this.closeWebSocketSession(t,e):{ok:!1,error:`sessionId is required`}}};const _e=[`TLSv1`,`TLSv1.1`,`TLSv1.2`,`TLSv1.3`];var ve=class extends ge{async handleWebSocketOpen(e){let t=l(e,`url`)?.trim()??null,n=l(e,`host`)?.trim()??null,r=l(e,`path`)?.trim()??null,i=f(e,`port`),a=l(e,`scheme`)?.trim()??null;if(t&&(n||r||i!==void 0||a))return{ok:!1,error:`url is mutually exclusive with explicit scheme/host/port/path inputs`};let o=`ws`,s=n,c=i??void 0,m=J(r),h;if(t){let e;try{e=new URL(t)}catch(e){return{ok:!1,error:`Invalid url: ${O(e)}`}}if(e.protocol!==`ws:`&&e.protocol!==`wss:`)return{ok:!1,error:`url must use ws:// or wss:// protocol`};o=e.protocol===`wss:`?`wss`:`ws`,s=e.hostname,c=e.port.length>0?Number(e.port):o===`wss`?443:80,m=J(`${e.pathname}${e.search}`),h=`${o}://${e.host}${m}`}else{if(!s)return{ok:!1,error:`host or url is required`};if(a){if(a!==`ws`&&a!==`wss`)return{ok:!1,error:`scheme must be ws or wss`};o=a}c??=o===`wss`?443:80;let e=c===(o===`wss`?443:80)?s:`${s}:${String(c)}`;h=`${o}://${e}${m}`}if(!s||!c||!Number.isInteger(c)||c<1||c>65535)return{ok:!1,error:`port must be an integer between 1 and 65535`};let g=f(e,`timeoutMs`)??5e3;if(!Number.isFinite(g)||g<=0)return{ok:!1,error:`timeoutMs must be a positive number`};let _=[...new Set(d(e,`subprotocols`).map(e=>e.trim()))].filter(e=>e.length>0),y=j(s);if(y)return y;let b=p(e,`allowInvalidCertificates`)??!1,x=p(e,`skipHostnameCheck`)??!1,C=l(e,`servername`)?.trim()??null,k=[...new Set(d(e,`alpnProtocols`).map(e=>e.trim()))].filter(e=>e.length>0),A,I;try{A=u(e,`minVersion`,D),I=u(e,`maxVersion`,D)}catch(e){return{ok:!1,error:O(e)}}if(A&&I&&_e.indexOf(A)>_e.indexOf(I))return{ok:!1,error:`minVersion must not be greater than maxVersion`};let R=o===`wss`?await F(e):{ok:!0,ca:void 0,source:null,path:null,bytes:null};if(!R.ok)return{ok:!1,error:R.error};let B={scheme:o,url:h,host:s,port:c,path:m,requestedServername:o===`wss`?C??(w(s)===0?s:void 0)??null:null,validationTarget:o===`wss`?C??s:null},V=v(16).toString(`base64`),W=re(V),G=Date.now();return new Promise(e=>{let t=!1,n=Buffer.alloc(0),r=null,i=null,a=null,l=o===`wss`?E(P({host:s,port:c,servername:B.requestedServername??void 0,...A?{minVersion:A}:{},...I?{maxVersion:I}:{},...k.length>0?{ALPNProtocols:k}:{},...R.ca?{ca:R.ca}:{}},b)):new S,u=n=>{t||(t=!0,clearTimeout(f),l.off(`error`,p),l.off(`connect`,v),l.off(`secureConnect`,y),l.off(`data`,C),e(n))},d=()=>{let e=c===(o===`wss`?443:80)?s:`${s}:${String(c)}`,t=[`GET ${m} HTTP/1.1`,`Host: ${e}`,`Upgrade: websocket`,`Connection: Upgrade`,`Sec-WebSocket-Key: ${V}`,`Sec-WebSocket-Version: 13`];return _.length>0&&t.push(`Sec-WebSocket-Protocol: ${_.join(`, `)}`),t.push(``,``),Buffer.from(t.join(`\r
|
|
2
|
-
`),`utf8`)},f=setTimeout(()=>{l.destroy(),u({ok:!1,error:`WebSocket open timed out`,target:B})},g),p=e=>{u({ok:!1,error:e.message,errorCode:e.code??null,target:B})},h=()=>{l.write(d())},v=()=>{l instanceof S&&l.setNoDelay(!0),r={...U(l),protocol:null,alpnProtocol:null,servernameSent:null,sessionReused:null},h()},y=()=>{let e=l,t=e.getPeerCertificate(!0),n=L(t),o=n?z(t):[],s=o[0]??null,c=x||!n||!B.validationTarget?void 0:T(B.validationTarget,t),d={checked:!x,target:x?null:B.validationTarget,matched:x?null:c===void 0,error:!x&&!n?`Peer certificate was not presented by the server`:c?.message??null},f=[e.authorized?`Certificate chain validated against the active trust store.`:`Certificate chain validation failed: ${e.authorizationError??`unknown_authority`}`,x?`Hostname validation was skipped by request.`:d.matched?`Hostname validation passed.`:`Hostname validation failed: ${d.error??`unknown_error`}`,!e.authorized&&b?`Policy allowed the session to continue despite certificate trust failure.`:null].filter(e=>!!e);if(i={socketAuthorized:e.authorized,authorizationError:typeof e.authorizationError==`string`?e.authorizationError:e.authorizationError?.message??null,hostnameValidation:d,policyAllowed:(e.authorized||b)&&(x||d.matched===!0),reasons:f},a={leaf:s,chain:o},r={...U(e),protocol:e.getProtocol()??null,alpnProtocol:N(e.alpnProtocol),servernameSent:M(e.servername),sessionReused:e.isSessionReused()},!i.policyAllowed){e.destroy(),u({ok:!1,error:`WebSocket TLS authorization failed`,target:B,authorization:i,certificates:a});return}h()},C=e=>{n=Buffer.concat([n,e]);let t=n.indexOf(`\r
|
|
3
|
-
\r
|
|
4
|
-
`);if(t<0)return;let d=n.subarray(0,t).toString(`utf8`).split(`\r
|
|
5
|
-
`),f=d.shift()??``;if(!/^HTTP\/1\.1 101\b/.test(f)){l.destroy(),u({ok:!1,error:`Unexpected WebSocket upgrade response: ${f}`,target:B});return}let p=new Map;for(let e of d){let t=e.indexOf(`:`);if(t<=0)continue;let n=e.slice(0,t).trim().toLowerCase(),r=e.slice(t+1).trim();p.set(n,r)}let h=p.get(`upgrade`)?.toLowerCase()??``,g=p.get(`connection`)?.toLowerCase()??``,v=p.get(`sec-websocket-accept`)??null;if(h!==`websocket`){l.destroy(),u({ok:!1,error:`Upgrade header did not confirm websocket`,target:B});return}if(!g.split(`,`).map(e=>e.trim()).includes(`upgrade`)){l.destroy(),u({ok:!1,error:`Connection header did not confirm upgrade`,target:B});return}if(v!==W){l.destroy(),u({ok:!1,error:`sec-websocket-accept did not match the client key`,target:B});return}let y=p.get(`sec-websocket-protocol`)??null;if(y&&!_.includes(y)){l.destroy(),u({ok:!1,error:`Server selected unexpected subprotocol "${y}"`,target:B});return}let b=H(`websocket`),x={id:b,kind:`websocket`,scheme:o,socket:l,host:s,port:c,path:m,createdAt:Date.now(),parserBuffer:n.subarray(t+4),frames:[],ended:!1,closed:!1,error:null,waiters:new Set,activeRead:!1,closeSent:!1,closeReceived:!1,metadata:{target:B,handshake:{requestKey:V,acceptKey:W,responseAcceptKey:v,subprotocol:y},transport:r??{...U(l),protocol:null,alpnProtocol:null,servernameSent:null,sessionReused:null},authorization:i,certificates:a}};this.attachWebSocketSession(x),this.websocketSessions.set(b,x),this.emitWebSocketEvent(`websocket:session_opened`,{sessionId:b,scheme:o,host:s,port:c,path:m,timestamp:new Date().toISOString()}),u({ok:!0,sessionId:b,kind:x.kind,scheme:o,target:B,handshake:x.metadata.handshake,transport:x.metadata.transport,authorization:x.metadata.authorization,certificates:x.metadata.certificates,timing:{handshakeMs:Date.now()-G},state:q(x)})};l.once(`error`,p),l.on(`data`,C),o===`wss`?l.once(`secureConnect`,y):(l.once(`connect`,v),l.connect(c,s))})}async handleBypassCertPinning(t){if(this.extensionInvoke)try{let n=await this.extensionInvoke(t);if(n)return e({success:!0,strategy:`frida-injection`,result:n})}catch{}return e({success:!0,strategy:`manual-bypass`,instructions:{android:[`Use Frida to hook X509TrustManager.checkServerTrusted and return without throwing.`,`Alternatively, use OkHttp CertificatePinner.Builder().add() with the target cert.`],ios:[`Hook SecTrustEvaluateWithError to always return true.`,`Or use SSLSetSessionOption to disable certificate validation.`],desktop:[`Set NODE_TLS_REJECT_UNAUTHORIZED=0 for Node.js targets.`,`Or patch the certificate comparison function in the HTTP client.`]},args:t})}},ye=class extends ve{async handleRawTcpSend(e){let t=l(e,`host`)??`127.0.0.1`,n=f(e,`port`);if(n===void 0||n<1||n>65535)return{ok:!1,error:`port must be a number between 1 and 65535`};let r=j(t);if(r)return r;let i=l(e,`dataHex`),a=l(e,`dataText`);if(!i&&!a)return{ok:!1,error:`dataHex or dataText is required`};let o=i?Buffer.from(k(i),`hex`):Buffer.from(a??``,`utf8`),s=f(e,`timeout`)??5e3;return new Promise(e=>{let r=new S,i=setTimeout(()=>{r.destroy(),e({ok:!1,error:`Connection timed out`})},s);r.on(`connect`,()=>{r.write(o,()=>{r.end()})}),r.on(`data`,a=>{clearTimeout(i),e({ok:!0,host:t,port:n,sentBytes:o.length,responseHex:a.toString(`hex`).toUpperCase(),responseText:a.toString(`utf8`)}),r.destroy()}),r.on(`error`,t=>{clearTimeout(i),e({ok:!1,error:t.message})}),r.connect(n,t)})}async handleRawTcpListen(e){let t=f(e,`port`);if(t===void 0||t<1||t>65535)return{ok:!1,error:`port must be a number between 1 and 65535`};let n=f(e,`timeout`)??1e4;return new Promise(e=>{let r=C(),i=setTimeout(()=>{r.close(),e({ok:!1,error:`Listen timed out - no connection received`})},n);r.on(`connection`,n=>{clearTimeout(i);let a=[];n.on(`data`,e=>{a.push(e)}),n.on(`end`,()=>{let n=Buffer.concat(a);r.close(),e({ok:!0,port:t,receivedBytes:n.length,dataHex:n.toString(`hex`).toUpperCase(),dataText:n.toString(`utf8`)})}),n.on(`error`,t=>{clearTimeout(i),r.close(),e({ok:!1,error:t.message})})}),r.on(`error`,t=>{clearTimeout(i),e({ok:!1,error:t.message})}),r.listen(t,`127.0.0.1`)})}async handleRawUdpSend(e){let t=l(e,`host`)??`127.0.0.1`,n=f(e,`port`);if(n===void 0||n<1||n>65535)return{ok:!1,error:`port must be a number between 1 and 65535`};let r=j(t);if(r)return r;let i=l(e,`dataHex`),a=l(e,`dataText`);if(!i&&!a)return{ok:!1,error:`dataHex or dataText is required`};let o=i?Buffer.from(k(i),`hex`):Buffer.from(a??``,`utf8`),s=f(e,`timeout`)??5e3;return new Promise(e=>{let r=x(`udp4`),i=setTimeout(()=>{r.close(),e({ok:!1,error:`UDP response timed out`})},s);r.on(`message`,a=>{clearTimeout(i),r.close(),e({ok:!0,host:t,port:n,sentBytes:o.length,responseHex:a.toString(`hex`).toUpperCase(),responseText:a.toString(`utf8`)})}),r.on(`error`,t=>{clearTimeout(i),r.close(),e({ok:!1,error:t.message})}),r.send(o,0,o.length,n,t)})}async handleRawUdpListen(e){let t=f(e,`port`);if(t===void 0||t<1||t>65535)return{ok:!1,error:`port must be a number between 1 and 65535`};let n=f(e,`timeout`)??1e4;return new Promise(e=>{let r=x(`udp4`),i=setTimeout(()=>{r.close(),e({ok:!1,error:`UDP listen timed out`})},n);r.on(`message`,(n,a)=>{clearTimeout(i),r.close(),e({ok:!0,localPort:t,receivedBytes:n.length,from:a,dataHex:n.toString(`hex`).toUpperCase(),dataText:n.toString(`utf8`)})}),r.on(`error`,t=>{clearTimeout(i),r.close(),e({ok:!1,error:t.message})}),r.bind(t,`127.0.0.1`)})}},be=class extends ye{};export{be as BoringsslInspectorHandlers};
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import{An as e,Dn as t,En as n,On as r,kn as i}from"./constants-BYj8Xek8.mjs";import{n as a}from"./response-C7rKQst4.mjs";import{i as o,o as s,s as c}from"./parse-args-Bw413PlW.mjs";import{readFile as l,writeFile as u}from"node:fs/promises";import{isIP as d}from"node:net";const f={20:`ChangeCipherSpec`,21:`Alert`,22:`Handshake`,23:`ApplicationData`},p={"0300":`SSL 3.0`,"0301":`TLS 1.0`,"0302":`TLS 1.1`,"0303":`TLS 1.2`,"0304":`TLS 1.3`},ee={1301:`TLS_AES_128_GCM_SHA256`,1302:`TLS_AES_256_GCM_SHA384`,1303:`TLS_CHACHA20_POLY1305_SHA256`,c02b:`TLS_ECDHE_ECDSA_AES_128_GCM_SHA256`,c02f:`TLS_ECDHE_RSA_AES_128_GCM_SHA256`,c02c:`TLS_ECDHE_ECDSA_AES_256_GCM_SHA384`,c030:`TLS_ECDHE_RSA_AES_256_GCM_SHA384`,cca9:`TLS_ECDHE_ECDSA_CHACHA20_POLY1305`,cca8:`TLS_ECDHE_RSA_CHACHA20_POLY1305`,"009c":`TLS_RSA_AES_128_GCM_SHA256`,"009d":`TLS_RSA_AES_256_GCM_SHA384`,"002f":`TLS_RSA_AES_128_CBC_SHA`,"0035":`TLS_RSA_AES_256_CBC_SHA`,c013:`TLS_ECDHE_RSA_AES_128_CBC_SHA`,c014:`TLS_ECDHE_RSA_AES_256_CBC_SHA`,"00ff":`TLS_EMPTY_RENEGOTIATION_INFO_SCSV`,5600:`TLS_FALLBACK_SCSV`},m={0:`NOERROR`,1:`FORMERR`,2:`SERVFAIL`,3:`NXDOMAIN`,4:`NOTIMP`,5:`REFUSED`},h={0:`QUERY`,1:`IQUERY`,2:`STATUS`,3:`UNASSIGNED`,4:`NOTIFY`,5:`UPDATE`},g={474554:`GET`,"504f5354":`POST`,505554:`PUT`,"44454c45":`DELETE`,48454144:`HEAD`,50415443:`PATCH`,"4f505449":`OPTIONS`,"434f4e4e":`CONNECT`},_={"0000":`server_name`,"000a":`supported_groups`,"000b":`ec_point_formats`,"000d":`signature_algorithms`,"0010":`application_layer_protocol_negotiation`,"0015":`padding`,"0017":`extended_master_secret`,"001b":`compress_certificate`,"0023":`session_ticket`,"0029":`pre_shared_key`,"002b":`supported_versions`,"002d":`psk_key_exchange_modes`,"0033":`key_share`,"0039":`quic_transport_parameters`,4469:`next_protocol_negotiation`,fe0d:`encrypted_client_hello`,ff01:`renegotiation_info`},te={0:`continuation`,1:`text`,2:`binary`,8:`close`,9:`ping`,10:`pong`};function v(e,t){return Number.parseInt(e.substring(t*2,t*2+2),16)}function y(e,t){return Number.parseInt(e.substring(t*2,t*2+4),16)}function b(e,t,n){return e.substring(t*2,(t+n)*2)}function x(e){return e.length>=24&&/^0{24}$/i.test(e.slice(0,24))}function ne(e){if(e.length<44)return null;let t=v(e,0);if(t!==22)return null;let n=b(e,1,2),r=y(e,3);if(e.length/2<5+r||v(e,5)!==1)return null;let i={recordType:f[t]??`0x${t.toString(16)}`,recordVersion:p[n]??n,recordLength:r,handshakeType:`ClientHello`},a=9;if(a+2>e.length/2)return i;let o=b(e,a,2);if(i.clientVersion=p[o]??o,a+=34,a>=e.length/2)return i;let s=v(e,a);if(a+=1+s,a+2>e.length/2)return i;let c=y(e,a);a+=2;let l=[];for(let t=0;t<c/2&&a+2<=e.length/2;t++){let t=b(e,a,2).toLowerCase();l.push({hex:t,name:ee[t]??`Unknown(0x${t})`}),a+=2}if(i.cipherSuites=l,i.cipherSuiteCount=l.length,a>=e.length/2)return i;let u=v(e,a);if(a+=1+u,a+2>e.length/2)return i;let d=y(e,a);a+=2;let m=a+d,h=[];for(;a+4<=m&&a+4<=e.length/2;){let t=b(e,a,2).toLowerCase(),n=y(e,a+2);h.push({type:t,length:n,name:_[t]}),a+=4+n}return i.extensions=h,i.extensionCount=h.length,i}function re(e){if(e.length<24)return null;let t=y(e,0),n=v(e,2),r=v(e,3),i=n>>7&1,a=n>>3&15,o=n>>2&1,s=n>>1&1,c=n&1,l=r>>7&1,u=r>>4&7,d=r&15;return{transactionId:`0x${t.toString(16).padStart(4,`0`)}`,flags:{qr:i===1?`Response`:`Query`,opcode:h[a]??a,authoritativeAnswer:!!o,truncation:!!s,recursionDesired:!!c,recursionAvailable:!!l,reserved:u,responseCode:m[d]??d},questionCount:y(e,4),answerCount:y(e,6),authorityCount:y(e,8),additionalCount:y(e,10)}}function ie(e){if(e.length<24||x(e))return!1;let t=v(e,2),n=v(e,3),r=t>>7&1,i=t>>3&15,a=n&15,o=y(e,4),s=y(e,6);return!(i>2||o+s===0||r===0&&a!==0||r===1&&a>5)}function S(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function ae(e,t){if(!S(e))throw Error(`fields[${t}] must be an object`);let n=e.name,r=e.offset,i=e.length,a=e.type;if(typeof n!=`string`||n.trim().length===0)throw Error(`fields[${t}].name must be a non-empty string`);if(typeof r!=`number`||!Number.isInteger(r)||r<0)throw Error(`fields[${t}].offset must be a non-negative integer`);if(typeof i!=`number`||!Number.isInteger(i)||i<=0)throw Error(`fields[${t}].length must be a positive integer`);if(a!==`int`&&a!==`string`&&a!==`bytes`&&a!==`bool`&&a!==`float`)throw Error(`fields[${t}].type is invalid`);return{name:n,offset:r,length:i,type:a}}function oe(e,t){if(!S(e))throw Error(`fields[${t}] must be an object`);let n=e.name,r=e.offset,i=e.length,a=e.type,o=e.description;if(typeof n!=`string`||n.trim().length===0)throw Error(`fields[${t}].name must be a non-empty string`);if(typeof r!=`number`||!Number.isInteger(r)||r<0)throw Error(`fields[${t}].offset must be a non-negative integer`);if(typeof i!=`number`||!Number.isInteger(i)||i<=0)throw Error(`fields[${t}].length must be a positive integer`);if(a!==`uint8`&&a!==`uint16`&&a!==`uint32`&&a!==`int64`&&a!==`float`&&a!==`string`&&a!==`bytes`)throw Error(`fields[${t}].type is invalid`);return{name:n,offset:r,length:i,type:a,...typeof o==`string`?{description:o}:{}}}function se(e,t){let n=t.fields;if(!Array.isArray(n))throw Error(`spec.fields must be an array`);let r=typeof t.fieldDelimiter==`string`&&t.fieldDelimiter.length>0?t.fieldDelimiter:void 0,i=t.byteOrder,a=i===`le`||i===`be`?i:void 0;return{name:e,...r?{fieldDelimiter:r}:{},...a?{byteOrder:a}:{},fields:n.map((e,t)=>ae(e,t))}}function ce(e){if(!S(e))return;let t=e.type;if(t!==`aes`&&t!==`xor`&&t!==`rc4`&&t!==`custom`)return;let n=typeof e.key==`string`?e.key:void 0,r=typeof e.iv==`string`?e.iv:void 0,i=typeof e.notes==`string`?e.notes:void 0;return{type:t,...n?{key:n}:{},...r?{iv:r}:{},...i?{notes:i}:{}}}function le(e,t){if(!S(e))throw Error(`messages[${t}] must be an object`);let n=e.direction,r=e.timestamp,i=e.fields,a=e.raw;if(n!==`req`&&n!==`res`)throw Error(`messages[${t}].direction must be "req" or "res"`);if(typeof r!=`number`||!Number.isFinite(r))throw Error(`messages[${t}].timestamp must be a number`);if(!S(i))throw Error(`messages[${t}].fields must be an object`);if(typeof a!=`string`)throw Error(`messages[${t}].raw must be a string`);return{direction:n,timestamp:r,fields:i,raw:a}}const ue=[`utf8`,`ascii`],C=[`utf8`,`ascii`,`hex`,`base64`],de=[`u8`,`u16`,`u32`,`i8`,`i16`,`i32`,`string`,`bytes`],fe=[`set_byte`,`flip_bit`,`overwrite_bytes`,`append_bytes`,`truncate`,`increment_integer`];function w(e,t=`big`){return e===`little`?`little`:t}function T(e,t){if(typeof e!=`number`||!Number.isInteger(e)||e<0)throw Error(`${t} must be a non-negative integer`);return e}function E(e,t){if(typeof e!=`number`||!Number.isInteger(e)||e<=0)throw Error(`${t} must be a positive integer`);return e}function D(e,t){if(typeof e!=`number`||!Number.isInteger(e))throw Error(`${t} must be an integer`);return e}function O(e,t){let n=D(e,t);if(n<0||n>255)throw Error(`${t} must be between 0 and 255`);return n}function pe(e,t){return e===void 0?void 0:E(e,t)}function k(e,t,n,r){if(e===void 0)return n;if(typeof e!=`string`||!t.includes(e))throw Error(`${r} is invalid`);return e}function A(e,t){if(typeof e!=`string`)throw Error(`${t} must be a string`);return e}function j(e,t){let n=e.replace(/^0x/i,``).replace(/\s+/g,``);if(n.length===0)return n;if(n.length%2!=0||/[^0-9a-f]/i.test(n))throw Error(`${t} must be a valid even-length hex string`);return n.toLowerCase()}function M(e,t,n){switch(t){case`utf8`:case`ascii`:return Buffer.from(e,t);case`hex`:return Buffer.from(j(e,n),`hex`);case`base64`:return Buffer.from(e,`base64`)}}function me(e,t){let n=e*8;return t?{min:-(2**(n-1)),max:2**(n-1)-1}:{min:0,max:2**n-1}}function N(e){switch(e){case`u8`:return{width:1,signed:!1};case`u16`:return{width:2,signed:!1};case`u32`:return{width:4,signed:!1};case`i8`:return{width:1,signed:!0};case`i16`:return{width:2,signed:!0};case`i32`:return{width:4,signed:!0};default:return null}}function P(e,t,n,r,i){if(r)switch(n){case 1:e.writeInt8(t,0);return;case 2:i===`little`?e.writeInt16LE(t,0):e.writeInt16BE(t,0);return;case 4:i===`little`?e.writeInt32LE(t,0):e.writeInt32BE(t,0);return}switch(n){case 1:e.writeUInt8(t,0);return;case 2:i===`little`?e.writeUInt16LE(t,0):e.writeUInt16BE(t,0);return;case 4:i===`little`?e.writeUInt32LE(t,0):e.writeUInt32BE(t,0);return}}function he(e,t,n,r,i){if(r)switch(n){case 1:return e.readInt8(t);case 2:return i===`little`?e.readInt16LE(t):e.readInt16BE(t);case 4:return i===`little`?e.readInt32LE(t):e.readInt32BE(t)}switch(n){case 1:return e.readUInt8(t);case 2:return i===`little`?e.readUInt16LE(t):e.readUInt16BE(t);case 4:return i===`little`?e.readUInt32LE(t):e.readUInt32BE(t)}}function F(e,t,n){return t===void 0||e.length===t?e:e.length>t?e.subarray(0,t):Buffer.concat([e,Buffer.alloc(t-e.length,n)])}function ge(e,t){if(!S(e))throw Error(`fields[${t}] must be an object`);let n=e.name,r=e.type,i=e.value;if(typeof n!=`string`||n.trim().length===0)throw Error(`fields[${t}].name must be a non-empty string`);if(typeof r!=`string`||!de.includes(r))throw Error(`fields[${t}].type is invalid`);let a=r,o=N(a);if(o){let s=D(i,`fields[${t}].value`),c=me(o.width,o.signed);if(s<c.min||s>c.max)throw Error(`fields[${t}].value is out of range for ${r} (${c.min}..${c.max})`);if(e.length!==void 0||e.padByte!==void 0||e.encoding!==void 0)throw Error(`fields[${t}] does not support length, padByte, or encoding`);return{name:n,type:a,value:s}}let s=A(i,`fields[${t}].value`),c=pe(e.length,`fields[${t}].length`),l=e.padByte===void 0?0:O(e.padByte,`fields[${t}].padByte`);return r===`string`?{name:n,type:`string`,value:s,encoding:k(e.encoding,ue,`utf8`,`fields[${t}].encoding`),...c===void 0?{}:{length:c},padByte:l}:{name:n,type:`bytes`,value:s,encoding:k(e.encoding,C,`hex`,`fields[${t}].encoding`),...c===void 0?{}:{length:c},padByte:l}}function _e(e,t){switch(e.type){case`u8`:case`u16`:case`u32`:case`i8`:case`i16`:case`i32`:{let n=N(e.type);if(!n)throw Error(`Unsupported numeric field type: ${e.type}`);let r=Buffer.alloc(n.width);return P(r,e.value,n.width,n.signed,t),r}case`string`:return F(Buffer.from(e.value,e.encoding),e.length,e.padByte);case`bytes`:return F(M(e.value,e.encoding,`field ${e.name}`),e.length,e.padByte)}}function ve(e,t){let n=[],r=[],i=0;for(let a of e){let e=_e(a,t);n.push(e),r.push({name:a.name,offset:i,length:e.length,hex:e.toString(`hex`)}),i+=e.length}return{payload:Buffer.concat(n),segments:r}}function ye(e,t){if(!S(e))throw Error(`mutations[${t}] must be an object`);let n=e.strategy;if(typeof n!=`string`||!fe.includes(n))throw Error(`mutations[${t}].strategy is invalid`);switch(n){case`set_byte`:return{strategy:`set_byte`,offset:T(e.offset,`mutations[${t}].offset`),value:O(e.value,`mutations[${t}].value`)};case`flip_bit`:return{strategy:`flip_bit`,offset:T(e.offset,`mutations[${t}].offset`),bit:(()=>{let n=D(e.bit,`mutations[${t}].bit`);if(n<0||n>7)throw Error(`mutations[${t}].bit must be between 0 and 7`);return n})()};case`overwrite_bytes`:return{strategy:`overwrite_bytes`,offset:T(e.offset,`mutations[${t}].offset`),data:M(A(e.data,`mutations[${t}].data`),k(e.encoding,C,`hex`,`mutations[${t}].encoding`),`mutations[${t}].data`)};case`append_bytes`:return{strategy:`append_bytes`,data:M(A(e.data,`mutations[${t}].data`),k(e.encoding,C,`hex`,`mutations[${t}].encoding`),`mutations[${t}].data`)};case`truncate`:return{strategy:`truncate`,length:T(e.length,`mutations[${t}].length`)};case`increment_integer`:{let n=e.width;if(n!==1&&n!==2&&n!==4)throw Error(`mutations[${t}].width must be 1, 2, or 4`);return{strategy:`increment_integer`,offset:T(e.offset,`mutations[${t}].offset`),width:n,delta:D(e.delta,`mutations[${t}].delta`),endian:w(e.endian),signed:e.signed===!0}}}}function be(e,t,n){let r=Buffer.from(e);switch(t.strategy){case`set_byte`:if(t.offset>=r.length)throw Error(`mutations[${n}] offset is outside the payload`);return r[t.offset]=t.value,{payload:r,summary:{index:n,strategy:t.strategy,detail:`set payload[${t.offset}] to ${t.value}`}};case`flip_bit`:if(t.offset>=r.length)throw Error(`mutations[${n}] offset is outside the payload`);{let e=r[t.offset];r[t.offset]=e^1<<t.bit}return{payload:r,summary:{index:n,strategy:t.strategy,detail:`flipped bit ${t.bit} at offset ${t.offset}`}};case`overwrite_bytes`:if(t.offset+t.data.length>r.length)throw Error(`mutations[${n}] overwrite exceeds payload length`);return t.data.copy(r,t.offset),{payload:r,summary:{index:n,strategy:t.strategy,detail:`overwrote ${t.data.length} bytes at offset ${t.offset}`}};case`append_bytes`:return{payload:Buffer.concat([r,t.data]),summary:{index:n,strategy:t.strategy,detail:`appended ${t.data.length} bytes`}};case`truncate`:if(t.length>r.length)throw Error(`mutations[${n}] length exceeds payload size`);return{payload:r.subarray(0,t.length),summary:{index:n,strategy:t.strategy,detail:`truncated payload to ${t.length} bytes`}};case`increment_integer`:{if(t.offset+t.width>r.length)throw Error(`mutations[${n}] integer range exceeds payload length`);let e=he(r,t.offset,t.width,t.signed,t.endian)+t.delta,i=me(t.width,t.signed);if(e<i.min||e>i.max)throw Error(`mutations[${n}] integer overflow (${i.min}..${i.max})`);return P(r.subarray(t.offset,t.offset+t.width),e,t.width,t.signed,t.endian),{payload:r,summary:{index:n,strategy:t.strategy,detail:`incremented ${t.signed?`signed`:`unsigned`} ${t.width}-byte integer at offset ${t.offset} by ${t.delta}`}}}}}const xe=Object.freeze({arp:2054,ipv4:2048,ipv6:34525,vlan:33024}),Se=Object.freeze({icmp:1,igmp:2,tcp:6,udp:17,gre:47,esp:50,ah:51,icmpv6:58,ospf:89}),Ce=Object.freeze({loopback:0,ethernet:1,raw:101});function I(e,t,n,r){if(typeof e==`number`){if(!Number.isInteger(e)||e<0||e>r)throw Error(`${t} must be an integer between 0 and ${r}`);return e}if(typeof e!=`string`||e.trim().length===0)throw Error(`${t} must be a non-empty string or integer`);let i=e.trim().toLowerCase(),a=n[i];if(a!==void 0)return a;if(/^\d+$/.test(i)){let e=Number.parseInt(i,10);if(e>r)throw Error(`${t} must be less than or equal to ${r}`);return e}let o=j(i,t),s=Number.parseInt(o,16);if(s>r)throw Error(`${t} must be less than or equal to ${r}`);return s}function L(e,t){if(typeof e!=`string`||e.trim().length===0)throw Error(`${t} must be a non-empty MAC address string`);let n=e.trim().toLowerCase().replace(/^0x/,``).replace(/[:\-.\s]/g,``);if(!/^[0-9a-f]{12}$/i.test(n))throw Error(`${t} must be a valid 6-byte MAC address`);let r=n.match(/.{2}/g)?.join(`:`);if(!r)throw Error(`${t} must be a valid 6-byte MAC address`);return{canonical:r,bytes:Buffer.from(n,`hex`)}}function R(e,t){if(typeof e!=`string`||d(e.trim())!==4)throw Error(`${t} must be a valid IPv4 address`);let n=e.trim().split(`.`).map(e=>Number.parseInt(e,10));return Buffer.from(n)}function z(e,t){return e.length===0?[]:e.split(`:`).flatMap(e=>{if(e.length===0)return[];if(e.includes(`.`)){let n=R(e,t);return[n.readUInt16BE(0).toString(16),n.readUInt16BE(2).toString(16)]}if(!/^[0-9a-f]{1,4}$/i.test(e))throw Error(`${t} contains an invalid IPv6 group`);return[e]})}function we(e,t){if(typeof e!=`string`)throw Error(`${t} must be a valid IPv6 address`);let n=e.trim().toLowerCase().split(`%`)[0]??``;if(d(n)!==6)throw Error(`${t} must be a valid IPv6 address`);let r=n.split(`::`);if(r.length>2)throw Error(`${t} must be a valid IPv6 address`);let i=z(r[0]??``,t),a=z(r[1]??``,t),o=r.length===2?[...i,...Array.from({length:8-i.length-a.length},()=>`0`),...a]:i;if(o.length!==8)throw Error(`${t} must expand to exactly 8 IPv6 groups`);let s=Buffer.alloc(16);for(let[e,t]of o.entries())s.writeUInt16BE(Number.parseInt(t,16),e*2);return s}function B(e,t,n){return t===`ipv4`?R(e,n):we(e,n)}function V(e,t){return I(e,t,xe,65535)}function Te(e,t){return I(e,t,Se,255)}function Ee(e,t){return I(e,t,Ce,4294967295)}function De(e){return e===`little`?`little`:`big`}function Oe(e){return e===`big`?`big`:`little`}function ke(e){return e===`nano`?`nano`:`micro`}function H(e,t){if(typeof e!=`string`)throw Error(`${t} must be a hex string`);return Buffer.from(j(e,t),`hex`)}function U(e){let t=0;for(let n=0;n<e.length;n+=2){let r=e[n]??0,i=e[n+1]??0;for(t+=r<<8|i;t>65535;)t=(t&65535)+(t>>>16)}return~t&65535}function Ae(e,t,n,r){let i=Buffer.alloc(14);return e.bytes.copy(i,0),t.bytes.copy(i,6),i.writeUInt16BE(n,12),Buffer.concat([i,r])}function je(e){if(e.hardwareSize!==e.senderMac.bytes.length||e.hardwareSize!==e.targetMac.bytes.length)throw Error(`hardwareSize must match the provided MAC address lengths`);if(e.protocolSize!==e.senderIp.length||e.protocolSize!==e.targetIp.length)throw Error(`protocolSize must match the provided IP address lengths`);let t=Buffer.alloc(8+e.hardwareSize*2+e.protocolSize*2),n=0;return t.writeUInt16BE(e.hardwareType,n),n+=2,t.writeUInt16BE(e.protocolType,n),n+=2,t.writeUInt8(e.hardwareSize,n++),t.writeUInt8(e.protocolSize,n++),t.writeUInt16BE(e.operation===`reply`?2:1,n),n+=2,e.senderMac.bytes.copy(t,n),n+=e.hardwareSize,e.senderIp.copy(t,n),n+=e.protocolSize,e.targetMac.bytes.copy(t,n),n+=e.hardwareSize,e.targetIp.copy(t,n),t}function Me(e){let t=Buffer.alloc(20);t[0]=69,t[1]=(e.dscp&63)<<2|e.ecn&3,t.writeUInt16BE(t.length+e.payload.length,2),t.writeUInt16BE(e.identification,4);let n=!!e.dontFragment<<1|!!e.moreFragments;t.writeUInt16BE((n&7)<<13|e.fragmentOffset&8191,6),t[8]=e.ttl,t[9]=e.protocol,t.writeUInt16BE(0,10),e.sourceIp.copy(t,12),e.destinationIp.copy(t,16);let r=U(t);return t.writeUInt16BE(r,10),{packet:Buffer.concat([t,e.payload]),checksum:r}}function Ne(e){let t=Buffer.alloc(40),n=6<<28|(((e.dscp&63)<<2|e.ecn&3)&255)<<20|e.flowLabel&1048575;return t.writeUInt32BE(n>>>0,0),t.writeUInt16BE(e.payload.length,4),t.writeUInt8(e.protocol,6),t.writeUInt8(e.hopLimit,7),e.sourceIp.copy(t,8),e.destinationIp.copy(t,24),Buffer.concat([t,e.payload])}function Pe(e){let t=Buffer.alloc(8+e.payload.length);t[0]=e.operation===`reply`?0:8,t[1]=0,t.writeUInt16BE(0,2),t.writeUInt16BE(e.identifier,4),t.writeUInt16BE(e.sequenceNumber,6),e.payload.copy(t,8);let n=U(t);return t.writeUInt16BE(n,2),{packet:t,checksum:n}}function W(e,t,n,r){r===`little`?e.writeUInt32LE(n,t):e.writeUInt32BE(n,t)}function G(e,t,n,r){r===`little`?e.writeUInt16LE(n,t):e.writeUInt16BE(n,t)}function K(e,t,n){return n===`little`?e.readUInt32LE(t):e.readUInt32BE(t)}function q(e,t,n){return n===`little`?e.readUInt16LE(t):e.readUInt16BE(t)}function Fe(e,t){let n=e===`little`?t===`nano`?`4d3cb2a1`:`d4c3b2a1`:t===`nano`?`a1b23c4d`:`a1b2c3d4`;return Buffer.from(n,`hex`)}function Ie(e){if(e.length<24)throw Error(`PCAP file is too small to contain a global header`);let t=e.subarray(0,4).toString(`hex`),n,r;switch(t){case`d4c3b2a1`:n=`little`,r=`micro`;break;case`4d3cb2a1`:n=`little`,r=`nano`;break;case`a1b2c3d4`:n=`big`,r=`micro`;break;case`a1b23c4d`:n=`big`,r=`nano`;break;default:throw Error(`Unsupported capture format: only classic PCAP files are supported`)}return{endianness:n,timestampPrecision:r,versionMajor:q(e,4,n),versionMinor:q(e,6,n),snapLength:K(e,16,n),linkType:K(e,20,n)}}function Le(e,t){if(!S(e))throw Error(`packets[${t}] must be an object`);let n=H(e.dataHex,`packets[${t}].dataHex`),r=e.timestampSeconds===void 0?0:T(e.timestampSeconds,`packets[${t}].timestampSeconds`),i=e.timestampFraction===void 0?0:T(e.timestampFraction,`packets[${t}].timestampFraction`),a=e.originalLength===void 0?n.length:E(e.originalLength,`packets[${t}].originalLength`);if(a<n.length)throw Error(`packets[${t}].originalLength must be >= included packet length`);return{data:n,timestampSeconds:r,timestampFraction:i,originalLength:a}}function Re(e){let t=Buffer.alloc(24);Fe(e.endianness,e.timestampPrecision).copy(t,0),G(t,4,2,e.endianness),G(t,6,4,e.endianness),W(t,8,0,e.endianness),W(t,12,0,e.endianness),W(t,16,e.snapLength,e.endianness),W(t,20,e.linkType,e.endianness);let n=e.packets.map(t=>{let n=Buffer.alloc(16);return W(n,0,t.timestampSeconds,e.endianness),W(n,4,t.timestampFraction,e.endianness),W(n,8,t.data.length,e.endianness),W(n,12,t.originalLength,e.endianness),Buffer.concat([n,t.data])});return Buffer.concat([t,...n])}function ze(e,t,n){let r=Ie(e),i=[],a=24;for(;a<e.length&&!(t!==void 0&&i.length>=t);){if(a+16>e.length)throw Error(`PCAP file ends with an incomplete packet header`);let t=K(e,a,r.endianness),o=K(e,a+4,r.endianness),s=K(e,a+8,r.endianness),c=K(e,a+12,r.endianness);if(a+=16,a+s>e.length)throw Error(`PCAP file ends with an incomplete packet payload`);let l=e.subarray(a,a+s);a+=s;let u=n===void 0?l.length:n,d=Math.min(u,l.length);i.push({index:i.length,timestampSeconds:t,timestampFraction:o,includedLength:s,originalLength:c,dataHex:l.subarray(0,d).toString(`hex`),truncated:d<l.length})}return{header:r,packets:i}}const Be=[Buffer.from([44]),Buffer.from([124]),Buffer.from([58]),Buffer.from([59]),Buffer.from([9]),Buffer.from([0]),Buffer.from([13,10])];function J(e){return e.replace(/^0x/i,``).replace(/\s+/g,``).toLowerCase()}function Y(e){let t=J(e);return t.length===0||t.length%2!=0?!1:/^[0-9a-f]+$/i.test(t)}function X(e){return Y(e)?Buffer.from(J(e),`hex`):null}function Z(e){return e>=32&&e<=126}function Q(e){if(e.length===0)return 0;let t=0;for(let n of e.values())Z(n)&&(t+=1);return t/e.length}function Ve(e){return e.length===0?0:e.reduce((e,t)=>e+Q(t),0)/e.length}function He(e,t){if(t.length===0)return[e];let n=[],r=0,i=e.indexOf(t,r);for(;i>=0;)n.push(e.subarray(r,i)),r=i+t.length,i=e.indexOf(t,r);return n.push(e.subarray(r)),n}function Ue(e){return Q(e)===1?e.toString(`utf8`):e.toString(`hex`)}function We(e){let t=[];for(let n of e){let e=X(n);e&&t.push(e)}return t}function Ge(e,t){if(e.length===0)return null;if(e.length===1)return e.readUInt8(0);if(e.length===2)return t===`le`?e.readUInt16LE(0):e.readUInt16BE(0);if(e.length===4)return t===`le`?e.readUInt32LE(0):e.readUInt32BE(0);if(e.length===8){let n=Number(t===`le`?e.readBigUInt64LE(0):e.readBigUInt64BE(0));return Number.isFinite(n)?n:null}let n=0,r=t===`le`?[...e.values()].toReversed():[...e.values()];for(let e of r)n=n*256+e;return Number.isFinite(n)?n:null}function Ke(e,t){if(e.length===4){let n=t===`le`?e.readFloatLE(0):e.readFloatBE(0);return Number.isFinite(n)?n:null}if(e.length===8){let n=t===`le`?e.readDoubleLE(0):e.readDoubleBE(0);return Number.isFinite(n)?n:null}return null}function qe(e,t){if(t.length===0)return 0;let n=0,r=0,i=e.indexOf(t,r);for(;i>=0;)n+=1,r=i+t.length,i=e.indexOf(t,r);return n}function Je(e){return e.length===0?`bytes`:e.every(e=>e.length===1)&&e.every(e=>e[0]===0||e[0]===1)?`bool`:Ve(e)>=.7?`string`:e.every(e=>e.length===4)&&Ye(e)?`float`:e.every(e=>e.length<=4)?`int`:`bytes`}function Ye(e){let t=[];for(let n of e){let e=Ke(n,`be`);if(e===null)return!1;t.push(e)}return t.some(e=>Math.abs(e)>.001&&Math.abs(e)<1e6)}function Xe(e,t){let n=0,r=0;for(let i of e){let e=i[t];e!==void 0&&(n+=1,Z(e)&&(r+=1))}return n>0&&r/n>=.8}function Ze(e,t){let n=0;for(let r of e){let e=r[t];if(e!==void 0&&(n+=1,e!==0&&e!==1))return!1}return n>0}function Qe(e,t){if(t.length===0)return[];let n=e.map(e=>He(e,t)),r=n[0];if(!r||r.length<2)return[];let i=r.length;if(!n.every(e=>e.length===i))return[];let a=[],o=0;for(let e=0;e<i;e+=1){let i=r[e];if(!i)continue;let s=n.map(t=>t[e]).filter(e=>Buffer.isBuffer(e));a.push({name:`field_${e+1}`,offset:o,length:i.length,type:Je(s)}),o+=i.length+t.length}return a}function $e(e){let t=Math.min(...e.map(e=>e.length)),n=[],r=0;for(;r<t&&n.length<24;){if(Xe(e,r)){let i=r+1;for(;i<t&&Xe(e,i);)i+=1;n.push({name:`field_${n.length+1}`,offset:r,length:i-r,type:`string`}),r=i;continue}if(Ze(e,r)){n.push({name:`field_${n.length+1}`,offset:r,length:1,type:`bool`}),r+=1;continue}let i=t-r;if(i>=4&&Ye(e.map(e=>e.subarray(r,r+4)))){n.push({name:`field_${n.length+1}`,offset:r,length:4,type:`float`}),r+=4;continue}let a=i>=4?4:Math.min(i,2),o=e.map(e=>e.subarray(r,r+a));n.push({name:`field_${n.length+1}`,offset:r,length:a,type:Je(o)}),r+=a}return n}function et(e){for(let t of Be){let n=e.map(e=>qe(e,t)),r=n[0];if(typeof r==`number`&&r>=2&&n.every(e=>e===r))return Ue(t)}}function tt(e){let t=Math.min(...e.map(e=>e.length));if(t<2)return`be`;let n=0,r=0,i=Math.min(t-1,8);for(let t=0;t<i;t+=2){let i=0,a=0;for(let n of e){let e=n.readUInt16LE(t),r=n.readUInt16BE(t);e<4096&&(i+=1),r<4096&&(a+=1)}i>a?n+=1:a>i&&(r+=1)}return n>r?`le`:`be`}function nt(e,t){if(e.length===0||t.length<2)return e;let n=Math.min(...t.map(e=>e.length)),r=0;for(let e=0;e<n;e+=1){let n=t[0][e];if(t.every(t=>t[e]===n))r=e+1;else break}if(r===0)return e;let i=!1;return e.map(e=>!i&&e.offset===0&&r>=2?(i=!0,{...e,name:`magic`}):i&&e.type===`int`&&e.length<=2&&e.offset<=r?{...e,name:`version`}:e)}var rt=class{patterns=new Map;legacyPatterns=new Map;definePattern(e,t,n){let r=Array.isArray(t)?this.createLegacyPattern(e,t,n):this.createLegacyPatternFromSpec(e,t),i=this.createSpecFromLegacyPattern(r);if(this.patterns.set(e,i),this.legacyPatterns.set(e,r),Array.isArray(t))return r}detectPattern(e){let t=X(e);if(!t)return null;let n=null;for(let e of this.patterns.values()){let r=e.fields.length+ +!!e.fieldDelimiter;if(r===0)continue;let i=0;e.fieldDelimiter&&this.payloadContainsDelimiter(t,e.fieldDelimiter)&&(i+=1);for(let n of e.fields)this.matchesField(t,n,e.byteOrder??`be`)&&(i+=1);let a=Number((i/r).toFixed(2));if(a<=0)continue;let o={pattern:e,confidence:a,matches:i,total:r};(!n||o.confidence>n.confidence||o.confidence===n.confidence&&o.matches>n.matches)&&(n=o)}return n}autoDetect(e){let t=We(e);if(t.length===0)return null;let n=et(t),r=this.inferFields(e);return{name:`auto-detected-pattern`,fieldDelimiter:n,byteOrder:tt(t),fields:r}}inferFields(e){let t=We(e);if(t.length===0)return[];let n=et(t);if(n){let e=Qe(t,this.parseDelimiter(n));if(e.length>0)return nt(e,t)}return nt($e(t),t)}autoDetectPattern(e,t){let n=e.map(e=>e.toString(`hex`)),r=this.autoDetect(n),i=t?.name??r?.name??`auto_detected`;if(!r){let e=this.createLegacyPattern(i,[]);return this.patterns.set(i,this.createSpecFromLegacyPattern(e)),this.legacyPatterns.set(i,e),e}let a={...r,name:i};return this.definePattern(i,a),this.getPattern(i)??this.createLegacyPatternFromSpec(i,a)}getPattern(e){return this.legacyPatterns.get(e)}listPatterns(){return[...this.patterns.keys()]}exportProto(e){let t=this.isLegacyPattern(e)?e:this.createLegacyPatternFromSpec(e.name,e),n=[`// Protocol: ${t.name}`,`// Byte order: ${t.byteOrder}`,``];t.encryption&&(n.push(`// Encryption: ${t.encryption.type}`),t.encryption.notes&&n.push(`// Notes: ${t.encryption.notes}`),n.push(``)),n.push(`message ${this.toPascalCase(t.name)} {`);for(let e=0;e<t.fields.length;e+=1){let r=t.fields[e];if(!r)continue;let i=r.description?` // ${r.description}`:``;n.push(` ${this.toProtoType(r.type)} ${r.name} = ${e+1};${i}`)}return n.push(`}`),n.push(``),n.join(`
|
|
2
|
-
`)}payloadContainsDelimiter(e,t){let n=this.parseDelimiter(t);return n.length===0?!1:e.includes(n)}matchesField(e,t,n){if(t.offset<0||t.length<=0||e.length<t.offset+t.length)return!1;let r=e.subarray(t.offset,t.offset+t.length);switch(t.type){case`bytes`:return r.length===t.length;case`bool`:return r.length===1&&(r[0]===0||r[0]===1);case`string`:return Q(r)>=.6;case`int`:return Ge(r,n)!==null;case`float`:return Ke(r,n)!==null;default:return!1}}createLegacyPattern(e,t,n){return{name:e,fields:t.map(e=>({name:e.name,offset:e.offset,length:e.length,type:e.type,...e.description?{description:e.description}:{}})).toSorted((e,t)=>e.offset-t.offset),byteOrder:n?.byteOrder??`big`,...n?.encryption?{encryption:n.encryption}:{}}}createLegacyPatternFromSpec(e,t){return{name:e,fieldDelimiter:t.fieldDelimiter,byteOrder:t.byteOrder===`le`?`little`:`big`,fields:t.fields.map(e=>({name:e.name,offset:e.offset,length:e.length,type:this.toLegacyFieldType(e),...e.description?{description:e.description}:{}}))}}createSpecFromLegacyPattern(e){return{name:e.name,fieldDelimiter:e.fieldDelimiter,byteOrder:e.byteOrder===`little`?`le`:`be`,fields:e.fields.map(e=>({name:e.name,offset:e.offset,length:e.length,type:this.toSpecFieldType(e.type),...e.description?{description:e.description}:{}}))}}isLegacyPattern(e){return e.byteOrder===`big`||e.byteOrder===`little`}toLegacyFieldType(e){return e.type===`float`?`float`:e.type===`string`?`string`:e.type===`bytes`?`bytes`:e.length===1?`uint8`:e.length===2?`uint16`:e.length===4?`uint32`:`int64`}toSpecFieldType(e){return e===`float`?`float`:e===`string`?`string`:e===`bytes`?`bytes`:`int`}parseDelimiter(e){if(Y(e)){let t=X(e);if(t)return t}return Buffer.from(e,`utf8`)}toProtoType(e){return{uint8:`uint32`,uint16:`uint32`,uint32:`uint32`,int64:`int64`,float:`float`,string:`string`,bytes:`bytes`}[e]}toPascalCase(e){return e.replace(/[^a-zA-Z0-9_]/g,`_`).split(`_`).filter(Boolean).map(e=>e.charAt(0).toUpperCase()+e.slice(1)).join(``)||`Message`}};function it(e){return typeof e==`object`&&!!e&&!Array.isArray(e)}function $(e){return e.trim().toLowerCase()}function at(e){if(e.length===0)return 0;let t=new Map;for(let n of e)t.set(n,(t.get(n)??0)+1);let n=0;for(let r of t.values()){let t=r/e.length;t>0&&(n-=t*Math.log2(t))}return n}function ot(e){if(e.length===0)return 0;let t=0;for(let n=0;n<e.length;n+=1){let r=e.charCodeAt(n);r>=32&&r<=126&&(t+=1)}return t/e.length}var st=class{infer(e){if(e.length===0)return{states:[],transitions:[],initial:``,initialState:``,finalStates:[]};let t=new Map,n=new Map,r=``;for(let i=0;i<e.length;i+=1){let a=e[i];if(!a)continue;let o=this.buildSignature(a),s=t.get(o);if(s?s.type=this.mergeStateTypes(s.type,this.inferStateType(a,i===e.length-1)):(s={id:`state_${t.size+1}`,name:this.buildStateName(a,t.size+1),type:this.inferStateType(a,i===e.length-1)},t.set(o,s)),r&&a.timestamp!==void 0){let t=e[0];t&&t.timestamp!==void 0&&(s.timeout=a.timestamp-t.timestamp)}if(r){let e=this.buildEventName(a),t=this.buildCondition(a.fields),i=this.buildAction(a),o=`${r}:${s.id}:${e}`;n.has(o)||n.set(o,{from:r,to:s.id,event:e,confidence:this.computeTransitionConfidence(a),...t?{condition:t}:{},...i?{action:i}:{}})}r=s.id}let i=e[0],a=i?t.get(this.buildSignature(i))?.id??``:``;return{states:[...t.values()],transitions:[...n.values()],initial:a,initialState:a,finalStates:this.collectTerminalStates([...t.values()])}}visualize(e){if(e.states.length===0)return["```mermaid",`stateDiagram-v2`,` [*] --> empty`,"```"].join(`
|
|
3
|
-
`);let t=["```mermaid",`stateDiagram-v2`],n=e.initialState??e.initial;n&&t.push(` [*] --> ${n}`);for(let n of e.states){let e=n.type??`normal`,r=e===`normal`?n.name:`${n.name} (${e})`;t.push(` state "${r}" as ${n.id}`)}for(let n of e.transitions){let e=[n.event??n.trigger??`transition`];typeof n.confidence==`number`&&e.push(`(${n.confidence.toFixed(2)})`),n.condition&&e.push(`[${n.condition}]`),n.action&&e.push(`/ ${n.action}`),t.push(` ${n.from} --> ${n.to} : ${e.join(` `)}`)}let r=new Set(e.finalStates??[]);for(let n of e.states){let e=n.type??`normal`;(e===`accept`||e===`reject`||r.has(n.id))&&t.push(` ${n.id} --> [*]`)}return t.push("```"),t.join(`
|
|
4
|
-
`)}inferStateMachine(e){let t=e.map(e=>({direction:e.direction===`out`?`req`:`res`,timestamp:e.timestamp??0,fields:{},raw:e.payload.length>0?e.payload.toString(`utf8`):e.payload.toString(`hex`),rawBuffer:e.payload}));return this.infer(t)}generateMermaid(e){return this.visualize(e)}simplify(e){if(e.states.length<2)return{...e,initialState:e.initialState??e.initial,finalStates:e.finalStates??this.collectTerminalStates(e.states)};let t=new Map,n=new Map;for(let r of e.states){let e=this.getPayloadPrefix(r);if(!e)continue;let i=[...n.entries()].find(([t])=>t===e);i?t.set(r.id,i[0]):(n.set(e,r.id),t.set(r.id,e))}let r=new Map,i=new Map;for(let[e,t]of n)i.set(e,t);for(let t of e.states){let e=this.getPayloadPrefix(t);if(!e)continue;let n=i.get(e);n&&n!==t.id&&r.set(t.id,n)}if(r.size===0)return{...e,initialState:e.initialState??e.initial,finalStates:e.finalStates??this.collectTerminalStates(e.states)};let a=e.states.filter(e=>!r.has(e.id)),o=e.transitions.map(e=>({...e,from:r.get(e.from)??e.from,to:r.get(e.to)??e.to})).filter(e=>e.from!==e.to),s=e.initialState??e.initial??``,c=r.get(s)??s;return{states:a,transitions:o,initial:c,initialState:c,finalStates:e.finalStates.map(e=>r.get(e)??e).filter((e,t,n)=>n.indexOf(e)===t)}}getPayloadPrefix(e){let t=e.expectedPayload;return!t||t.length<8?null:t.slice(0,8).toLowerCase()}buildSignature(e){let t=Object.keys(e.fields).toSorted().join(`,`),n=$(e.rawBuffer?e.rawBuffer.toString(`hex`):e.raw).slice(0,24);return`${e.direction}|${t}|${n}`}buildStateName(e,t){let n=e.direction===`req`?`send`:`recv`,r=this.findPrimaryFieldName(e.fields),i=e.raw;if(i.length===0)return`${n}_empty`;let a=e.rawBuffer,o=Buffer.isBuffer(a)?a.toString(`hex`):i;if(o.startsWith(`16`)||o.startsWith(`15`)||o.startsWith(`17`))return`${n}_tls_handshake`;let s=i.trimStart();if(s.startsWith(`{`)||s.startsWith(`[`))return`${n}_json_${r||`step_${t}`}`;if(ot(i)>=.7){let e=$(i);return e.includes(`close`)||e.includes(`fin`)||e.includes(`bye`)?`${n}_close`:e.startsWith(`get `)||e.startsWith(`post `)||e.startsWith(`http`)?`${n}_text_http`:`${n}_text_${r||`step_${t}`}`}return Buffer.isBuffer(a)&&a.length>=32&&at(a)>6?`${n}_encrypted`:Buffer.isBuffer(a)&&a.length<=4?`${n}_control`:`${n}_${r||`step_${t}`}`}findPrimaryFieldName(e){return Object.keys(e).toSorted()[0]||``}inferStateType(e,t){let n=$(e.raw),r=this.findStatusValue(e.fields);return this.containsRejectSignal(n)||this.containsRejectSignal(r)?`reject`:this.containsAcceptSignal(n)||this.containsAcceptSignal(r)||t&&e.direction===`res`?`accept`:`normal`}mergeStateTypes(e,t){return e===`reject`||t===`reject`?`reject`:e===`accept`||t===`accept`?`accept`:`normal`}findStatusValue(e){for(let t of[`status`,`result`,`code`,`reason`,`message`]){let n=e[t];if(typeof n==`string`||typeof n==`number`||typeof n==`boolean`)return String(n)}return``}containsRejectSignal(e){return[`error`,`fail`,`denied`,`reject`,`timeout`,`invalid`].some(t=>$(e).includes(t))}containsAcceptSignal(e){return[`ok`,`success`,`accept`,`ready`,`done`,`complete`].some(t=>$(e).includes(t))}buildEventName(e){let t=this.findStatusValue(e.fields);if(t)return`${e.direction}_${$(t).replace(/[^a-z0-9]+/g,`_`)}`;let n=this.findPrimaryFieldName(e.fields);return n?`${e.direction}_${n}`:`${e.direction}_message`}buildCondition(e){let t=this.findStatusValue(e);if(t)return`status=${t}`;let n=Object.keys(e).toSorted().slice(0,2);if(n.length===0)return;let r=[];for(let t of n){let n=e[t];(typeof n==`string`||typeof n==`number`||typeof n==`boolean`)&&r.push(`${t}=${n}`)}return r.length>0?r.join(`, `):void 0}buildAction(e){let t=this.findStatusValue(e.fields);if(this.containsRejectSignal(t)||this.containsRejectSignal(e.raw))return`reject`;if(this.containsAcceptSignal(t)||this.containsAcceptSignal(e.raw))return`complete`;let n=$(e.raw);if(n.includes(`ack`))return`acknowledge`;if(n.includes(`retry`))return`retry`;if(Object.keys(e.fields).length>0&&it(e.fields))return e.direction===`req`?`send`:`receive`}collectTerminalStates(e){let t=e.filter(e=>{let t=e.type??`normal`;return t===`accept`||t===`reject`}).map(e=>e.id);for(let n of e){let e=$(n.name);(e.includes(`close`)||e.includes(`fin`)||e.includes(`bye`))&&(t.includes(n.id)||t.push(n.id))}return t}computeTransitionConfidence(e){let t=.3;return Object.keys(e.fields).length>0&&(t+=.3),this.findStatusValue(e.fields)&&(t+=.2),e.raw.length>0&&(t+=.2),Math.min(t,1)}};const ct={states:[],transitions:[],initial:``,initialState:``,finalStates:[]};var lt=class{engine;inferrer;eventBus;constructor(e,t,n){this.engine=e,this.inferrer=t,this.eventBus=n}emitEvent(e,t){this.eventBus?.emit(e,{...t,timestamp:new Date().toISOString()})}getEngine(){return this.engine||=new rt,this.engine}getInferrer(){return this.inferrer||=new st,this.inferrer}errorMessage(e){return e instanceof Error?e.message:String(e)}},ut=class extends lt{async handleDefinePattern(e){try{let t=typeof e.name==`string`&&e.name.trim().length>0?e.name:`unnamed_pattern`,n=o(e,`spec`);if(n){let e=se(t,n);return this.getEngine().definePattern(t,e),{patternId:t,pattern:this.getEngine().getPattern(t)??{name:t,fields:[],byteOrder:`big`},success:!0}}let r=(Array.isArray(e.fields)?e.fields:[]).map((e,t)=>oe(e,t)),i=e.byteOrder===`little`||e.byteOrder===`big`?e.byteOrder:void 0,a=ce(e.encryption);return{patternId:t,pattern:this.getEngine().definePattern(t,r,{...i?{byteOrder:i}:{},...a?{encryption:a}:{}}),success:!0}}catch(e){return{patternId:`error`,pattern:{name:`error`,fields:[],byteOrder:`big`},success:!1,error:this.errorMessage(e)}}}async handleAutoDetect(e){try{let t=(()=>{let t=s(e,`hexPayloads`);return t.length>0?t:s(e,`payloads`)})(),n=this.getEngine().autoDetect(t),r=typeof e.name==`string`&&e.name.trim().length>0?e.name:void 0;if(!n)return{patterns:[this.getEngine().autoDetectPattern([],r?{name:r}:{})],success:!0};let i={...n,name:r??n.name};this.getEngine().definePattern(i.name,i);let a=this.getEngine().getPattern(i.name)??{name:i.name,fields:[],byteOrder:`big`};return this.emitEvent(`protocol:pattern_detected`,{patternName:i.name,confidence:0}),{patterns:[a],success:!0}}catch(e){return{patterns:[],success:!1,error:this.errorMessage(e)}}}async handleInferFields(e){try{let t=s(e,`hexPayloads`);return{success:!0,fields:this.getEngine().inferFields(t)}}catch(e){return{fields:[],success:!1,error:this.errorMessage(e)}}}async handleExportSchema(e){try{let t=c(e,`patternId`),n=this.getEngine().getPattern(t);return n?{schema:this.getEngine().exportProto(n)}:{schema:`// Error: pattern '${t}' not found`}}catch(e){return{schema:`// Error: ${this.errorMessage(e)}`}}}async handleInferStateMachine(e){try{let t=e.messages;if(!Array.isArray(t))throw Error(`messages must be an array`);let n=t.some(e=>S(e)&&(e.direction===`in`||e.direction===`out`)),r;if(n){let e=t.map((e,t)=>{if(!S(e))throw Error(`messages[${t}] must be an object`);let n=e.direction,r=typeof e.payloadHex==`string`?e.payloadHex:``,i=typeof e.timestamp==`number`?e.timestamp:void 0,a=Buffer.from(r.replace(/\s+/g,``),`hex`);if(n!==`in`&&n!==`out`)throw Error(`messages[${t}].direction must be "in" or "out"`);return{direction:n,payload:a,...i===void 0?{}:{timestamp:i}}});r=this.getInferrer().inferStateMachine(e)}else{let e=t.map((e,t)=>le(e,t));r=this.getInferrer().infer(e)}return e.simplify===!0&&(r=this.getInferrer().simplify(r)),{stateMachine:r,mermaid:this.getInferrer().generateMermaid(r),success:!0}}catch(e){return{stateMachine:{...ct},success:!1,error:this.errorMessage(e)}}}async handleVisualizeState(e){try{let t=e.stateMachine;if(!S(t))return{mermaidDiagram:this.getInferrer().generateMermaid(ct)};let n=Array.isArray(t.states)?t.states:[],r=Array.isArray(t.transitions)?t.transitions:[],i=typeof t.initialState==`string`?t.initialState:``,a=Array.isArray(t.finalStates)?t.finalStates.filter(e=>typeof e==`string`):[];return{mermaidDiagram:this.getInferrer().generateMermaid({states:n.filter(e=>S(e)),transitions:r.filter(e=>S(e)),initial:i,initialState:i,finalStates:a})}}catch(e){return{mermaidDiagram:`stateDiagram-v2\n note right of empty: ${this.errorMessage(e)}`}}}},dt=class extends ut{async handlePayloadTemplateBuild(e){try{let t=e.fields;if(!Array.isArray(t))throw Error(`fields must be an array`);let{payload:n,segments:r}=ve(t.map((e,t)=>ge(e,t)),w(e.endian));return this.emitEvent(`protocol:payload_built`,{byteLength:n.length,fieldCount:r.length}),{hexPayload:n.toString(`hex`),byteLength:n.length,fields:r,success:!0}}catch(e){return{hexPayload:``,byteLength:0,fields:[],success:!1,error:this.errorMessage(e)}}}async handlePayloadMutate(e){let t=``;try{if(typeof e.hexPayload!=`string`)throw Error(`hexPayload must be a string`);t=j(e.hexPayload,`hexPayload`);let n=e.mutations;if(!Array.isArray(n))throw Error(`mutations must be an array`);let r=Buffer.from(t,`hex`),i=[];for(let[e,t]of n.entries()){let n=ye(t,e),a=be(r,n,e);r=a.payload,i.push(a.summary)}return this.emitEvent(`protocol:payload_mutated`,{byteLength:r.length,mutationCount:i.length}),{originalHex:t,mutatedHex:r.toString(`hex`),byteLength:r.length,appliedMutations:i,success:!0}}catch(e){return{originalHex:t,mutatedHex:``,byteLength:0,appliedMutations:[],success:!1,error:this.errorMessage(e)}}}},ft=class extends dt{async handleEthernetFrameBuild(e){try{let t=L(e.destinationMac,`destinationMac`),n=L(e.sourceMac,`sourceMac`),r=V(e.etherType,`etherType`),i=Ae(t,n,r,H(e.payloadHex,`payloadHex`));return this.emitEvent(`protocol:ethernet_frame_built`,{byteLength:i.length,etherType:`0x${r.toString(16).padStart(4,`0`)}`}),{destinationMac:t.canonical,sourceMac:n.canonical,etherType:r,etherTypeHex:`0x${r.toString(16).padStart(4,`0`)}`,byteLength:i.length,headerHex:i.subarray(0,14).toString(`hex`),frameHex:i.toString(`hex`),success:!0}}catch(e){return{destinationMac:``,sourceMac:``,etherType:0,etherTypeHex:`0x0000`,byteLength:0,headerHex:``,frameHex:``,success:!1,error:this.errorMessage(e)}}}async handleArpBuild(e){try{let t=e.operation===`reply`?`reply`:`request`,n=L(e.senderMac,`senderMac`),r=L(e.targetMac??`00:00:00:00:00:00`,`targetMac`),i=R(e.senderIp,`senderIp`),a=R(e.targetIp,`targetIp`),o=je({operation:t,hardwareType:e.hardwareType===void 0?1:T(e.hardwareType,`hardwareType`),protocolType:V(e.protocolType??`ipv4`,`protocolType`),hardwareSize:e.hardwareSize===void 0?6:E(e.hardwareSize,`hardwareSize`),protocolSize:e.protocolSize===void 0?4:E(e.protocolSize,`protocolSize`),senderMac:n,senderIp:i,targetMac:r,targetIp:a});return this.emitEvent(`protocol:arp_built`,{operation:t,byteLength:o.length}),{operation:t,byteLength:o.length,payloadHex:o.toString(`hex`),senderMac:n.canonical,senderIp:e.senderIp,targetMac:r.canonical,targetIp:e.targetIp,success:!0}}catch(e){return{operation:null,byteLength:0,payloadHex:``,senderMac:``,senderIp:``,targetMac:``,targetIp:``,success:!1,error:this.errorMessage(e)}}}},pt=class extends ft{async handleRawIpPacketBuild(e){try{let t=e.version===`ipv6`?`ipv6`:`ipv4`,n=H(e.payloadHex??``,`payloadHex`),r=Te(e.protocol,`protocol`),i=e.dscp===void 0?0:T(e.dscp,`dscp`),a=e.ecn===void 0?0:T(e.ecn,`ecn`);if(i>63)throw Error(`dscp must be between 0 and 63`);if(a>3)throw Error(`ecn must be between 0 and 3`);if(t===`ipv4`){let o=e.ttl===void 0?64:O(e.ttl,`ttl`),s=e.identification===void 0?0:T(e.identification,`identification`),c=e.fragmentOffset===void 0?0:T(e.fragmentOffset,`fragmentOffset`);if(s>65535)throw Error(`identification must be between 0 and 65535`);if(c>8191)throw Error(`fragmentOffset must be between 0 and 8191`);let{packet:l,checksum:u}=Me({sourceIp:B(e.sourceIp,`ipv4`,`sourceIp`),destinationIp:B(e.destinationIp,`ipv4`,`destinationIp`),protocol:r,payload:n,ttl:o,identification:s,dontFragment:e.dontFragment===!0,moreFragments:e.moreFragments===!0,fragmentOffset:c,dscp:i,ecn:a});return this.emitEvent(`protocol:ip_packet_built`,{version:t,protocol:r,byteLength:l.length}),{version:t,protocol:r,byteLength:l.length,headerLength:20,packetHex:l.toString(`hex`),headerHex:l.subarray(0,20).toString(`hex`),payloadHex:n.toString(`hex`),checksumHex:u.toString(16).padStart(4,`0`),success:!0}}let o=e.hopLimit===void 0?e.ttl===void 0?64:O(e.ttl,`ttl`):O(e.hopLimit,`hopLimit`),s=e.flowLabel===void 0?0:T(e.flowLabel,`flowLabel`);if(s>1048575)throw Error(`flowLabel must be between 0 and 1048575`);let c=Ne({sourceIp:B(e.sourceIp,`ipv6`,`sourceIp`),destinationIp:B(e.destinationIp,`ipv6`,`destinationIp`),protocol:r,payload:n,hopLimit:o,dscp:i,ecn:a,flowLabel:s});return this.emitEvent(`protocol:ip_packet_built`,{version:t,protocol:r,byteLength:c.length}),{version:t,protocol:r,byteLength:c.length,headerLength:40,packetHex:c.toString(`hex`),headerHex:c.subarray(0,40).toString(`hex`),payloadHex:n.toString(`hex`),checksumHex:null,success:!0}}catch(e){return{version:null,protocol:null,byteLength:0,headerLength:0,packetHex:``,headerHex:``,payloadHex:``,checksumHex:null,success:!1,error:this.errorMessage(e)}}}async handleIcmpEchoBuild(e){try{let t=e.operation===`reply`?`reply`:`request`,n=e.identifier===void 0?0:T(e.identifier,`identifier`),r=e.sequenceNumber===void 0?0:T(e.sequenceNumber,`sequenceNumber`);if(n>65535)throw Error(`identifier must be between 0 and 65535`);if(r>65535)throw Error(`sequenceNumber must be between 0 and 65535`);let i=H(e.payloadHex??``,`payloadHex`),{packet:a,checksum:o}=Pe({operation:t,identifier:n,sequenceNumber:r,payload:i}),s=o.toString(16).padStart(4,`0`);return this.emitEvent(`protocol:icmp_echo_built`,{operation:t,byteLength:a.length,checksumHex:s}),{operation:t,identifier:n,sequenceNumber:r,checksum:o,checksumHex:s,byteLength:a.length,packetHex:a.toString(`hex`),payloadHex:i.toString(`hex`),success:!0}}catch(e){return{operation:null,identifier:null,sequenceNumber:null,checksum:null,checksumHex:``,byteLength:0,packetHex:``,payloadHex:``,success:!1,error:this.errorMessage(e)}}}},mt=class extends pt{async handleChecksumApply(e){try{let t=H(e.hexPayload,`hexPayload`),n=e.startOffset===void 0?0:T(e.startOffset,`startOffset`),r=e.endOffset===void 0?t.length:T(e.endOffset,`endOffset`);if(n>r||r>t.length)throw Error(`checksum range must stay within the payload`);let i=e.zeroOffset===void 0?void 0:T(e.zeroOffset,`zeroOffset`),a=e.zeroLength===void 0?2:E(e.zeroLength,`zeroLength`),o=e.writeOffset===void 0?i:T(e.writeOffset,`writeOffset`),s=De(e.endian),c=Buffer.from(t);if(i!==void 0){if(i+a>c.length)throw Error(`zeroOffset and zeroLength must stay within the payload`);c.fill(0,i,i+a)}let l=U(c.subarray(n,r));if(o!==void 0){if(o+2>c.length)throw Error(`writeOffset must leave room for a 16-bit checksum field`);s===`little`?c.writeUInt16LE(l,o):c.writeUInt16BE(l,o)}let u=l.toString(16).padStart(4,`0`);return this.emitEvent(`protocol:checksum_applied`,{checksumHex:u,byteLength:c.length}),{checksumHex:u,checksum:l,mutatedHex:c.toString(`hex`),byteLength:c.length,rangeStart:n,rangeEnd:r,success:!0}}catch(e){return{checksumHex:``,checksum:0,mutatedHex:``,byteLength:0,rangeStart:0,rangeEnd:0,success:!1,error:this.errorMessage(e)}}}},ht=class extends mt{},gt=class extends ht{async handlePcapWrite(e){try{let t=this.parseRequiredPath(e);if(!Array.isArray(e.packets))throw Error(`packets must be an array`);let n=e.packets.map((e,t)=>Le(e,t)),r=Oe(e.endianness),i=ke(e.timestampPrecision),a=e.snapLength===void 0?65535:E(e.snapLength,`snapLength`),o=Ee(e.linkType??`ethernet`,`linkType`),s=Re({packets:n,endianness:r,timestampPrecision:i,snapLength:a,linkType:o});return await u(t,s),this.emitEvent(`protocol:pcap_written`,{path:t,packetCount:n.length,byteLength:s.length}),{path:t,packetCount:n.length,byteLength:s.length,endianness:r,timestampPrecision:i,linkType:o,success:!0}}catch(t){return{path:typeof e.path==`string`?e.path:``,packetCount:0,byteLength:0,endianness:null,timestampPrecision:null,linkType:null,success:!1,error:this.errorMessage(t)}}}async handlePcapRead(e){try{let t=this.parseRequiredPath(e),n=e.maxPackets===void 0?void 0:E(e.maxPackets,`maxPackets`),r=e.maxBytesPerPacket===void 0?void 0:E(e.maxBytesPerPacket,`maxBytesPerPacket`),{header:i,packets:a}=ze(await l(t),n,r);return this.emitEvent(`protocol:pcap_read`,{path:t,packetCount:a.length}),{path:t,header:i,packets:a,success:!0}}catch(t){return{path:typeof e.path==`string`?e.path:``,header:null,packets:[],success:!1,error:this.errorMessage(t)}}}parseRequiredPath(e){if(typeof e.path!=`string`||e.path.trim().length===0)throw Error(`path must be a non-empty string`);return e.path}},_t=class extends gt{},vt=class extends _t{async handleProtoFingerprint(o){let c=s(o,`hexPayloads`),l=o.includeKnownProtocols!==!1,u=o.includeFieldHints!==!1;return c.length===0?a({success:!1,error:`hexPayloads is required`}):a({success:!0,fingerprints:c.map((a,o)=>{let s=a.replace(/\s/g,``),c=[],d=s.length/2,f=d>=5?y(s,3):-1,p=Number.isFinite(f)&&f>=0&&d>=5+f,ee=p&&f>=i&&v(s,0)===22&&v(s,5)===1,m=ie(s),h=Object.keys(g).some(e=>s.toUpperCase().startsWith(e)),_=s.toUpperCase().startsWith(`5353482D`),b=s.length>=4&&(()=>{let e=v(s,0),t=v(s,1),n=e&15;if(n===0)return!1;let r=n<=10&&!(n>=3&&n<=7),i=(t>>7&1)==1,a=s.length/2,o=t&127,c=2;if(o===126){if(a<4)return!1;o=y(s,2),c=4}else if(o===127){if(a<10)return!1;let e=y(s,2)<<16|y(s,4),t=y(s,6)<<16|y(s,8);o=e>0?4294967295:t,c=10}return r&&a>=c+(i?4:0)+o})(),x=null;if(ee)c.push({protocol:`TLS ClientHello`,layer:`L6-TLS`,confidence:r}),u&&(x=ne(s));else if(h)c.push({protocol:`HTTP/1.x`,layer:`L7-HTTP`,confidence:n}),u&&(x={method:Object.entries(g).find(([e])=>s.toUpperCase().startsWith(e))?.[1]??`UNKNOWN`,httpVersion:s.indexOf(`2048545450`)>0?`1.x`:`unknown`});else if(_)c.push({protocol:`SSH`,layer:`L7-SSH`,confidence:t}),u&&s.length>=20&&(x={banner:Buffer.from(s.substring(0,Math.min(s.length,80)),`hex`).toString(`ascii`)});else if(b){if(c.push({protocol:`WebSocket`,layer:`L7-WS`,confidence:e}),u&&s.length>=4){let e=v(s,0),t=v(s,1),n=e&15,r=t>>7&1,i=t&127,a=2;if(i===126)i=s.length>=4?y(s,2):0,a=4;else if(i===127){if(s.length>=20){let e=y(s,2)<<16|y(s,4),t=y(s,6)<<16|y(s,8);i=e>0?4294967295:t}else i=0;a=10}r&&(a+=4),x={fin:e>>7&1,rsv1:e>>6&1,opcode:n,opcodeName:te[n]??`reserved(${n})`,masked:!!r,payloadLength:i,headerSize:a}}}else m&&(c.push({protocol:`DNS`,layer:`L7-DNS`,confidence:.85}),u&&(x=re(s)));l&&c.length===0&&(p&&/^160301|^160302|^160303/i.test(s.substring(0,8))&&c.push({protocol:`TLS Record`,layer:`L6-TLS`,confidence:.9}),s.substring(0,8).startsWith(`50524920`)&&c.push({protocol:`HTTP/2 PRI`,layer:`L7-HTTP2`,confidence:.9}));let S=[];if(u&&!x&&s.length>=8){let e=y(s,0);e>0&&e<s.length/2&&S.push({offset:0,hint:`possible length field (${e} bytes)`})}return{index:o,size:d,protocolMatches:c.length>0?c:[{protocol:`unknown`,layer:`unknown`,confidence:0}],...x?{parsedFields:x}:{},...S.length>0?{fieldHints:S}:{}}})})}},yt=class extends vt{};export{yt as ProtocolAnalysisHandlers};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./response-C7rKQst4.mjs";import{t}from"./ToolError-DWU_z7gp.mjs";import{t as n}from"./ToolProbe-C7ZU2x7M.mjs";import{a as r,r as i,s as a,t as o}from"./parse-args-Bw413PlW.mjs";import{join as s}from"node:path";import{mkdir as c}from"node:fs/promises";import{execFile as l}from"node:child_process";function u(e){return e instanceof Error?e.message:String(e)}function d(e){return e?[`-s`,e]:[]}async function f(e,t){return new Promise((n,r)=>{l(e,t,{encoding:`utf8`,windowsHide:!0},(e,t,i)=>{e?r(e):n({stdout:t??``,stderr:i??``})})})}async function p(e,t){let{stdout:n}=await f(e,[...d(t),`shell`,`cat /proc/net/unix`]),r=[];for(let e of n.split(/\r?\n/)){let t=e.trim();if(t.includes(`@webview_devtools_remote`)){let e=t.match(/@webview_devtools_remote\S+/);e&&r.push(e[0])}}return r}function m(e){return e.trim().replace(/\/+$/,``)}function h(e,t,n){let r=new Set;for(let i of[/nativeLibraryDir=([^\s]+)/g,/legacyNativeLibraryDir=([^\s]+)/g,/secondaryNativeLibraryDir=([^\s]+)/g]){let a;for(;(a=i.exec(e))!==null;){let e=m(a[1]??``);e&&(!n&&!e.includes(t)||r.add(e))}}return[...r]}var g=class{cachedAdb;async resolveAdb(){if(this.cachedAdb)return this.cachedAdb;let e=await n(`adb`);if(!e.available)throw new t(`PREREQUISITE`,e.reason??`adb not found in PATH. Install Android Platform Tools.`,{toolName:`adb-bridge`});return this.cachedAdb=e.path??`adb`,this.cachedAdb}async run(n,r){try{return e(await r())}catch(e){throw e instanceof t?e:new t(`RUNTIME`,u(e),{toolName:n})}}async handleDeviceList(e){return this.run(`adb_device_list`,async()=>{let{stdout:e}=await f(await this.resolveAdb(),[`devices`,`-l`]),t=[];for(let n of e.split(/\r?\n/)){let e=n.trim();if(!e||e.startsWith(`List of devices`))continue;let r=e.split(/\s+/),i=r[0];if(!i)continue;let a={};for(let e=2;e<r.length;e++){let t=r[e];if(!t)continue;let n=t.indexOf(`:`);if(n>0){let e=t.slice(0,n),r=t.slice(n+1);e&&r&&(a[e]=r)}}t.push({serial:i,state:r[1]??``,model:a.model??``,product:a.product??``})}return{success:!0,count:t.length,devices:t}})}async handleShell(e){return this.run(`adb_shell`,async()=>{let t=a(e,`serial`),n=a(e,`command`),{stdout:r,stderr:i}=await f(await this.resolveAdb(),[...d(t),`shell`,n]);return{success:!0,serial:t,command:n,stdout:r,stderr:i||``}})}async handleApkPull(e){return this.run(`adb_apk_pull`,async()=>{let t=a(e,`serial`),n=r(e,`packageName`),i=r(e,`outputPath`)??`.`;if(!n)return{success:!1,error:`packageName is required`};let o=await this.resolveAdb(),{stdout:c}=await f(o,[...d(t),`shell`,`pm path ${n}`]),l=c.match(/package:([\w./]+)/)?.[1];if(!l)return{success:!1,error:`APK not found for ${n}`,raw:c};let u=s(i,`${n}.apk`).replace(/\\/g,`/`);return await f(o,[...d(t),`pull`,l,u]),{success:!0,serial:t,packageName:n,remotePath:l,localPath:u}})}async handleAnalyzeApk(e){return this.run(`adb_apk_analyze`,async()=>{let t=a(e,`serial`),n=a(e,`packageName`),{stdout:r}=await f(await this.resolveAdb(),[...d(t),`shell`,`dumpsys package ${n}`]),i={packageName:n},o=r.match(/versionName=([^\s]+)/);o?.[1]&&(i.versionName=o[1]);let s=r.match(/versionCode=(\d+)/);s?.[1]&&(i.versionCode=s[1]);let c=r.match(/minSdk=(\d+)/);c?.[1]&&(i.minSdk=c[1]);let l=r.match(/targetSdk=(\d+)/);l?.[1]&&(i.targetSdk=l[1]);let u=[],p=[],m=[],h=[],g=``;for(let e of r.split(/\r?\n/)){if(e.includes(`requested permissions:`)||e.includes(`install permissions:`)){g=`permissions`;continue}if(e.includes(`Activity Resolver Table`)||e.includes(`activities:`)){g=`activities`;continue}if(e.includes(`Service Resolver Table`)||e.includes(`services:`)){g=`services`;continue}if(e.includes(`Receiver Resolver Table`)||e.includes(`receivers:`)){g=`receivers`;continue}let t=e.trim(),r=t.split(` `)[0];g===`permissions`?r&&t.startsWith(`android.permission.`)&&u.push(r):g===`activities`&&t.includes(n)?r&&p.push(r):g===`services`&&t.includes(n)?r&&m.push(r):g===`receivers`&&t.includes(n)&&r&&h.push(r)}return i.permissions=[...new Set(u)],i.activities=[...new Set(p)],i.services=[...new Set(m)],i.receivers=[...new Set(h)],{success:!0,serial:t,...i}})}async handlePullNativeLibs(e){return this.run(`adb_pull_native_libs`,async()=>{let t=a(e,`serial`),n=a(e,`packageName`),i=r(e,`outputPath`)??`.`,l=o(e,`includeSystemLibs`)??!1,u=await this.resolveAdb(),{stdout:p}=await f(u,[...d(t),`shell`,`dumpsys package ${n}`]),m=h(p,n,l);if(m.length===0)return{success:!1,serial:t,packageName:n,error:`No native library directories found for ${n}`};let g=s(i,`${n}-native-libs`).replace(/\\/g,`/`);await c(g,{recursive:!0});let _=[];for(let e of m){let n=s(g,e.split(`/`).filter(Boolean).pop()??`lib`).replace(/\\/g,`/`);await c(n,{recursive:!0}),await f(u,[...d(t),`pull`,e,n]),_.push({remoteDir:e,localPath:n})}return{success:!0,serial:t,packageName:n,includeSystemLibs:l,count:_.length,outputPath:g,libraries:_}})}async handleWebViewList(e){return this.run(`adb_webview_list`,async()=>{let t=a(e,`serial`),n=i(e,`hostPort`)??9222,r=await this.resolveAdb(),o=await p(r,t);if(o.length===0)return{success:!0,serial:t,hostPort:n,webviews:[],count:0};let s=o[0];await f(r,[...d(t),`forward`,`tcp:${n}`,`localabstract:${s}`]);let c=await import(`node:http`),l=await new Promise(e=>{c.get(`http://localhost:${n}/json/list`,t=>{let n=``;t.on(`data`,e=>{n+=e}),t.on(`end`,()=>{try{e(JSON.parse(n))}catch{e([])}})}).on(`error`,()=>e([]))});return{success:!0,serial:t,hostPort:n,webviews:l.map(e=>({id:e.id,url:e.url,title:e.title,webSocketDebuggerUrl:e.webSocketDebuggerUrl})),count:l.length}})}async handleWebViewAttach(e){return this.run(`adb_webview_attach`,async()=>{let t=a(e,`serial`),n=a(e,`targetId`),r=i(e,`hostPort`)??9222,o=await this.resolveAdb(),s=await p(o,t);if(s.length===0)return{success:!1,error:`No WebView devtools sockets found on device`};let c=s[0];await f(o,[...d(t),`forward`,`tcp:${r}`,`localabstract:${c}`]);let l=await import(`node:http`),u=await new Promise(e=>{l.get(`http://localhost:${r}/json`,t=>{let r=``;t.on(`data`,e=>{r+=e}),t.on(`end`,()=>{try{e(JSON.parse(r).find(e=>e.id===n)?.webSocketDebuggerUrl)}catch{e(void 0)}})}).on(`error`,()=>e(void 0))});return u?{success:!0,serial:t,targetId:n,hostPort:r,webSocketDebuggerUrl:u,attached:!0}:{success:!1,error:`Target ${n} not found`}})}};export{g as ADBBridgeHandlers};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-sBC6IdRT.mjs";import{It as t,Lt as n}from"./constants-BYj8Xek8.mjs";import{i as r}from"./outputPaths-B4Ic4RZh.mjs";import{n as i}from"./WorkflowEngine-D876meOO.mjs";import{extname as a,resolve as o}from"node:path";import{readFile as s,readdir as c}from"node:fs/promises";function l(e){return`kind`in e?e:e.build()}function u(e,t){return t?.(e),e}function d(e,t){let n={},r,i,a,o;return n.input=e=>(r=e,n),n.inputFrom=e=>(i=e,n),n.retry=e=>(a=e,n),n.timeout=e=>(o=e,n),n.build=()=>({kind:`tool`,id:e,toolName:t,input:r,inputFrom:i,retry:a,timeoutMs:o}),n}function f(e,t){return t?typeof t==`function`?(t(e),e):(t.input&&e.input(t.input),t.inputFrom&&e.inputFrom(t.inputFrom),t.retry&&e.retry(t.retry),t.timeoutMs!==void 0&&e.timeout(t.timeoutMs),e):e}function p(e,t){return e.step=n=>(t.push(n),e),e.tool=(n,r,i)=>(t.push(f(d(n,r),i)),e),e.sequence=(n,r)=>(t.push(u(m(n),r)),e),e.parallel=(n,r)=>(t.push(u(h(n),r)),e),e.branch=(n,r,i)=>(t.push(u(g(n,r),i)),e),e.fallback=(n,r)=>(t.push(u(_(n),r)),e),e}function m(e){let t=[],n=p({},t);return n.build=()=>({kind:`sequence`,id:e,steps:t.map(l)}),n}function h(e){let t=[],n=p({},t),r=4,i=!1;return n.maxConcurrency=e=>(r=e,n),n.failFast=e=>(i=e,n),n.build=()=>({kind:`parallel`,id:e,steps:t.map(l),maxConcurrency:r,failFast:i}),n}function g(e,t){let n={},r,i,a;return n.predicateFn=e=>(r=e,n),n.whenTrue=e=>(i=e,n),n.whenFalse=e=>(a=e,n),n.build=()=>{if(!i)throw Error(`BranchNode '${e}' requires a whenTrue step`);return{kind:`branch`,id:e,predicateId:t,predicateFn:r,whenTrue:l(i),whenFalse:a?l(a):void 0}},n}function _(e){let t={},n,r;return t.primary=e=>(n=e,t),t.fallback=e=>(r=e,t),t.build=()=>{if(!n)throw Error(`FallbackNode '${e}' requires a primary step`);if(!r)throw Error(`FallbackNode '${e}' requires a fallback step`);return{kind:`fallback`,id:e,primary:l(n),fallback:l(r)}},t}function v(e,t){let n={},r,i,a,o,s,c,l,u,d;return n.description=e=>(r=e,n),n.tags=e=>(i=e,n),n.timeoutMs=e=>(a=e,n),n.defaultMaxConcurrency=e=>(o=e,n),n.route=e=>(s=e,n),n.buildGraph=e=>(c=e,n),n.onStart=e=>(l=e,n),n.onFinish=e=>(u=e,n),n.onError=e=>(d=e,n),n.build=()=>{if(!c)throw Error(`Workflow '${e}' needs a buildGraph() function.`);return{kind:`workflow-contract`,version:1,id:e,displayName:t,description:r,tags:i,timeoutMs:a,defaultMaxConcurrency:o,route:s,build:c,onStart:l,onFinish:u,onError:d}},n}function y(e,t,n){let r=v(e,t);return n(r),r.build()}function b(e,t,n){return f(d(e,t),n).build()}function x(e,t){return u(m(e),t).build()}var S=class{ctx;constructor(e){this.ctx=e}buildWorkflowFromDefinition(e){return y(e.id,e.displayName,t=>t.description(e.description).tags(e.tags).timeoutMs(e.timeoutMs??n).buildGraph(()=>x(`${e.id}-root`,t=>{for(let n of e.steps)t.step(b(n.id,n.toolName,e=>{e.input(n.input??{}).timeout(n.timeoutMs??0),n.inputFrom&&e.inputFrom(n.inputFrom)}))})).onStart(t=>{t.emitSpan(`macro.start`,{macroId:e.id,totalSteps:e.steps.length})}).onError((t,n)=>{t.emitSpan(`macro.error`,{macroId:e.id,error:n.message})}))}async execute(e,t){let n=this.buildWorkflowFromDefinition(e),r=Date.now();try{let r=await i(this.ctx,n,{nodeInputOverrides:t}),a=this.buildProgress(e,r.spans,r.stepResults);return{macroId:e.id,displayName:e.displayName,ok:!0,durationMs:r.durationMs,stepsCompleted:e.steps.length,totalSteps:e.steps.length,stepResults:r.stepResults,progress:a}}catch(t){let n=Date.now()-r,i=t instanceof Error?t.message:String(t),a=this.buildPartialProgress(e,i);return{macroId:e.id,displayName:e.displayName,ok:!1,durationMs:n,stepsCompleted:a.filter(e=>e.status===`complete`).length,totalSteps:e.steps.length,stepResults:{},progress:a,error:i}}}formatProgressReport(e){let t=[];t.push(`**Macro:** ${e.displayName} (\`${e.macroId}\`)`),t.push(``);for(let n of e.progress){let e=n.durationMs===void 0?``:` (${n.durationMs}ms)`,r=n.error?`: ${n.error}`:``,i=n.status===`complete`?`✓`:n.status===`failed`?`✗`:`○`;t.push(`[stage ${n.step}/${n.totalSteps}] ${i} ${n.stepName} — ${n.status}${e}${r}`)}return t.push(``),e.ok?t.push(`✓ Macro complete (${e.stepsCompleted}/${e.totalSteps} steps, ${e.durationMs}ms)`):t.push(`✗ Macro failed at step ${e.stepsCompleted+1}/${e.totalSteps}: ${e.error??`unknown error`}`),t.join(`
|
|
2
|
-
`)}buildProgress(e,t,n){return e.steps.map((r,i)=>{let a=t.find(e=>e.name===`workflow.node.start`&&e.attrs?.nodeId===r.id),o=t.find(e=>e.name===`workflow.node.finish`&&e.attrs?.nodeId===r.id),s;a&&o&&(s=new Date(o.at).getTime()-new Date(a.at).getTime());let c=r.id in n;return{step:i+1,totalSteps:e.steps.length,stepName:r.id,status:c?`complete`:`skipped`,durationMs:s}})}buildPartialProgress(e,t){return e.steps.map((n,r)=>({step:r+1,totalSteps:e.steps.length,stepName:n.id,status:`failed`,error:r===0?t:void 0}))}};async function C(t){let n;try{n=await c(t)}catch{return[]}let r=n.filter(e=>a(e)===`.json`),i=[];for(let n of r){let r=o(t,n);try{let t=JSON.parse(await s(r,`utf-8`));w(t)?(i.push(T(t)),e.info(`[macros] Loaded user macro "${t.id}" from ${n}`)):e.warn(`[macros] Skipping ${n}: invalid macro schema`)}catch(t){e.warn(`[macros] Skipping ${n}: ${t instanceof Error?t.message:String(t)}`)}}return i}function w(e){if(!e||typeof e!=`object`)return!1;let t=e;if(typeof t.id!=`string`||!t.id||typeof t.displayName!=`string`||!t.displayName||!Array.isArray(t.steps)||t.steps.length===0)return!1;for(let e of t.steps){if(!e||typeof e!=`object`)return!1;let t=e;if(typeof t.id!=`string`||!t.id||typeof t.toolName!=`string`||!t.toolName)return!1}return!0}function T(e){return{id:e.id,displayName:e.displayName,description:e.description??``,tags:e.tags??[],timeoutMs:e.timeoutMs,steps:e.steps.map(e=>({id:e.id,toolName:e.toolName,input:e.input,inputFrom:e.inputFrom,timeoutMs:e.timeoutMs,optional:e.optional}))}}const E={loadFromDirectory:C,validate:w},D=[{id:`deobfuscate_ast_flow`,displayName:`Deobfuscate AST Flow`,description:`Chain: deobfuscate → optional webcrack unpack → semantic analysis`,tags:[`analysis`,`deobfuscation`,`ast`],timeoutMs:t,steps:[{id:`deobfuscate`,toolName:`deobfuscate`,input:{}},{id:`advanced_deobfuscate`,toolName:`webcrack_unpack`,input:{unpack:!0,unminify:!0},inputFrom:{code:`deobfuscate.code`},optional:!0},{id:`analyze_deobfuscated`,toolName:`understand_code`,inputFrom:{code:`deobfuscate.code`}}]},{id:`unpacker_flow`,displayName:`Unpacker Flow`,description:`Detect packer type → extract inner code → optional deep unpack → normalize output`,tags:[`analysis`,`unpacking`,`deobfuscation`],timeoutMs:9e4,steps:[{id:`detect_and_unpack`,toolName:`deobfuscate`,input:{unpack:!0}},{id:`deep_deobfuscate`,toolName:`webcrack_unpack`,input:{unpack:!0,unminify:!0},inputFrom:{code:`detect_and_unpack.code`},optional:!0},{id:`normalize_output`,toolName:`ast_transform_apply`,input:{transforms:[`dead_code_remove`,`rename_vars`]},inputFrom:{code:`detect_and_unpack.code`}}]}];var O=class{runner;macros=null;constructor(e){this.runner=new S(e)}async ensureMacrosLoaded(){if(this.macros)return this.macros;this.macros=new Map;for(let e of D)this.macros.set(e.id,e);try{let e=await E.loadFromDirectory(o(r(),`macros`));for(let t of e)this.macros.set(t.id,t)}catch{}return this.macros}async handleRunMacro(e){let t=e.macroId,n=e.inputOverrides;if(!t||typeof t!=`string`)return{content:[{type:`text`,text:JSON.stringify({ok:!1,error:`macroId parameter is required`})}]};let r=await this.ensureMacrosLoaded(),i=r.get(t);if(!i)return{content:[{type:`text`,text:JSON.stringify({ok:!1,error:`Macro "${t}" not found`,available:Array.from(r.keys())})}]};let a=await this.runner.execute(i,n);return{content:[{type:`text`,text:this.runner.formatProgressReport(a)}]}}async handleListMacros(){let e=await this.ensureMacrosLoaded(),t=Array.from(e.values()).map(e=>({id:e.id,displayName:e.displayName,description:e.description,tags:e.tags,stepCount:e.steps.length}));return{content:[{type:`text`,text:JSON.stringify({macros:t,count:t.length})}]}}};export{O as MacroToolHandlers};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ni as e}from"./constants-BYj8Xek8.mjs";import{t}from"./ToolProbe-C7ZU2x7M.mjs";import{a as n,c as r,i,n as a,o,r as s,s as c}from"./binary-instrument-DU7V6TUM.mjs";import{n as l,t as u}from"./capabilities-CyXuKUl1.mjs";import{tmpdir as d}from"node:os";import{join as f,relative as p}from"node:path";import{access as m,mkdir as h,mkdtemp as g,readFile as _,readdir as v,rm as y}from"node:fs/promises";import{execFile as b}from"node:child_process";import{open as x}from"yauzl";const S={plugin_frida_bridge:`Install @jshookmcpextension/plugin-frida-bridge and reload extensions.`,plugin_ghidra_bridge:`Install @jshookmcpextension/plugin-ghidra-bridge and reload extensions.`,plugin_ida_bridge:`Install @jshookmcpextension/plugin-ida-bridge and reload extensions.`,plugin_jadx_bridge:`Install @jshookmcpextension/plugin-jadx-bridge and reload extensions.`};function C(e){return{content:[{type:`text`,text:e}]}}function w(e){return C(JSON.stringify(e))}function T(e,t){let n=e[t];if(typeof n!=`string`||n.trim().length===0)throw Error(`${t} is required`);return n.trim()}function E(e,t){let n=e[t];return typeof n==`string`&&n.trim().length>0?n.trim():void 0}function D(e,t){let n=e[t];return typeof n==`number`&&Number.isFinite(n)?n:void 0}function O(e,t){let n=e[t];return typeof n==`boolean`?n:void 0}function k(e,t){let n=e[t];return Array.isArray(n)?n.filter(e=>typeof e==`string`&&e.length>0):[]}function A(e){return typeof e==`object`&&!!e}function j(e){return A(e)&&e.extensionPluginsById instanceof Map&&e.extensionPluginRuntimeById instanceof Map}function M(e,t){if(!e)return;let n=e.extensionPluginsById;if(n instanceof Map)return n.has(t)}function N(e){return S[e]}function P(e,t){let n=M(e,t);return n===!0?{status:`available`,fix:N(t)}:n===!1?{status:`unavailable`,reason:`Plugin ${t.replaceAll(`_`,`-`)} is not installed`,fix:N(t)}:{status:`unknown`,reason:`Extension plugin registry is not available in the current server context`,fix:`Run inside the full MCP server with extension support enabled.`}}async function F(e,t,r,i){let a=P(e,t);if(!e||a.status!==`available`)return w({...u(r,t,a.reason??`Plugin ${t.replaceAll(`_`,`-`)} is not available`,a.fix),status:a.status});let o=await n(e,{pluginId:t,toolName:r,args:i});return o.success?w(o):w({...u(r,t,o.error??`Plugin invocation failed`,a.fix)})}function I(e,t){let n=e[t];if(!A(n))return;let r={},i=n.includeArgs,a=n.includeRetAddr;return typeof i==`boolean`&&(r.includeArgs=i),typeof a==`boolean`&&(r.includeRetAddr=a),r}function L(e){if(!/^\d+$/.test(e))return null;let t=Number.parseInt(e,10);return Number.isNaN(t)?null:t}function R(e){return e.toLowerCase().replace(/[^a-z0-9]+/g,`-`).replace(/^-+|-+$/g,``).slice(0,24)}async function z(){let e=process.env.UNIDBG_JAR??``;if(e.length===0)return{available:!1,reason:`UNIDBG_JAR is not configured`,command:`java`,jarPath:``};try{await m(e)}catch{return{available:!1,reason:`UNIDBG_JAR not found: ${e}`,command:`java`,jarPath:e}}return{available:!0,reason:``,command:`java`,jarPath:e}}function B(e,t,n){return new Promise((r,i)=>{b(e,t,{timeout:n,windowsHide:!0,maxBuffer:8388608,encoding:`utf8`},(e,t,n)=>{if(e){i(e);return}r({stdout:typeof t==`string`?t:``,stderr:typeof n==`string`?n:``})})})}function V(e){return A(e)&&Array.isArray(e.functions)&&Array.isArray(e.imports)}function H(e){let t=[];for(let n of e){if(!A(n))continue;let e=U(n,`functionName`),r=U(n,`hookCode`),i=U(n,`description`),a=W(n.parameters);!e||!r||!i||t.push({functionName:e,hookCode:r,description:i,parameters:a})}return t}function U(e,t){let n=e[t];return typeof n==`string`?n:void 0}function W(e){if(!Array.isArray(e))return[];let t=[];for(let n of e){if(!A(n))continue;let e=U(n,`name`),r=U(n,`type`),i=U(n,`description`);e&&r&&i&&t.push({name:e,type:r,description:i})}return t}var G=class{state;constructor(e){this.state=e}async handleFridaAttach(e){let t=E(e,`pid`);if(!E(e,`target`)&&t)return F(this.state.context,`plugin_frida_bridge`,`frida_attach`,e);let n=T(e,`target`),r=this.getFridaSession(),i=await r.getAvailability();if(!i.available){let e=`mock-frida-${R(n)}`;return w({success:!1,available:!1,capability:`frida_cli`,fix:`Install frida-tools and ensure the frida CLI is on PATH.`,target:n,sessionId:e,reason:i.reason??`Frida CLI is not available`,sessions:[{id:e,target:n,pid:L(n),status:`unavailable`}]})}let a;try{a=await r.attach(n)}catch(e){return w({success:!1,available:!0,capability:`frida_attach`,fix:`Run the server elevated or choose a target process that allows Frida injection.`,target:n,reason:e instanceof Error?e.message:String(e),sessions:r.listSessions()})}return this.state.context?.eventBus.emit(`frida:attached`,{target:n,sessionId:a,timestamp:new Date().toISOString()}),w({success:!0,available:!0,target:n,sessionId:a,sessions:r.listSessions()})}async handleFridaEnumerateModules(e){let t=T(e,`sessionId`),n=this.getFridaSession(),r=await n.getAvailability();if(!r.available)return w({available:!1,capability:`frida_cli`,fix:`Install frida-tools and ensure the frida CLI is on PATH.`,sessionId:t,reason:r.reason??`Frida CLI is not available`,modules:[{name:`mock-module`,base:`0x0`,size:0,path:`<unavailable>`}]});if(!n.useSession(t))return w({available:!1,capability:`frida_session`,fix:`Call frida_attach first and reuse the returned sessionId.`,sessionId:t,reason:`Unknown Frida session: ${t}`,modules:[]});let i=await n.enumerateModules(),a=n.getSessionDiagnostics(t);return a?.status===`error`&&a.lastError?w({success:!1,available:!0,sessionId:t,reason:a.lastError,modules:i}):w({success:!0,available:!0,sessionId:t,modules:i})}async handleFridaRunScript(e){let t=E(e,`sessionId`);if(!t)return C(`Missing required string argument: sessionId`);let n=T(e,`script`),r=this.getFridaSession(),i=await r.getAvailability();if(!i.available)return{available:!1,capability:`frida_cli`,fix:`Install frida-tools and ensure the frida CLI is on PATH.`,sessionId:t,reason:i.reason??`Frida CLI is not available`,execution:{output:``,error:`Frida unavailable`}};if(!r.useSession(t))return{available:!1,capability:`frida_session`,fix:`Call frida_attach first and reuse the returned sessionId.`,sessionId:t,reason:`Unknown Frida session: ${t}`,execution:{output:``,error:`Unknown session`}};let a=await r.executeScript(n);return a.error?w({success:!1,available:!0,sessionId:t,reason:a.error,execution:a}):w({success:!0,available:!0,sessionId:t,execution:a})}async handleFridaDetach(e){let t=E(e,`sessionId`);if(!t)return C(`Missing required string argument: sessionId`);let n=this.getFridaSession();return(await n.getAvailability()).available&&n.hasSession(t)?(n.useSession(t),await n.detach(),w({success:!0,sessionId:t,detached:!0})):F(this.state.context,`plugin_frida_bridge`,`frida_detach`,e)}async handleFridaListSessions(e){let t=this.getFridaSession(),n=await t.getAvailability(),r=t.listSessions();if(n.available)return w({success:!0,available:!0,sessions:r,count:r.length});let i=P(this.state.context,`plugin_frida_bridge`);return r.length>0||i.status===`unavailable`?w({success:!0,available:!1,capability:`frida_cli`,reason:n.reason??`Frida CLI is not available`,fix:`Install frida-tools and ensure the frida CLI is on PATH.`,sessions:r,count:r.length}):F(this.state.context,`plugin_frida_bridge`,`frida_list_sessions`,e)}async handleFridaGenerateScript(e){let t=E(e,`target`)??`unknown`,n=E(e,`template`)??`trace`,r=E(e,`functionName`)??`target_function`,i=[{functionName:r,hookCode:`console.log('[${n}] ${r} called');`,description:`${n} hook for ${r}`,parameters:[]}];return w({success:!0,target:t,template:n,functionName:r,script:this.state.hookCodeGenerator.exportScript(i,`frida`)})}async handleFridaEnumerateFunctions(e){let t=T(e,`sessionId`),n=T(e,`moduleName`),r=this.getFridaSession(),i=await r.getAvailability();if(!i.available)return{available:!1,capability:`frida_cli`,fix:`Install frida-tools and ensure the frida CLI is on PATH.`,sessionId:t,moduleName:n,reason:i.reason??`Frida CLI is not available`,functions:[]};if(!r.useSession(t))return{available:!1,capability:`frida_session`,fix:`Call frida_attach first and reuse the returned sessionId.`,sessionId:t,reason:`Unknown Frida session: ${t}`,functions:[]};let a=await r.enumerateFunctions(n),o=r.getSessionDiagnostics(t);return o?.status===`error`&&o.lastError?w({success:!1,available:!0,sessionId:t,moduleName:n,reason:o.lastError,functions:a,count:a.length}):w({success:!0,available:!0,sessionId:t,moduleName:n,functions:a,count:a.length})}async handleFridaFindSymbols(e){let t=T(e,`sessionId`),n=T(e,`pattern`),r=this.getFridaSession(),i=await r.getAvailability();if(!i.available)return{available:!1,capability:`frida_cli`,fix:`Install frida-tools and ensure the frida CLI is on PATH.`,sessionId:t,pattern:n,reason:i.reason??`Frida CLI is not available`,symbols:[]};if(!r.useSession(t))return{available:!1,capability:`frida_session`,fix:`Call frida_attach first and reuse the returned sessionId.`,sessionId:t,reason:`Unknown Frida session: ${t}`,symbols:[]};let a=await r.findSymbols(n),o=r.getSessionDiagnostics(t);return o?.status===`error`&&o.lastError?w({success:!1,available:!0,sessionId:t,pattern:n,reason:o.lastError,symbols:a,count:a.length}):w({success:!0,available:!0,sessionId:t,pattern:n,symbols:a,count:a.length})}getFridaSession(){return this.state.fridaSession||(this.state.fridaSession=new r),this.state.fridaSession}},K=class{state;constructor(e){this.state=e}async handleGhidraAnalyze(e){let t=T(e,`binaryPath`),n=D(e,`timeout`),r=this.getGhidraAnalyzer(),i=await r.getAvailability(),a=await r.analyze(t,n===void 0?void 0:{timeout:n});return i.available?{available:!0,binaryPath:t,analysis:a}:{available:!1,capability:`ghidra_headless`,fix:`Install Ghidra and ensure analyzeHeadless is on PATH.`,binaryPath:t,reason:i.reason??`Ghidra analyzeHeadless is not available`,analysis:a}}async handleGhidraDecompile(e){return F(this.state.context,`plugin_ghidra_bridge`,`ghidra_decompile`,e)}async handleIdaDecompile(e){return F(this.state.context,`plugin_ida_bridge`,`ida_decompile`,e)}async handleJadxDecompile(e){let n=T(e,`apkPath`),r=T(e,`className`),i=E(e,`methodName`),a=await t(`jadx`,[`--version`]);return a.available?this.jadxNativeDecompile(a.path??`jadx`,n,r,i):F(this.state.context,`plugin_jadx_bridge`,`jadx_decompile`,e)}async handleApktoolDecode(e){let n=T(e,`apkPath`),r=E(e,`outputDir`),i=O(e,`force`)??!1,a=await t(`apktool`,[`--version`]);if(!a.available)return w({available:!1,capability:`apktool_cli`,fix:`Install apktool and ensure it is on PATH.`,apkPath:n,reason:a.reason??`apktool is not available`});let o=r??f(d(),`jshook-apktool-${Date.now()}`);r&&await h(o,{recursive:!0});try{let e=[`decode`,`--output`,o];i&&e.push(`--force`),e.push(n);let t=await B(a.path??`apktool`,e,12e4);return w({available:!0,apkPath:n,outputDir:o,force:i,stdout:t.stdout.trim(),stderr:t.stderr.trim()})}catch(e){return w({available:!0,apkPath:n,outputDir:o,force:i,error:e instanceof Error?e.message:String(e)})}}async handleApkManifestDump(e){let n=T(e,`apkPath`),r=await this.readZipEntryBuffer(n,`AndroidManifest.xml`);if(!r.success)return w({available:!1,apkPath:n,entry:`AndroidManifest.xml`,error:r.error});let i=this.decodeTextEntry(r.buffer);if(i!==null)return w({available:!0,apkPath:n,entry:`AndroidManifest.xml`,format:`xml`,decodedBy:`zip-entry`,manifest:i});let a=await t(`jadx`,[`--version`]);if(a.available){let e=await this.decodeManifestWithJadx(a.path??`jadx`,n);if(e.success)return w({available:!0,apkPath:n,entry:`AndroidManifest.xml`,format:`xml`,decodedBy:`jadx_cli`,manifest:e.manifest})}return w({available:!0,apkPath:n,entry:`AndroidManifest.xml`,format:`binary-axml`,decodedBy:`zip-entry`,size:r.buffer.length,manifestBase64:r.buffer.toString(`base64`)})}async handleApkNativeLibsList(e){let t=T(e,`apkPath`),n=await this.listZipEntries(t);if(!n.success)return w({available:!1,apkPath:t,error:n.error});let r=n.entries.filter(e=>/^lib\/.+\/[^/]+\.so$/i.test(e)).map(e=>{let t=e.split(`/`);return{path:e,abi:t[1]??``,name:t[t.length-1]??``}});return w({available:!0,apkPath:t,count:r.length,libraries:r})}async handleGenerateHooks(e){let t=E(e,`ghidraOutput`);if(t)return this.handleLegacyGenerateHooks(t);let n=e.ghidraOutput;if(A(n))return this.handleLegacyGenerateHooks(JSON.stringify(n));let r=k(e,`symbols`);if(r.length===0)return C(`symbols or ghidraOutput is required`);let i=I(e,`options`),a=this.getHookGenerator().generateFridaHookScript(r,i);return w({available:!0,symbolCount:r.length,script:a})}async handleExportHookScript(e){let t=E(e,`hookTemplates`);if(!t){let e=this.state.hookCodeGenerator.exportScript([],`frida`);return w({format:`frida`,hookCount:0,script:e.includes(`Java.perform`)?e:`Java.perform(function() {\n${e}\n});`})}try{let e=JSON.parse(t);if(!Array.isArray(e))return C(`Invalid JSON`);let n=H(e),r=this.state.hookCodeGenerator.exportScript(n,`frida`);return w({format:`frida`,hookCount:n.length,script:r})}catch{return C(`Invalid JSON`)}}async handleUnidbgEmulate(t){let n=T(t,`binaryPath`),r=T(t,`functionName`),i=k(t,`args`),a=await z();if(!a.available)return{available:!1,capability:`unidbg_jar`,fix:`Set UNIDBG_JAR to a reachable Unidbg JAR path.`,binaryPath:n,functionName:r,args:i,reason:a.reason,result:{returnValue:`0x0`,stdout:``,stderr:``,trace:[`mock-unidbg-unavailable`]}};let o=await B(a.command,[`-jar`,a.jarPath,n,r,...i],e);return{available:!0,binaryPath:n,functionName:r,args:i,result:{returnValue:`0x0`,stdout:o.stdout.trim(),stderr:o.stderr.trim(),trace:[]}}}async handleUnidbgLaunch(e){let t=E(e,`soPath`);if(!t)return C(`Missing required string argument: soPath`);let n=E(e,`arch`)??`arm`;try{let e=await this.state.unidbgRunner.launch(t,n);return{available:!0,sessionId:e.sessionId,soPath:e.soPath,arch:e.arch,sessions:this.state.unidbgRunner.listSessions()}}catch(e){return{available:!1,capability:`unidbg_jar`,fix:`Set UNIDBG_JAR to a reachable Unidbg JAR path and retry.`,soPath:t,arch:n,reason:e instanceof Error?e.message:String(e),sessions:this.state.unidbgRunner.listSessions()}}}async handleUnidbgCall(e){let t=E(e,`sessionId`);if(!t)return C(`Missing required string argument: sessionId`);let n=E(e,`functionName`);if(!n)return C(`Missing required string argument: functionName`);let r=A(e.args)?e.args:{};try{return w(await this.state.unidbgRunner.callFunction(t,n,r))}catch(e){let t=e instanceof Error?e.message:String(e);return C(t.startsWith(`No unidbg session found`)?`${t} (not found)`:t)}}async handleUnidbgTrace(e){let t=E(e,`sessionId`);if(!t)return C(`Missing required string argument: sessionId`);try{return w(await this.state.unidbgRunner.trace(t))}catch(e){let t=e instanceof Error?e.message:String(e);return C(t.startsWith(`No unidbg session found`)?`${t} (not found)`:t)}}async handleGetAvailablePlugins(e){let t=this.state.context?i(this.state.context):[];return w({plugins:t,count:t.length})}getGhidraAnalyzer(){return this.state.ghidra||(this.state.ghidra=new c),this.state.ghidra}getHookGenerator(){return this.state.hookGen||(this.state.hookGen=new s),this.state.hookGen}handleLegacyGenerateHooks(e){let t;try{t=JSON.parse(e)}catch{return C(`Invalid JSON`)}if(!V(t))return C(`ghidraOutput is required`);let n=this.state.hookCodeGenerator.generateHooks(t);return w({count:n.length,hooks:n})}async listZipEntries(e){try{let t=await this.openZipFile(e);return{success:!0,entries:await new Promise((e,n)=>{let r=[],i=!1,a=e=>{r.push(e.fileName),t.readEntry()},o=()=>c(()=>e(r)),s=e=>c(()=>n(e)),c=e=>{i||(i=!0,t.removeListener(`entry`,a),t.removeListener(`end`,o),t.removeListener(`error`,s),e())};t.on(`entry`,a),t.on(`end`,o),t.on(`error`,s),t.readEntry()})}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}async readZipEntryBuffer(e,t){try{let n=await this.openZipFile(e);return{success:!0,buffer:await new Promise((e,r)=>{let i=!1,a=()=>{try{n.close()}catch{}},o=i=>{if(i.fileName!==t){n.readEntry();return}n.openReadStream(i,(n,i)=>{if(n||!i){l(()=>r(n??Error(`Unable to read ZIP entry: ${t}`))),a();return}this.readStreamToBuffer(i).then(t=>{l(()=>e(t)),a()}).catch(e=>{l(()=>r(e)),a()})})},s=()=>l(()=>r(Error(`ZIP entry not found: ${t}`))),c=e=>l(()=>r(e)),l=e=>{i||(i=!0,n.removeListener(`entry`,o),n.removeListener(`end`,s),n.removeListener(`error`,c),e())};n.on(`entry`,o),n.on(`end`,s),n.on(`error`,c),n.readEntry()})}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}}async jadxNativeDecompile(e,t,n,r){let i=await g(f(d(),`jshook-jadx-`));try{let a=[`--no-res`,`--no-debug-info`,`-d`,i,t];await this.runJadx(e,a);let o=f(i,`sources`),s=await this.resolveDecompiledClassFile(o,n);if(!s.success)return w({available:!0,apkPath:t,className:n,error:`Class file not found after decompilation: ${n}`,suggestions:s.suggestions});let c;try{c=await _(s.classFile,`utf8`)}catch{return w({available:!0,apkPath:t,className:n,...s.resolvedClassName===n?{}:{resolvedClassName:s.resolvedClassName},error:`Class file not found after decompilation: ${n}`})}if(r){let e=this.extractMethodSource(c,r);return w(e?{available:!0,apkPath:t,className:n,...s.resolvedClassName===n?{}:{resolvedClassName:s.resolvedClassName},methodName:r,source:e}:{available:!0,apkPath:t,className:n,...s.resolvedClassName===n?{}:{resolvedClassName:s.resolvedClassName},methodName:r,source:``,error:`Method ${r} not found in ${n}`})}return w({available:!0,apkPath:t,className:n,...s.resolvedClassName===n?{}:{resolvedClassName:s.resolvedClassName},source:c})}catch(e){return w({available:!0,apkPath:t,className:n,error:e instanceof Error?e.message:String(e)})}finally{await y(i,{recursive:!0,force:!0})}}openZipFile(e){return new Promise((t,n)=>{x(e,{autoClose:!0,lazyEntries:!0,decodeStrings:!0,validateEntrySizes:!0,strictFileNames:!1},(r,i)=>{if(r||!i){n(r??Error(`Unable to open ZIP archive: ${e}`));return}t(i)})})}readStreamToBuffer(e){return new Promise((t,n)=>{let r=[];e.on(`data`,e=>{r.push(Buffer.isBuffer(e)?e:Buffer.from(e))}),e.on(`end`,()=>t(Buffer.concat(r))),e.on(`error`,n)})}decodeTextEntry(e){if(e.length===0)return``;let t=e.subarray(0,Math.min(e.length,1024)),n=0;for(let e of t){if(e===0)return null;(e<9||e>13&&e<32)&&(n+=1)}if(n>t.length*.1)return null;let r=e.toString(`utf8`);return r.trimStart().startsWith(`<`)?r:null}async decodeManifestWithJadx(e,t){let n=await g(f(d(),`jshook-jadx-manifest-`));try{await this.runJadx(e,[`--no-src`,`-d`,n,t]);let r=await _(f(n,`resources`,`AndroidManifest.xml`),`utf8`);return r.trimStart().startsWith(`<`)?{success:!0,manifest:r}:{success:!1,error:`Decoded manifest is not XML`}}catch(e){return{success:!1,error:e instanceof Error?e.message:String(e)}}finally{await y(n,{recursive:!0,force:!0})}}async runJadx(e,t){await new Promise((n,r)=>{b(e,t,{encoding:`utf8`,windowsHide:!0,timeout:12e4},e=>{if(e&&e.code!==1){r(e);return}n()})})}async resolveDecompiledClassFile(e,t){let n=this.buildExpectedClassFile(e,t);try{return await _(n,`utf8`),{success:!0,classFile:n,resolvedClassName:t}}catch{}let r=await this.findClassCandidates(e,t);if(r.length===0)return{success:!1,suggestions:[]};if(r.length===1){let e=r[0];return e?{success:!0,classFile:e.classFile,resolvedClassName:e.className}:{success:!1,suggestions:[]}}let i=r[0],a=r[1];return!i||!a?{success:!1,suggestions:r.slice(0,10).map(e=>e.className)}:i.score>a.score?{success:!0,classFile:i.classFile,resolvedClassName:i.className}:{success:!1,suggestions:r.slice(0,10).map(e=>e.className)}}buildExpectedClassFile(e,t){let n=t.split(`.`),r=(n[n.length-1]??``).split(`$`)[0]??``;return f(e,...n.slice(0,-1),`${r}.java`)}async findClassCandidates(e,t){let n=t.split(`.`),r=(n[n.length-1]??``).split(`$`)[0]??``,i=n.slice(0,-1),a=`${r}.java`,o=[],s=async t=>{let n=await v(t,{withFileTypes:!0});for(let r of n){let n=f(t,r.name);if(r.isDirectory()){await s(n);continue}if(!r.isFile()||r.name!==a)continue;let c=p(e,n).replace(/\\/g,`/`).replace(/\.java$/i,``).split(`/`).join(`.`),l=c.split(`.`).slice(0,-1);o.push({className:c,classFile:n,score:this.scoreClassCandidate(i,l)})}};return await s(e),o.toSorted((e,t)=>t.score-e.score||e.className.localeCompare(t.className))}scoreClassCandidate(e,t){let n=0,r=Math.min(e.length,t.length);for(;n<r&&e[n]===t[n];)n+=1;let i=0,a=Math.min(e.length,t.length);for(;i<a&&e[e.length-1-i]===t[t.length-1-i];)i+=1;return n*10+i}extractMethodSource(e,t){let n=RegExp(`(?:public|private|protected|static|final|abstract|synchronized|native)\\s+[\\w<>\\[\\]]+\\s+${t.replace(/[.*+?^${}()|[\]\\]/g,`\\$&`)}\\s*\\([^)]*\\)\\s*(?:throws[^{]*)?\\{`),r=e.search(n);if(r===-1)return null;let i=0,a=e.indexOf(`{`,r);for(;a<e.length;a++)if(e[a]===`{`)i+=1;else if(e[a]===`}`&&(--i,i===0))break;return e.slice(r,a+1)}},q=class{state;constructor(e){this.state=e}async handleBinaryInstrumentCapabilities(){let[e,n,r,i,a]=await Promise.all([this.getFridaSession().getAvailability(),this.getGhidraAnalyzer().getAvailability(),t(`jadx`,[`--version`]),t(`apktool`,[`--version`]),z()]);return w(l(`binary_instrument_capabilities`,[{capability:`frida_cli`,status:e.available?`available`:`unavailable`,reason:e.reason,fix:e.available?void 0:`Install frida-tools and ensure the frida CLI is on PATH.`,details:{tools:[`frida_attach`,`frida_enumerate_modules`,`frida_run_script`,`frida_enumerate_functions`,`frida_find_symbols`],...e.path?{path:e.path}:{},...e.version?{version:e.version}:{}}},{capability:`plugin_frida_bridge`,...P(this.state.context,`plugin_frida_bridge`),details:{tools:[`frida_attach`,`frida_detach`,`frida_list_sessions`]}},{capability:`ghidra_headless`,status:n.available?`available`:`unavailable`,reason:n.reason,fix:n.available?void 0:`Install Ghidra and ensure analyzeHeadless is on PATH.`,details:{tools:[`ghidra_analyze`],...n.path?{path:n.path}:{},...n.version?{version:n.version}:{}}},{capability:`plugin_ghidra_bridge`,...P(this.state.context,`plugin_ghidra_bridge`),details:{tools:[`ghidra_decompile`]}},{capability:`plugin_ida_bridge`,...P(this.state.context,`plugin_ida_bridge`),details:{tools:[`ida_decompile`]}},{capability:`jadx_cli`,status:r.available?`available`:`unavailable`,reason:r.reason,fix:r.available?void 0:`Install JADX and ensure the jadx CLI is on PATH.`,details:{tools:[`jadx_decompile`],...r.path?{path:r.path}:{},...r.version?{version:r.version}:{}}},{capability:`plugin_jadx_bridge`,...P(this.state.context,`plugin_jadx_bridge`),details:{tools:[`jadx_decompile`]}},{capability:`apktool_cli`,status:i.available?`available`:`unavailable`,reason:i.reason,fix:i.available?void 0:`Install apktool and ensure it is on PATH.`,details:{tools:[`apktool_decode`],...i.path?{path:i.path}:{},...i.version?{version:i.version}:{}}},{capability:`unidbg_jar`,status:a.available?`available`:`unavailable`,reason:a.reason||void 0,fix:a.available?void 0:`Set UNIDBG_JAR to a reachable Unidbg JAR path.`,details:{tools:[`unidbg_emulate`,`unidbg_launch`,`unidbg_call`,`unidbg_trace`],command:a.command,jarPath:a.jarPath}}]))}getFridaSession(){return this.state.fridaSession||(this.state.fridaSession=new r),this.state.fridaSession}getGhidraAnalyzer(){return this.state.ghidra||(this.state.ghidra=new c),this.state.ghidra}},J=class{state;frida;analysis;capabilities;constructor(e,t,n){this.state={hookCodeGenerator:new o,unidbgRunner:new a},e instanceof r?this.state.fridaSession=e:j(e)&&(this.state.context=e),t&&(this.state.ghidra=t),n&&(this.state.hookGen=n),this.frida=new G(this.state),this.analysis=new K(this.state),this.capabilities=new q(this.state)}handleBinaryInstrumentCapabilities(){return this.capabilities.handleBinaryInstrumentCapabilities()}handleFridaAttach(e){return this.frida.handleFridaAttach(e)}handleFridaEnumerateModules(e){return this.frida.handleFridaEnumerateModules(e)}handleFridaRunScript(e){return this.frida.handleFridaRunScript(e)}handleFridaDetach(e){return this.frida.handleFridaDetach(e)}handleFridaListSessions(e){return this.frida.handleFridaListSessions(e)}handleFridaGenerateScript(e){return this.frida.handleFridaGenerateScript(e)}handleFridaEnumerateFunctions(e){return this.frida.handleFridaEnumerateFunctions(e)}handleFridaFindSymbols(e){return this.frida.handleFridaFindSymbols(e)}handleGhidraAnalyze(e){return this.analysis.handleGhidraAnalyze(e)}handleGhidraDecompile(e){return this.analysis.handleGhidraDecompile(e)}handleIdaDecompile(e){return this.analysis.handleIdaDecompile(e)}handleJadxDecompile(e){return this.analysis.handleJadxDecompile(e)}handleApktoolDecode(e){return this.analysis.handleApktoolDecode(e)}handleApkManifestDump(e){return this.analysis.handleApkManifestDump(e)}handleApkNativeLibsList(e){return this.analysis.handleApkNativeLibsList(e)}handleGenerateHooks(e){return this.analysis.handleGenerateHooks(e)}handleExportHookScript(e){return this.analysis.handleExportHookScript(e)}handleUnidbgEmulate(e){return this.analysis.handleUnidbgEmulate(e)}handleUnidbgLaunch(e){return this.analysis.handleUnidbgLaunch(e)}handleUnidbgCall(e){return this.analysis.handleUnidbgCall(e)}handleUnidbgTrace(e){return this.analysis.handleUnidbgTrace(e)}handleGetAvailablePlugins(e){return this.analysis.handleGetAvailablePlugins(e)}};export{J as BinaryInstrumentHandlers};
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{n as e}from"./response-C7rKQst4.mjs";import{a as t,t as n}from"./parse-args-Bw413PlW.mjs";function r(e){return e.toLowerCase().replace(/[^a-z0-9]/g,``)}function i(e,t){let n=r(e),i=r(t);return n===i&&n.length>0?1:n.length===0||i.length===0?0:n.includes(i)||i.includes(n)?.8:0}function a(e,t){let n=0,r;for(let a of t){let t=i(e,a.name);t>n&&(n=t,r={objectId:a.objectId,name:a.name,score:t});for(let t of a.stringProps){let o=i(e,t);o>n&&(n=o,r={objectId:a.objectId,name:a.name,score:o})}}if(r&&n>=.5)return r}function o(e,t){let n=[],r=[],i=[],o=new Set,s=[];for(let e of t.sceneTree.layers)s.push({id:e.id,label:e.label,heapObjectId:e.heapObjectId});for(let e of t.sceneTree.drawCommands)s.push({id:e.id,label:e.label});let c=s.length;for(let c of s){let s=e.addCanvasNode({nodeId:c.id,label:c.label});if(n.push(s.id),c.heapObjectId){let i=t.jsObjects.find(e=>e.objectId===c.heapObjectId);if(i){let t=e.addV8Object({address:c.heapObjectId,name:i.name});n.push(t.id),e.getGraph().addEdge(t.id,s.id,`canvas-rendered-by`,{domain:`cross-domain`,matchScore:1}),r.push({skiaNodeId:c.id,matchedObjectId:i.objectId,matchedObjectName:i.name,matchScore:1}),o.add(c.id);continue}}let l=a(c.label,t.jsObjects);if(l){let t=e.addV8Object({address:l.objectId,name:l.name});n.push(t.id),e.getGraph().addEdge(t.id,s.id,`canvas-rendered-by`,{domain:`cross-domain`,matchScore:l.score}),r.push({skiaNodeId:c.id,matchedObjectId:l.objectId,matchedObjectName:l.name,matchScore:l.score}),o.add(c.id)}else i.push(c.id)}return{skiaNodes:c,correlations:r,unmatchedSkiaNodes:i,confidence:c===0?0:r.length/c,graphNodeIds:n}}const s=[{mojoPattern:/URLLoader/i,cdpPattern:/Network\./i},{mojoPattern:/WebSocket/i,cdpPattern:/Network\.webSocket/i},{mojoPattern:/Fetch/i,cdpPattern:/Fetch\./i}];function c(e,t,n,r){let i=[],a=[],o=new Set,c=new Map;for(let t of r){let{node:n}=e.addNetworkRequest({requestId:t.requestId,url:t.url});c.set(t.requestId,n.id),i.push(n.id)}if(t.length===0)return{mojoMessages:0,matchedPairs:[],unmatchedMojo:[],confidence:0,graphNodeIds:i};let l=new Map;for(let n of t){let t=e.addMojoMessage({interface:n.interface,method:n.method,timestamp:n.timestamp});l.set(n.messageId,t.id),i.push(t.id)}for(let e of t)if(!o.has(e.messageId))for(let t of s){if(!t.mojoPattern.test(e.interface))continue;let r=n.find(n=>t.cdpPattern.test(n.eventType)&&!o.has(e.messageId));if(r){a.push({mojoMessageId:e.messageId,matchType:`interface`,cdpEventType:r.eventType}),o.add(e.messageId);break}}for(let n of t)if(!o.has(n.messageId)&&/URLLoader/i.test(n.interface)){let t=r.find(e=>Math.abs(e.timestamp-n.timestamp)<=50);if(t){let r=c.get(t.requestId),i=l.get(n.messageId);r&&i&&e.getGraph().addEdge(r,i,`mojo-routed-to`,{domain:`cross-domain`,relation:`network-request-correlates-to-mojo`,matchType:`urlloader`,timestampDelta:Math.abs(t.timestamp-n.timestamp)}),a.push({mojoMessageId:n.messageId,matchType:`urlloader`,networkRequestId:t.requestId,timestampDelta:Math.abs(t.timestamp-n.timestamp)}),o.add(n.messageId)}}for(let e of t){if(o.has(e.messageId))continue;let t=1/0,r;for(let i of n){let n=Math.abs(i.timestamp-e.timestamp);n<=50&&n<t&&(t=n,r=i)}r&&(a.push({mojoMessageId:e.messageId,matchType:`timestamp`,cdpEventType:r.eventType,timestampDelta:t}),o.add(e.messageId))}let u=t.filter(e=>!o.has(e.messageId)).map(e=>e.messageId),d=t.length===0?0:o.size/t.length;return{mojoMessages:t.length,matchedPairs:a,unmatchedMojo:u,confidence:d,graphNodeIds:i}}const l={NtReadFile:/read|fs[_.]read/i,NtWriteFile:/write|fs[_.]write/i,NtOpenFile:/open|fs[_.]open/i,NtCreateFile:/create|fs[_.]create/i,NtClose:/close|fs[_.]close/i,NtDeviceIoControlFile:/ioctl|device/i,NtQueryInformationFile:/stat|info|query/i,NtSetInformationFile:/set|chmod|chown/i};function u(e,t){let n=l[e];return n&&n.test(t)?`high`:/file|fs|read|write|open|close/i.test(t)?`medium`:`low`}function d(e,t,n){let r=[],i=[],a=[];if(t.length===0)return{syscalls:0,correlations:[],unmatchedSyscalls:[],correlationConfidence:0,graphNodeIds:[]};for(let o of t){let t=e.addSyscallEvent({pid:o.pid,tid:o.tid,syscallName:o.syscallName,timestamp:o.timestamp});r.push(t.id);let s=n.find(e=>e.threadId===o.tid&&e.timestamp===o.timestamp);if(s&&s.frames.length>0){let n=s.frames[0];if(n){let a=n.functionName,s=u(o.syscallName,a),c=e.addNode(`function`,a,{domain:`v8-inspector`,functionName:a,threadId:o.tid});r.push(c.id),e.getGraph().addEdge(c.id,t.id,`syscall-emitted-by`,{domain:`cross-domain`,confidence:s}),i.push({syscallName:o.syscallName,topJsFunction:a,threadId:o.tid,timestamp:o.timestamp,confidence:s})}else a.push({syscallName:o.syscallName,tid:o.tid})}else a.push({syscallName:o.syscallName,tid:o.tid})}let o=t.length===0?0:i.length/t.length;return{syscalls:t.length,correlations:i,unmatchedSyscalls:a,correlationConfidence:o,graphNodeIds:r}}const f=[/^native_/i,/^JS_/i,/^Java_/i];function p(e){return e.calledFrom&&e.calledFrom.length>0?!0:f.some(t=>t.test(e.name))}function m(e,t){let n=[];n.push(`// Binary-to-JS Hook Script`),n.push(`// Module: ${t}`),n.push(`// Generated at: ${new Date().toISOString()}`),n.push(``);for(let r of e){let e=r.moduleName||t;r.address?(n.push(`// Hook: ${r.name} at ${r.address} in ${e}`),n.push(`Interceptor.attach(Module.findBaseAddress('${e}').add(${r.address}), {`)):(n.push(`// Hook: ${r.name} in ${e}`),n.push(`Interceptor.attach(Module.findExportByName('${e}', '${r.name}'), {`)),n.push(` onEnter(args) {`),n.push(` console.log('[${r.name}] called with args:', args[0], args[1]);`),n.push(` },`),n.push(` onLeave(retval) {`),n.push(` console.log('[${r.name}] returned:', retval);`),n.push(` }`),n.push(`});`),n.push(``)}return n.push(`console.log('Binary-to-JS hook script loaded for ${t}');`),n.join(`
|
|
2
|
-
`)}function h(e,t,n){let r=[],i=[],a;if(n&&n.length>0){let e=new Set(n);a=t.functions.filter(t=>e.has(t.name))}else a=t.functions.filter(p);let o=m(a,t.moduleName);for(let n of a){let a=e.addBinarySymbol({moduleName:n.moduleName||t.moduleName,symbolName:n.name,address:n.address??`0x0`}),o=e.addNode(`breakpoint-hook`,`frida:${n.name}`,{domain:`binary-instrument`,hookType:`frida-interceptor`,functionName:n.name,moduleName:n.moduleName||t.moduleName});e.getGraph().addEdge(a.id,o.id,`binary-exports`,{domain:`cross-domain`,relation:`binary-to-frida-hook`}),r.push({binarySymbolNodeId:a.id,hookScriptNodeId:o.id,functionName:n.name}),i.push(n.name)}return{hookCount:a.length,generatedHookScript:o,injectedFunctions:i,evidenceGraphLinks:r}}function g(e){return typeof e==`object`&&!!e}function _(e){return Array.isArray(e)?e.filter(g):[]}function v(e,t=``){return typeof e==`string`?e:t}function y(e){return typeof e==`string`?e:void 0}function b(e,t=0){return typeof e==`number`?e:t}function x(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):[]}function S(e){return Array.isArray(e)?e.filter(e=>typeof e==`string`):void 0}function C(e){return g(e)?Object.fromEntries(Object.entries(e).filter(e=>typeof e[1]==`number`)):{}}function w(e){return g(e)?{layers:Array.isArray(e.layers)?e.layers:[],drawCommands:Array.isArray(e.drawCommands)?e.drawCommands:[]}:{layers:[],drawCommands:[]}}function T(e){return _(e).map(e=>({objectId:v(e.objectId),className:v(e.className),name:v(e.name),stringProps:x(e.stringProps),numericProps:C(e.numericProps),colorProps:x(e.colorProps),urlProps:x(e.urlProps)}))}function E(e){return _(e).map(e=>({interface:v(e.interface),method:v(e.method),timestamp:b(e.timestamp),messageId:v(e.messageId)}))}function D(e){return _(e).map(e=>({eventType:v(e.eventType),timestamp:b(e.timestamp),url:y(e.url)}))}function O(e){return _(e).map(e=>({requestId:v(e.requestId),url:v(e.url),timestamp:b(e.timestamp)}))}function k(e){return _(e).map(e=>({pid:b(e.pid),tid:b(e.tid),syscallName:v(e.syscallName),timestamp:b(e.timestamp)}))}function A(e){return _(e).map(e=>({threadId:b(e.threadId),timestamp:b(e.timestamp),frames:_(e.frames).map(e=>({functionName:v(e.functionName)}))}))}function j(e){if(!g(e))return null;let t=v(e.moduleName);return t?{functions:_(e.functions).map(e=>({name:v(e.name),moduleName:v(e.moduleName),address:y(e.address),calledFrom:S(e.calledFrom)})),moduleName:t}:null}const M={WORKFLOW_REVERSE_OBFUSCATED:{id:`reverse-obfuscated-api`,displayName:`Reverse Obfuscated API`,steps:[{tool:`deobfuscate`,args:{targetUrl:"${input.targetUrl}"}},{tool:`js_heap_search`,args:{pattern:"${previous.cryptoKeys}"}},{tool:`network_enable`,args:{}},{tool:`tls_cert_pin_bypass`,args:{target:"${input.target}"}},{tool:`console_inject_fetch_interceptor`,args:{urls:["${input.apiEndpoint}"]}}]},WORKFLOW_GAME_CANVAS_SKIA:{id:`game-canvas-skia-v8`,displayName:`Game Canvas + SKIA + V8 Analysis`,steps:[{tool:`canvas_engine_fingerprint`,args:{canvasId:"${input.canvasId}"}},{tool:`canvas_scene_dump`,args:{canvasId:"${input.canvasId}"}},{tool:`skia_correlate_objects`,args:{skiaNodeIds:"${previous.nodeIds}"}},{tool:`performance_take_heap_snapshot`,args:{}},{tool:`js_heap_search`,args:{pattern:"${input.searchTerm}"}}]},WORKFLOW_BINARY_NATIVE_HOOK:{id:`binary-native-hook`,displayName:`Binary Analysis + Native Hook`,steps:[{tool:`ghidra_analyze`,args:{binaryPath:"${input.binaryPath}"}},{tool:`generate_hooks`,args:{symbols:"${previous.exportedSymbols}"}},{tool:`frida_attach`,args:{target:"${input.target}"}},{tool:`frida_run_script`,args:{script:"${previous.hookScript}"}}]}},N=[`analysis`,`browser`,`network`,`canvas`,`skia-capture`,`v8-inspector`,`mojo-ipc`,`syscall-hook`,`binary-instrument`,`boringssl-inspector`,`evidence`];var P=class{ctx;evidenceBridgeReady;constructor(e,t){this.ctx=e,this.evidenceBridgeReady=t}getCapabilities(){let e=this.getAvailableDomains(),t=N.filter(t=>!e.includes(t)),n=Object.entries(M).map(([e,t])=>{let n=this.evaluateWorkflow(t);return{workflowKey:e,id:t.id,displayName:t.displayName,stepCount:t.steps.length,...n}});return{availableDomains:e,missingDomains:t,supportedDomains:[...N],workflows:n}}suggestWorkflow(e,t){let n=e.toLowerCase(),r=Object.entries(M).map(([e,t])=>({workflowKey:e,workflow:t,keywordScore:this.scoreWorkflowGoal(n,e,t),evaluation:this.evaluateWorkflow(t)})),i=t?r.filter(e=>e.evaluation.missingDomains.length===0):r,a=i.length>0?i:r;a.sort((e,t)=>t.keywordScore===e.keywordScore?t.evaluation.coverage-e.evaluation.coverage:t.keywordScore-e.keywordScore);let o=a[0];if(!o)throw Error(`No workflow definitions are available for cross-domain suggestion`);let s=this.describeWorkflowReason(n,o.evaluation);return{workflowKey:o.workflowKey,id:o.workflow.id,displayName:o.workflow.displayName,reason:s,...o.evaluation}}getHealth(){let e=this.getAvailableDomains();return{evidenceBridgeReady:this.evidenceBridgeReady,orchestratorReady:!0,availableDomains:e,missingDomains:N.filter(t=>!e.includes(t))}}getAvailableDomains(){let e=this.ctx.enabledDomains.size>0?this.ctx.enabledDomains:this.ctx.resolveEnabledDomains(this.ctx.selectedTools),t=[];for(let n of N)e.has(n)&&t.push(n);return t}evaluateWorkflow(e){let t=new Set;for(let n of e.steps)for(let e of this.inferDomainsForTool(n.tool))t.add(e);let n=[...t],r=this.getAvailableDomains().filter(e=>t.has(e));return{requiredDomains:n,availableDomains:r,missingDomains:n.filter(e=>!r.includes(e)),coverage:n.length===0?1:r.length/n.length}}inferDomainsForTool(e){return e.startsWith(`deobfuscate`)||e.startsWith(`advanced_deobfuscate`)?[`analysis`]:e.startsWith(`js_heap`)||e.startsWith(`performance_take_heap_snapshot`)?[`v8-inspector`]:e.startsWith(`network_`)?[`network`]:e.startsWith(`console_`)?[`browser`]:e.startsWith(`tls_`)||e.startsWith(`net_raw_`)?[`boringssl-inspector`]:e.startsWith(`canvas_`)?[`canvas`]:e.startsWith(`skia_`)?[`skia-capture`]:e.startsWith(`v8_`)?[`v8-inspector`]:e.startsWith(`mojo_`)?[`mojo-ipc`]:e.startsWith(`syscall_`)?[`syscall-hook`]:e.startsWith(`adb_`)?[`adb-bridge`]:e.startsWith(`ghidra_`)||e.startsWith(`frida_`)||e.startsWith(`generate_hooks`)||e.startsWith(`unidbg_`)||e.startsWith(`export_hook_script`)?[`binary-instrument`]:e.startsWith(`extension_`)||e===`webhook`?[`extension-registry`]:e.startsWith(`cross_domain_`)?[`cross-domain`]:e.startsWith(`evidence_`)?[`evidence`]:e.startsWith(`boringssl_`)?[`boringssl-inspector`]:[]}scoreWorkflowGoal(e,t,n){let r=0;return t===`WORKFLOW_REVERSE_OBFUSCATED`&&((e.includes(`obfus`)||e.includes(`api`))&&(r+=3),(e.includes(`tls`)||e.includes(`pin`))&&(r+=2)),t===`WORKFLOW_GAME_CANVAS_SKIA`&&((e.includes(`canvas`)||e.includes(`game`))&&(r+=3),(e.includes(`skia`)||e.includes(`scene`))&&(r+=2)),t===`WORKFLOW_BINARY_NATIVE_HOOK`&&((e.includes(`binary`)||e.includes(`native`))&&(r+=3),(e.includes(`hook`)||e.includes(`frida`))&&(r+=2)),r===0&&n.displayName.toLowerCase().includes(e)&&(r+=1),r}describeWorkflowReason(e,t){return t.missingDomains.length===0?`Matched goal "${e}" and all required domains are enabled.`:`Matched goal "${e}" with ${Math.round(t.coverage*100)}% domain coverage. Missing: ${t.missingDomains.join(`, `)}.`}},F=class{evidenceBridge;workflowClassifier;constructor(e,t){this.evidenceBridge=e,this.workflowClassifier=t}async handleCapabilities(t){let n={evidenceGraphAvailable:!0,workflowClassifierAvailable:this.workflowClassifier!==void 0};return this.workflowClassifier?e({capabilities:n,...this.workflowClassifier.getCapabilities()}):e({capabilities:n})}async handleSuggestWorkflow(r){let i=t(r,`query`,``)||t(r,`goal`,``),a=n(r,`preferAvailableOnly`,!0);return this.workflowClassifier&&i?e(this.workflowClassifier.suggestWorkflow(i,a)):e({message:`Cross-domain workflow suggestion requires a classifier and query.`})}async handleHealth(){let t=this.evidenceBridge.getStats();return this.workflowClassifier?e({...this.workflowClassifier.getHealth(),evidenceGraph:t}):e({evidenceBridgeReady:!0,orchestratorReady:!1,evidenceGraph:t})}async handleCorrelateAll(t){let n=[],r={};try{let e=w(t.sceneTree),n=T(t.jsObjects);r.skia=o(this.evidenceBridge,{sceneTree:e,jsObjects:n})}catch(e){n.push(`SKIA-03: ${e instanceof Error?e.message:String(e)}`)}try{let e=E(t.mojoMessages),n=D(t.cdpEvents),i=O(t.networkRequests);r.mojo=c(this.evidenceBridge,e,n,i)}catch(e){n.push(`MOJO-03: ${e instanceof Error?e.message:String(e)}`)}try{let e=k(t.syscallEvents),n=A(t.jsStacks);r.syscall=d(this.evidenceBridge,e,n)}catch(e){n.push(`SYSCALL-02: ${e instanceof Error?e.message:String(e)}`)}try{let e=j(t.ghidraOutput);e&&(r.binary=h(this.evidenceBridge,e))}catch(e){n.push(`BIN-04: ${e instanceof Error?e.message:String(e)}`)}let i=this.evidenceBridge.exportGraph();return e({correlationResults:{...r,errors:n},evidenceGraph:i})}async handleEvidenceExport(){return e(this.evidenceBridge.exportGraph())}async handleEvidenceStats(){return e(this.evidenceBridge.getStats())}};export{F as CrossDomainHandlers,P as CrossDomainWorkflowClassifier};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{an as e}from"./constants-BYj8Xek8.mjs";import{n as t}from"./ResponseBuilder-BfWP-uaT.mjs";import{t as n}from"./renderer-pid-9tJnZ_9N.mjs";var r=class{sessionManager;constructor(e){this.sessionManager=e}async handleScanList(e){return t(async()=>{let e=this.sessionManager.listSessions();return{sessions:e,count:e.length}})}async handleScanDelete(e){return t(async()=>({deleted:this.sessionManager.deleteSession(e.sessionId)}))}async handleScanExport(e){return t(async()=>({exportedData:this.sessionManager.exportSession(e.sessionId)}))}};async function i(e,t,r){return await n(e,t,r)}function a(t){return t===void 0||!Number.isFinite(t)||t<=0?e:Math.min(t,e)}var o=class{scanner;eventBus;processManager;ctx;constructor(e,t,n,r){this.scanner=e,this.eventBus=t,this.processManager=n,this.ctx=r}async resolvePid(e){return this.processManager?await i(e,this.processManager,this.ctx):e}async handleFirstScan(e){return t(async()=>{let t=await this.resolvePid(e.pid),n={valueType:e.valueType,alignment:e.alignment,maxResults:a(e.maxResults),regionFilter:e.regionFilter,onProgress:e.onProgress},r=await this.scanner.firstScan(t,e.value,n);return this.eventBus?.emit(`memory:scan_completed`,{scanType:`first`,resultCount:r.totalMatches??0,timestamp:new Date().toISOString()}),{...r,hint:r.totalMatches>0?`Found ${r.totalMatches} matches. Use memory_next_scan with sessionId "${r.sessionId}" to narrow down.`:`No matches found. Try a different value or type.`}})}async handleNextScan(e){return t(async()=>{let t=await this.scanner.nextScan(e.sessionId,e.mode,e.value,e.value2);return{...t,hint:t.totalMatches<=10?`Few matches remaining — inspect these addresses.`:`${t.totalMatches} matches remain. Continue narrowing with memory_next_scan.`}})}async handleUnknownScan(e){return t(async()=>{let t=await this.resolvePid(e.pid),n={valueType:e.valueType,alignment:e.alignment,maxResults:a(e.maxResults),regionFilter:e.regionFilter,onProgress:e.onProgress},r=await this.scanner.unknownInitialScan(t,n);return{...r,hint:`Captured ${r.totalMatches} addresses. Use memory_next_scan with changed/unchanged/increased/decreased to narrow.`}})}async handlePointerScan(e){return t(async()=>{let t=await this.resolvePid(e.pid);return{...await this.scanner.pointerScan(t,e.targetAddress,{maxResults:a(e.maxResults),moduleOnly:e.moduleOnly})}})}async handleGroupScan(e){return t(async()=>{let t=await this.resolvePid(e.pid);return{...await this.scanner.groupScan(t,e.pattern,{alignment:e.alignment,maxResults:a(e.maxResults)})}})}},s=class{ptrEngine;processManager;ctx;constructor(e,t,n){this.ptrEngine=e,this.processManager=t,this.ctx=n}async resolvePid(e){return this.processManager?await i(e,this.processManager,this.ctx):e}async handlePointerChainScan(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=await this.ptrEngine.scan(t,e.targetAddress,{maxDepth:e.maxDepth,maxOffset:e.maxOffset,staticOnly:e.staticOnly,modules:e.modules,maxResults:e.maxResults});return{...n,hint:n.totalFound>0?`Found ${n.totalFound} pointer chains. Static chains survive process restarts.`:`No pointer chains found. Try increasing maxDepth or maxOffset.`}})}async handlePointerChainValidate(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=JSON.parse(e.chains),r=await this.ptrEngine.validateChains(t,n);return{results:r,validCount:r.filter(e=>e.isValid).length,totalChecked:n.length}})}async handlePointerChainResolve(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=JSON.parse(e.chain),r=await this.ptrEngine.resolveChain(t,n);return{chainId:n.id,resolvedAddress:r,isResolvable:r!==null}})}async handlePointerChainExport(e){return t(async()=>{let t=JSON.parse(e.chains);return{exportedData:this.ptrEngine.exportChains(t),chainCount:t.length}})}};const c={int8_t:`int8`,uint8_t:`uint8`,int16_t:`int16`,uint16_t:`uint16`,int32_t:`int32`,uint32_t:`uint32`,int64_t:`int64`,uint64_t:`uint64`,void_ptr:`pointer`,char_ptr:`string_ptr`};function l(e){if(typeof e!=`string`||e.length===0)return`unknown`;let t=e.toLowerCase().replace(/\s+/g,`_`).replace(/\*/g,`_ptr`);return c[t]??t}function u(e){if(!e||typeof e!=`object`)throw Error(`structure must be a JSON object`);let t=e,n=(Array.isArray(t.fields)?t.fields:[]).map((e,t)=>{let n=e;return{offset:typeof n.offset==`number`?n.offset:0,size:typeof n.size==`number`?n.size:1,type:l(n.type),name:typeof n.name==`string`&&n.name.length>0?n.name:`field_${t}`,value:typeof n.value==`string`?n.value:``,confidence:typeof n.confidence==`number`?n.confidence:1,notes:typeof n.notes==`string`?n.notes:void 0}}),r=n.reduce((e,t)=>Math.max(e,t.offset+t.size),0),i=typeof t.totalSize==`number`?t.totalSize:typeof t.size==`number`?t.size:r;return{baseAddress:typeof t.baseAddress==`string`?t.baseAddress:`0x0`,totalSize:i,fields:n,vtableAddress:typeof t.vtableAddress==`string`?t.vtableAddress:void 0,className:typeof t.className==`string`?t.className:void 0,baseClasses:Array.isArray(t.baseClasses)?t.baseClasses.filter(e=>typeof e==`string`):void 0,timestamp:typeof t.timestamp==`number`?t.timestamp:Date.now()}}var d=class{structAnalyzer;processManager;ctx;constructor(e,t,n){this.structAnalyzer=e,this.processManager=t,this.ctx=n}async resolvePid(e){return this.processManager?await i(e,this.processManager,this.ctx):e}async handleStructureAnalyze(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=await this.structAnalyzer.analyzeStructure(t,e.address,{size:e.size,otherInstances:e.otherInstances,parseRtti:e.parseRtti});return{...n,hint:n.className?`Detected class: ${n.className}${n.baseClasses?.length?` (inherits: ${n.baseClasses.join(` → `)})`:``}`:`Inferred ${n.fields.length} fields. Use memory_structure_export_c to export as C struct.`}})}async handleVtableParse(e){return t(async()=>{let t=await this.resolvePid(e.pid);return{...await this.structAnalyzer.parseVtable(t,e.vtableAddress)}})}async handleStructureExportC(e){return t(async()=>{let t=u(JSON.parse(e.structure));return{...this.structAnalyzer.exportToCStruct(t,e.name)}})}async handleStructureCompare(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=await this.structAnalyzer.compareInstances(t,e.address1,e.address2,e.size);return{matchingFieldCount:n.matching.length,differingFieldCount:n.differing.length,...n}})}},f=class{bpEngine;injector;processManager;ctx;constructor(e,t,n,r){this.bpEngine=e,this.injector=t,this.processManager=n,this.ctx=r}async resolvePid(e){return this.processManager?await i(e,this.processManager,this.ctx):e}async handleBreakpointSet(e){return t(async()=>{let t=await this.resolvePid(e.pid);return{...await this.bpEngine.setBreakpoint(t,e.address,e.access,e.size??4),hint:`Hardware breakpoint set on DR register. Use memory_breakpoint with action='trace' to collect hits.`}})}async handleBreakpointRemove(e){return t(async()=>({removed:await this.bpEngine.removeBreakpoint(e.breakpointId)}))}async handleBreakpointList(e){return t(async()=>{let e=this.bpEngine.listBreakpoints();return{breakpoints:e,count:e.length}})}async handleBreakpointTrace(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=await this.bpEngine.traceAccess(t,e.address,e.access,e.maxHits,e.timeoutMs);return{hits:n,hitCount:n.length,hint:n.length>0?`${n.length} accesses captured. Check instructionAddress to find the code accessing this address.`:`No hits captured within timeout.`}})}async handlePatchBytes(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=await this.injector.patchBytes(t,e.address,e.bytes);return{...n,hint:`Patch applied. Use memory_patch_undo with patchId "${n.id}" to restore.`}})}async handlePatchNop(e){return t(async()=>{let t=await this.resolvePid(e.pid);return{...await this.injector.nopBytes(t,e.address,e.count),hint:`${e.count} bytes NOP'd. Use memory_patch_undo to restore.`}})}async handlePatchUndo(e){return t(async()=>({restored:await this.injector.unpatch(e.patchId)}))}async handleCodeCaves(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=await this.injector.findCodeCaves(t,e.minSize);return{caves:n,count:n.length}})}},p=class{memCtrl;processManager;ctx;constructor(e,t,n){this.memCtrl=e,this.processManager=t,this.ctx=n}async resolvePid(e){return this.processManager?await i(e,this.processManager,this.ctx):e}async handleWriteValue(e){return t(async()=>{let t=await this.resolvePid(e.pid);return{...await this.memCtrl.writeValue(t,e.address,e.value,e.valueType),hint:`Use memory_write_history with action='undo' to revert.`}})}async handleFreeze(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=await this.memCtrl.freeze(t,e.address,e.value,e.valueType,e.intervalMs);return{...n,hint:`Frozen. Use memory_freeze with action="unfreeze" and freezeId "${n.id}" to stop.`}})}async handleUnfreeze(e){return t(async()=>({unfrozen:await this.memCtrl.unfreeze(e.freezeId)}))}async handleDump(e){return t(async()=>{let t=await this.resolvePid(e.pid);return{dump:await this.memCtrl.dumpMemoryHex(t,e.address,e.size??256)}})}async handleWriteUndo(e){return t(async()=>{let e=await this.memCtrl.undo();return{undone:e!==null,entry:e}})}async handleWriteRedo(e){return t(async()=>{let e=await this.memCtrl.redo();return{redone:e!==null,entry:e}})}},m=class{speedhackEngine;heapAnalyzer;peAnalyzer;antiCheatDetector;processManager;ctx;constructor(e,t,n,r,i,a){this.speedhackEngine=e,this.heapAnalyzer=t,this.peAnalyzer=n,this.antiCheatDetector=r,this.processManager=i,this.ctx=a}async resolvePid(e){return this.processManager?await i(e,this.processManager,this.ctx):e}async handleSpeedhackApply(e){return t(async()=>{let t=await this.resolvePid(e.pid);return{...await this.speedhackEngine.apply(t,e.speed),hint:`Speedhack active (${e.speed}x). Use memory_speedhack({ action: 'set' }) to adjust.`}})}async handleSpeedhackSet(e){return t(async()=>{let t=await this.resolvePid(e.pid);return{updated:await this.speedhackEngine.setSpeed(t,e.speed),newSpeed:e.speed}})}async handleHeapEnumerate(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=await this.heapAnalyzer.enumerateHeaps(t);return{...n,hint:`Enumerated ${n.heaps.length} heaps. Use memory_heap_stats for statistics or memory_heap_anomalies to check for issues.`}})}async handleHeapStats(e){return t(async()=>{let t=await this.resolvePid(e.pid);return{...await this.heapAnalyzer.getStats(t)}})}async handleHeapAnomalies(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=await this.heapAnalyzer.detectAnomalies(t);return{anomalies:n,count:n.length,hint:n.length>0?`Found ${n.length} anomalies — inspect types for spray, UAF, or suspicious patterns.`:`No heap anomalies detected.`}})}async handlePEHeaders(e){return t(async()=>{let t=await this.resolvePid(e.pid);return{...await this.peAnalyzer.parseHeaders(t,e.moduleBase)}})}async handlePEImportsExports(e){return t(async()=>{let t=e.table||`both`,n=e.moduleBase,r=await this.resolvePid(e.pid),i={};return(t===`imports`||t===`both`)&&(i.imports=await this.peAnalyzer.parseImports(r,n)),(t===`exports`||t===`both`)&&(i.exports=await this.peAnalyzer.parseExports(r,n)),i})}async handleInlineHookDetect(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=await this.peAnalyzer.detectInlineHooks(t,e.moduleName);return{hooks:n,count:n.length,hint:n.length>0?`Detected ${n.length} inline hooks — check hookType and jumpTarget for each.`:`No inline hooks detected — exports match disk bytes.`}})}async handleAntiCheatDetect(e){return t(async()=>{let t=await this.resolvePid(e.pid),n=await this.antiCheatDetector.detect(t);return{detections:n,count:n.length,hint:n.length>0?`Found ${n.length} anti-debug mechanisms. Each includes a bypassSuggestion.`:`No anti-debug mechanisms detected in imports.`}})}async handleGuardPages(e){return t(async()=>{let t=await this.resolvePid(e.pid),{guardPages:n,stats:r}=await this.antiCheatDetector.scanGuardPages(t);return{guardPages:n,count:n.length,scan:r,hint:r.truncated?`Scan stopped after ${r.scannedRegions} regions in ${r.durationMs}ms to avoid hanging. Results may be partial.`:n.length>0?`Found ${n.length} guard page regions — these may indicate anti-tampering.`:`No guard pages found.`}})}async handleIntegrityCheck(e){return t(async()=>{let t=await this.resolvePid(e.pid),{sections:n,stats:r}=await this.antiCheatDetector.scanIntegrity(t,e.moduleName),i=n.filter(e=>e.isModified);return{sections:n,totalChecked:n.length,modifiedCount:i.length,scan:r,hint:r.truncated?`Checked ${r.scannedSections} executable section(s) across ${r.scannedModules} module(s) before hitting safety limits. Results may be partial.`:i.length>0?`${i.length} section(s) modified — code may have been patched or hooked.`:`All checked sections match disk — no runtime modifications detected.`}})}},h=class{sessions;scans;ptrChains;structures;hooks;readwrite;integrity;constructor(e,t,n,i,a,c,l,u,h,g,_,v,y,b){this.sessions=new r(t),this.scans=new o(e,v,y,b),this.ptrChains=new s(n,y,b),this.structures=new d(i,y,b),this.hooks=new f(a,c,y,b),this.readwrite=new p(l,y,b),this.integrity=new m(u,h,g,_,y,b)}handleScanSessionDispatch(e){switch(String(e.action??``)){case`delete`:return this.sessions.handleScanDelete(e);case`export`:return this.sessions.handleScanExport(e);default:return this.sessions.handleScanList(e)}}handleScanList=e=>this.sessions.handleScanList(e);handleScanDelete=e=>this.sessions.handleScanDelete(e);handleScanExport=e=>this.sessions.handleScanExport(e);handleFirstScan=e=>this.scans.handleFirstScan(e);handleNextScan=e=>this.scans.handleNextScan(e);handleUnknownScan=e=>this.scans.handleUnknownScan(e);handlePointerScan=e=>this.scans.handlePointerScan(e);handleGroupScan=e=>this.scans.handleGroupScan(e);handlePointerChainDispatch(e){switch(String(e.action??``)){case`validate`:return this.ptrChains.handlePointerChainValidate(e);case`resolve`:return this.ptrChains.handlePointerChainResolve(e);case`export`:return this.ptrChains.handlePointerChainExport(e);default:return this.ptrChains.handlePointerChainScan(e)}}handlePointerChainScan=e=>this.ptrChains.handlePointerChainScan(e);handlePointerChainValidate=e=>this.ptrChains.handlePointerChainValidate(e);handlePointerChainResolve=e=>this.ptrChains.handlePointerChainResolve(e);handlePointerChainExport=e=>this.ptrChains.handlePointerChainExport(e);handleStructureAnalyze=e=>this.structures.handleStructureAnalyze(e);handleVtableParse=e=>this.structures.handleVtableParse(e);handleStructureExportC=e=>this.structures.handleStructureExportC(e);handleStructureCompare=e=>this.structures.handleStructureCompare(e);handleBreakpointDispatch(e){switch(String(e.action??``)){case`remove`:return this.hooks.handleBreakpointRemove(e);case`list`:return this.hooks.handleBreakpointList(e);case`trace`:return this.hooks.handleBreakpointTrace(e);default:return this.hooks.handleBreakpointSet(e)}}handleBreakpointSet=e=>this.hooks.handleBreakpointSet(e);handleBreakpointRemove=e=>this.hooks.handleBreakpointRemove(e);handleBreakpointList=e=>this.hooks.handleBreakpointList(e);handleBreakpointTrace=e=>this.hooks.handleBreakpointTrace(e);handlePatchBytes=e=>this.hooks.handlePatchBytes(e);handlePatchNop=e=>this.hooks.handlePatchNop(e);handlePatchUndo=e=>this.hooks.handlePatchUndo(e);handleCodeCaves=e=>this.hooks.handleCodeCaves(e);handleFreezeDispatch(e){return String(e.action??``)===`unfreeze`?this.readwrite.handleUnfreeze(e):this.readwrite.handleFreeze(e)}handleWriteHistoryDispatch(e){return String(e.action??``)===`redo`?this.readwrite.handleWriteRedo(e):this.readwrite.handleWriteUndo(e)}handleWriteValue=e=>this.readwrite.handleWriteValue(e);handleFreeze=e=>this.readwrite.handleFreeze(e);handleUnfreeze=e=>this.readwrite.handleUnfreeze(e);handleDump=e=>this.readwrite.handleDump(e);handleWriteUndo=e=>this.readwrite.handleWriteUndo(e);handleWriteRedo=e=>this.readwrite.handleWriteRedo(e);handleSpeedhackDispatch(e){return String(e.action??``)===`set`?this.integrity.handleSpeedhackSet(e):this.integrity.handleSpeedhackApply(e)}handleSpeedhackApply=e=>this.integrity.handleSpeedhackApply(e);handleSpeedhackSet=e=>this.integrity.handleSpeedhackSet(e);handleHeapEnumerate=e=>this.integrity.handleHeapEnumerate(e);handleHeapStats=e=>this.integrity.handleHeapStats(e);handleHeapAnomalies=e=>this.integrity.handleHeapAnomalies(e);handlePEHeaders=e=>this.integrity.handlePEHeaders(e);handlePEImportsExports=e=>this.integrity.handlePEImportsExports(e);handleInlineHookDetect=e=>this.integrity.handleInlineHookDetect(e);handleAntiCheatDetect=e=>this.integrity.handleAntiCheatDetect(e);handleGuardPages=e=>this.integrity.handleGuardPages(e);handleIntegrityCheck=e=>this.integrity.handleIntegrityCheck(e)};export{h as MemoryScanHandlers};
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./ToolError-DWU_z7gp.mjs";import{o as t,r as n,s as r,t as i}from"./parse-args-Bw413PlW.mjs";import{n as a}from"./ResponseBuilder-BfWP-uaT.mjs";import"./definitions-DP1vgxEY.mjs";import{promises as o}from"node:fs";import{posix as s,resolve as c,sep as l}from"node:path";import{execFile as u,spawn as d}from"node:child_process";import{promisify as f}from"node:util";const p=(e,t)=>{let n=process.env[e];if(n===void 0||n===``)return t;let r=parseInt(n,10);return Number.isFinite(r)?r:t},m=(e,t)=>process.env[e]||t,h=p(`JADX_SEARCH_MAX_RESULTS`,500),g=p(`JADX_SEARCH_DEFAULT_CONTEXT_LINES`,2),_=p(`JADX_SEARCH_MAX_CONTEXT_LINES`,20),v=p(`JADX_SEARCH_MAX_MATCHES_PER_FILE`,100),y=p(`JADX_SEARCH_TIMEOUT_MS`,6e4),b=p(`JADX_SEARCH_REGEX_TIMEOUT_MS`,50),x=p(`JADX_SEARCH_MAX_QUERY_LENGTH`,1024),S=p(`JADX_SEARCH_FALLBACK_FILE_LIMIT`,5e4),C=p(`JADX_SEARCH_RG_MAX_BUFFER_BYTES`,128*1024*1024),w=m(`JADX_SEARCH_DEFAULT_GLOBS`,`**/*.java,**/*.kt`).split(`,`),T=p(`JADX_SEARCH_MAX_LINE_BYTES`,64*1024),E=Object.freeze([/\([^()]*[+*][^()]*\)[+*]/,/\([^()]*\|[^()]*\)[+*][^()]*[+*]/]);function D(e){return e.replace(/[\\^$.*+?()[\]{}|]/g,`\\$&`)}function O(t,n,r){let i=n?D(t):t;if(!n){for(let n of E)if(n.test(i))throw new e(`VALIDATION`,`query rejected as potentially catastrophic (ReDoS heuristic match)`,{details:{query:t}})}let a=r?`gi`:`g`;try{return new RegExp(i,a)}catch(n){throw new e(`VALIDATION`,`query failed to compile as regex: ${n.message}`,{cause:n,details:{query:t}})}}function k(e){return e.map(e=>{let t=e.startsWith(`!`);return{negate:t,re:M(t?e.slice(1):e)}})}function A(e,t){let n=!1,r=!1;for(let{negate:i,re:a}of t)if(i||(r=!0),a.test(e)){if(i)return!1;n=!0}return r?n:!0}const j=/[\\^$.+()|[\]{}]/;function M(e){let t=`^`,n=0;for(;n<e.length;){let r=e[n];if(r===`*`){if(e[n+1]===`*`){t+=`.*`,n+=2,e[n]===`/`&&(n+=1);continue}t+=`[^/]*`}else r===`?`?t+=`[^/]`:r!==void 0&&j.test(r)?t+=`\\`+r:r===`/`?t+=`/`:r!==void 0&&(t+=r);n+=1}return t+=`$`,new RegExp(t)}function N(e,t){let n=e.split(l).join(`/`),r=t.split(l).join(`/`),i=r.endsWith(`/`)?r:`${r}/`;return n.startsWith(i)?n.slice(i.length):n}function P(e){return e.split(/\r?\n/)}function F(t,n,r){t.lastIndex=r;let i=performance.now(),a=t.exec(n),o=performance.now()-i;if(o>b)throw new e(`TIMEOUT`,`Regex match exceeded JADX_SEARCH_REGEX_TIMEOUT_MS (${b} ms): ${o.toFixed(2)} ms`,{details:{pattern:t.source,elapsedMs:o}});return a}async function I(t,n,r=S){let i;try{i=await o.readdir(t,{recursive:!0})}catch(n){throw new e(`NOT_FOUND`,`decompileDir not readable: ${t}`,{cause:n})}let a=k(n),s=[];for(let e of i){if(s.length>=r)break;let t=e.split(l).join(`/`);A(t,a)&&s.push(t)}return s}var L=class{async run(e){let t=c(e.decompileDir),n=await I(t,e.globs),r=O(e.query,e.literal,e.caseInsensitive),i=[],a=new Set,u=!1;outer:for(let c of n){let n=s.join(t.split(l).join(`/`),c),d;try{d=await o.readFile(n,`utf8`)}catch{continue}let f=P(d),p=0,m=N(n,t);for(let t=0;t<f.length;t+=1){let n=f[t];if(n===void 0||n.length>T)continue;let o=0,s=F(r,n,o);for(;s!==null;){if(p>=e.maxMatchesPerFile){u=!0;break}let c=s.index+1,l=s.index+s[0].length+1,d={file:m,line:t+1,column:c,text:n,matchStart:c,matchEnd:l};if(e.contextLines>0){let n=[];for(let r=Math.max(0,t-e.contextLines);r<t;r+=1){let e=f[r];e!==void 0&&n.push({line:r+1,text:e})}let r=[];for(let n=t+1;n<Math.min(f.length,t+1+e.contextLines);n+=1){let e=f[n];e!==void 0&&r.push({line:n+1,text:e})}d.context={before:n,after:r}}if(i.push(d),a.add(m),p+=1,i.length>=e.maxResults){u=!0;break outer}let h=s[0].length;if(o=s.index+(h>0?h:1),o>n.length)break;s=F(r,n,o)}}}return{matches:i,filesMatched:a.size,truncated:u}}};const R=f(u);let z,B;async function V(e=3e3){return z||B||(B=(async()=>{try{let t=process.platform===`win32`?`where`:`which`,{stdout:n}=await R(t,[`rg`],{timeout:e,windowsHide:!0}),r=n.trim().split(/\r?\n/)[0];if(!r){let e={available:!1,reason:`'${t} rg' produced empty output`};return z=e,e}let i;try{let{stdout:t}=await R(`rg`,[`--version`],{timeout:e,windowsHide:!0}),n=t.trim().split(/\r?\n/)[0];i=n?n.substring(0,100):void 0}catch{}let a=i?{available:!0,path:r,version:i}:{available:!0,path:r};return z=a,a}catch(e){let t=typeof e==`object`&&e&&`code`in e?e.code:void 0,n=e instanceof Error?e.message:String(e?.message??e),r={available:!1,reason:t===`ENOENT`?`Command 'rg' not found in PATH — install ripgrep (brew/apt/scoop install ripgrep)`:`Probe failed: ${n.substring(0,200)}`};return z=r,r}finally{B=void 0}})(),B)}function H(e,t){let n=t.split(l).join(`/`),r=e.split(l).join(`/`),i=n.endsWith(`/`)?n:`${n}/`;return r.startsWith(i)?r.slice(i.length):r}function U(e){return e.endsWith(`\r
|
|
2
|
-
`)?e.slice(0,-2):e.endsWith(`
|
|
3
|
-
`)||e.endsWith(`\r`)?e.slice(0,-1):e}function W(e){return U(e)}function G(e){let t=[`--json`,`--no-heading`,`-n`,`--no-config`];e.literal&&t.push(`-F`),e.caseInsensitive&&t.push(`-i`),e.contextLines>0&&t.push(`-C`,String(e.contextLines)),t.push(`--max-count`,String(e.maxMatchesPerFile));for(let n of e.globs)t.push(`--glob`,n);return t.push(`--`,e.query,e.decompileDir),t}var K=class{spawnFn;rgExecutable;constructor(e=d,t=`rg`){this.spawnFn=e,this.rgExecutable=t}async run(t){let n=c(t.decompileDir),r=G({...t,decompileDir:n}),i=this.spawnFn(this.rgExecutable,r,{stdio:[`ignore`,`pipe`,`pipe`],windowsHide:!0}),a=0,o=``,s=``,l=[],u=new Set,d=!1,f=new Map,p=e=>{f.delete(e)},m=e=>{if(e.type===`begin`){let t=e.data.path.text,r=H(t,n);return f.has(r)||f.set(r,{recentLines:[],pendingAfter:[],matchCount:0}),!0}if(e.type===`end`){let t=e.data.path.text;return p(H(t,n)),!0}if(e.type===`context`){let r=e,i=H(r.data.path.text,n),a=f.get(i);if(!a)return!0;let o=W(r.data.lines.text),s={line:r.data.line_number,text:o},c=[];for(let e of a.pendingAfter)e.afterRemaining>0&&e.match.context&&(e.match.context.after.push(s),--e.afterRemaining),e.afterRemaining>0&&c.push(e);return a.pendingAfter=c,a.recentLines.push(s),a.recentLines.length>Math.max(t.contextLines,8)&&a.recentLines.shift(),!0}if(e.type===`match`){let r=e,i=H(r.data.path.text,n),a=f.get(i)??{recentLines:[],pendingAfter:[],matchCount:0};if(f.has(i)||f.set(i,a),a.matchCount>=t.maxMatchesPerFile)return d=!0,!0;if(l.length>=t.maxResults)return d=!0,!1;let o=r.data.submatches[0];if(!o)return!0;let s=W(r.data.lines.text),c=o.start+1,p=o.end+1,m={file:i,line:r.data.line_number,column:c,text:s,matchStart:c,matchEnd:p};return t.contextLines>0&&(m.context={before:a.recentLines.filter(e=>e.line<r.data.line_number).slice(-t.contextLines),after:[]},a.pendingAfter.push({match:m,afterRemaining:t.contextLines})),l.push(m),u.add(i),a.matchCount+=1,l.length>=t.maxResults?(d=!0,!1):!0}return!0};return new Promise((t,n)=>{let r=setTimeout(()=>{i.kill(`SIGKILL`),n(new e(`TIMEOUT`,`ripgrep timed out after ${y} ms`,{details:{timeoutMs:y}}))},y),c=!1,f=()=>{c||(c=!0,clearTimeout(r))};i.stdout?.setEncoding(`utf8`),i.stderr?.setEncoding(`utf8`),i.stdout?.on(`data`,t=>{if(c)return;if(a+=t.length,a>C){i.kill(`SIGKILL`),f(),n(new e(`RUNTIME`,`ripgrep stdout exceeded JADX_SEARCH_RG_MAX_BUFFER_BYTES (${C} bytes)`));return}s+=t;let r=s.indexOf(`
|
|
4
|
-
`);for(;r!==-1;){let e=s.slice(0,r).trimEnd();if(s=s.slice(r+1),e.length>0){let t;try{t=JSON.parse(e)}catch{}if(t&&!m(t)){s=``,f(),i.kill(`SIGTERM`);break}}r=s.indexOf(`
|
|
5
|
-
`)}}),i.stderr?.on(`data`,e=>{o+=e}),i.on(`error`,t=>{f(),n(new e(`RUNTIME`,`ripgrep spawn failed: ${t.message}`,{cause:t}))}),i.on(`close`,(r,i)=>{if(f(),r===2&&i!==`SIGTERM`&&i!==`SIGKILL`){n(new e(`RUNTIME`,`ripgrep exited with code 2: ${o.trim()}`,{details:{exitCode:r,signal:i??null,stderr:o.trim()}}));return}t({matches:l,filesMatched:u.size,truncated:d})})})}},q=class{rg;fallback;probe;constructor(e={}){this.rg=e.ripgrep??new K,this.fallback=e.fallback??new L,this.probe=e.probe??(()=>V())}async search(t){let n=await this.validateAndNormalize(t),r=performance.now(),i=`node-fallback`,a;if(t.forceFallback)a=await this.fallback.run(n);else if((await this.probe()).available){i=`ripgrep`;try{a=await this.rg.run(n)}catch(t){if(t instanceof e&&t.code===`VALIDATION`)throw t;i=`node-fallback`,a=await this.fallback.run(n)}}else a=await this.fallback.run(n);let o=Math.round(performance.now()-r),s={matches:a.matches,filesMatched:a.filesMatched,totalMatches:a.matches.length,engine:i,decompileDir:n.decompileDir,durationMs:o};return a.truncated&&(s.truncated=!0),s}async validateAndNormalize(t){if(typeof t.decompileDir!=`string`||t.decompileDir.length===0)throw new e(`VALIDATION`,`decompileDir must be a non-empty string`);if(typeof t.query!=`string`||t.query.length===0)throw new e(`VALIDATION`,`query must be a non-empty string`);if(t.query.length>x)throw new e(`VALIDATION`,`query length ${t.query.length} exceeds JADX_SEARCH_MAX_QUERY_LENGTH (${x})`);let n=t.contextLines??g;if(!Number.isFinite(n)||n<0||!Number.isInteger(n))throw new e(`VALIDATION`,`contextLines must be a non-negative integer`);if(n>_)throw new e(`VALIDATION`,`contextLines ${n} exceeds JADX_SEARCH_MAX_CONTEXT_LINES (${_})`);let r=t.maxMatchesPerFile??v;if(!Number.isFinite(r)||r<1||!Number.isInteger(r))throw new e(`VALIDATION`,`maxMatchesPerFile must be a positive integer`);let i=t.maxResults??h;if(!Number.isFinite(i)||i<1||!Number.isInteger(i))throw new e(`VALIDATION`,`maxResults must be a positive integer`);let a=c(t.decompileDir),s;try{s=await o.stat(a)}catch(t){throw new e(`NOT_FOUND`,`decompileDir not found: ${a}`,{cause:t,details:{decompileDir:a}})}if(!s.isDirectory())throw new e(`VALIDATION`,`decompileDir is not a directory: ${a}`);let l=t.globs&&t.globs.length>0?Array.from(t.globs):[...w];return{decompileDir:a,query:t.query,globs:l,literal:t.literal===!0,caseInsensitive:t.caseInsensitive===!0,contextLines:n,maxMatchesPerFile:r,maxResults:i}}},J=class{engine;constructor(e=new q){this.engine=e}handleJadxSearchCode(o){return a(async()=>{let a=r(o,`decompileDir`),s=r(o,`query`);if(typeof o.apkPath==`string`&&o.apkPath.length>0)throw new e(`VALIDATION`,`apkPath is not supported by jadx_search_code (read-only). Run jadx via the binary-instrument domain first, then pass decompileDir.`);let c={decompileDir:a,query:s},l=i(o,`literal`);l!==void 0&&(c.literal=l);let u=i(o,`caseInsensitive`);u!==void 0&&(c.caseInsensitive=u);let d=n(o,`contextLines`);d!==void 0&&(c.contextLines=d);let f=n(o,`maxMatchesPerFile`);f!==void 0&&(c.maxMatchesPerFile=f);let p=n(o,`maxResults`);p!==void 0&&(c.maxResults=p);let m=o.globs;if(m!==void 0){if(!Array.isArray(m))throw new e(`VALIDATION`,`globs must be an array of strings`);let n=t(o,`globs`);if(n.length!==m.length)throw new e(`VALIDATION`,`globs contains non-string entries`);n.length>0&&(c.globs=n)}let h=await this.engine.search(c);return{matches:h.matches,filesMatched:h.filesMatched,totalMatches:h.totalMatches,engine:h.engine,durationMs:h.durationMs,decompileDir:h.decompileDir,...h.truncated?{truncated:!0}:{}}})}};export{J as JadxSearchHandlers};
|
package/dist/logger-sBC6IdRT.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const e={gray:`\x1B[90m`,blue:`\x1B[34m`,yellow:`\x1B[33m`,red:`\x1B[31m`,green:`\x1B[32m`,reset:`\x1B[0m`},t=(t,n)=>`${t}${n}${e.reset}`,n=/^(auth(orization)?|cookie|set[_-]?cookie|x[_-]?api[_-]?key|token|access[_-]?token|refresh[_-]?token|id[_-]?token|secret|client[_-]?secret|password|passwd|api[_-]?key|private[_-]?key|credentials?|session[_-]?id|csrf[_-]?token)$/i,r=/^(Bearer\s+\S|eyJ[A-Za-z0-9_-]{10,}|[A-Fa-f0-9]{32,}|sk[_-][A-Za-z0-9]{20,})/;function i(e,t){return e&&n.test(e)&&typeof t==`string`||typeof t==`string`&&r.test(t)?`[REDACTED]`:t}const a=new class{level;listeners=[];constructor(e=`info`){this.level=e}shouldLog(e){let t=[`debug`,`info`,`warn`,`error`];return t.indexOf(e)>=t.indexOf(this.level)}formatMessage(e,t,...n){let r=`[${new Date().toISOString()}] [${e.toUpperCase()}]`,a=``;if(n.length>0)try{a=` `+JSON.stringify(n,i,void 0)}catch{a=` [unserializable]`}return`${r} ${t}${a}`}emit(e,t,n){for(let r of this.listeners)try{r(e,t,n)}catch{}}onLog(e){return this.listeners.push(e),()=>{this.listeners=this.listeners.filter(t=>t!==e)}}debug(n,...r){this.shouldLog(`debug`)&&(console.error(t(e.gray,this.formatMessage(`debug`,n,...r))),this.emit(`debug`,n,r))}info(n,...r){this.shouldLog(`info`)&&(console.error(t(e.blue,this.formatMessage(`info`,n,...r))),this.emit(`info`,n,r))}warn(n,...r){this.shouldLog(`warn`)&&(console.error(t(e.yellow,this.formatMessage(`warn`,n,...r))),this.emit(`warn`,n,r))}error(n,...r){this.shouldLog(`error`)&&(console.error(t(e.red,this.formatMessage(`error`,n,...r))),this.emit(`error`,n,r))}success(n,...r){this.shouldLog(`info`)&&(console.error(t(e.green,this.formatMessage(`info`,n,...r))),this.emit(`info`,n,r))}setLevel(e){this.level=e}}(process.env.LOG_LEVEL||`info`);export{a as t};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./logger-sBC6IdRT.mjs";import{at as t,ht as n,jt as r,ot as i}from"./constants-BYj8Xek8.mjs";import{n as a,t as o}from"./artifactRetention-BCPQASm7.mjs";import{a as s,n as c}from"./response-C7rKQst4.mjs";import{t as l}from"./types-Fz69RzbZ.mjs";import{i as u,l as d}from"./outputPaths-B4Ic4RZh.mjs";import{r as f}from"./betterSqlite3-Brtq-SIQ.mjs";import{r as p}from"./concurrency-DCr8WQ2M.mjs";import{n as m}from"./ResponseBuilder-BfWP-uaT.mjs";import{t as h}from"./ToolRegistry-C5oB8KP8.mjs";import"./definitions-Bf3H1EwV.mjs";import{createRequire as g}from"node:module";import{existsSync as _}from"node:fs";import{dirname as v,isAbsolute as y,join as b,relative as x,resolve as S}from"node:path";import{fileURLToPath as C}from"node:url";import{mkdir as w,readFile as T,writeFile as E}from"node:fs/promises";import{execFile as D}from"node:child_process";import{promisify as O}from"node:util";const k=O(D),A=g(import.meta.url);let j=null,M=0;function ee(){let e=Date.now();return(!j||e-M>12e4)&&(j=new h,M=e),j}function te(e){let t=v(A.resolve(e));for(;;){let n=b(t,`package.json`);if(_(n))return n;let r=v(t);if(r===t)throw Error(`Could not locate package.json for ${e}`);t=r}}function N(e){return A(te(e))}async function ne(e){let t=e?.includeBridgeHealth??!0,i=ee().probeAll(!0),o=p(()=>L(`git`,[`--version`])),s=p(()=>L(`python`,[`--version`])),c=p(()=>I()),l=p(()=>L(`corepack`,[`--version`])),d=t?Promise.all([p(()=>z(`ghidra-bridge`,`${n.replace(/\/$/,``)}/health`)),p(()=>z(`ida-bridge`,`${r.replace(/\/$/,``)}/health`)),p(()=>z(`burp-mcp-sse`,process.env.BURP_MCP_SSE_URL?.trim()||`http://127.0.0.1:9876`))]):Promise.resolve([]),[f,m,h,g,_,v]=await Promise.all([i,o,s,c,l,d]),y=ie(_,g),b=[P(`@modelcontextprotocol/sdk`),P(`rebrowser-puppeteer-core`),re(),P(`camoufox-js`,`Optional Firefox anti-detect driver`),P(`playwright-core`,`Optional browser automation dependency`),ae()],x=[m,h,g,y,...Object.entries(f).map(([e,t])=>({name:e,status:t.available?`ok`:`missing`,detail:t.available?`${t.path??`PATH`}${t.version?` (${t.version})`:``}`:t.reason??`Unavailable`}))],S=oe(),C=se(b,x,v,S);return{success:[...b,...x,...v].every(e=>e.status!==`error`),generatedAt:new Date().toISOString(),runtime:{platform:process.platform,arch:process.arch,node:process.version,cwd:process.cwd(),projectRoot:u()},packages:b,commands:x,bridges:v,config:{transport:(process.env.MCP_TRANSPORT??`stdio`).toLowerCase(),toolProfile:(process.env.MCP_TOOL_PROFILE??`search`).toLowerCase(),pluginRoots:process.env.MCP_PLUGIN_ROOTS??`<jshook-install>/plugins`,workflowRoots:process.env.MCP_WORKFLOW_ROOTS??`<jshook-install>/workflows`,pluginSignatureRequired:process.env.MCP_PLUGIN_SIGNATURE_REQUIRED??(process.env.NODE_ENV===`production`?`true (production default)`:`false`),pluginStrictLoad:process.env.MCP_PLUGIN_STRICT_LOAD??(process.env.NODE_ENV===`production`?`true (production default)`:`false`),artifactRetention:a()},limitations:S,recommendations:C}}function P(e,t){try{let t=N(e);return{name:e,status:`ok`,detail:t.version?`installed (${t.version})`:`installed`}}catch{return{name:e,status:`missing`,detail:t??`Not installed`}}}function re(){let e=f();return{name:`better-sqlite3`,status:e.status,detail:e.detail}}function F(e){return e.status===`ok`||e.detail.includes(`npx fallback works`)}async function I(){let e=await L(`pnpm`,[`--version`]);if(e.status===`ok`)return e;let t=await L(`npx`,[`pnpm`,`--version`],1e4);return t.status===`ok`?{name:`pnpm`,status:`warn`,detail:`direct pnpm command unavailable; npx fallback works (${t.detail})`}:e}function ie(e,t){return e.status!==`missing`||!F(t)?e:{name:e.name,status:`warn`,detail:process.platform===`win32`?t.detail.includes(`npx fallback works`)?"corepack not found; use `npx pnpm` directly (common with nvm4w-managed Node on Windows)":`corepack not found; standalone pnpm is available (common with nvm4w-managed Node on Windows)`:t.detail.includes(`npx fallback works`)?"corepack not found; use `npx pnpm` directly":`corepack not found; standalone pnpm is available`}}function ae(){try{let e=N(`koffi`).version??`unknown`;if(process.platform===`win32`)return{name:`native-memory`,status:`ok`,detail:`koffi ${e} — Win32 kernel32.dll available`};if(process.platform===`darwin`)try{return A(`koffi`).load(`/usr/lib/libSystem.B.dylib`).unload(),delete A.cache[A.resolve(`koffi`)],{name:`native-memory`,status:`ok`,detail:`koffi ${e} — macOS libSystem.B.dylib available (Mach APIs need root + SIP config)`}}catch{return{name:`native-memory`,status:`warn`,detail:`koffi ${e} installed but cannot load libSystem.B.dylib`}}return{name:`native-memory`,status:`warn`,detail:`koffi ${e} — no native FFI memory provider for ${process.platform} (proc-based ops available on Linux)`}}catch{return{name:`native-memory`,status:`missing`,detail:`koffi not installed — native memory tools unavailable. Install with: pnpm add koffi`}}}async function L(e,t,n=4e3){try{let{stdout:r,stderr:i}=await k(e,t,{timeout:n,windowsHide:!0});return{name:e,status:`ok`,detail:`${r||i}`.trim().split(/\r?\n/)[0]||`available`}}catch(r){if(process.platform===`win32`)try{let{stdout:r,stderr:i}=await k(`cmd`,[`/c`,e,...t],{timeout:n,windowsHide:!0});return{name:e,status:`ok`,detail:`${`${r||i}`.trim().split(/\r?\n/)[0]||`available`} (via cmd)`}}catch(t){return R(e,t)}return R(e,r)}}function R(e,t){let n=t instanceof Error?t.message:String(t);return{name:e,status:/ENOENT|not recognized|not found/i.test(n)?`missing`:`warn`,detail:n}}async function z(e,t){try{let n=await fetch(t,{method:`GET`,signal:AbortSignal.timeout(3e3)});return{name:e,status:n.ok?`ok`:`warn`,detail:`${t} -> HTTP ${n.status}`}}catch(n){return{name:e,status:`warn`,detail:`${t} -> ${n instanceof Error?n.message:String(n)}`}}}function oe(){let e=[];return process.platform===`darwin`?(e.push(`26 cross-platform memory tools available (scan, pointer-chain, structure-analysis, heap). 15 Windows-only tools unavailable (PE analysis, anti-cheat, code injection, speedhack, hardware breakpoints).`),e.push(`Native memory operations (mach_vm_read/write) require root privileges and may require SIP configuration on ARM64.`)):process.platform===`linux`?(e.push(`Process management available via /proc. Native FFI memory provider not implemented — memory read/write uses /proc/pid/mem (requires root or CAP_SYS_PTRACE).`),e.push(`Camoufox runs on Linux, but some Chrome/CDP-heavy workflows are better served by the Chrome driver.`)):process.platform!==`win32`&&e.push(`Platform ${process.platform} is not supported for native memory operations. Use Windows or macOS.`),e}function se(e,t,n,r){let i=[],a=t.find(e=>e.name===`pnpm`),o=t.find(e=>e.name===`corepack`);return e.some(e=>e.name===`better-sqlite3`&&e.status!==`ok`)&&i.push("Install or rebuild the optional SQLite trace backend with `pnpm add -O better-sqlite3@12.10.0` or `npm rebuild better-sqlite3 --foreground-scripts` under the active Node version if you need trace tooling."),e.some(e=>e.name===`camoufox-js`&&e.status!==`ok`)&&i.push("Install optional browser dependencies with `pnpm run install:full` if you need Camoufox support."),t.some(e=>e.name.startsWith(`wabt.`)&&e.status!==`ok`)&&i.push(`Install wabt if you need full WASM disassembly/decompilation; otherwise the server will stay in basic mode.`),a&&!F(a)?i.push("Install pnpm or enable Corepack (`corepack enable`) before running package-management workflows."):a?.detail.includes(`npx fallback works`)?i.push("Use `npx pnpm` directly on this machine or repair the local pnpm/Corepack shim if scripts expect bare `pnpm`."):o?.status===`warn`&&o.detail.includes(`standalone pnpm`)&&i.push("Use `pnpm` or `npx pnpm` directly on this machine; `corepack` is optional and may be absent on nvm4w-managed Windows installs."),n.some(e=>e.status!==`ok`)&&i.push(`Check local bridge endpoints (Ghidra / IDA / Burp) before relying on native-bridge workflows.`),r.length>0&&i.push(`Review platform limitations before using process/memory tooling on non-Windows hosts.`),i}var ce=class{tokenBudget;unifiedCache;artifactCleanup;environmentDoctor;constructor(e){this.tokenBudget=e.tokenBudget,this.unifiedCache=e.unifiedCache,this.artifactCleanup=e.artifactCleanup??o,this.environmentDoctor=e.environmentDoctor??ne}async handleGetTokenBudgetStats(){return m(async()=>{let e=this.tokenBudget.getStats();return{...e,sessionDuration:`${Math.round((Date.now()-e.sessionStartTime)/1e3)}s`}})}async handleManualTokenCleanup(){return m(async()=>{let e=this.tokenBudget.getStats();this.tokenBudget.manualCleanup();let t=this.tokenBudget.getStats(),n=e.currentUsage-t.currentUsage;return{message:`Manual cleanup completed`,before:{usage:e.currentUsage,percentage:e.usagePercentage},after:{usage:t.currentUsage,percentage:t.usagePercentage},freed:{tokens:n,percentage:Math.round(n/e.maxTokens*100)}}})}async handleResetTokenBudget(){return m(async()=>(this.tokenBudget.reset(),{message:`Token budget reset successfully`,currentUsage:0,maxTokens:2e5,usagePercentage:0}))}async handleGetCacheStats(){return m(async()=>this.unifiedCache.getGlobalStats())}async handleSmartCacheCleanup(e){return m(async()=>this.unifiedCache.smartCleanup(e))}async handleClearAllCaches(){return m(async()=>(await this.unifiedCache.clearAll(),{message:`All caches cleared`}))}async handleCleanupArtifacts(e){return m(async()=>this.artifactCleanup({retentionDays:e.retentionDays,maxTotalBytes:e.maxTotalBytes,dryRun:e.dryRun}))}async handleEnvironmentDoctor(e){return m(async()=>this.environmentDoctor({includeBridgeHealth:e.includeBridgeHealth}))}};const B=O(D);function V(){return C(new URL(`../../../../`,import.meta.url))}function H(e){let t=e?.trim();if(t)return t.split(`,`).map(e=>e.trim()).find(e=>e.length>0)}function U(e){let t=e===`workflow`?`MCP_WORKFLOW_ROOTS`:`MCP_PLUGIN_ROOTS`,n=H(process.env[t]);return n?S(n):S(V(),e===`workflow`?`workflows`:`plugins`)}function W(){let e=(process.env.EXTENSION_REGISTRY_BASE_URL??``).trim().replace(/\/+$/,``);if(!e)throw Error(`EXTENSION_REGISTRY_BASE_URL is not configured. Set it in .env or environment before browsing or installing extensions.`);return e}function G(e,t){let n=e?.trim();if(!n){if(t===`subpath`)return`.`;throw Error(`Registry source.${t} must be a non-empty string`)}return n}function K(e,t,n){let r=x(e,t).replace(/\\/g,`/`);if(r===`..`||r.startsWith(`../`)||y(r))throw Error(`Registry source.${n} must stay within ${e}: ${t}`)}function le(e,t){let n=S(e,G(t,`subpath`));return K(e,n,`subpath`),n}function q(e,t){let n=S(e,G(t,`entry`));return K(e,n,`entry`),n}function ue(e){let t=G(e,`entry`).replace(/\\/g,`/`),n=[t];if(!t.endsWith(`.ts`))return n;let r=`${t.slice(0,-3)}.js`;return n.unshift(r),t.startsWith(`dist/`)||n.unshift(`dist/${r}`),[...new Set(n)]}function de(e,t){let n=ue(t);for(let t of n)if(_(q(e,t)))return t;return G(t,`entry`)}async function fe(e,t,n,r){let i={version:1,kind:e,slug:t.slug,id:t.id,source:{type:t.source.type,repo:t.source.repo,ref:t.source.ref,commit:t.source.commit,subpath:G(t.source.subpath,`subpath`),entry:G(r,`entry`)}},a=S(n,l);return await E(a,`${JSON.stringify(i,null,2)}\n`,`utf8`),a}const J=`@jshookmcp/extension-sdk`,pe=[`workspace:`,`link:`,`file:`];function me(){return d().paths.registryCacheDir}var Y=class extends Error{code;url;cachePath;status;constructor(e,t,n,r,i){super(n),this.code=e,this.url=t,this.cachePath=r,this.status=i,this.name=`RegistryFetchError`}};function he(e,t){return process.platform===`win32`?{command:`${e}.cmd`,args:t}:{command:e,args:t}}async function X(e,t,n){let r=he(e,t);return B(r.command,r.args,{...n,env:{...process.env,...n?.env,CI:`true`}})}async function Z(e){let t=S(e,`package.json`),n=S(e,`pnpm-lock.yaml`),r=S(e,`package-lock.json`);if(_(t))try{let e=await T(t,`utf8`),n=JSON.parse(e).packageManager?.trim().toLowerCase().split(`@`)[0];if(n===`pnpm`)return`pnpm`;if(n===`npm`)return`npm`}catch{}return _(n)?`pnpm`:_(r)?`npm`:`pnpm`}function Q(e){return S(me(),`registry-${e}.json`)}async function ge(e){let t=Q(e);try{let e=await T(t,`utf8`);return JSON.parse(e)}catch{return null}}async function _e(e,t){let n=Q(e);await w(v(n),{recursive:!0}),await E(n,JSON.stringify(t,null,2),`utf8`)}function ve(e,t,n){if(t instanceof Y)return t;if(t instanceof DOMException&&t.name===`AbortError`)return new Y(`timeout`,e,`Registry fetch timed out after 10000ms: ${e}`,n);let r=t instanceof Error?t.message:String(t);if(r.includes(`ENOTFOUND`)||r.includes(`getaddrinfo`))return new Y(`dns_failure`,e,`DNS resolution failed for registry URL: ${e}`,n);if(r.includes(`ECONNREFUSED`))return new Y(`connection_refused`,e,`Connection refused by registry server: ${e}`,n);if(r.includes(`CERT_`)||r.includes(`certificate`)||r.includes(`SSL`))return new Y(`tls_error`,e,`TLS/certificate error when connecting to registry: ${e}`,n);let i=r.match(/HTTP\s+(\d+)/i);return i?new Y(`http_error`,e,r,n,Number(i[1])):new Y(`fetch_failed`,e,r,n)}function ye(e){return{success:!1,error:e.code,message:e.message,url:e.url,...typeof e.status==`number`?{status:e.status}:{}}}async function $(t,n){let r=new AbortController,i=setTimeout(()=>r.abort(),1e4),a=n?.cacheKey?Q(n.cacheKey):void 0;try{let i=await fetch(t,{signal:r.signal});if(!i.ok)throw new Y(`http_error`,t,`HTTP ${i.status} ${i.statusText} from ${t}`,a,i.status);let o=await i.json();if(n?.cacheKey)try{await _e(n.cacheKey,o)}catch(r){e.warn(`[extensions] Failed to persist ${n.cacheKey} registry cache for ${t}:`,r)}return{data:o,stale:!1,source:`network`,cachePath:a}}catch(r){let i=ve(t,r,a);if(n?.cacheKey){let r=await ge(n.cacheKey);if(r)return e.warn(`[extensions] Using stale ${n.cacheKey} registry cache after ${i.code}: ${t}`),{data:r,stale:!0,source:`cache`,cachePath:a}}throw i}finally{clearTimeout(i)}}function be(e){let t=e.trim();return t?pe.some(e=>t.startsWith(e))||t.startsWith(`./`)||t.startsWith(`../`)||t.startsWith(`/`)?!0:/^[A-Za-z]:[\\/]/.test(t):!1}async function xe(e){let t=await T(S(e,`package.json`),`utf8`),n=JSON.parse(t);for(let e of[`dependencies`,`devDependencies`,`peerDependencies`,`optionalDependencies`]){let t=n[e];if(!t||typeof t!=`object`)continue;let r=t[J];if(typeof r==`string`&&be(r))throw Error(`package.json ${e}.${J} uses unsupported local dependency spec "${r}". Declare a published npm version instead, for example "^0.3.2".`)}}async function Se(e,t){let[n,r]=await Promise.allSettled([$(`${e}/workflows.index.json`,{cacheKey:`workflows`}),$(`${e}/plugins.index.json`,{cacheKey:`plugins`})]);if(n.status===`fulfilled`){let e=(Array.isArray(n.value.data.workflows)?n.value.data.workflows:[]).find(e=>e.slug===t);if(e)return{entry:e,kind:`workflow`}}if(r.status===`fulfilled`){let e=(Array.isArray(r.value.data.plugins)?r.value.data.plugins:[]).find(e=>e.slug===t);if(e)return{entry:e,kind:`plugin`}}let i=n.status===`rejected`?n.reason instanceof Error?n.reason:Error(String(n.reason)):void 0,a=r.status===`rejected`?r.reason instanceof Error?r.reason:Error(String(r.reason)):void 0;throw Error(i&&a?`Failed to resolve extension slug "${t}": workflow registry error: ${i.message}; plugin registry error: ${a.message}`:a?`Extension "${t}" was not found in workflow registry, and plugin registry lookup failed: ${a.message}`:i?`Extension "${t}" was not found in plugin registry, and workflow registry lookup failed: ${i.message}`:`Extension "${t}" not found in workflow or plugin registry`)}var Ce=class{ctx;constructor(e){this.ctx=e}async handleListExtensions(){try{return c({success:!0,...this.ctx.listExtensions()})}catch(t){return e.error(`Failed to list extensions:`,t),c(s(t))}}async handleReloadExtensions(){try{return c({success:!0,...await this.ctx.reloadExtensions()})}catch(t){return e.error(`Failed to reload extensions:`,t),c(s(t))}}async handleBrowseExtensionRegistry(t){try{let e=W(),n=t===`all`||t===`plugin`,r=t===`all`||t===`workflow`,i={success:!0},a=!1,o=n?$(`${e}/plugins.index.json`,{cacheKey:`plugins`}):void 0,s=r?$(`${e}/workflows.index.json`,{cacheKey:`workflows`}):void 0,[l,u]=await Promise.all([o??Promise.resolve(void 0),s??Promise.resolve(void 0)]);if(l){let e=Array.isArray(l.data.plugins)?l.data.plugins:[];i.plugins=e.map(e=>({slug:e.slug,id:e.id,name:e.meta.name,description:e.meta.description,author:e.meta.author,repo:e.source.repo,commit:e.source.commit,entry:e.source.entry})),i.pluginCount=e.length,i.pluginSource=l.source,a||=l.stale}if(u){let e=Array.isArray(u.data.workflows)?u.data.workflows:[];i.workflows=e.map(e=>({slug:e.slug,id:e.id,name:e.meta.name,description:e.meta.description,author:e.meta.author,repo:e.source.repo,commit:e.source.commit,entry:e.source.entry})),i.workflowCount=e.length,i.workflowSource=u.source,a||=u.stale}return a&&(i.stale=!0),c(i)}catch(t){return e.error(`Failed to browse extension registry:`,t),t instanceof Y?c(ye(t)):c(s(t))}}async handleInstallExtension(n,r){try{let{entry:e,kind:a}=await Se(W(),n),o=a===`workflow`,s=U(o?`workflow`:`plugin`),l=r?S(r):S(s,n),u=le(l,e.source.subpath);if(q(u,e.source.entry),_(l))return c({success:!1,error:`Target directory already exists: ${l}`,hint:`Remove the existing directory first, or specify a different targetDir`});if(await w(v(l),{recursive:!0}),await B(`git`,[`clone`,e.source.repo,l],{timeout:i}),await B(`git`,[`-C`,l,`checkout`,e.source.commit],{timeout:t}),_(S(u,`package.json`))){await xe(u);let e=await Z(u);await X(e,e===`pnpm`?[`--ignore-workspace`,`install`,`--no-frozen-lockfile`,`--ignore-scripts`]:[`install`,`--ignore-scripts`],{cwd:u,timeout:Math.max(i,12e4)}),await X(e,e===`pnpm`?[`--ignore-workspace`,`run`,`--if-present`,`build`]:[`run`,`build`,`--if-present`],{cwd:u,timeout:Math.max(i,12e4)})}let d=de(u,e.source.entry),f=q(u,d);if(!_(f))return c({success:!1,error:`Installed extension entry not found: ${d}`,installDir:l,projectDir:u,expectedEntryFile:f,hint:`The registry source.entry or its compiled JS output must exist after clone/build before reloadExtensions can load it.`});let p=await fe(o?`workflow`:`plugin`,e,u,d),m=await this.ctx.reloadExtensions();return c({success:!0,installed:{slug:e.slug,id:e.id,name:e.meta.name,repo:e.source.repo,commit:e.source.commit,installDir:l,projectDir:u,entry:d,entryFile:f,metadataPath:p},reload:{addedTools:m.addedTools,pluginCount:m.pluginCount,workflowCount:m.workflowCount,errors:m.errors,warnings:m.warnings}})}catch(t){return e.error(`Failed to install extension:`,t),c(s(t))}}};export{ce as CoreMaintenanceHandlers,Ce as ExtensionManagementHandlers};
|