rea-agents 5.0.0 → 6.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (507) hide show
  1. package/README.md +168 -655
  2. package/bridge/android/ReaJadxBridge.java +14 -5
  3. package/bridge/ghidra/ReaGhidraBridge.java +173 -47
  4. package/bridge/hopper_bridge.py +310 -128
  5. package/bridge/mitmproxy/capture.py +208 -0
  6. package/bridge/native/rea_lldb_tracer.py +839 -0
  7. package/bridge/process/ProcessRunTokenReader.swift +297 -0
  8. package/bridge/process/ProcessRunTokenReaderMain.swift +35 -0
  9. package/bridge/pwndbg/core_context.py +101 -0
  10. package/bridge/pwndbg/launch.py +39 -0
  11. package/bridge/pwndbg/launch_impl.py +34 -0
  12. package/bridge/pwntools/decoder_runtime.py +59 -0
  13. package/bridge/pwntools/layout.py +39 -0
  14. package/bridge/pwntools/layout_impl.py +309 -0
  15. package/bridge/pwntools/recorded_crash.py +39 -0
  16. package/bridge/pwntools/recorded_crash_impl.py +147 -0
  17. package/dist/android/JadxConfiguration.js +196 -33
  18. package/dist/android/JadxMcpTransport.js +4 -0
  19. package/dist/android/JadxProtocol.js +6 -0
  20. package/dist/android/JadxProvider.js +20 -2
  21. package/dist/android/JadxSession.js +23 -4
  22. package/dist/application/AnalysisContextQueries.js +8 -35
  23. package/dist/application/AnalysisDocument.js +32 -0
  24. package/dist/application/AppBundleExecutable.js +67 -21
  25. package/dist/application/CallPathTracing.js +19 -3
  26. package/dist/application/CapabilityInventory.js +27 -3
  27. package/dist/application/ClientConfigurationDocument.js +871 -6
  28. package/dist/application/ClientRegistrationIdentity.js +26 -5
  29. package/dist/application/ClientRegistrationStatus.js +29 -14
  30. package/dist/application/DirectAnalysis.js +97 -33
  31. package/dist/application/Doctor.js +4 -2
  32. package/dist/application/DoctorScope.js +25 -13
  33. package/dist/application/EnhancedLiteralTracing.js +22 -25
  34. package/dist/application/EnhancedTools.js +13 -11
  35. package/dist/application/EvidenceBundleFiles.js +24 -12
  36. package/dist/application/FunctionAnalysisEvidence.js +2 -3
  37. package/dist/application/InventoryProjectionEvidence.js +4 -3
  38. package/dist/application/InvestigationProviders.js +3 -2
  39. package/dist/application/JsonFiles.js +50 -28
  40. package/dist/application/ProcedureAddressResolution.js +11 -0
  41. package/dist/application/ReconstructionCoverageService.js +7 -4
  42. package/dist/application/ReconstructionObligationCandidates.js +5 -1
  43. package/dist/application/ReconstructionObligationLedgerService.js +4 -3
  44. package/dist/application/Setup.js +13 -1
  45. package/dist/application/SetupClientConfiguration.js +10 -15
  46. package/dist/application/SetupHost.js +5 -2
  47. package/dist/application/SetupPlan.js +5 -3
  48. package/dist/application/SupportedClients.js +34 -1
  49. package/dist/application/Uninstall.js +4 -3
  50. package/dist/application/Update.js +18 -3
  51. package/dist/application/UpdateRuntime.js +46 -25
  52. package/dist/application/WebModuleTraceService.js +4 -2
  53. package/dist/application/WebNetworkCapturePort.js +1 -0
  54. package/dist/application/WebNetworkCaptureService.js +134 -0
  55. package/dist/application/WebRuntimeService.js +5 -3
  56. package/dist/application/WebScriptExportService.js +2 -2
  57. package/dist/application/WebSourceLocationService.js +4 -2
  58. package/dist/application/WindowsCapabilities.js +1 -1
  59. package/dist/application/WorkflowEvidence.js +82 -0
  60. package/dist/application/binary/AnalysisProviderEvaluation.js +21 -5
  61. package/dist/application/binary/AnalysisProviderRegistry.js +2 -0
  62. package/dist/application/binary/AnalysisSnapshotCache.js +52 -12
  63. package/dist/application/binary/BinarySession.js +131 -76
  64. package/dist/application/binary/BinarySessionOpen.js +19 -6
  65. package/dist/application/binary/BinarySessionRecords.js +45 -3
  66. package/dist/application/binary/BinarySessionStatus.js +17 -1
  67. package/dist/application/binary/CompositeProvider.js +13 -0
  68. package/dist/application/binary/LazyAnalysisProvider.js +3 -0
  69. package/dist/application/binaryDiagnostics/BinaryLayoutPort.js +1 -0
  70. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +59 -0
  71. package/dist/application/binaryDiagnostics/RecordedCrashPort.js +1 -0
  72. package/dist/application/binaryDiagnostics/RecordedCrashService.js +62 -0
  73. package/dist/application/evm/EvmInterfacePort.js +1 -0
  74. package/dist/application/evm/EvmInterfaceService.js +64 -0
  75. package/dist/application/investigation/EvidenceLedger.js +21 -7
  76. package/dist/application/investigation/InvestigationRecords.js +8 -0
  77. package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
  78. package/dist/application/javascript/JavaScriptApplicationEvidence.js +25 -5
  79. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
  80. package/dist/application/javascript/JavaScriptApplicationService.js +34 -14
  81. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
  82. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +47 -27
  83. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +39 -7
  84. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +26 -2
  85. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +80 -27
  86. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +33 -12
  87. package/dist/application/javascript/JavaScriptModuleRelationships.js +37 -8
  88. package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
  89. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -1
  90. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
  91. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +7 -7
  92. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +149 -72
  93. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +14 -15
  94. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +41 -1
  95. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +7 -7
  96. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -9
  97. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +3 -3
  98. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +118 -12
  99. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -3
  100. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +27 -5
  101. package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
  102. package/dist/application/managed/ManagedMemberComparisonService.js +7 -4
  103. package/dist/application/managed/ManagedNativeVerificationService.js +4 -3
  104. package/dist/application/managed/ManagedReconstructionService.js +4 -3
  105. package/dist/application/{ProcessCli.js → process/ProcessCli.js} +23 -15
  106. package/dist/application/{ProcessEvidence.js → process/ProcessEvidence.js} +8 -7
  107. package/dist/application/workflowInputError.js +18 -0
  108. package/dist/artifacts/ArtifactProvider.js +42 -5
  109. package/dist/artifacts/ArtifactProviderMetadata.js +2 -1
  110. package/dist/artifacts/MachOSliceArtifactReader.js +98 -14
  111. package/dist/artifacts/NativeDmgArtifactReader.js +13 -6
  112. package/dist/artifacts/ZipArtifactReader.js +3 -0
  113. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +22 -3
  114. package/dist/artifacts/apple/DylibResolutionReader.js +259 -0
  115. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
  116. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
  117. package/dist/artifacts/apple/KeyedArchiveReader.js +36 -22
  118. package/dist/artifacts/apple/MachoLoadCommandReader.js +355 -0
  119. package/dist/artifacts/apple/NibArchive.js +81 -14
  120. package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
  121. package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
  122. package/dist/{application → artifacts/extraction}/ArtifactExtraction.js +10 -10
  123. package/dist/{application → artifacts/inventory}/ArtifactGraphConstruction.js +16 -11
  124. package/dist/{application → artifacts/inventory}/ArtifactInventory.js +4 -4
  125. package/dist/{application/ArtifactInventory → artifacts/inventory}/classify.js +2 -2
  126. package/dist/{application/ArtifactInventory → artifacts/inventory}/reader.js +5 -5
  127. package/dist/{application/ArtifactInventory → artifacts/inventory}/scanCanonical.js +14 -17
  128. package/dist/{application/ArtifactInventory → artifacts/inventory}/scanReader.js +5 -5
  129. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
  130. package/dist/artifacts/readStableArtifact.js +20 -4
  131. package/dist/browser/CdpCaptureCompleteness.js +2 -0
  132. package/dist/browser/CdpCaptureEventHandlers.js +165 -12
  133. package/dist/browser/CdpCaptureEventTypes.js +5 -1
  134. package/dist/browser/CdpCaptureEvents.js +34 -0
  135. package/dist/browser/CdpConnection.js +30 -11
  136. package/dist/browser/CdpOptionalCommand.js +2 -3
  137. package/dist/browser/CdpPageCapture.js +23 -1
  138. package/dist/browser/PlaywrightElectronActiveActions.js +32 -23
  139. package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
  140. package/dist/browser/PlaywrightElectronActiveProvider.js +130 -122
  141. package/dist/browser/WebSourceMapFetcher.js +426 -72
  142. package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
  143. package/dist/browser/history/CaptureFailures.js +137 -0
  144. package/dist/browser/history/CaptureFormatError.js +10 -0
  145. package/dist/browser/history/CaptureRedaction.js +65 -0
  146. package/dist/browser/history/CaptureRelease.js +17 -0
  147. package/dist/browser/history/HarCapture.js +165 -0
  148. package/dist/browser/history/HarCaptureAdapter.js +20 -0
  149. package/dist/browser/history/HarCaptureProcess.js +57 -0
  150. package/dist/browser/history/HarJson.js +92 -0
  151. package/dist/browser/history/HarSchema.js +72 -0
  152. package/dist/browser/history/HistoricalCaptureDecoder.js +188 -0
  153. package/dist/browser/history/HistoricalCaptureFormatAdapter.js +1 -0
  154. package/dist/browser/history/MitmproxyCaptureAdapter.js +42 -0
  155. package/dist/cli/analysisSelector.js +23 -0
  156. package/dist/cli/applicationCommands.js +2 -3
  157. package/dist/cli/artifactCommands.js +26 -1
  158. package/dist/cli/binaryDiagnosticsCommands.js +39 -0
  159. package/dist/cli/coreAnalysisCommands.js +2 -2
  160. package/dist/cli/coreBinaryCommands.js +78 -20
  161. package/dist/cli/electronCommands.js +21 -13
  162. package/dist/cli/evmCommands.js +24 -0
  163. package/dist/cli/firmwareCommands.js +6 -3
  164. package/dist/cli/javascriptApplicationAnalysis.js +20 -3
  165. package/dist/cli/jsonOutput.js +38 -0
  166. package/dist/cli/nativeCallCommands.js +34 -0
  167. package/dist/cli/processCommands.js +1 -1
  168. package/dist/cli/streamedJsonOutput.js +56 -0
  169. package/dist/cli/utilityCommands.js +2 -0
  170. package/dist/cli/webNetworkCaptureCommands.js +40 -0
  171. package/dist/cli/webRuntimeCommands.js +8 -8
  172. package/dist/cli.js +11 -4
  173. package/dist/cliBrowserScenarioCommands.js +2 -2
  174. package/dist/cliCommandNames.js +6 -1
  175. package/dist/cliJsonInput.js +35 -1
  176. package/dist/cliOutput.js +21 -6
  177. package/dist/composition/binaryDiagnostics.js +8 -0
  178. package/dist/composition/evm.js +4 -0
  179. package/dist/composition/webNetworkCaptures.js +6 -0
  180. package/dist/config/environment.js +4 -0
  181. package/dist/config/ghidraStartupTimeout.js +17 -0
  182. package/dist/config/mcpResponseBudget.js +22 -0
  183. package/dist/config/parseConfig.js +2 -1
  184. package/dist/contracts/artifactToolContracts.js +6 -0
  185. package/dist/contracts/browserCaptureToolInputSchema.js +43 -0
  186. package/dist/contracts/browserToolContracts.js +4 -3
  187. package/dist/contracts/enhancedInputs.js +5 -3
  188. package/dist/contracts/enhancedToolContracts.js +3 -3
  189. package/dist/contracts/errorSchemas.js +8 -1
  190. package/dist/contracts/evm/evmToolContracts.js +20 -0
  191. package/dist/contracts/hopperMemoryContracts.js +2 -5
  192. package/dist/contracts/investigationExamples.js +2 -2
  193. package/dist/contracts/javascript/electronToolContracts.js +1 -1
  194. package/dist/contracts/managed/managedToolContracts.js +8 -6
  195. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +42 -0
  196. package/dist/contracts/native/nativeToolContracts.js +21 -3
  197. package/dist/contracts/officialToolContracts.js +26 -24
  198. package/dist/contracts/process/processCaptureExample.js +2 -0
  199. package/dist/contracts/promptContracts.js +3 -3
  200. package/dist/contracts/sessionLifecycleInputs.js +18 -5
  201. package/dist/contracts/sessionStatusContract.js +8 -2
  202. package/dist/contracts/sessionToolContracts.js +8 -3
  203. package/dist/contracts/sessionToolSchemas.js +8 -4
  204. package/dist/contracts/toolContractExamples.js +1 -2
  205. package/dist/contracts/toolContractHelpers.js +4 -1
  206. package/dist/contracts/toolContracts.js +6 -0
  207. package/dist/contracts/toolEffects.js +30 -1
  208. package/dist/contracts/toolOutputSchemaGroups.js +33 -28
  209. package/dist/contracts/toolOutputSchemaPrimitives.js +19 -1
  210. package/dist/contracts/toolSchemaMetadata.js +69 -10
  211. package/dist/contracts/webNetworkCaptureToolContracts.js +24 -0
  212. package/dist/domain/analysisErrorBase.js +22 -2
  213. package/dist/domain/analysisErrorCore.js +61 -5
  214. package/dist/domain/analysisErrorPresentation.js +95 -12
  215. package/dist/domain/analysisErrorProjection.js +148 -19
  216. package/dist/domain/analysisSnapshot.js +166 -2
  217. package/dist/domain/android/androidAnalysis.js +2 -4
  218. package/dist/domain/android/androidApplication.js +17 -9
  219. package/dist/domain/apple/appleApplication.js +41 -14
  220. package/dist/domain/apple/dyldEnvironment.js +73 -0
  221. package/dist/domain/apple/dyldPaths.js +81 -0
  222. package/dist/domain/apple/dylibResolution.js +478 -0
  223. package/dist/domain/apple/dylibResolutionFindings.js +77 -0
  224. package/dist/domain/apple/interfaceBuilderGraph.js +25 -13
  225. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
  226. package/dist/domain/apple/keyedArchive.js +9 -1
  227. package/dist/domain/apple/machoContainer.js +54 -0
  228. package/dist/domain/apple/plistNumbers.js +76 -0
  229. package/dist/domain/artifactIdentity.js +29 -0
  230. package/dist/domain/artifactInventoryEvidence.js +19 -24
  231. package/dist/domain/artifactPathSyntax.js +1 -1
  232. package/dist/domain/bridgeCandidateProjection.js +71 -0
  233. package/dist/domain/browserCompleteness.js +1 -0
  234. package/dist/domain/browserObservation.js +1 -1
  235. package/dist/domain/browserObservationError.js +24 -5
  236. package/dist/domain/browserObservationSchemas.js +13 -0
  237. package/dist/domain/browserScenarioValues.js +5 -2
  238. package/dist/domain/bundleComparison.js +3 -2
  239. package/dist/domain/callPathSchemas.js +1 -1
  240. package/dist/domain/canonicalDigest.js +13 -1
  241. package/dist/domain/canonicalJsonDigestSteps.js +133 -0
  242. package/dist/domain/canonicalOrdering.js +9 -5
  243. package/dist/domain/changedBehavior.js +9 -9
  244. package/dist/domain/comparisonSourceEvidence.js +40 -0
  245. package/dist/domain/comparisonStatus.js +2 -30
  246. package/dist/domain/configurationErrors.js +1 -1
  247. package/dist/domain/conformanceTrustGate.js +0 -16
  248. package/dist/domain/evidence.js +78 -11
  249. package/dist/domain/evidenceBundle.js +42 -1
  250. package/dist/domain/evidenceErrors.js +12 -1
  251. package/dist/domain/evm/evmInterface.js +63 -0
  252. package/dist/domain/explicitSensitiveFailure.js +108 -0
  253. package/dist/domain/explicitSensitiveValues.js +10 -0
  254. package/dist/domain/firmware/firmwareAnalysis.js +10 -4
  255. package/dist/domain/hopperErrors.js +23 -2
  256. package/dist/domain/hopperValues.js +51 -8
  257. package/dist/domain/immutableJson.js +114 -0
  258. package/dist/domain/inputIssueProjection.js +3 -0
  259. package/dist/domain/javascript/electronActiveObservation.js +37 -6
  260. package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
  261. package/dist/domain/javascript/htmlArtifactReferences.js +40 -0
  262. package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
  263. package/dist/domain/javascript/javascriptApplicationGraph.js +13 -0
  264. package/dist/domain/javascript/javascriptAstValues.js +20 -0
  265. package/dist/domain/javascript/javascriptExportShapeComparison.js +21 -5
  266. package/dist/domain/javascript/javascriptExportShapeVariants.js +0 -10
  267. package/dist/domain/javascript/javascriptRecovery.js +3 -8
  268. package/dist/domain/javascript/javascriptSemanticAnalysis.js +97 -2
  269. package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
  270. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
  271. package/dist/domain/javascript/javascriptSemanticDataEffects.js +22 -5
  272. package/dist/domain/javascript/javascriptSemanticGraph.js +34 -5
  273. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
  274. package/dist/domain/javascript/javascriptSemanticPrimitives.js +25 -17
  275. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
  276. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
  277. package/dist/domain/javascript/javascriptSemanticValues.js +83 -11
  278. package/dist/domain/javascript/javascriptSourceParser.js +6 -2
  279. package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
  280. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
  281. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +14 -4
  282. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
  283. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -16
  284. package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
  285. package/dist/domain/jsonSerialization.js +109 -0
  286. package/dist/domain/jsonValue.js +91 -3
  287. package/dist/domain/localPath.js +8 -0
  288. package/dist/domain/managed/managedApplicationGraph.js +10 -10
  289. package/dist/domain/managed/managedInspectionEvidence.js +16 -0
  290. package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
  291. package/dist/domain/managed/managedNativeVerification.js +3 -9
  292. package/dist/domain/native/binaryLayout.js +357 -0
  293. package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
  294. package/dist/domain/native/nativeCallObservation.js +186 -0
  295. package/dist/domain/native/nativeCallPartialObservation.js +33 -0
  296. package/dist/domain/native/objcSwiftMetadata.js +0 -39
  297. package/dist/domain/native/recordedCrash.js +266 -0
  298. package/dist/domain/native/recordedCrashNoteCoverage.js +73 -0
  299. package/dist/domain/{processCapture.js → process/processCapture.js} +143 -2
  300. package/dist/domain/{processCaptureExample.js → process/processCaptureExample.js} +5 -0
  301. package/dist/domain/process/processCaptureParsing.js +54 -0
  302. package/dist/domain/{processCaptureValidation.js → process/processCaptureValidation.js} +18 -2
  303. package/dist/domain/{processComparison.js → process/processComparison.js} +39 -5
  304. package/dist/domain/{processObservation.js → process/processObservation.js} +1 -1
  305. package/dist/domain/{processScenario.js → process/processScenario.js} +11 -10
  306. package/dist/domain/{processTraceSpecification.js → process/processTraceSpecification.js} +1 -1
  307. package/dist/domain/propertyListKeys.js +1 -1
  308. package/dist/domain/propertyListXmlText.js +19 -0
  309. package/dist/domain/providerAdapterError.js +1 -1
  310. package/dist/domain/providerOperationHealth.js +54 -0
  311. package/dist/domain/providerSelectionError.js +4 -2
  312. package/dist/domain/reconstructionVerification.js +9 -46
  313. package/dist/domain/reconstructionVerificationSchemas.js +3 -3
  314. package/dist/domain/residualUnknown.js +3 -2
  315. package/dist/domain/staticRuntimeCorrelation.js +9 -46
  316. package/dist/domain/webBundleAnalysis.js +20 -8
  317. package/dist/domain/webBundleAnalyzerInspection.js +13 -8
  318. package/dist/domain/webBundleAnalyzerResult.js +41 -2
  319. package/dist/domain/webCaptureDiff.js +1 -0
  320. package/dist/domain/webNetworkCapture.js +118 -0
  321. package/dist/domain/webNetworkCaptureCoordinates.js +58 -0
  322. package/dist/domain/webRuntime.js +19 -5
  323. package/dist/domain/webSourceLocation.js +1 -0
  324. package/dist/dotnet/ManagedExceptionRegionValidation.js +41 -0
  325. package/dist/dotnet/ManagedMemberInspector.js +4 -2
  326. package/dist/dotnet/ManagedMemberInspectorCore.js +38 -32
  327. package/dist/dotnet/ManagedMemberInstructionDecoder.js +23 -7
  328. package/dist/dotnet/ManagedMemberRows.js +14 -3
  329. package/dist/dotnet/ManagedMetadataHeaps.js +20 -2
  330. package/dist/dotnet/ManagedMetadataInventory.js +38 -28
  331. package/dist/dotnet/ManagedMetadataInventoryRows.js +24 -10
  332. package/dist/dotnet/ManagedMethodBodyReader.js +7 -1
  333. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +15 -3
  334. package/dist/dotnet/ManagedNativeBoundaryInspector.js +3 -1
  335. package/dist/dotnet/ManagedPeReader.js +11 -0
  336. package/dist/evm/EvmBytecodeCarrier.js +21 -0
  337. package/dist/evm/EvmWorkerLimits.js +40 -0
  338. package/dist/evm/EvmoleFailures.js +126 -0
  339. package/dist/evm/EvmoleInterfaceAdapter.js +53 -0
  340. package/dist/evm/EvmoleInterfaceProvider.js +273 -0
  341. package/dist/evm/EvmoleInterfaceWorker.js +87 -0
  342. package/dist/evm/EvmoleRelease.js +16 -0
  343. package/dist/firmware/FirmwareCommand.js +1 -0
  344. package/dist/firmware/FirmwareFiles.js +1 -1
  345. package/dist/generatedPackageMetadata.js +2 -2
  346. package/dist/ghidra/GhidraAnalysisProfile.js +5 -0
  347. package/dist/ghidra/GhidraClient.js +47 -14
  348. package/dist/ghidra/GhidraDiagnostics.js +7 -7
  349. package/dist/ghidra/GhidraFunctionValues.js +10 -7
  350. package/dist/ghidra/GhidraInstallation.js +18 -21
  351. package/dist/ghidra/GhidraInventoryValues.js +14 -4
  352. package/dist/ghidra/GhidraJavaLaunch.js +62 -0
  353. package/dist/ghidra/GhidraLauncher.js +34 -16
  354. package/dist/ghidra/GhidraProvider.js +2 -2
  355. package/dist/ghidra/GhidraProviderCapabilities.js +15 -3
  356. package/dist/ghidra/GhidraProviderClient.js +23 -12
  357. package/dist/ghidra/GhidraSessionError.js +11 -7
  358. package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
  359. package/dist/ghidra/GhidraTransport.js +20 -0
  360. package/dist/hopper/BridgeLauncher.js +33 -11
  361. package/dist/hopper/HopperAnalysisProfile.js +62 -4
  362. package/dist/hopper/HopperCleanup.js +15 -3
  363. package/dist/hopper/HopperClient.js +222 -14
  364. package/dist/hopper/HopperFileOffset.js +237 -0
  365. package/dist/hopper/HopperMachOImage.js +196 -0
  366. package/dist/hopper/HopperOperationStage.js +6 -0
  367. package/dist/hopper/HopperProvider.js +63 -9
  368. package/dist/hopper/HopperProviderCapabilities.js +19 -1
  369. package/dist/hopper/HopperRegexSearch.js +137 -0
  370. package/dist/hopper/HopperRegexWorker.js +27 -0
  371. package/dist/hopper/HopperRequestQueue.js +68 -19
  372. package/dist/hopper/HopperTargetLease.js +3 -2
  373. package/dist/hopper/LinuxPrivateDisplayProbe.js +4 -2
  374. package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
  375. package/dist/inspector/V8InspectorCaptureProjection.js +8 -3
  376. package/dist/inspector/V8InspectorProvider.js +47 -11
  377. package/dist/javascript/recovery/WakaruCommand.js +3 -0
  378. package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
  379. package/dist/javascript/sourceMaps/SourceMapCommand.js +17 -0
  380. package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
  381. package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
  382. package/dist/mcpDoctor.js +62 -2
  383. package/dist/native/AppleDispatchCoverage.js +47 -6
  384. package/dist/native/AppleDispatchDecodeFacts.js +6 -0
  385. package/dist/native/AppleDispatchMetadata.js +6 -3
  386. package/dist/native/AppleMachoFixups.js +48 -24
  387. package/dist/native/AppleMachoSelection.js +32 -16
  388. package/dist/native/AppleObjcCategories.js +6 -2
  389. package/dist/native/AppleObjcDispatchFacets.js +5 -2
  390. package/dist/native/AppleObjcProperties.js +2 -1
  391. package/dist/native/AppleSwiftDispatchFacets.js +27 -21
  392. package/dist/native/AppleSwiftVtables.js +21 -15
  393. package/dist/native/CommandRunner.js +82 -84
  394. package/dist/native/LldbCallTracer.js +541 -0
  395. package/dist/native/LldbRetainedObservations.js +178 -0
  396. package/dist/native/NativeCallObservation.js +194 -0
  397. package/dist/native/NativeMacOSProvider.js +117 -20
  398. package/dist/native/NativeMacOSProviderMetadata.js +8 -3
  399. package/dist/native/SignatureTargetBinding.js +155 -0
  400. package/dist/native/parsers/lipo.js +71 -1
  401. package/dist/native/pwndbg/PwndbgCoreContext.js +180 -0
  402. package/dist/native/pwntools/PwntoolsDecoder.js +203 -0
  403. package/dist/native/pwntools/PwntoolsFailures.js +180 -0
  404. package/dist/native/pwntools/PwntoolsLayoutProvider.js +36 -0
  405. package/dist/native/pwntools/PwntoolsRecordedCrashProvider.js +75 -0
  406. package/dist/native/pwntools/PwntoolsRelease.js +19 -0
  407. package/dist/native/pwntools/PwntoolsResourceLimits.js +76 -0
  408. package/dist/native/pwntools/RecordedCrashSourceBindings.js +46 -0
  409. package/dist/native/pwntools/RecordedCrashStructureBindings.js +103 -0
  410. package/dist/process/DarwinProcessRunTokenReader.js +293 -0
  411. package/dist/process/ExecFileOutput.js +20 -0
  412. package/dist/process/OwnedCommand.js +118 -0
  413. package/dist/process/ProcessOwnership.js +431 -51
  414. package/dist/process/ProcessOwnershipObservation.js +209 -27
  415. package/dist/process/ProviderProcess.js +68 -10
  416. package/dist/{application → process/capture}/ProcessCaptureCapability.js +15 -0
  417. package/dist/{application → process/capture}/ProcessCaptureError.js +18 -2
  418. package/dist/process/capture/ProcessCaptureLifecycle.js +681 -0
  419. package/dist/{application → process/capture}/ProcessHarness.js +195 -29
  420. package/dist/{application → process/capture}/ProcessSampling.js +2 -2
  421. package/dist/server/EvidenceMcpServer.js +146 -0
  422. package/dist/server/createServer.js +37 -8
  423. package/dist/server/promptCompletion.js +10 -3
  424. package/dist/server/registerAndroidTools.js +2 -4
  425. package/dist/server/registerApplicationTools/helpers.js +2 -4
  426. package/dist/server/registerArtifactComparisonTool.js +11 -7
  427. package/dist/server/registerBinaryDiagnosticsTools.js +15 -0
  428. package/dist/server/registerBrowserScenarioTool.js +2 -4
  429. package/dist/server/registerBrowserTools.js +2 -4
  430. package/dist/server/registerBundleComparisonTool.js +2 -3
  431. package/dist/server/registerCloseLifecycleTool.js +8 -18
  432. package/dist/server/registerElectronTools.js +2 -4
  433. package/dist/server/registerEnhancedTools.js +18 -59
  434. package/dist/server/registerEvidenceTools.js +3 -5
  435. package/dist/server/registerEvmTools.js +15 -0
  436. package/dist/server/registerFirmwareTools.js +2 -4
  437. package/dist/server/registerFunctionComparisonTool.js +10 -6
  438. package/dist/server/registerInvestigationTools.js +7 -7
  439. package/dist/server/registerJavaScriptRecoveryTool.js +2 -4
  440. package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -4
  441. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +2 -4
  442. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +2 -4
  443. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +2 -4
  444. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +2 -4
  445. package/dist/server/registerOfficialTools.js +2 -4
  446. package/dist/server/registerProcessComparisonTool.js +72 -46
  447. package/dist/server/registerRecordedCrashTools.js +15 -0
  448. package/dist/server/registerSessionRecordTools.js +5 -6
  449. package/dist/server/registerSessionStatusTool.js +17 -3
  450. package/dist/server/registerSessionTools.js +13 -5
  451. package/dist/server/registerWebModuleTool.js +2 -4
  452. package/dist/server/registerWebNetworkCaptureTool.js +26 -0
  453. package/dist/server/registerWebRuntimeTools.js +3 -7
  454. package/dist/server/registerWebScriptTool.js +2 -4
  455. package/dist/server/registerWebSourceLocationTool.js +2 -4
  456. package/dist/server/runDerivedOperation.js +15 -3
  457. package/dist/server/sessionAvailabilityPolicy.js +3 -1
  458. package/dist/server/sessionToolPolicies.js +1 -1
  459. package/dist/server/toolRegistrationOptions.js +2 -2
  460. package/dist/server/toolResult.js +63 -11
  461. package/dist/server/toolResultEncoding.js +33 -0
  462. package/install.sh +1 -1
  463. package/native/windows/build/manifest.json +2 -2
  464. package/native/windows/build/rea-windows-x64.node +0 -0
  465. package/package.json +42 -9
  466. package/scripts/electron-active-hook-boundaries.cjs +18 -20
  467. package/scripts/electron-active-hook.cjs +241 -37
  468. package/scripts/rea.mjs +11 -3
  469. package/skills/reverse-engineer-anything/SKILL.md +32 -4
  470. package/skills/reverse-engineer-anything/references/javascript-applications.md +8 -1
  471. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +29 -0
  472. package/third_party/README.md +60 -0
  473. package/third_party/evmole/LICENSE +21 -0
  474. package/third_party/evmole/README.md +22 -0
  475. package/third_party/pwndbg/LICENSE.md +21 -0
  476. package/third_party/pwndbg/README.md +23 -0
  477. package/third_party/pwntools/README.md +40 -0
  478. package/dist/application/AuthorizedArtifactInventory.js +0 -7
  479. package/dist/application/ProcessCaptureLifecycle.js +0 -299
  480. package/dist/application/StoreFileLock.js +0 -124
  481. package/dist/contracts/processCaptureExample.js +0 -2
  482. package/dist/domain/bytecodeProvider.js +0 -178
  483. package/dist/domain/customProtocolCapture.js +0 -137
  484. package/dist/domain/eventProcessTree.js +0 -225
  485. package/dist/domain/mobileApplicationInvestigation.js +0 -159
  486. package/dist/domain/packageAnalysis.js +0 -123
  487. package/dist/domain/peInspection.js +0 -197
  488. package/dist/domain/processCaptureParsing.js +0 -21
  489. package/dist/domain/protocolCapture.js +0 -217
  490. package/dist/domain/runtimeIdentification.js +0 -212
  491. package/dist/generatedMcpToolCatalog.js +0 -37
  492. package/dist/ghidra/GhidraDefaults.js +0 -2
  493. /package/dist/application/{ArtifactExtractionDestination.js → artifacts/ArtifactExtractionDestination.js} +0 -0
  494. /package/dist/{application/ArtifactInventory → artifacts/inventory}/policy.js +0 -0
  495. /package/dist/{application/ArtifactInventory → artifacts/inventory}/types.js +0 -0
  496. /package/dist/domain/{processEvidenceProvider.js → process/processEvidenceProvider.js} +0 -0
  497. /package/dist/domain/{processTraceComparison.js → process/processTraceComparison.js} +0 -0
  498. /package/dist/domain/{processTraceDimensionProjection.js → process/processTraceDimensionProjection.js} +0 -0
  499. /package/dist/domain/{processTraceEvaluation.js → process/processTraceEvaluation.js} +0 -0
  500. /package/dist/{application → process/capture}/FilesystemSnapshot.js +0 -0
  501. /package/dist/{application → process/capture}/ProcessCaptureEnvironment.js +0 -0
  502. /package/dist/{application → process/capture}/ProcessCaptureJournal.js +0 -0
  503. /package/dist/{application → process/capture}/ProcessFilesystemEffects.js +0 -0
  504. /package/dist/{application → process/capture}/ProcessNormalization.js +0 -0
  505. /package/dist/{application → process/capture}/ProcessScenarioRuntimeValidation.js +0 -0
  506. /package/dist/{application → process/capture}/ProcessTimer.js +0 -0
  507. /package/dist/{application → process/capture}/TerminalRenderer.js +0 -0
