rea-agents 6.2.0 → 6.4.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 (636) hide show
  1. package/README.md +24 -23
  2. package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
  3. package/bridge/ghidra/ReaGhidraBridge.java +597 -209
  4. package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
  5. package/bridge/hopper_bridge.py +2 -0
  6. package/dist/adb/AdbConfiguration.js +88 -0
  7. package/dist/adb/AdbDeviceOutput.js +186 -0
  8. package/dist/adb/AdbProvider.js +1190 -0
  9. package/dist/adb/AdbShellOutput.js +309 -0
  10. package/dist/android/AndroidTargetSnapshot.js +104 -22
  11. package/dist/android/JadxConfiguration.js +44 -24
  12. package/dist/android/JadxProvider.js +59 -21
  13. package/dist/android/JadxSession.js +51 -9
  14. package/dist/apktool/ApktoolConfiguration.js +84 -0
  15. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  16. package/dist/apktool/ApktoolProvider.js +506 -0
  17. package/dist/application/AnalysisProvider.js +8 -2
  18. package/dist/application/AppBundleExecutable.js +27 -22
  19. package/dist/application/BinaryTargetResolver.js +85 -19
  20. package/dist/application/BrowserScenarioEvidence.js +2 -2
  21. package/dist/application/CapabilityInventory.js +11 -1
  22. package/dist/application/ClientConfigurationDocument.js +98 -0
  23. package/dist/application/ClientConfigurationFiles.js +91 -0
  24. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  25. package/dist/application/ClientRegistrationStatus.js +75 -27
  26. package/dist/application/DirectAnalysis.js +14 -8
  27. package/dist/application/DirectAnalysisCleanup.js +1 -2
  28. package/dist/application/DirectAnalysisStatus.js +3 -6
  29. package/dist/application/Doctor.js +27 -34
  30. package/dist/application/DoctorDiagnostics.js +1 -1
  31. package/dist/application/EvidenceBundleCommands.js +6 -12
  32. package/dist/application/EvidenceBundleFiles.js +1 -1
  33. package/dist/application/GeminiClientSettings.js +139 -0
  34. package/dist/application/HermesClientHome.js +115 -0
  35. package/dist/application/HopperDownload.js +39 -0
  36. package/dist/application/InvestigationProviders.js +10 -4
  37. package/dist/application/JsonFiles.js +16 -15
  38. package/dist/application/JsonInputFile.js +252 -0
  39. package/dist/application/LinuxHopper.js +6 -13
  40. package/dist/application/MacHopper.js +172 -149
  41. package/dist/application/MipsElfAbiFlags.js +140 -0
  42. package/dist/application/ProviderOperationExecution.js +31 -0
  43. package/dist/application/ReconstructionObligationCandidates.js +16 -3
  44. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
  45. package/dist/application/ReferenceSourceImport.js +76 -29
  46. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  47. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  48. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  49. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  50. package/dist/application/RegularFileRead.js +103 -0
  51. package/dist/application/Setup.js +69 -10
  52. package/dist/application/SetupClientConfiguration.js +134 -23
  53. package/dist/application/SetupHost.js +102 -22
  54. package/dist/application/SetupPlan.js +18 -17
  55. package/dist/application/SetupSkill.js +81 -13
  56. package/dist/application/SupportedClients.js +305 -37
  57. package/dist/application/Uninstall.js +172 -8
  58. package/dist/application/UpdateMaintenance.js +23 -23
  59. package/dist/application/Utf8JsonInput.js +71 -0
  60. package/dist/application/WebScriptExportService.js +130 -57
  61. package/dist/application/WebSourceLocationService.js +3 -0
  62. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  63. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  64. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  65. package/dist/application/android/AndroidAnalysisService.js +1 -1
  66. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  67. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  68. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  69. package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
  70. package/dist/application/binary/BinarySession.js +18 -1
  71. package/dist/application/binary/BinarySessionOpen.js +9 -1
  72. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  73. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  74. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  75. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  76. package/dist/application/evm/EvmInterfaceService.js +3 -0
  77. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  78. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  79. package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
  80. package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
  81. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  82. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  83. package/dist/application/javascript/ElectronBoundaryGraphNative.js +20 -3
  84. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  85. package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
  86. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
  87. package/dist/application/javascript/JavaScriptApplicationService.js +23 -11
  88. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  89. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
  90. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -36
  91. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  92. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +74 -36
  93. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  94. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  95. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +53 -42
  96. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  97. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +293 -238
  98. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +120 -28
  99. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -0
  100. package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
  101. package/dist/application/javascript/JavaScriptModuleRelationships.js +10 -20
  102. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  103. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
  104. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +11 -5
  105. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +206 -66
  106. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
  107. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +18 -23
  108. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +5 -2
  109. package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
  110. package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
  111. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +7 -5
  112. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +6 -4
  113. package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
  114. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
  115. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +29 -15
  116. package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
  117. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  118. package/dist/application/jeb/JebAnalysisService.js +13 -0
  119. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  120. package/dist/application/native/NativeCallRoutes.js +2 -4
  121. package/dist/application/native/NativeUiActionTrace.js +16 -8
  122. package/dist/application/native/NativeValueTrace.js +23 -6
  123. package/dist/application/process/ProcessCli.js +25 -20
  124. package/dist/artifacts/ArtifactPaths.js +129 -8
  125. package/dist/artifacts/ArtifactProvider.js +34 -31
  126. package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
  127. package/dist/artifacts/ArtifactReader.js +23 -0
  128. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  129. package/dist/artifacts/AsarArtifactReader.js +218 -80
  130. package/dist/artifacts/AsarHeader.js +24 -0
  131. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  132. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  133. package/dist/artifacts/NativeDmgArtifactReader.js +179 -87
  134. package/dist/artifacts/NativeDmgOwnership.js +109 -0
  135. package/dist/artifacts/SafeOutputTree.js +245 -70
  136. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  137. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  138. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  139. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  140. package/dist/artifacts/ZipArtifactReader.js +77 -27
  141. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  142. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  143. package/dist/artifacts/apple/KeyedArchiveReader.js +76 -49
  144. package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
  145. package/dist/artifacts/extraction/ArtifactExtraction.js +134 -92
  146. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +116 -50
  147. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  148. package/dist/artifacts/inventory/classify.js +87 -25
  149. package/dist/artifacts/inventory/hashStableRootArtifact.js +70 -0
  150. package/dist/artifacts/inventory/reader.js +13 -5
  151. package/dist/artifacts/inventory/scanCanonical.js +73 -30
  152. package/dist/artifacts/inventory/scanReader.js +43 -20
  153. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +72 -28
  154. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  155. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  156. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  157. package/dist/browser/CdpBrowserProvider.js +9 -3
  158. package/dist/browser/CdpCaptureDocuments.js +40 -6
  159. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  160. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  161. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  162. package/dist/browser/CdpCaptureEvents.js +4 -9
  163. package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
  164. package/dist/browser/CdpConnection.js +22 -5
  165. package/dist/browser/CdpElectronInspection.js +2 -2
  166. package/dist/browser/CdpElectronProvider.js +4 -3
  167. package/dist/browser/CdpElectronScripts.js +2 -2
  168. package/dist/browser/CdpPageCapture.js +1 -1
  169. package/dist/browser/CdpTargetSession.js +30 -34
  170. package/dist/browser/CdpWebMcpDiscovery.js +48 -23
  171. package/dist/browser/ElectronFileScope.js +99 -9
  172. package/dist/browser/PlaywrightBrowserScenarioProvider.js +63 -7
  173. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  174. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  175. package/dist/browser/PlaywrightScenarioBrowser.js +208 -43
  176. package/dist/browser/PlaywrightScenarioSession.js +130 -65
  177. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  178. package/dist/browser/PngVisualDiff.js +198 -29
  179. package/dist/browser/WebSourceMapFetcher.js +35 -9
  180. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  181. package/dist/browser/assets/PublishWebScripts.js +75 -20
  182. package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
  183. package/dist/browser/assets/WebArtifactReads.js +23 -1
  184. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  185. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  186. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  187. package/dist/browser/history/HarCapture.js +14 -0
  188. package/dist/browser/history/HarCaptureProcess.js +2 -10
  189. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  190. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  191. package/dist/cli/adbCommands.js +337 -0
  192. package/dist/cli/analysisViewCommands.js +39 -1
  193. package/dist/cli/apktoolCommands.js +53 -0
  194. package/dist/cli/artifactCommands.js +8 -11
  195. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  196. package/dist/cli/browserAdvancedCommands.js +65 -36
  197. package/dist/cli/coreAnalysisCommands.js +2 -2
  198. package/dist/cli/coreBinaryCommands.js +12 -13
  199. package/dist/cli/coreNativeCommands.js +1 -14
  200. package/dist/cli/electronCommands.js +14 -10
  201. package/dist/cli/evmCommands.js +13 -4
  202. package/dist/cli/firmwareCommands.js +7 -2
  203. package/dist/cli/javascriptApplicationAnalysis.js +19 -13
  204. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  205. package/dist/cli/jebCommands.js +99 -0
  206. package/dist/cli/jsonOutput.js +12 -4
  207. package/dist/cli/referenceSourceImportStatus.js +7 -0
  208. package/dist/cli/setupCommands.js +15 -3
  209. package/dist/cli/streamedJsonOutput.js +83 -4
  210. package/dist/cli/utilityCommands.js +68 -22
  211. package/dist/cli/webScriptCommands.js +20 -1
  212. package/dist/cli/webSourceLocationCommands.js +21 -9
  213. package/dist/cli.js +11 -2
  214. package/dist/cliBrowserScenarioCommands.js +2 -1
  215. package/dist/cliCommandNames.js +32 -0
  216. package/dist/cliJsonInput.js +47 -34
  217. package/dist/cliObservationOptions.js +7 -0
  218. package/dist/composition/adb.js +3 -0
  219. package/dist/composition/apktool.js +3 -0
  220. package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
  221. package/dist/composition/binaryDiagnostics.js +4 -0
  222. package/dist/composition/browserScenario.js +2 -2
  223. package/dist/composition/directAnalysis.js +14 -7
  224. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  225. package/dist/composition/jeb.js +6 -0
  226. package/dist/config/environment.js +10 -0
  227. package/dist/config/ghidraLanguageOverride.js +9 -0
  228. package/dist/config/mcpInputSchemaProfile.js +27 -0
  229. package/dist/config/parseConfig.js +28 -1
  230. package/dist/contracts/adb/adbToolContracts.js +353 -0
  231. package/dist/contracts/advertisedInputExamples.js +48 -0
  232. package/dist/contracts/analysisDetail.js +10 -0
  233. package/dist/contracts/analysisViewToolContracts.js +17 -2
  234. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  235. package/dist/contracts/artifactComparisonExample.js +5 -5
  236. package/dist/contracts/artifactToolContracts.js +8 -5
  237. package/dist/contracts/browserToolContracts.js +1 -1
  238. package/dist/contracts/compactInputSchema.js +256 -0
  239. package/dist/contracts/errorSchemas.js +3 -1
  240. package/dist/contracts/functionComparisonExample.js +8 -0
  241. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  242. package/dist/contracts/inputSchemaPresentation.js +104 -13
  243. package/dist/contracts/javascript/electronToolContracts.js +16 -3
  244. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
  245. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
  246. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  247. package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
  248. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  249. package/dist/contracts/managed/managedToolContracts.js +3 -2
  250. package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
  251. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  252. package/dist/contracts/native/nativeToolContracts.js +1 -1
  253. package/dist/contracts/officialToolContracts.js +5 -5
  254. package/dist/contracts/sessionLifecycleInputs.js +4 -3
  255. package/dist/contracts/sessionStatusContract.js +3 -2
  256. package/dist/contracts/sessionToolContracts.js +5 -4
  257. package/dist/contracts/sessionToolSchemas.js +9 -4
  258. package/dist/contracts/toolContractExamples.js +6 -0
  259. package/dist/contracts/toolContractTypes.js +3 -0
  260. package/dist/contracts/toolContracts.js +6 -0
  261. package/dist/contracts/toolEffects.js +167 -0
  262. package/dist/contracts/toolOutputSchemaGroups.js +7 -5
  263. package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
  264. package/dist/contracts/toolSchemaMetadata.js +82 -7
  265. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  266. package/dist/domain/analysisErrorBase.js +5 -0
  267. package/dist/domain/analysisErrorCleanup.js +29 -0
  268. package/dist/domain/analysisErrorPresentation.js +18 -4
  269. package/dist/domain/analysisErrorProjection.js +4 -1
  270. package/dist/domain/analysisSnapshot.js +5 -2
  271. package/dist/domain/analysisView/analysisView.js +53 -5
  272. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  273. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  274. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  275. package/dist/domain/android/androidApplication.js +25 -20
  276. package/dist/domain/android/androidPartialObservation.js +36 -0
  277. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  278. package/dist/domain/apple/appleApplication.js +40 -23
  279. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  280. package/dist/domain/apple/dyldPaths.js +9 -1
  281. package/dist/domain/apple/dylibResolution.js +3 -3
  282. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  283. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  284. package/dist/domain/artifactComparison.js +39 -11
  285. package/dist/domain/artifactGraph.js +6 -4
  286. package/dist/domain/artifactIdentity.js +37 -9
  287. package/dist/domain/artifactInspection.js +10 -50
  288. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  289. package/dist/domain/artifactInventoryEvidence.js +16 -17
  290. package/dist/domain/artifactPathSyntax.js +1 -1
  291. package/dist/domain/binaryTarget.js +16 -0
  292. package/dist/domain/binaryTargetTypes.js +8 -1
  293. package/dist/domain/browserCompleteness.js +3 -2
  294. package/dist/domain/browserObservationSchemas.js +8 -4
  295. package/dist/domain/browserScenarioCaptureValues.js +2 -2
  296. package/dist/domain/browserScenarioNormalization.js +3 -3
  297. package/dist/domain/browserScenarioValues.js +3 -2
  298. package/dist/domain/callPath.js +8 -10
  299. package/dist/domain/canonicalDigest.js +7 -1
  300. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  301. package/dist/domain/canonicalOrdering.js +1 -13
  302. package/dist/domain/changedBehavior.js +2 -3
  303. package/dist/domain/compactStringIdentity.js +9 -0
  304. package/dist/domain/comparisonSemantics.js +0 -5
  305. package/dist/domain/digests.js +0 -3
  306. package/dist/domain/evidence.js +12 -6
  307. package/dist/domain/evidenceBundle.js +51 -33
  308. package/dist/domain/evidenceRecordSummary.js +144 -0
  309. package/dist/domain/firmware/firmwareAnalysis.js +4 -3
  310. package/dist/domain/functionComparison.js +2 -1
  311. package/dist/domain/functionComparisonNormalization.js +4 -3
  312. package/dist/domain/functionComparisonResults.js +2 -2
  313. package/dist/domain/functionDossierEvidence.js +2 -1
  314. package/dist/domain/hopperValues.js +11 -15
  315. package/dist/domain/inputIssueProjection.js +16 -1
  316. package/dist/domain/javascript/electronActiveObservation.js +4 -3
  317. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +14 -15
  318. package/dist/domain/javascript/electronStaticAnalysisIpc.js +20 -21
  319. package/dist/domain/javascript/electronStaticAnalysisNative.js +73 -41
  320. package/dist/domain/javascript/electronStaticAnalysisValues.js +24 -4
  321. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  322. package/dist/domain/javascript/javascriptApplicationAnalysis.js +6 -1
  323. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +18 -14
  324. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
  325. package/dist/domain/javascript/javascriptApplicationGraph.js +91 -28
  326. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  327. package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
  328. package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
  329. package/dist/domain/javascript/javascriptApplicationVersionItems.js +72 -45
  330. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +16 -8
  331. package/dist/domain/javascript/javascriptAstFingerprint.js +60 -33
  332. package/dist/domain/javascript/javascriptAstValues.js +54 -0
  333. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  334. package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
  335. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
  336. package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
  337. package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
  338. package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
  339. package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
  340. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
  341. package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
  342. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  343. package/dist/domain/javascript/javascriptNativeHandoff.js +12 -7
  344. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  345. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  346. package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
  347. package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
  348. package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
  349. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
  350. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +12 -6
  351. package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
  352. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
  353. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
  354. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
  355. package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
  356. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
  357. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +15 -17
  358. package/dist/domain/javascript/javascriptSemanticAnalysis.js +379 -30
  359. package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
  360. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  361. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  362. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
  363. package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
  364. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
  365. package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
  366. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  367. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  368. package/dist/domain/javascript/javascriptSemanticFingerprints.js +43 -42
  369. package/dist/domain/javascript/javascriptSemanticGraph.js +205 -52
  370. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +21 -11
  371. package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
  372. package/dist/domain/javascript/javascriptSemanticIterationSources.js +139 -0
  373. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +774 -136
  374. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
  375. package/dist/domain/javascript/javascriptSemanticMutationValues.js +98 -41
  376. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  377. package/dist/domain/javascript/javascriptSemanticObjects.js +9 -7
  378. package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
  379. package/dist/domain/javascript/javascriptSemanticProjection.js +72 -28
  380. package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
  381. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +100 -0
  382. package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
  383. package/dist/domain/javascript/javascriptSemanticQuery.js +33 -29
  384. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +4 -5
  385. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
  386. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
  387. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  388. package/dist/domain/javascript/javascriptSemanticReturns.js +34 -48
  389. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  390. package/dist/domain/javascript/javascriptSemanticTraversal.js +25 -2
  391. package/dist/domain/javascript/javascriptSemanticValues.js +169 -30
  392. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  393. package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
  394. package/dist/domain/javascript/javascriptSourceParser.js +34 -9
  395. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  396. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +13 -12
  397. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  398. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  399. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
  400. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  401. package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
  402. package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
  403. package/dist/domain/jeb/jebAnalysis.js +114 -0
  404. package/dist/domain/jsonSerialization.js +109 -55
  405. package/dist/domain/jsonShape.js +69 -31
  406. package/dist/domain/jsonValue.js +3 -0
  407. package/dist/domain/localPath.js +10 -4
  408. package/dist/domain/managed/managedApplicationGraph.js +47 -6
  409. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  410. package/dist/domain/managed/managedApplicationGraphNodes.js +94 -59
  411. package/dist/domain/managed/managedArtifact.js +1 -0
  412. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  413. package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
  414. package/dist/domain/native/nativeAotPe.js +1408 -0
  415. package/dist/domain/native/nativeCallObservation.js +2 -4
  416. package/dist/domain/native/nativeInstruction.js +21 -0
  417. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  418. package/dist/domain/native/nativeValueFlow.js +5 -11
  419. package/dist/domain/native/objcSwiftMetadata.js +15 -17
  420. package/dist/domain/native/peResources.js +94 -0
  421. package/dist/domain/nativeConvention.js +33 -0
  422. package/dist/domain/process/processCapture.js +102 -11
  423. package/dist/domain/process/processCaptureCoverage.js +8 -5
  424. package/dist/domain/process/processCaptureExample.js +67 -0
  425. package/dist/domain/process/processCaptureValidation.js +83 -3
  426. package/dist/domain/process/processComparison.js +0 -23
  427. package/dist/domain/process/processScenario.js +62 -10
  428. package/dist/domain/process/processTraceEvaluation.js +4 -4
  429. package/dist/domain/process/processTraceSpecification.js +1 -3
  430. package/dist/domain/propertyListKeys.js +3 -1
  431. package/dist/domain/providerCleanupError.js +6 -2
  432. package/dist/domain/reconstructionCoverage.js +2 -1
  433. package/dist/domain/reconstructionUnknowns.js +4 -3
  434. package/dist/domain/reconstructionVerification.js +3 -2
  435. package/dist/domain/referenceSourceGraph.js +32 -23
  436. package/dist/domain/referenceSourceImportParsing.js +40 -48
  437. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  438. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  439. package/dist/domain/residualUnknown.js +3 -2
  440. package/dist/domain/staticRuntimeCorrelation.js +2 -1
  441. package/dist/domain/swiftSymbolClassification.js +6 -1
  442. package/dist/domain/symbolAnalysis.js +17 -2
  443. package/dist/domain/unicodeCodePointOrder.js +6 -0
  444. package/dist/domain/webBundleAnalyzerInspection.js +23 -3
  445. package/dist/domain/webCaptureDiff.js +170 -30
  446. package/dist/domain/webCaptureDiffSchemas.js +2 -8
  447. package/dist/domain/webInventory.js +3 -2
  448. package/dist/domain/webMcpDiscovery.js +4 -3
  449. package/dist/domain/webScriptExport.js +1 -1
  450. package/dist/domain/webScriptExportError.js +10 -4
  451. package/dist/domain/webScriptExportPlan.js +7 -13
  452. package/dist/domain/zipPackageFormat.js +4 -1
  453. package/dist/domain/zodCollectionSteps.js +24 -0
  454. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  455. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  456. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  457. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  458. package/dist/dotnet/ManagedMemberInstructionDecoder.js +5 -4
  459. package/dist/dotnet/ManagedMemberRows.js +9 -4
  460. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  461. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  462. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  463. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  464. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  465. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  466. package/dist/dotnet/ManagedPeReader.js +41 -25
  467. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  468. package/dist/dotnet/ManagedStaticProvider.js +65 -31
  469. package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
  470. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  471. package/dist/evaluation/CodexAgentEval.js +43 -13
  472. package/dist/evm/EvmoleFailures.js +0 -2
  473. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  474. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  475. package/dist/filesystem/OwnedFileHandle.js +36 -0
  476. package/dist/filesystem/RegularFile.js +73 -0
  477. package/dist/filesystem/StableFileHash.js +46 -0
  478. package/dist/filesystem/readFileHandleChunks.js +26 -0
  479. package/dist/firmware/FirmwareCommand.js +25 -3
  480. package/dist/firmware/FirmwareFiles.js +23 -8
  481. package/dist/firmware/FirmwareProvider.js +156 -32
  482. package/dist/firmware/FirmwarePublication.js +24 -3
  483. package/dist/firmware/FirmwareRelease.js +1 -0
  484. package/dist/generatedPackageMetadata.js +2 -2
  485. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  486. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  487. package/dist/ghidra/GhidraClient.js +90 -8
  488. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  489. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  490. package/dist/ghidra/GhidraInstallation.js +111 -10
  491. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  492. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  493. package/dist/ghidra/GhidraLauncher.js +123 -58
  494. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  495. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  496. package/dist/ghidra/GhidraProvider.js +57 -9
  497. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  498. package/dist/ghidra/GhidraProviderClient.js +282 -21
  499. package/dist/ghidra/GhidraSessionValues.js +9 -2
  500. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  501. package/dist/hopper/HopperCleanup.js +1 -1
  502. package/dist/hopper/HopperClient.js +15 -6
  503. package/dist/hopper/HopperMachOImage.js +2 -0
  504. package/dist/hopper/HopperProvider.js +13 -2
  505. package/dist/ida/IdaOperationRunner.js +10 -2
  506. package/dist/ida/IdaProvider.js +7 -0
  507. package/dist/ida/IdaSessionClient.js +7 -3
  508. package/dist/ida/IdaWorkspace.js +4 -2
  509. package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
  510. package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
  511. package/dist/inspector/V8InspectorProvider.js +60 -8
  512. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  513. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  514. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  515. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  516. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  517. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  518. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  519. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  520. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  521. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  522. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  523. package/dist/javascript/recovery/WakaruReport.js +12 -7
  524. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  525. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  526. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  527. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  528. package/dist/jeb/JebMcpConnection.js +179 -0
  529. package/dist/jeb/JebMcpEndpoint.js +40 -0
  530. package/dist/jeb/JebProvider.js +299 -0
  531. package/dist/main/shutdown.js +76 -32
  532. package/dist/main/transport.js +1 -1
  533. package/dist/mcpDoctor.js +15 -6
  534. package/dist/native/AppleDispatchCoverage.js +25 -12
  535. package/dist/native/AppleDispatchMetadata.js +14 -7
  536. package/dist/native/AppleMachoFixups.js +71 -15
  537. package/dist/native/AppleMachoSelection.js +23 -3
  538. package/dist/native/AppleObjcDispatchFacets.js +3 -3
  539. package/dist/native/AppleObjcProperties.js +17 -7
  540. package/dist/native/LldbCallTracer.js +241 -75
  541. package/dist/native/NativeMacOSProvider.js +100 -20
  542. package/dist/native/NativeMacOSProviderMetadata.js +1 -2
  543. package/dist/native/NativeMachoInspection.js +11 -7
  544. package/dist/native/NativeUiHelperRuntime.js +6 -1
  545. package/dist/native/NativeUiObservation.js +4 -3
  546. package/dist/native/pe/PeResourceLayout.js +120 -0
  547. package/dist/native/pe/PeResourceParser.js +286 -0
  548. package/dist/native/pe/PeResourcesProvider.js +63 -0
  549. package/dist/process/BoundedFileBytes.js +30 -7
  550. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  551. package/dist/process/OwnedCommand.js +4 -3
  552. package/dist/process/ProcessOwnership.js +104 -112
  553. package/dist/process/ProcessOwnershipObservation.js +104 -51
  554. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  555. package/dist/process/ProcessRunTokenObservations.js +48 -0
  556. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  557. package/dist/process/ProviderProcess.js +4 -3
  558. package/dist/process/capture/FilesystemSnapshot.js +116 -22
  559. package/dist/process/capture/ProcessCaptureLifecycle.js +363 -86
  560. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  561. package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
  562. package/dist/process/capture/ProcessHarness.js +202 -47
  563. package/dist/process/capture/ProcessNormalization.js +3 -1
  564. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  565. package/dist/process/capture/TerminalRenderer.js +24 -7
  566. package/dist/reference/ReferenceSourceReader.js +22 -5
  567. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  568. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  569. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  570. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  571. package/dist/server/EvidenceMcpServer.js +36 -1
  572. package/dist/server/admittedToolOperation.js +9 -0
  573. package/dist/server/analysisAdmission.js +8 -0
  574. package/dist/server/contractToolHandler.js +21 -0
  575. package/dist/server/createServer.js +118 -47
  576. package/dist/server/registerAdbTools.js +36 -0
  577. package/dist/server/registerAnalysisViewTool.js +4 -9
  578. package/dist/server/registerAndroidTools.js +3 -12
  579. package/dist/server/registerApktoolTools.js +14 -0
  580. package/dist/server/registerApplicationTools/compareExportShapes.js +6 -7
  581. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  582. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  583. package/dist/server/registerApplicationTools/coverage.js +3 -2
  584. package/dist/server/registerApplicationTools/helpers.js +3 -2
  585. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  586. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  587. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  588. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  589. package/dist/server/registerArtifactComparisonTool.js +5 -2
  590. package/dist/server/registerArtifactTools.js +2 -2
  591. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  592. package/dist/server/registerBrowserScenarioTool.js +10 -7
  593. package/dist/server/registerBrowserTools.js +12 -9
  594. package/dist/server/registerBundleComparisonTool.js +16 -2
  595. package/dist/server/registerCloseLifecycleTool.js +36 -5
  596. package/dist/server/registerElectronTools.js +28 -10
  597. package/dist/server/registerEnhancedTools.js +78 -73
  598. package/dist/server/registerEvidenceTools.js +54 -46
  599. package/dist/server/registerEvmTools.js +4 -9
  600. package/dist/server/registerFirmwareTools.js +3 -11
  601. package/dist/server/registerFunctionComparisonTool.js +5 -2
  602. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  603. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  604. package/dist/server/registerJebTools.js +16 -0
  605. package/dist/server/registerManagedTools.js +7 -4
  606. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  607. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  608. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  609. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  610. package/dist/server/registerOfficialTools.js +31 -25
  611. package/dist/server/registerPeResourcesTool.js +9 -0
  612. package/dist/server/registerProcessComparisonTool.js +5 -2
  613. package/dist/server/registerRecordedCrashTools.js +4 -9
  614. package/dist/server/registerSessionRecordTools.js +2 -1
  615. package/dist/server/registerSessionTools.js +58 -21
  616. package/dist/server/registerWebModuleTool.js +4 -9
  617. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  618. package/dist/server/registerWebRuntimeTools.js +6 -5
  619. package/dist/server/registerWebScriptTool.js +6 -3
  620. package/dist/server/registerWebSourceLocationTool.js +4 -9
  621. package/dist/server/toolResult.js +21 -2
  622. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  623. package/install.sh +7 -4
  624. package/licenses/nativeaot-parser-MIT.txt +28 -0
  625. package/native/windows/build/manifest.json +2 -2
  626. package/native/windows/build/rea-windows-x64.node +0 -0
  627. package/package.json +38 -7
  628. package/scripts/rea.mjs +16 -1
  629. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  630. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  631. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  632. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  633. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +31 -1
  634. package/dist/artifacts/inventory/policy.js +0 -2
  635. package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
  636. package/dist/server/registerNativeTools.js +0 -6