@@ -4,6 +4,11 @@ import { accessSync, readFileSync } from "node:fs";
4
4
  import { posix, win32 } from "node:path";
5
5
  import { ghidraApplicationProperties, ghidraJavaMajorAccepted, ghidraJavaRangeLabel, ghidraJavaRequirement, ghidraReleaseAccepted, ghidraReleaseCompatibility, ghidraReleaseLine, ghidraVersionDetail, SUPPORTED_GHIDRA_JAVA_MAJOR, SUPPORTED_GHIDRA_VERSION, } from "./GhidraInstallationPolicy.js";
6
6
  export { SUPPORTED_GHIDRA_JAVA_MAJOR, SUPPORTED_GHIDRA_VERSION };
7
+ const NATIVE_PLATFORMS = {
8
+ linux: { x64: "linux_x86_64", arm64: "linux_arm_64" },
9
+ darwin: { x64: "mac_x86_64", arm64: "mac_arm_64" },
10
+ win32: { x64: "win_x86_64" },
11
+ };
7
12
  /** Inspect an installation without importing a target or modifying Ghidra. */
8
13
  export const inspectGhidraInstallation = (options, host = systemGhidraInstallationHost()) => {
9
14
  const platform = options.platform ?? process.platform;
@@ -67,16 +72,13 @@ const installationCoordinates = (options, platform, architecture, host) => {
67
72
  const analyzeHeadlessPath = installDir === null
68
73
  ? null
69
74
  : path.join(installDir, "support", platform === "win32" ? "analyzeHeadless.bat" : "analyzeHeadless");
70
- const decompilerPlatform = platform === "darwin"
71
- ? architecture === "arm64"
72
- ? "mac_arm_64"
73
- : "mac_x86_64"
74
- : null;
75
- const nativeDecompilerPath = installDir === null || decompilerPlatform === null
75
+ const decompilerPlatform = NATIVE_PLATFORMS[platform]?.[architecture];
76
+ const decompilerExecutable = platform === "win32" ? "decompile.exe" : "decompile";
77
+ const nativeDecompilerPath = installDir === null || decompilerPlatform === undefined
76
78
  ? null
77
79
  : ([
78
- path.join(installDir, "Ghidra", "Features", "Decompiler", "os", decompilerPlatform, "decompile"),
79
- path.join(installDir, "Ghidra", "Features", "Decompiler", "build", "os", decompilerPlatform, "decompile"),
80
+ path.join(installDir, "Ghidra", "Features", "Decompiler", "os", decompilerPlatform, decompilerExecutable),
81
+ path.join(installDir, "Ghidra", "Features", "Decompiler", "build", "os", decompilerPlatform, decompilerExecutable),
80
82
  ].find((candidate) => host.executable(candidate)) ?? null);
81
83
  const properties = applicationPropertiesPath === null
82
84
  ? undefined
@@ -108,20 +110,17 @@ const installationChecks = ({ coordinates, platform, architecture, javaHome, hos
108
110
  }),
109
111
  installationCheck({
110
112
  name: "platform",
111
- passed: platform === "linux" || platform === "win32" || platform === "darwin",
113
+ passed: NATIVE_PLATFORMS[platform] !== undefined,
112
114
  code: "unsupported_host",
113
115
  detail: platform,
114
- remediation: "Use Linux or Windows x64, or macOS x64/arm64 with matching native Ghidra tools.",
116
+ remediation: "Use Linux or macOS x64/arm64, or Windows x64 with matching native Ghidra tools.",
115
117
  }),
116
118
  installationCheck({
117
119
  name: "architecture",
118
- passed: ((platform === "linux" || platform === "win32") &&
119
- architecture === "x64") ||
120
- (platform === "darwin" &&
121
- (architecture === "x64" || architecture === "arm64")),
120
+ passed: NATIVE_PLATFORMS[platform]?.[architecture] !== undefined,
122
121
  code: "unsupported_host",
123
122
  detail: architecture,
124
- remediation: "Use x64 on Linux or Windows, or x64/arm64 on macOS.",
123
+ remediation: "Use x64/arm64 on Linux or macOS, or x64 on Windows.",
125
124
  }),
126
125
  installationCheck({
127
126
  name: "installation",
@@ -142,13 +141,11 @@ const installationChecks = ({ coordinates, platform, architecture, javaHome, hos
142
141
  }),
143
142
  installationCheck({
144
143
  name: "native_decompiler",
145
- passed: platform !== "darwin" || coordinates.nativeDecompilerPath !== null,
144
+ passed: coordinates.nativeDecompilerPath !== null,
146
145
  code: "executable_missing",
147
- detail: platform !== "darwin"
148
- ? "not required on this platform"
149
- : (coordinates.nativeDecompilerPath ??
150
- "matching macOS native decompiler was not found"),
151
- remediation: "REA does not build native tools. Build Ghidra's native components for this macOS architecture or provide an installation containing Ghidra/Features/Decompiler/os/<platform>/decompile.",
146
+ detail: coordinates.nativeDecompilerPath ??
147
+ `Matching native decompiler for ${platform}/${architecture} was not found`,
148
+ remediation: `Provide an executable Ghidra/Features/Decompiler/os/${NATIVE_PLATFORMS[platform]?.[architecture] ?? "<platform>"}/${platform === "win32" ? "decompile.exe" : "decompile"}, or its build/os equivalent. REA does not build or install native tools.`,
152
149
  }),
153
150
  javaCheck(coordinates.java, coordinates.javaCommand, javaHome, coordinates.properties),
154
151
  ];
@@ -1,9 +1,10 @@
1
1
  import { z } from "zod";
2
2
  import { nativeLoadImageObservationSchema } from "../domain/native/nativeLoadImage.js";
3
- import { AnalysisInputError, AnalysisOutputError, } from "../domain/analysisErrorCore.js";
3
+ import { AnalysisOutputError, } from "../domain/analysisErrorCore.js";
4
4
  import { functionBodySchema, functionBodyEntryAgrees, } from "../domain/hopperValues.js";
5
5
  import { jsonValueSchema } from "../domain/jsonValue.js";
6
6
  import { err, ok } from "../domain/result.js";
7
+ import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
7
8
  /** Read-only direct inventory operations admitted by the Ghidra adapter. */
8
9
  export const GHIDRA_INVENTORY_OPERATIONS = [
9
10
  "inspect_native_load_image",
@@ -26,7 +27,11 @@ export const isGhidraInventoryOperation = (operation) => operationSet.has(operat
26
27
  export const ghidraIdentifierSchema = z.string().min(1);
27
28
  const identifier = ghidraIdentifierSchema;
28
29
  const document = identifier.nullable().default(null);
29
- const explicitAddress = identifier;
30
+ /** Caller address spelling; the bridge resolves its space and emits canonical output. */
31
+ export const ghidraInputAddressSchema = z
32
+ .string()
33
+ .regex(/^(?:(?:0[xX])?[0-9a-fA-F]+|(?:[A-Za-z0-9._~-]|%[0-9a-fA-F]{2})+:0[xX][0-9a-fA-F]+)$/u, "Use hexadecimal digits, optionally prefixed with 0x, or an encoded address-space name followed by :0x and hexadecimal digits");
34
+ const explicitAddress = ghidraInputAddressSchema;
30
35
  const filteredAddress = explicitAddress.nullable().default(null);
31
36
  const searchInput = {
32
37
  pattern: z.string().min(1),
@@ -62,7 +67,9 @@ const inputSchemas = {
62
67
  export const parseGhidraInventoryInput = (operation, value) => {
63
68
  const parsed = inputSchemas[operation].safeParse(value);
64
69
  if (!parsed.success)
65
- return err(new AnalysisInputError(operation, { cause: parsed.error }));
70
+ return err(analysisInputErrorFromIssues(operation, parsed.error.issues, value, {
71
+ cause: parsed.error,
72
+ }));
66
73
  return ok(parsed.data);
67
74
  };
68
75
  export const ghidraCanonicalAddressSchema = z
@@ -171,7 +178,10 @@ const containingProcedure = z.discriminatedUnion("found", [
171
178
  .strict()
172
179
  .superRefine((value, context) => {
173
180
  const body = value.procedure.body;
174
- if (body.available &&
181
+ const exactExternalEntry = value.procedure.classification.external &&
182
+ value.query_address === value.procedure.address;
183
+ if (!exactExternalEntry &&
184
+ body.available &&
175
185
  !functionBodyEntryAgrees({ ...body, contains_entry: true }, value.query_address))
176
186
  context.addIssue({
177
187
  code: "custom",
@@ -0,0 +1,62 @@
1
+ import { dirname, join } from "node:path";
2
+ import { execFileOutput } from "../process/ExecFileOutput.js";
3
+ /** Launch coordinates obtained from Ghidra's own release configuration helper. */
4
+ export const ghidraJavaLaunch = async (options) => {
5
+ const supportRoot = dirname(options.analyzeHeadlessPath);
6
+ const installRoot = dirname(supportRoot);
7
+ const command = join(options.javaHome, "bin", "java");
8
+ const isolatedProperties = [
9
+ `-Duser.home=${options.homeRoot}`,
10
+ `-Djava.io.tmpdir=${options.tempRoot}`,
11
+ ];
12
+ const supportArguments = [
13
+ ...isolatedProperties,
14
+ "-cp",
15
+ join(supportRoot, "LaunchSupport.jar"),
16
+ "LaunchSupport",
17
+ installRoot,
18
+ ];
19
+ const environment = { ...options.environment };
20
+ const configuredEnvironment = await execFileOutput(command, [...supportArguments, "-envvars"], {
21
+ env: environment,
22
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
23
+ });
24
+ for (const line of configuredEnvironment.stdout.split(/\r?\n/u)) {
25
+ if (line === "")
26
+ continue;
27
+ const separator = line.indexOf("=");
28
+ const key = line.slice(0, separator);
29
+ if (separator < 1 || !/^[A-Za-z_][A-Za-z0-9_]*$/u.test(key))
30
+ throw new Error(`Invalid Ghidra LaunchSupport environment entry: ${line}`);
31
+ if ((environment[key] ?? "") === "")
32
+ environment[key] = line.slice(separator + 1);
33
+ }
34
+ const configuredArguments = await execFileOutput(command, [...supportArguments, "-vmargs"], {
35
+ env: environment,
36
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
37
+ });
38
+ const vmArguments = configuredArguments.stdout
39
+ .split(/\r?\n/u)
40
+ .filter((line) => line !== "");
41
+ if (vmArguments.some((argument) => !argument.startsWith("-") || argument.includes("\0")))
42
+ throw new Error("Invalid Ghidra LaunchSupport JVM argument");
43
+ return {
44
+ command,
45
+ environment,
46
+ arguments: [
47
+ ...vmArguments,
48
+ ...(options.platform === "darwin" ? ["-Xdock:name=Ghidra-Headless"] : []),
49
+ `-Xmx${environment.GHIDRA_HEADLESS_MAXMEM || environment.GHIDRA_MAXMEM || "2G"}`,
50
+ "-XX:ParallelGCThreads=2",
51
+ "-XX:CICompilerCount=2",
52
+ "-Djava.awt.headless=true",
53
+ ...isolatedProperties,
54
+ "-showversion",
55
+ "-cp",
56
+ join(installRoot, "Ghidra", "Framework", "Utility", "lib", "Utility.jar"),
57
+ "ghidra.Ghidra",
58
+ "ghidra.app.util.headless.AnalyzeHeadless",
59
+ ...options.arguments,
60
+ ],
61
+ };
62
+ };
@@ -7,6 +7,7 @@ import { err, ok } from "../domain/result.js";
7
7
  import { cleanupOwnedProcessGroup, cleanupWindowsProcessTree, } from "../process/ProcessOwnership.js";
8
8
  import { spawnOwnedProviderProcess, } from "../process/ProviderProcess.js";
9
9
  import { ghidraJavaEnvironment } from "./GhidraInstallation.js";
10
+ import { ghidraJavaLaunch } from "./GhidraJavaLaunch.js";
10
11
  import { snapshotGhidraExtensions, } from "./extensions/GhidraExtensions.js";
11
12
  /** Local launch failure retained as the cause of a provider-neutral error. */
12
13
  export class GhidraLaunchError extends Error {
@@ -58,7 +59,7 @@ export class GhidraHeadlessLauncher {
58
59
  ? {}
59
60
  : { dosMz: this.options.dosMz }),
60
61
  });
61
- const command = ghidraHeadlessCommand({
62
+ const scriptCommand = ghidraHeadlessCommand({
62
63
  platform,
63
64
  analyzeHeadlessPath: this.options.analyzeHeadlessPath,
64
65
  arguments: headlessArguments,
@@ -66,24 +67,45 @@ export class GhidraHeadlessLauncher {
66
67
  ? {}
67
68
  : { comSpec: this.options.comSpec }),
68
69
  });
70
+ const environment = ghidraLaunchEnvironment(paths, this.options.javaHome, platform, scriptCommand.command);
71
+ if (platform !== "win32" && this.options.javaHome === undefined)
72
+ throw new GhidraLaunchError("POSIX Ghidra requires its inspected JDK home");
73
+ const command = platform !== "win32" && this.options.javaHome !== undefined
74
+ ? await ghidraJavaLaunch({
75
+ platform,
76
+ analyzeHeadlessPath: this.options.analyzeHeadlessPath,
77
+ javaHome: this.options.javaHome,
78
+ homeRoot: paths.homeRoot,
79
+ tempRoot: paths.tempRoot,
80
+ arguments: headlessArguments,
81
+ environment,
82
+ ...(options.signal === undefined
83
+ ? {}
84
+ : { signal: options.signal }),
85
+ })
86
+ : { ...scriptCommand, environment };
69
87
  started = await spawnOwnedProviderProcess({
70
88
  command: command.command,
71
89
  arguments: command.arguments,
72
90
  runId: session.runId,
73
- // analyzeHeadless is an interpreter-driven script. Parent identity and
74
- // the per-process run token remain the cleanup authority.
75
- expectedCommand: null,
91
+ // POSIX launches the inspected JVM directly; script wrappers cannot
92
+ // preserve JVM property paths containing spaces as single arguments.
93
+ expectedCommand: platform !== "win32" ? command.command : null,
76
94
  windowsVerbatimArguments: platform === "win32",
77
95
  platform,
78
- env: ghidraLaunchEnvironment(paths, this.options.javaHome, platform, command.command),
96
+ env: command.environment,
97
+ ...(options.signal === undefined ? {} : { signal: options.signal }),
79
98
  });
80
99
  await writeGhidraRuntimeFile(paths.ownershipPath, `${JSON.stringify({
81
100
  run_id: session.runId,
101
+ transport: session.transport,
102
+ endpoint_path: session.endpointPath,
82
103
  pid: started.ownership.leaderPid,
83
104
  process_group_id: started.ownership.processGroupId,
84
105
  parent_pid: process.pid,
85
106
  ownership_kind: platform === "win32" ? "windows-job-object" : "posix-process-group",
86
- launcher: this.options.analyzeHeadlessPath,
107
+ launcher: command.command,
108
+ headless_script: this.options.analyzeHeadlessPath,
87
109
  created_at: new Date().toISOString(),
88
110
  })}\n`, platform);
89
111
  if (isAborted(options.signal)) {
@@ -266,22 +288,18 @@ const ghidraLaunchEnvironment = (paths, javaHome, platform, executable) => {
266
288
  XDG_DATA_HOME: paths.dataRoot,
267
289
  };
268
290
  };
269
- /** Encode provider-owned JVM paths for the parser that actually consumes them. */
291
+ /** Encode provider-owned JVM paths for the platform launcher that consumes them. */
270
292
  export const ghidraHeadlessJavaOptions = (homeRoot, tempRoot, platform) => {
271
293
  const options = [`-Duser.home=${homeRoot}`, `-Djava.io.tmpdir=${tempRoot}`];
272
- // analyzeHeadless.bat quotes VMARG_LIST, then launch.bat expands it again.
273
- // Inner quotes fail in cmd.exe; unquoted paths with spaces split at the JVM.
274
- // JDK_JAVA_OPTIONS is parsed by Java itself, outside that batch expansion.
275
- return platform === "win32"
276
- ? {
294
+ if (platform === "win32")
295
+ return {
277
296
  JDK_JAVA_OPTIONS: [...options, "-XX:-UsePerfData"]
278
297
  .map(quoteWindowsBatchToken)
279
298
  .join(" "),
280
299
  GHIDRA_HEADLESS_JAVA_OPTIONS: "",
281
- }
282
- : {
283
- JDK_JAVA_OPTIONS: "",
284
- GHIDRA_HEADLESS_JAVA_OPTIONS: options.join(" "),
285
300
  };
301
+ // POSIX launches the JVM directly, so these properties travel as separate
302
+ // argv items instead of the shell-split analyzeHeadless option list.
303
+ return { JDK_JAVA_OPTIONS: "", GHIDRA_HEADLESS_JAVA_OPTIONS: "" };
286
304
  };
287
305
  const isAborted = (signal) => signal?.aborted === true;
@@ -163,11 +163,11 @@ const inspectWindowsP0TargetSupport = (target, diagnostics) => {
163
163
  reason: "Windows Ghidra P0 accepts PE targets only.",
164
164
  diagnostics,
165
165
  };
166
- if (target.architecture !== "x86_64")
166
+ if (target.architecture !== "x86" && target.architecture !== "x86_64")
167
167
  return {
168
168
  status: "unsupported",
169
169
  code: "architecture_unsupported",
170
- reason: "Windows Ghidra P0 accepts x86-64 PE targets only.",
170
+ reason: "Windows Ghidra P0 accepts x86 and x86-64 PE targets only.",
171
171
  diagnostics,
172
172
  };
173
173
  if (target.executableRole !== "application")
@@ -16,10 +16,11 @@ export const GHIDRA_OPERATIONS = Object.freeze([
16
16
  export const healthLimitations = Object.freeze([
17
17
  "The session serves operations only after Ghidra reports default auto-analysis complete; incomplete analysis does not expose partial results.",
18
18
  "The imported Program and temporary project are ephemeral and deleted on close. Annotation operations edit session database metadata; original executable bytes are never written.",
19
+ "Cancelling an active Ghidra request terminates its ephemeral database and discards session annotations. The selected target remains open; the next provider query imports the original artifact again.",
19
20
  ]);
20
21
  /** Additional limitations applied to the experimental Windows x64 P0 boundary. */
21
22
  export const windowsP0Limitations = Object.freeze([
22
- "Windows Ghidra P0 accepts approved native x86-64 PE applications only; DLL, managed, hostile, sensitive, and mutable-path targets are unsupported.",
23
+ "Windows Ghidra P0 accepts approved native x86 and x86-64 PE applications only; DLL, managed, hostile, sensitive, and mutable-path targets are unsupported.",
23
24
  "The Windows bridge uses authenticated IPv4 loopback because Node path-based IPC does not expose Java AF_UNIX sockets; the endpoint file contains no bearer token.",
24
25
  "Windows sessions require the matching packaged Windows x64 native addon, local NTFS targets and runtimes, and Windows 10 or later. Native handles enforce path admission, private DACLs, and Job Object ownership automatically.",
25
26
  ]);
@@ -33,7 +34,8 @@ export const limitationsFor = (operation) => {
33
34
  case "annotate_native_function":
34
35
  return [
35
36
  ...common,
36
- "Names use Ghidra USER_DEFINED source. Name writes preserve the existing namespace; readback uses the fully qualified name. Regular comments map to PRE and inline comments to EOL at the exact function entry. Changes commit together after readback and refreshed analysis; failure rolls them all back.",
37
+ "Names use Ghidra USER_DEFINED source. Name writes accept a leaf name or a fully qualified name within the existing namespace; readback uses the fully qualified name and can be reused without adding namespace prefixes. Edits retain the current namespace; other namespace-like text remains literal leaf-name text. Regular comments map to PRE and inline comments to EOL at the exact function entry. Changes commit together after readback and refreshed analysis; failure rolls them all back.",
38
+ "Annotation text rejects NUL and unpaired Unicode surrogates before mutation, with the field and UTF-16 index in the error. Supported Unicode and line endings are preserved.",
37
39
  "Metadata edits invalidate immutable analysis snapshots and are discarded on close. CLI returns the updated dossier before session cleanup; this is not a saved Ghidra project.",
38
40
  ];
39
41
  case "inspect_native_load_image":
@@ -72,6 +74,11 @@ export const limitationsFor = (operation) => {
72
74
  ...common,
73
75
  "Only Ghidra-defined string Data is observed; charset is reported, while a non-missing terminator cannot distinguish a present terminator from a fixed or Pascal layout.",
74
76
  ];
77
+ case "resolve_containing_procedure":
78
+ return [
79
+ ...common,
80
+ "An exact external entry resolves to its observed function identity even when its body is empty. This does not establish mapped executable bytes or containment of nearby external addresses.",
81
+ ];
75
82
  case "list_segments":
76
83
  return [
77
84
  ...common,
@@ -79,7 +86,10 @@ export const limitationsFor = (operation) => {
79
86
  ];
80
87
  case "search_procedures":
81
88
  case "search_strings":
82
- return common;
89
+ return [
90
+ ...common,
91
+ "Regex mode uses Java Pattern semantics. Matcher or compiler stack exhaustion returns a resource constraint without closing the session; literal mode avoids regex recursion and returns complete matching values.",
92
+ ];
83
93
  case "procedure_pseudo_code":
84
94
  return [
85
95
  ...common,
@@ -112,12 +122,14 @@ export const limitationsFor = (operation) => {
112
122
  case "procedure_references":
113
123
  return [
114
124
  ...common,
125
+ "References cover the complete Ghidra function-body AddressSet and exact entry, including instruction-interior destinations and embedded-data sources; an enclosing address span does not establish function ownership.",
115
126
  "Reference kinds are direct Ghidra ReferenceManager observations; unresolved computed flows without a target are absent and remain unknown.",
116
127
  "Synthetic Ghidra entry-point references without actionable memory sources are omitted.",
117
128
  ];
118
129
  case "analyze_function":
119
130
  return [
120
131
  ...common,
132
+ "References cover the complete Ghidra function-body AddressSet and exact entry. Dossier incoming edges omit sources owned by that function; procedure_references also retains those internal edges.",
121
133
  "The dossier combines Ghidra FunctionManager, Listing, ReferenceManager, BasicBlockModel, and decompiler observations; provider-specific pseudocode and assembly are not cross-provider text invariants.",
122
134
  "Resolved reference metadata identifies computed, indirect, external, call, jump, and data edges; unresolved targetless flows remain unknown, and function classifications distinguish thunks and externals.",
123
135
  "Synthetic Ghidra entry-point references without actionable memory sources are omitted.",
@@ -1,11 +1,10 @@
1
1
  import { fileURLToPath } from "node:url";
2
2
  import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
3
- import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
3
+ import { AnalysisCancelledError, AnalysisArtifactChangedError, AnalysisAccessDeniedError, AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisResourceConstraintError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
4
4
  import {} from "../domain/analysisErrorBase.js";
5
5
  import { ProviderAdapterError } from "../domain/providerAdapterError.js";
6
6
  import { err, ok } from "../domain/result.js";
7
7
  import { GhidraClient } from "./GhidraClient.js";
8
- import { GHIDRA_STARTUP_TIMEOUT_MS } from "./GhidraDefaults.js";
9
8
  import { isGhidraFunctionOperation, parseGhidraFunctionInput, parseGhidraFunctionResult, } from "./GhidraFunctionValues.js";
10
9
  import { isGhidraInventoryOperation, parseGhidraInventoryInput, parseGhidraInventoryResult, } from "./GhidraInventoryValues.js";
11
10
  import { ghidraInstallationDiagnostics, } from "./GhidraInstallation.js";
@@ -55,12 +54,11 @@ export const createGhidraProviderClient = (input) => {
55
54
  ]
56
55
  : [];
57
56
  const client = clientFactory({
57
+ startupTimeoutMs: config.ghidraStartupTimeoutMs,
58
58
  platform: installation.platform,
59
59
  launcher: new GhidraHeadlessLauncher({
60
60
  analyzeHeadlessPath: prerequisites.value.analyzeHeadlessPath,
61
- ...(config.ghidraJavaHome === undefined
62
- ? {}
63
- : { javaHome: config.ghidraJavaHome }),
61
+ javaHome: prerequisites.value.javaHome,
64
62
  bridgeScriptPath: fileURLToPath(new URL("../../bridge/ghidra/ReaGhidraBridge.java", import.meta.url)),
65
63
  ...(target.format === "dos-mz" ? { dosMz: true } : {}),
66
64
  ...(target.format === "dos-com" ? { dosCom: true } : {}),
@@ -110,7 +108,7 @@ export const createGhidraProviderClient = (input) => {
110
108
  if (operation === "health") {
111
109
  const started = await client.start(options?.signal);
112
110
  if (!started.ok)
113
- return err(projectSessionError(operation, started.error));
111
+ return err(projectSessionError(operation, started.error, config.ghidraStartupTimeoutMs));
114
112
  const failed = await checkExtensions(operation, started.value);
115
113
  if (failed !== undefined)
116
114
  return err(failed);
@@ -127,14 +125,14 @@ export const createGhidraProviderClient = (input) => {
127
125
  if (extensions.length > 0) {
128
126
  const started = await client.start(options?.signal);
129
127
  if (!started.ok)
130
- return err(projectSessionError(operation, started.error));
128
+ return err(projectSessionError(operation, started.error, config.ghidraStartupTimeoutMs));
131
129
  const failed = await checkExtensions(operation, started.value);
132
130
  if (failed !== undefined)
133
131
  return err(failed);
134
132
  }
135
133
  const called = await client.callTool(operation, input.value, options?.signal === undefined ? {} : { signal: options.signal });
136
134
  if (!called.ok)
137
- return err(projectSessionError(operation, called.error));
135
+ return err(projectSessionError(operation, called.error, config.ghidraStartupTimeoutMs));
138
136
  const result = isGhidraFunctionOperation(operation)
139
137
  ? parseGhidraFunctionResult(operation, called.value)
140
138
  : parseGhidraInventoryResult(operation, called.value);
@@ -142,7 +140,7 @@ export const createGhidraProviderClient = (input) => {
142
140
  return result;
143
141
  let normalized = result.value;
144
142
  if (operation === "inspect_native_load_image") {
145
- const attested = await attestGhidraNativeLoadImage(target, operation, result.value, client, (failure) => projectSessionError(operation, failure));
143
+ const attested = await attestGhidraNativeLoadImage(target, operation, result.value, client, (failure) => projectSessionError(operation, failure, config.ghidraStartupTimeoutMs));
146
144
  if (!attested.ok)
147
145
  return attested;
148
146
  normalized = attested.value;
@@ -176,6 +174,7 @@ const ghidraClientPrerequisites = (target, profile, installation) => {
176
174
  return err(new ProviderAdapterError("ghidra", "health"));
177
175
  return ok({
178
176
  analyzeHeadlessPath: installation.analyzeHeadlessPath,
177
+ javaHome: installation.javaHome,
179
178
  providerVersion: installation.providerVersion,
180
179
  profile,
181
180
  });
@@ -184,7 +183,11 @@ const unavailableClient = (failure) => ({
184
183
  execute: () => Promise.resolve(err(failure)),
185
184
  close: () => Promise.resolve(),
186
185
  });
187
- const projectSessionError = (operation, failure) => {
186
+ const projectSessionError = (operation, failure, startupTimeoutMs) => {
187
+ if (failure.cause instanceof AnalysisAccessDeniedError)
188
+ return new AnalysisAccessDeniedError(operation, failure.cause.path, failure.cause.systemCode, { cause: failure });
189
+ if (failure.cause instanceof AnalysisArtifactChangedError)
190
+ return new AnalysisArtifactChangedError(operation, failure.cause.path, failure.cause.reason, { cause: failure });
188
191
  if (operation === "annotate_native_function" &&
189
192
  failure.kind === "remote" &&
190
193
  failure.remoteCode === "invalid_function_name")
@@ -194,12 +197,20 @@ const projectSessionError = (operation, failure) => {
194
197
  if (failure.kind === "cancelled")
195
198
  return new AnalysisCancelledError(operation);
196
199
  if (failure.kind === "timeout" || failure.kind === "analysis_timeout")
197
- return new AnalysisTimeoutError(operation, failure.timeoutMs ?? GHIDRA_STARTUP_TIMEOUT_MS);
200
+ return new AnalysisTimeoutError(operation, failure.timeoutMs ?? startupTimeoutMs);
198
201
  if (failure.kind === "remote" && failure.remoteCode === "decompile_cancelled")
199
202
  return new AnalysisCancelledError(operation);
203
+ if (failure.kind === "remote" &&
204
+ failure.remoteCode === "regex_stack_exhausted")
205
+ return new AnalysisResourceConstraintError(operation, "memory", failure.message, null, {
206
+ cause: failure,
207
+ remediationAction: "Retry this search in literal mode or simplify the regex. The active analysis session and annotations remain available.",
208
+ });
200
209
  if (failure.kind === "remote" &&
201
210
  ["invalid_request", "not_found", "ambiguous"].includes(failure.remoteCode ?? ""))
202
- return new AnalysisInputError(operation, { cause: failure });
211
+ return new AnalysisInputError(operation, { cause: failure }, [
212
+ { path: [], reason: "invalid_value", message: failure.message },
213
+ ]);
203
214
  if (failure.kind === "remote" && failure.remoteCode === "method_unavailable")
204
215
  return new AnalysisCapabilityUnavailableError("ghidra", operation, failure.message);
205
216
  return new ProviderAdapterError("ghidra", operation, {
@@ -14,13 +14,17 @@ export class GhidraSessionError extends Error {
14
14
  }
15
15
  }
16
16
  /** Build a session failure while preserving bounded remote failure metadata. */
17
- const createGhidraSessionError = (failure) => new GhidraSessionError(failure.kind, failure.message, failure.remoteCode === undefined
18
- ? failure.diagnostics
19
- : {
20
- ...failure.diagnostics,
21
- remote_code: failure.redact(failure.remoteCode),
22
- remote_message: failure.message,
23
- }, {
17
+ const createGhidraSessionError = (failure) => new GhidraSessionError(failure.kind, failure.message, {
18
+ ...failure.diagnostics,
19
+ failure_kind: failure.kind,
20
+ failure_message: failure.message,
21
+ ...(failure.remoteCode === undefined
22
+ ? {}
23
+ : {
24
+ remote_code: failure.redact(failure.remoteCode),
25
+ remote_message: failure.message,
26
+ }),
27
+ }, {
24
28
  ...(failure.cause === undefined ? {} : { cause: failure.cause }),
25
29
  ...(failure.timeoutMs === undefined
26
30
  ? {}
@@ -1,7 +1,10 @@
1
1
  import { createHash } from "node:crypto";
2
- import { constants, createReadStream } from "node:fs";
3
- import { chmod, copyFile, rm } from "node:fs/promises";
2
+ import { constants } from "node:fs";
3
+ import { open, rm } from "node:fs/promises";
4
4
  import { extname, join } from "node:path";
5
+ import { Transform } from "node:stream";
6
+ import { pipeline } from "node:stream/promises";
7
+ import { AnalysisArtifactChangedError, AnalysisAccessDeniedError, } from "../domain/analysisErrorCore.js";
5
8
  import { windowsPrivateRuntime } from "../windows/WindowsPrivateRuntime.js";
6
9
  /** Copy one target and require its bytes to match the parsed target identity. */
7
10
  export const createGhidraTargetSnapshot = async (sourcePath, runtimeRoot, expectedSha256, options = {}) => {
@@ -12,29 +15,61 @@ export const createGhidraTargetSnapshot = async (sourcePath, runtimeRoot, expect
12
15
  if ((options.platform ?? process.platform) === "win32") {
13
16
  const observed = await windowsPrivateRuntime(runtimeRoot).snapshot(sourcePath, `target-${expectedSha256.slice(0, 12)}${suffix}`, options.signal);
14
17
  if (observed.sha256 !== expectedSha256)
15
- throw new Error(`Ghidra target snapshot digest mismatch: expected ${expectedSha256}, observed ${observed.sha256}`);
18
+ throw new AnalysisArtifactChangedError("open_binary", sourcePath, `Ghidra target snapshot digest mismatch: expected ${expectedSha256}, observed ${observed.sha256}`);
16
19
  return {
17
20
  path: snapshotPath,
18
21
  sha256: observed.sha256,
19
22
  admission: { source: observed.source, snapshot: observed.snapshot },
20
23
  };
21
24
  }
25
+ let source;
26
+ let destination;
22
27
  try {
23
- await copyFile(sourcePath, snapshotPath, constants.COPYFILE_EXCL);
24
- await chmod(snapshotPath, 0o600);
28
+ source = await openSnapshotSource(sourcePath);
29
+ if (!(await source.stat()).isFile())
30
+ throw new AnalysisArtifactChangedError("open_binary", sourcePath, "The selected Ghidra source is no longer a regular file");
31
+ destination = await open(snapshotPath, "wx", 0o600);
32
+ await destination.chmod(0o600);
25
33
  const hash = createHash("sha256");
26
- for await (const chunk of createReadStream(snapshotPath))
27
- hash.update(chunk);
34
+ const digest = new Transform({
35
+ transform(chunk, _encoding, done) {
36
+ if (!Buffer.isBuffer(chunk)) {
37
+ done(new TypeError("Ghidra snapshot stream must contain bytes"));
38
+ return;
39
+ }
40
+ hash.update(chunk);
41
+ done(null, chunk);
42
+ },
43
+ });
44
+ await pipeline(source.createReadStream(), digest, destination.createWriteStream(), options.signal === undefined ? {} : { signal: options.signal });
28
45
  const observedSha256 = hash.digest("hex");
29
46
  if (observedSha256 !== expectedSha256)
30
- throw new Error(`Ghidra target snapshot digest mismatch: expected ${expectedSha256}, observed ${observedSha256}`);
47
+ throw new AnalysisArtifactChangedError("open_binary", sourcePath, `Ghidra target snapshot digest mismatch: expected ${expectedSha256}, observed ${observedSha256}`);
31
48
  return { path: snapshotPath, sha256: observedSha256 };
32
49
  }
33
50
  catch (cause) {
34
- await rm(snapshotPath, { force: true }).catch((cause) => {
35
- // best-effort cleanup: snapshot removal must not mask the copy failure.
36
- void cause;
37
- });
51
+ if (destination !== undefined)
52
+ await rm(snapshotPath, { force: true }).catch((cause) => {
53
+ // best-effort cleanup: snapshot removal must not mask the copy failure.
54
+ void cause;
55
+ });
56
+ throw cause;
57
+ }
58
+ finally {
59
+ await Promise.all([source?.close(), destination?.close()]);
60
+ }
61
+ };
62
+ const openSnapshotSource = async (path) => {
63
+ try {
64
+ // A path replaced by a FIFO must not block startup before its type is checked.
65
+ return await open(path, constants.O_RDONLY | constants.O_NONBLOCK);
66
+ }
67
+ catch (cause) {
68
+ const code = cause instanceof Error && "code" in cause ? cause.code : undefined;
69
+ if (code === "EACCES" || code === "EPERM")
70
+ throw new AnalysisAccessDeniedError("open_binary", path, code, { cause });
71
+ if (code === "ENOENT" || code === "ENOTDIR" || code === "ELOOP")
72
+ throw new AnalysisArtifactChangedError("open_binary", path, `The selected Ghidra source could not be opened (${code})`, { cause });
38
73
  throw cause;
39
74
  }
40
75
  };
@@ -1,7 +1,27 @@
1
1
  import { access, open } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
2
4
  import { readWindowsPrivateRuntimeFile } from "../windows/WindowsPrivateRuntime.js";
3
5
  import { err, ok } from "../domain/result.js";
4
6
  import { GhidraSessionError } from "./GhidraSessionError.js";
7
+ /** Allocate an endpoint that fits the host's Unix sockaddr without moving the project. */
8
+ export const createGhidraEndpoint = async (runtimeRoot, transport, platform) => {
9
+ const path = join(runtimeRoot, transport === "unix-socket" ? "bridge.sock" : "bridge-endpoint.json");
10
+ // sockaddr_un includes a terminating NUL: macOS has 104 bytes, Linux 108.
11
+ const maximumPathBytes = platform === "darwin" ? 103 : 107;
12
+ if (transport !== "unix-socket" ||
13
+ Buffer.byteLength(path, "utf8") <= maximumPathBytes)
14
+ return { endpoint: { transport, path } };
15
+ const socketRoot = await PrivateRuntimeRoot.create({
16
+ parent: "/tmp",
17
+ prefix: "rea-ghidra-socket-",
18
+ platform,
19
+ });
20
+ return {
21
+ endpoint: { transport, path: join(socketRoot.path, "s") },
22
+ socketRoot,
23
+ };
24
+ };
5
25
  /** Observe a ready endpoint, returning null while its bridge is not listening. */
6
26
  export const observeGhidraEndpoint = async (endpoint) => {
7
27
  if (endpoint.transport === "unix-socket") {