@@ -0,0 +1,211 @@
1
+ import { createHash } from "node:crypto";
2
+ import { constants } from "node:fs";
3
+ import { mkdir, open, realpath, writeFile } from "node:fs/promises";
4
+ import { isAbsolute, join } from "node:path";
5
+ import { z } from "zod";
6
+ import { ConfigurationError } from "../domain/configurationErrors.js";
7
+ import { ProviderAdapterError } from "../domain/providerAdapterError.js";
8
+ import { err, ok } from "../domain/result.js";
9
+ /** Seed file format admitted by this adapter. */
10
+ export const GHIDRA_SEED_FORMAT = "rea-ghidra-seeds-v1";
11
+ export const GHIDRA_SEED_SCRIPT = "ReaGhidraApplySeeds.java";
12
+ export const MAX_GHIDRA_SEED_BYTES = 32 * 1024 * 1024;
13
+ export const MAX_GHIDRA_SEED_ENTRIES = 1_000_000;
14
+ const MAX_SEED_NAME_LENGTH = 2000;
15
+ const digest = z.string().regex(/^[a-f0-9]{64}$/u);
16
+ const count = z.number().int().nonnegative();
17
+ /** Caller-declared seeds committed into the analysis profile before import. */
18
+ export const ghidraSeedCommitmentSchema = z.strictObject({
19
+ format: z.literal(GHIDRA_SEED_FORMAT),
20
+ path: z.string().refine(isAbsolute, "Seed path must be absolute"),
21
+ configured_path: z.string().refine(isAbsolute, "Seed path must be absolute"),
22
+ sha256: digest,
23
+ entries: z.strictObject({ function: count, code: count, label: count }),
24
+ });
25
+ /** What the pre-analysis script applied, as reported by the bridge handshake. */
26
+ export const ghidraSeedReportSchema = z.strictObject({
27
+ format: z.literal(GHIDRA_SEED_FORMAT),
28
+ sha256: digest,
29
+ entries: count,
30
+ function_created: count,
31
+ function_existing: count,
32
+ function_failed: count,
33
+ code_decoded: count,
34
+ code_failed: count,
35
+ label_applied: count,
36
+ label_failed: count,
37
+ unmapped: count,
38
+ });
39
+ const seedLineError = (line, constraint) => new ConfigurationError("Invalid REA environment configuration", {
40
+ settings: [
41
+ {
42
+ setting: "REA_GHIDRA_SEED_FILE",
43
+ constraint: `line ${line}: ${constraint}`,
44
+ },
45
+ ],
46
+ });
47
+ /**
48
+ * Parse `address<TAB>kind[<TAB>name]` lines. Blank lines and `#` comments are
49
+ * ignored. Addresses are hexadecimal offsets in the default address space.
50
+ */
51
+ export const parseGhidraSeeds = (text) => {
52
+ const entries = [];
53
+ const seen = new Set();
54
+ const lines = text.split("\n");
55
+ for (const [index, raw] of lines.entries()) {
56
+ const line = raw.endsWith("\r") ? raw.slice(0, -1) : raw;
57
+ if (line.trim() === "" || line.startsWith("#"))
58
+ continue;
59
+ const number = index + 1;
60
+ const fields = line.split("\t");
61
+ if (fields.length < 2 || fields.length > 3)
62
+ return err(seedLineError(number, "expected address<TAB>kind[<TAB>name]"));
63
+ const [address, kind, name] = fields;
64
+ if (address === undefined || !/^0x[0-9a-fA-F]{1,16}$/u.test(address))
65
+ return err(seedLineError(number, "address must be 0x-prefixed hex"));
66
+ if (kind !== "function" && kind !== "code" && kind !== "label")
67
+ return err(seedLineError(number, "kind must be function, code or label"));
68
+ if (name !== undefined &&
69
+ (name.length === 0 ||
70
+ name.length > MAX_SEED_NAME_LENGTH ||
71
+ /[\s\0]/u.test(name)))
72
+ return err(seedLineError(number, `name must be 1..${MAX_SEED_NAME_LENGTH} characters without whitespace`));
73
+ if (kind === "label" && name === undefined)
74
+ return err(seedLineError(number, "a label seed requires a name"));
75
+ if (kind === "code" && name !== undefined)
76
+ return err(seedLineError(number, "a code seed takes no name; add a label seed"));
77
+ const value = BigInt(address);
78
+ const key = `${value.toString(16)}:${kind}`;
79
+ if (seen.has(key))
80
+ return err(seedLineError(number, `duplicate ${kind} seed at ${address}`));
81
+ seen.add(key);
82
+ entries.push({
83
+ address: value,
84
+ kind,
85
+ ...(name === undefined ? {} : { name }),
86
+ });
87
+ if (entries.length > MAX_GHIDRA_SEED_ENTRIES)
88
+ return err(seedLineError(number, `more than ${MAX_GHIDRA_SEED_ENTRIES} seed entries`));
89
+ }
90
+ return ok(entries);
91
+ };
92
+ /** Canonical script input: lowercase addresses, fixed field order, LF endings. */
93
+ const normalizedSeeds = (entries) => entries
94
+ .map((entry) => `0x${entry.address.toString(16)}\t${entry.kind}${entry.name === undefined ? "" : `\t${entry.name}`}\n`)
95
+ .join("");
96
+ /** Read a bounded regular file through one handle without following links. */
97
+ const readSeedFile = async (path) => {
98
+ const file = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
99
+ try {
100
+ const stat = await file.stat();
101
+ if (!stat.isFile() || stat.size > MAX_GHIDRA_SEED_BYTES)
102
+ throw new Error(`Ghidra seed file must be a regular file of at most ${MAX_GHIDRA_SEED_BYTES} bytes: ${path}`);
103
+ const bytes = Buffer.alloc(stat.size);
104
+ let offset = 0;
105
+ while (offset < bytes.length) {
106
+ const read = await file.read(bytes, offset, bytes.length - offset, offset);
107
+ if (read.bytesRead === 0)
108
+ throw new Error(`Incomplete Ghidra seed file read: ${path}`);
109
+ offset += read.bytesRead;
110
+ }
111
+ return bytes;
112
+ }
113
+ finally {
114
+ await file.close();
115
+ }
116
+ };
117
+ const sha256 = (bytes) => createHash("sha256").update(bytes).digest("hex");
118
+ const decodeSeeds = (bytes) => {
119
+ const text = new TextDecoder("utf-8", { fatal: true }).decode(bytes);
120
+ return parseGhidraSeeds(text);
121
+ };
122
+ /** Resolve the configured seed file into an immutable profile commitment. */
123
+ export const resolveGhidraAnalysisSeeds = async (configured) => {
124
+ if (configured === undefined)
125
+ return ok(undefined);
126
+ let bytes;
127
+ let path;
128
+ try {
129
+ path = await realpath(configured);
130
+ bytes = await readSeedFile(path);
131
+ }
132
+ catch (cause) {
133
+ return err(new ProviderAdapterError("ghidra", "resolve_analysis_profile", {
134
+ cause,
135
+ diagnostics: {
136
+ setting: "REA_GHIDRA_SEED_FILE",
137
+ path: configured,
138
+ reason: cause instanceof Error ? cause.message : String(cause),
139
+ },
140
+ }));
141
+ }
142
+ let parsed;
143
+ try {
144
+ parsed = decodeSeeds(bytes);
145
+ }
146
+ catch {
147
+ return err(seedLineError(0, "file is not valid UTF-8"));
148
+ }
149
+ if (!parsed.ok)
150
+ return parsed;
151
+ const normalized = normalizedSeeds(parsed.value);
152
+ const tally = { function: 0, code: 0, label: 0 };
153
+ for (const entry of parsed.value)
154
+ tally[entry.kind] += 1;
155
+ return ok({
156
+ format: GHIDRA_SEED_FORMAT,
157
+ path,
158
+ configured_path: configured,
159
+ sha256: sha256(normalized),
160
+ entries: tally,
161
+ });
162
+ };
163
+ /** Re-read the committed seeds and write the canonical copy the script applies. */
164
+ export const snapshotGhidraAnalysisSeeds = async (commitment, runtimeRoot) => {
165
+ ghidraSeedCommitmentSchema.parse(commitment);
166
+ if ((await realpath(commitment.configured_path)) !== commitment.path)
167
+ throw new Error("Ghidra seed file resolved path differs from explicit configuration");
168
+ const parsed = decodeSeeds(await readSeedFile(commitment.path));
169
+ if (!parsed.ok)
170
+ throw parsed.error;
171
+ const normalized = normalizedSeeds(parsed.value);
172
+ if (sha256(normalized) !== commitment.sha256)
173
+ throw new Error(`Ghidra seed file changed after the analysis profile was committed: ${commitment.path}`);
174
+ const directory = join(runtimeRoot, "seeds");
175
+ await mkdir(directory, { mode: 0o700 });
176
+ const path = join(directory, "seeds.tsv");
177
+ await writeFile(path, normalized, { flag: "wx", mode: 0o600 });
178
+ return path;
179
+ };
180
+ const totalEntries = (commitment) => commitment.entries.function +
181
+ commitment.entries.code +
182
+ commitment.entries.label;
183
+ /** Fail closed when the session did not apply exactly the committed seeds. */
184
+ export const ghidraSeedFailure = (commitment, report, operation) => {
185
+ if (commitment === undefined && report === undefined)
186
+ return undefined;
187
+ const reason = commitment === undefined
188
+ ? "The Ghidra session reported analysis seeds that the profile did not commit."
189
+ : report === undefined
190
+ ? "The Ghidra session did not report the committed analysis seeds."
191
+ : report.sha256 !== commitment.sha256 ||
192
+ report.entries !== totalEntries(commitment)
193
+ ? "The Ghidra session applied analysis seeds that differ from the committed profile."
194
+ : undefined;
195
+ return reason === undefined
196
+ ? undefined
197
+ : new ProviderAdapterError("ghidra", operation, {
198
+ diagnostics: { reason },
199
+ });
200
+ };
201
+ /** Session limitations that keep seeded facts distinct from Ghidra discoveries. */
202
+ export const ghidraSeedLimitations = (commitment, report) => commitment === undefined
203
+ ? []
204
+ : [
205
+ `Ghidra analysis was seeded before auto-analysis from ${commitment.path} (sha256 ${commitment.sha256}: ${commitment.entries.function} function, ${commitment.entries.code} code, ${commitment.entries.label} label entries). Seeded functions, code and names are caller assertions, not Ghidra discoveries.`,
206
+ ...(report === undefined
207
+ ? []
208
+ : [
209
+ `Seed outcome: ${report.function_created} functions created, ${report.function_existing} already present, ${report.function_failed} failed; ${report.code_decoded} code seeds decoded, ${report.code_failed} failed; ${report.label_applied} labels applied, ${report.label_failed} failed; ${report.unmapped} seeds outside initialized memory.`,
210
+ ]),
211
+ ];
@@ -9,7 +9,8 @@ import { ProviderStartupDeadline } from "../process/ProviderDeadline.js";
9
9
  import { ProviderRunLineage } from "../process/ProviderRunLineage.js";
10
10
  import { ProviderProcessSupervisor, } from "../process/ProviderProcess.js";
11
11
  import { DEFAULT_GHIDRA_STARTUP_TIMEOUT_MS } from "../config/ghidraStartupTimeout.js";
12
- import { createGhidraDiagnostics } from "./GhidraDiagnostics.js";
12
+ import { createGhidraDiagnostics, GHIDRA_PROCESS_DIAGNOSTIC_BYTES, } from "./GhidraDiagnostics.js";
13
+ import { GhidraLaunchError } from "./GhidraLauncher.js";
13
14
  import { GhidraResponseBuffer } from "./GhidraResponseBuffer.js";
14
15
  import { GhidraResponseRouter } from "./GhidraResponseRouter.js";
15
16
  import { GhidraRequestQueue } from "./GhidraRequestQueue.js";
@@ -17,6 +18,9 @@ import { bindGhidraSessionFailure, GhidraSessionError, } from "./GhidraSessionEr
17
18
  import { isGhidraShutdownAcknowledgement, parseGhidraSessionInfo, } from "./GhidraSessionValues.js";
18
19
  import { createGhidraTargetSnapshot } from "./GhidraTargetSnapshot.js";
19
20
  import { readFile } from "node:fs/promises";
21
+ import { readBoundedFileBytes } from "../process/BoundedFileBytes.js";
22
+ import { openRegularFile, RegularFileChangedError, sameRegularFileState, } from "../filesystem/RegularFile.js";
23
+ import { OwnedFileHandle } from "../filesystem/OwnedFileHandle.js";
20
24
  import { connectGhidraSocket } from "./GhidraSocketConnection.js";
21
25
  import { createGhidraEndpoint, } from "./GhidraTransport.js";
22
26
  import { GhidraWire } from "./GhidraClientWire.js";
@@ -37,6 +41,7 @@ export class GhidraClient {
37
41
  #socketRoot;
38
42
  #endpointPath;
39
43
  #snapshotPath;
44
+ #snapshotOwners = new Set();
40
45
  #targetAdmission;
41
46
  #token;
42
47
  // Retain authentication identities for diagnostics from late request settlement.
@@ -146,14 +151,76 @@ export class GhidraClient {
146
151
  return this.#requestQueue.run(operation, parameters, options.signal === undefined ? {} : { signal: options.signal });
147
152
  }
148
153
  /** Read the private immutable source for independent import verification. */
149
- async readTargetSnapshot() {
154
+ async readTargetSnapshot(maximumBytes, signal) {
150
155
  if (this.#snapshotPath === undefined)
151
156
  return err(this.#failure("protocol", "Ghidra target snapshot is unavailable before startup or after close"));
152
157
  try {
153
- return ok(await readFile(this.#snapshotPath));
158
+ if (maximumBytes !== undefined) {
159
+ signal?.throwIfAborted();
160
+ if (!Number.isSafeInteger(maximumBytes) || maximumBytes < 0)
161
+ throw new RangeError("Snapshot byte limit must be a safe integer");
162
+ const handle = await openRegularFile(this.#snapshotPath, {
163
+ symlinks: "reject",
164
+ });
165
+ const owner = new OwnedFileHandle(handle);
166
+ this.#snapshotOwners.add(owner);
167
+ let result;
168
+ let readFailure;
169
+ try {
170
+ const metadata = await handle.stat();
171
+ signal?.throwIfAborted();
172
+ if (metadata.size > maximumBytes)
173
+ result = {
174
+ kind: "over-capacity",
175
+ sourceBytesAtLeast: metadata.size,
176
+ maximumBytes,
177
+ };
178
+ else {
179
+ const bytes = await readBoundedFileBytes(handle, maximumBytes, signal, metadata.size);
180
+ signal?.throwIfAborted();
181
+ const after = await handle.stat();
182
+ if (bytes !== undefined &&
183
+ bytes.length === metadata.size &&
184
+ sameRegularFileState(metadata, after)) {
185
+ result = { kind: "captured", bytes };
186
+ }
187
+ else if (bytes === undefined &&
188
+ after.isFile() &&
189
+ after.size > maximumBytes) {
190
+ result = {
191
+ kind: "over-capacity",
192
+ sourceBytesAtLeast: after.size,
193
+ maximumBytes,
194
+ };
195
+ }
196
+ else {
197
+ throw new RegularFileChangedError(this.#snapshotPath);
198
+ }
199
+ }
200
+ }
201
+ catch (cause) {
202
+ readFailure = cause;
203
+ }
204
+ try {
205
+ await owner.close();
206
+ this.#snapshotOwners.delete(owner);
207
+ }
208
+ catch (closeFailure) {
209
+ throw new AggregateError(readFailure === undefined
210
+ ? [closeFailure]
211
+ : [readFailure, closeFailure], "Ghidra target snapshot read or descriptor cleanup failed");
212
+ }
213
+ if (readFailure !== undefined)
214
+ throw readFailure;
215
+ return ok(result);
216
+ }
217
+ return ok({
218
+ kind: "captured",
219
+ bytes: await readFile(this.#snapshotPath),
220
+ });
154
221
  }
155
222
  catch (cause) {
156
- return err(this.#failure("protocol", "Ghidra target snapshot could not be read for load-image verification", cause));
223
+ return err(this.#failure(signal?.aborted === true ? "cancelled" : "protocol", "Ghidra target snapshot could not be read for load-image verification", cause));
157
224
  }
158
225
  }
159
226
  /** Stop the owned process group and remove all project/runtime artifacts. */
@@ -290,8 +357,18 @@ export class GhidraClient {
290
357
  }, { signal: deadline.signal })
291
358
  .catch((cause) => err(this.#failure("start", "Ghidra launcher failed", cause)));
292
359
  if (!launched.ok) {
360
+ const partialLaunch = launched.error instanceof GhidraLaunchError
361
+ ? launched.error.partialLaunch
362
+ : undefined;
363
+ if (partialLaunch !== undefined) {
364
+ this.#launch = partialLaunch;
365
+ this.#process = new ProviderProcessSupervisor(partialLaunch, {
366
+ maxDiagnosticBytes: GHIDRA_PROCESS_DIAGNOSTIC_BYTES,
367
+ onDiagnostic: (event) => this.#onProcessDiagnostic(event),
368
+ });
369
+ }
293
370
  const failure = deadline.signal.aborted
294
- ? this.#interruptionFailure(deadline)
371
+ ? this.#interruptionFailure(deadline, launched.error)
295
372
  : launched.error instanceof GhidraSessionError
296
373
  ? launched.error
297
374
  : this.#failure("start", launched.error.message, launched.error);
@@ -299,6 +376,7 @@ export class GhidraClient {
299
376
  }
300
377
  this.#launch = launched.value;
301
378
  this.#process = new ProviderProcessSupervisor(launched.value, {
379
+ maxDiagnosticBytes: GHIDRA_PROCESS_DIAGNOSTIC_BYTES,
302
380
  onDiagnostic: (event) => this.#onProcessDiagnostic(event),
303
381
  });
304
382
  const connected = await this.#connect(endpoint, deadline);
@@ -423,6 +501,10 @@ export class GhidraClient {
423
501
  this.#lastDiagnostics = this.#diagnostics();
424
502
  this.#process = undefined;
425
503
  this.#launch = undefined;
504
+ for (const owner of this.#snapshotOwners) {
505
+ await owner.close();
506
+ this.#snapshotOwners.delete(owner);
507
+ }
426
508
  try {
427
509
  await this.#removeRuntimeRoots();
428
510
  }
@@ -519,10 +601,10 @@ export class GhidraClient {
519
601
  const failure = this.#interruptionFailure(deadline);
520
602
  return this.#startupFailure(failure);
521
603
  }
522
- #interruptionFailure(deadline) {
604
+ #interruptionFailure(deadline, cause) {
523
605
  return deadline.interruption === "cancelled"
524
- ? this.#failure("cancelled", "Ghidra startup was cancelled")
525
- : this.#failure("timeout", "Ghidra startup deadline elapsed", undefined, {
606
+ ? this.#failure("cancelled", "Ghidra startup was cancelled", cause)
607
+ : this.#failure("timeout", "Ghidra startup deadline elapsed", cause, {
526
608
  timeoutMs: deadline.timeoutMs,
527
609
  });
528
610
  }
@@ -1,12 +1,12 @@
1
+ import { redactCapturedTransportCredential } from "../process/ProviderDiagnosticRedaction.js";
2
+ /** Aggregate in-memory retention budget for this provider's launcher output. */
3
+ export const GHIDRA_PROCESS_DIAGNOSTIC_BYTES = 8 * 1024 * 1024;
1
4
  /** Preserve actionable runtime coordinates after cleanup and redact bearer data. */
2
5
  export const createGhidraDiagnostics = (options) => {
3
6
  if (options.runtimeRoot === undefined &&
4
7
  options.launch === undefined &&
5
8
  Object.keys(options.previous).length > 0)
6
9
  return options.previous;
7
- const redacted = (value) => options.token === undefined
8
- ? value
9
- : value.replaceAll(options.token, "[REDACTED]");
10
10
  return {
11
11
  target_path: options.targetPath,
12
12
  target_sha256: options.targetSha256,
@@ -39,12 +39,15 @@ export const createGhidraDiagnostics = (options) => {
39
39
  : {
40
40
  exit_code: options.snapshot.exitCode ?? null,
41
41
  exit_signal: options.snapshot.signal ?? null,
42
- stdout: boundedStream(options.snapshot.stdout, redacted),
43
- stderr: boundedStream(options.snapshot.stderr, redacted),
42
+ diagnostic_truncated: options.snapshot.diagnosticTruncated === true,
43
+ stdout: boundedStream(options.snapshot.stdout, options.token),
44
+ stderr: boundedStream(options.snapshot.stderr, options.token),
44
45
  }),
45
46
  };
46
47
  };
47
- const boundedStream = (stream, redact) => ({
48
- text: redact(stream.text),
49
- bytes: stream.bytes,
48
+ const boundedStream = (stream, token) => ({
49
+ text: redactCapturedTransportCredential(stream, token, "[REDACTED]"),
50
+ // Preserve the historical total-byte counter; text is now bounded separately.
51
+ bytes: stream.observedBytes,
52
+ retained_bytes: stream.bytes,
50
53
  });
@@ -285,11 +285,35 @@ const resultSchemas = {
285
285
  procedure_references: procedureReferences,
286
286
  xrefs: z.array(ghidraCanonicalAddressSchema),
287
287
  };
288
+ const functionBoundaryObservationOperations = new Set([
289
+ "analyze_function",
290
+ "procedure_assembly",
291
+ "procedure_info",
292
+ "procedure_pseudo_code",
293
+ "read_function_instructions",
294
+ ]);
295
+ const functionObservationEnvelope = z.strictObject({
296
+ value: z.unknown(),
297
+ limitations: z.array(z.string()),
298
+ });
288
299
  /** Require exact, bounded Java-bridge function output before creating Evidence. */
289
300
  export const parseGhidraFunctionResult = (operation, value) => {
290
- const parsed = resultSchemas[operation].safeParse(value);
301
+ let observation;
302
+ if (functionBoundaryObservationOperations.has(operation)) {
303
+ const envelope = functionObservationEnvelope.safeParse(value);
304
+ if (!envelope.success)
305
+ return err(new AnalysisOutputError(operation, "Ghidra bridge omitted the function observation envelope", { cause: envelope.error }));
306
+ observation = envelope.data;
307
+ }
308
+ else {
309
+ observation = { value, limitations: [] };
310
+ }
311
+ const parsed = resultSchemas[operation].safeParse(observation.value);
291
312
  return parsed.success
292
- ? ok(jsonValueSchema.parse(parsed.data))
313
+ ? ok({
314
+ value: jsonValueSchema.parse(parsed.data),
315
+ limitations: observation.limitations,
316
+ })
293
317
  : err(new AnalysisOutputError(operation, "Ghidra bridge output did not match the function-analysis contract", { cause: parsed.error }));
294
318
  };
295
319
  const referenceAddresses = (edge) => [
@@ -1,14 +1,84 @@
1
1
  import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
2
2
  import { spawnSync } from "node:child_process";
3
3
  import { constants } from "node:fs";
4
- import { accessSync, readFileSync } from "node:fs";
4
+ import { accessSync, closeSync, fstatSync, openSync, readFileSync, readSync, statSync, } from "node:fs";
5
5
  import { posix, win32 } from "node:path";
6
+ import { parseExecutableHeader, } from "../domain/binaryTarget.js";
6
7
  import { ghidraApplicationProperties, ghidraJavaMajorAccepted, ghidraJavaRangeLabel, ghidraJavaRequirement, ghidraReleaseAccepted, ghidraReleaseCompatibility, ghidraReleaseLine, ghidraVersionDetail, SUPPORTED_GHIDRA_JAVA_MAJOR, SUPPORTED_GHIDRA_VERSION, } from "./GhidraInstallationPolicy.js";
7
8
  const NATIVE_PLATFORMS = {
8
9
  linux: { x64: "linux_x86_64", arm64: "linux_arm_64" },
9
10
  darwin: { x64: "mac_x86_64", arm64: "mac_arm_64" },
10
11
  win32: { x64: "win_x86_64" },
11
12
  };
13
+ /** Executable format each supported host runs its own Ghidra native tools as. */
14
+ const NATIVE_TOOL_FORMATS = {
15
+ linux: "elf",
16
+ darwin: "mach-o",
17
+ win32: "pe",
18
+ };
19
+ /** Node architecture identifiers as the executable-header parser reports them. */
20
+ const NATIVE_ARCHITECTURES = [
21
+ { node: "x64", binary: "x86_64" },
22
+ { node: "ia32", binary: "x86" },
23
+ { node: "arm", binary: "arm" },
24
+ { node: "arm64", binary: "arm64" },
25
+ ];
26
+ /** Bound installation discovery reads; larger headers remain unknown. */
27
+ const EXECUTABLE_HEADER_PROBE_BYTES = 4096;
28
+ /**
29
+ * Judge a native decompiler by its own executable header instead of the
30
+ * directory name that admits it.
31
+ *
32
+ * Only a header that positively contradicts the host is `incompatible`. An
33
+ * absent, unreadable, truncated, or unrecognized header stays `unknown`, so a
34
+ * file the other checks already accept is never refused on missing evidence.
35
+ */
36
+ const assessNativeDecompiler = (path, platform, architecture, probe) => {
37
+ const expectedFormat = NATIVE_TOOL_FORMATS[platform];
38
+ const expectedArchitecture = NATIVE_ARCHITECTURES.find(({ node }) => node === architecture)?.binary;
39
+ if (expectedFormat === undefined || expectedArchitecture === undefined)
40
+ return {
41
+ status: "unknown",
42
+ detail: `${path} is executable, but no native tool format is defined for ${platform}/${architecture}`,
43
+ };
44
+ let parsed = probe === undefined
45
+ ? undefined
46
+ : parseExecutableHeader(probe.bytes, architecture, probe.size);
47
+ if (probe !== undefined && parsed !== undefined && !parsed.ok) {
48
+ // FAT parsing selects a host slice. A validated foreign slice can still
49
+ // prove that its complete architecture table excludes this host. If the
50
+ // host is listed but its slice is malformed, preserve the unknown outcome.
51
+ for (const { node } of NATIVE_ARCHITECTURES) {
52
+ if (node === architecture)
53
+ continue;
54
+ const alternative = parseExecutableHeader(probe.bytes, node, probe.size);
55
+ if (alternative.ok &&
56
+ !alternative.value.availableArchitectures.some((available) => available === expectedArchitecture)) {
57
+ parsed = alternative;
58
+ break;
59
+ }
60
+ }
61
+ }
62
+ if (parsed === undefined || !parsed.ok)
63
+ return {
64
+ status: "unknown",
65
+ detail: `${path} is executable, but its executable format for ${platform}/${architecture} could not be established`,
66
+ };
67
+ const observed = `${parsed.value.format} ${parsed.value.architecture}`;
68
+ const expected = `${expectedFormat} ${expectedArchitecture}`;
69
+ if (observed === expected)
70
+ return {
71
+ status: "compatible",
72
+ detail: `${path} reports ${observed}, which matches ${platform}/${architecture}`,
73
+ };
74
+ const nativeDirectory = NATIVE_PLATFORMS[platform]?.[architecture];
75
+ const executable = platform === "win32" ? "decompile.exe" : "decompile";
76
+ return {
77
+ status: "incompatible",
78
+ detail: `${path} reports ${observed}, but ${platform}/${architecture} requires ${expected}`,
79
+ remediation: `Provide an executable Ghidra/Features/Decompiler/os/${nativeDirectory ?? "<platform>"}/${executable} built for ${expected}, or its build/os equivalent. REA does not build or install native tools.`,
80
+ };
81
+ };
12
82
  /** Inspect an installation without importing a target or modifying Ghidra. */
13
83
  export const inspectGhidraInstallation = (options, host = systemGhidraInstallationHost()) => {
14
84
  const platform = options.platform ?? process.platform;
@@ -137,14 +207,7 @@ const installationChecks = ({ coordinates, platform, architecture, javaHome, hos
137
207
  detail: coordinates.analyzeHeadlessPath ?? "analyzeHeadless unavailable",
138
208
  remediation: "Restore support/analyzeHeadless or support/analyzeHeadless.bat from the official Ghidra release.",
139
209
  }),
140
- installationCheck({
141
- name: "native_decompiler",
142
- passed: coordinates.nativeDecompilerPath !== null,
143
- code: "executable_missing",
144
- detail: coordinates.nativeDecompilerPath ??
145
- `Matching native decompiler for ${platform}/${architecture} was not found`,
146
- 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.`,
147
- }),
210
+ nativeDecompilerCheck({ coordinates, platform, architecture, host }),
148
211
  javaCheck(coordinates.java, coordinates.javaCommand, javaHome, coordinates.properties),
149
212
  ];
150
213
  /**
@@ -226,6 +289,23 @@ const installationCheck = (options) => options.passed
226
289
  detail: options.detail,
227
290
  remediation: options.remediation,
228
291
  };
292
+ /** Require a present native decompiler without positively incompatible bytes. */
293
+ const nativeDecompilerCheck = ({ coordinates, platform, architecture, host, }) => {
294
+ const path = coordinates.nativeDecompilerPath;
295
+ const compatibility = path === null
296
+ ? undefined
297
+ : assessNativeDecompiler(path, platform, architecture, host.executableHeader?.(path));
298
+ return installationCheck({
299
+ name: "native_decompiler",
300
+ passed: path !== null && compatibility?.status !== "incompatible",
301
+ code: "executable_missing",
302
+ detail: compatibility?.detail ??
303
+ `Matching native decompiler for ${platform}/${architecture} was not found`,
304
+ remediation: compatibility?.status === "incompatible"
305
+ ? compatibility.remediation
306
+ : `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.`,
307
+ });
308
+ };
229
309
  const versionCheck = (properties) => {
230
310
  const raw = properties?.providerVersion;
231
311
  return installationCheck({
@@ -280,10 +360,31 @@ const systemGhidraInstallationHost = () => ({
280
360
  return undefined;
281
361
  }
282
362
  },
363
+ executableHeader(path) {
364
+ let handle;
365
+ try {
366
+ handle = openSync(path, constants.O_RDONLY | constants.O_NONBLOCK | constants.O_NOCTTY);
367
+ const metadata = fstatSync(handle);
368
+ if (!metadata.isFile())
369
+ return undefined;
370
+ const bytes = Buffer.alloc(EXECUTABLE_HEADER_PROBE_BYTES);
371
+ const read = readSync(handle, bytes, 0, bytes.length, 0);
372
+ return { bytes: bytes.subarray(0, read), size: metadata.size };
373
+ }
374
+ catch (cause) {
375
+ // best-effort cleanup: a header that cannot be read stays unknown.
376
+ void cause;
377
+ return undefined;
378
+ }
379
+ finally {
380
+ if (handle !== undefined)
381
+ closeSync(handle);
382
+ }
383
+ },
283
384
  executable(path) {
284
385
  try {
285
386
  accessSync(path, constants.X_OK);
286
- return true;
387
+ return statSync(path).isFile();
287
388
  }
288
389
  catch (cause) {
289
390
  // best-effort cleanup: optional executable probing; failure means missing.
@@ -5,7 +5,10 @@ import { functionBodySchema, functionBodyEntryAgrees, } from "../domain/hopperVa
5
5
  import { jsonValueSchema } from "../domain/jsonValue.js";
6
6
  import { err, ok } from "../domain/result.js";
7
7
  import { analysisInputErrorFromIssues } from "../domain/inputIssueProjection.js";
8
- /** Read-only direct inventory operations admitted by the Ghidra adapter. */
8
+ /**
9
+ * Direct inventory operations admitted by the Ghidra adapter. All are reads
10
+ * except the naming operations, which edit the ephemeral session database.
11
+ */
9
12
  export const GHIDRA_INVENTORY_OPERATIONS = [
10
13
  "inspect_native_load_image",
11
14
  "read_bytes",
@@ -20,6 +23,13 @@ export const GHIDRA_INVENTORY_OPERATIONS = [
20
23
  "resolve_containing_procedure",
21
24
  "search_procedures",
22
25
  "search_strings",
26
+ "set_address_name",
27
+ "set_addresses_names",
28
+ ];
29
+ /** Inventory operations that write analyst names into the session database. */
30
+ export const GHIDRA_NAMING_OPERATIONS = [
31
+ "set_address_name",
32
+ "set_addresses_names",
23
33
  ];
24
34
  const operationSet = new Set(GHIDRA_INVENTORY_OPERATIONS);
25
35
  /** Narrow an application operation to the Ghidra inventory surface. */
@@ -62,6 +72,16 @@ const inputSchemas = {
62
72
  .strict(),
63
73
  search_procedures: z.object(searchInput).strict(),
64
74
  search_strings: z.object(searchInput).strict(),
75
+ set_address_name: z
76
+ .object({ document, address: explicitAddress, name: z.string().min(1) })
77
+ .strict(),
78
+ set_addresses_names: z
79
+ .object({
80
+ document,
81
+ names: z.record(explicitAddress, z.string().min(1)),
82
+ })
83
+ .strict()
84
+ .refine((value) => Object.keys(value.names).length > 0, "Supply at least one address name"),
65
85
  };
66
86
  /** Validate and default one provider request before it crosses the socket. */
67
87
  export const parseGhidraInventoryInput = (operation, value) => {
@@ -230,6 +250,8 @@ const resultSchemas = {
230
250
  resolve_containing_procedure: containingProcedure,
231
251
  search_procedures: z.array(searchItem),
232
252
  search_strings: z.array(searchItem),
253
+ set_address_name: z.boolean(),
254
+ set_addresses_names: z.record(z.string(), z.boolean()),
233
255
  };
234
256
  /** Validate exact Java-bridge output before creating Evidence. */
235
257
  export const parseGhidraInventoryResult = (operation, value) => {