rea-agents 6.4.0 → 6.5.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 (1211) hide show
  1. package/DISCLAIMER.md +136 -0
  2. package/README.md +67 -16
  3. package/THIRD_PARTY_NOTICES.md +134 -0
  4. package/bridge/android/ReaJadxBridge.java +123 -11
  5. package/bridge/cutter/rea_bridge.py +816 -0
  6. package/bridge/ghidra/ReaGhidraAnalysisOptions.java +38 -0
  7. package/bridge/ghidra/ReaGhidraBridge.java +1181 -123
  8. package/bridge/ghidra/ReaGhidraBundleActivator.java +14 -0
  9. package/bridge/ghidra/ReaGhidraMipsSoftFloat.java +176 -0
  10. package/bridge/ghidra/ReaGhidraPrepareRaw.java +49 -0
  11. package/bridge/hopper_bridge.py +103 -69
  12. package/bridge/mitmproxy/capture.py +189 -13
  13. package/bridge/native/rea_lldb_tracer.py +40 -6
  14. package/bridge/process/ProcessRunTokenReader.swift +76 -34
  15. package/bridge/pwntools/layout_impl.py +5 -0
  16. package/bridge/pwntools/recorded_crash_impl.py +31 -10
  17. package/dist/adb/AdbConfiguration.js +15 -3
  18. package/dist/adb/AdbDeviceOutput.js +59 -37
  19. package/dist/adb/AdbDirectoryListing.js +80 -0
  20. package/dist/adb/AdbHostFileName.js +34 -0
  21. package/dist/adb/AdbProvider.js +416 -173
  22. package/dist/adb/AdbShellOutput.js +55 -57
  23. package/dist/android/JadxAnalysis.js +32 -7
  24. package/dist/android/JadxConfiguration.js +119 -29
  25. package/dist/android/JadxDoctor.js +115 -0
  26. package/dist/android/JadxMcpTransport.js +5 -3
  27. package/dist/android/JadxProtocol.js +14 -0
  28. package/dist/android/JadxProvider.js +15 -9
  29. package/dist/android/JadxRelease.js +12 -1
  30. package/dist/android/JadxWorkspaceRoot.js +157 -0
  31. package/dist/apktool/ApktoolConfiguration.js +165 -22
  32. package/dist/apktool/ApktoolDecodeOutput.js +124 -41
  33. package/dist/apktool/ApktoolProvider.js +70 -33
  34. package/dist/application/AnalysisContextQueries.js +5 -8
  35. package/dist/application/AnalysisProvider.js +24 -20
  36. package/dist/application/AppBundleExecutable.js +5 -5
  37. package/dist/application/BinaryTargetResolver.js +195 -38
  38. package/dist/application/BrowserEvidence.js +1 -1
  39. package/dist/application/BrowserObservationService.js +13 -2
  40. package/dist/application/BrowserScenarioCaptureService.js +0 -1
  41. package/dist/application/CallPathTracing.js +52 -13
  42. package/dist/application/CapabilityInventory.js +168 -28
  43. package/dist/application/ClaudeDesktopConfigLocation.js +152 -0
  44. package/dist/application/ClientConfigurationDocument.js +102 -25
  45. package/dist/application/ClientConfigurationFiles.js +51 -14
  46. package/dist/application/ClientRegistrationEnvironment.js +10 -4
  47. package/dist/application/ClientRegistrationIdentity.js +94 -29
  48. package/dist/application/ClientRegistrationStatus.js +180 -59
  49. package/dist/application/DirectAnalysis.js +85 -30
  50. package/dist/application/DirectAnalysisStatus.js +13 -1
  51. package/dist/application/Doctor.js +113 -32
  52. package/dist/application/DoctorDiagnostics.js +34 -12
  53. package/dist/application/DoctorProviderIds.js +2 -0
  54. package/dist/application/DoctorScope.js +11 -2
  55. package/dist/application/DshCordisPatch.js +355 -0
  56. package/dist/application/DshCordisYaml.js +155 -0
  57. package/dist/application/EnhancedLiteralTracing.js +30 -16
  58. package/dist/application/EnhancedToolTypes.js +0 -1
  59. package/dist/application/EnhancedTools.js +164 -54
  60. package/dist/application/EvidenceBundleCommands.js +30 -7
  61. package/dist/application/EvidenceBundleFiles.js +29 -7
  62. package/dist/application/FunctionAnalysisEvidence.js +3 -0
  63. package/dist/application/GeminiClientSettings.js +25 -13
  64. package/dist/application/HermesConfigurationYaml.js +272 -0
  65. package/dist/application/InventoryProjectionEvidence.js +0 -1
  66. package/dist/application/InvestigationProviders.js +13 -3
  67. package/dist/application/JsonFiles.js +110 -20
  68. package/dist/application/JsonInputFile.js +220 -62
  69. package/dist/application/LinuxHopper.js +126 -48
  70. package/dist/application/MacHopper.js +21 -17
  71. package/dist/application/MacHopperPaths.js +40 -0
  72. package/dist/application/{MipsElfAbiFlags.js → MipsElfMetadata.js} +70 -9
  73. package/dist/application/MipsElfSharedLoad.js +164 -0
  74. package/dist/application/MipsGnuAttributes.js +90 -0
  75. package/dist/application/MsixPackageStorage.js +133 -0
  76. package/dist/application/ProgressReporter.js +1 -1
  77. package/dist/application/ProviderOperationExecution.js +11 -3
  78. package/dist/application/ReconstructionCoverageService.js +0 -1
  79. package/dist/application/ReconstructionObligationCandidates.js +3 -2
  80. package/dist/application/ReconstructionObligationLedgerDiagnostics.js +2 -2
  81. package/dist/application/ReconstructionObligationLedgerEvaluation.js +15 -33
  82. package/dist/application/ReconstructionObligationLedgerProjection.js +3 -72
  83. package/dist/application/ReconstructionObligationLedgerService.js +3 -1
  84. package/dist/application/ReconstructionObligationOriginalCases.js +2 -1
  85. package/dist/application/ReferenceSourceImport.js +24 -8
  86. package/dist/application/ReferenceSourceImportEntries.js +22 -21
  87. package/dist/application/ReferenceSourceImportTypes.js +0 -1
  88. package/dist/application/ReferenceSourceVcsAdapter.js +33 -16
  89. package/dist/application/RegularFileRead.js +46 -18
  90. package/dist/application/Setup.js +36 -10
  91. package/dist/application/SetupClientConfiguration.js +206 -37
  92. package/dist/application/SetupClients.js +12 -6
  93. package/dist/application/SetupHost.js +66 -24
  94. package/dist/application/SetupInstallFailure.js +42 -2
  95. package/dist/application/SetupPlan.js +79 -50
  96. package/dist/application/SetupRecoveryBackup.js +66 -0
  97. package/dist/application/SetupRegistrationEnvironment.js +2 -1
  98. package/dist/application/SetupSkill.js +323 -76
  99. package/dist/application/SupportedClients.js +162 -28
  100. package/dist/application/TypeScriptEmittedSourceCandidates.js +26 -0
  101. package/dist/application/Uninstall.js +273 -82
  102. package/dist/application/UninstallFailure.js +14 -0
  103. package/dist/application/Update.js +54 -25
  104. package/dist/application/UpdateFailure.js +17 -0
  105. package/dist/application/UpdateMaintenance.js +11 -29
  106. package/dist/application/UpdateRuntime.js +141 -27
  107. package/dist/application/WebModuleTraceService.js +7 -0
  108. package/dist/application/WebNetworkCaptureService.js +16 -7
  109. package/dist/application/WebSourceLocationService.js +20 -4
  110. package/dist/application/WindowsCapabilities.js +18 -15
  111. package/dist/application/WorkflowEvidence.js +24 -1
  112. package/dist/application/analysisView/AnalysisViewService.js +90 -12
  113. package/dist/application/android/AndroidPackageInspection.js +25 -0
  114. package/dist/application/android/AndroidSearchEvidenceSummary.js +100 -0
  115. package/dist/application/binary/AnalysisProviderEvaluation.js +1 -1
  116. package/dist/application/binary/AnalysisProviderRegistry.js +36 -21
  117. package/dist/application/binary/AnalysisSnapshotCache.js +41 -20
  118. package/dist/application/binary/AnalysisSnapshotFiles.js +75 -9
  119. package/dist/application/binary/BinarySession.js +248 -96
  120. package/dist/application/binary/BinarySessionExecution.js +5 -4
  121. package/dist/application/binary/BinarySessionOpen.js +13 -6
  122. package/dist/application/binary/BinarySessionRecords.js +33 -7
  123. package/dist/application/binary/BinarySessionStatus.js +93 -23
  124. package/dist/application/binary/BinaryTargetSummary.js +9 -0
  125. package/dist/application/binary/CompositeProvider.js +71 -28
  126. package/dist/application/binary/LazyAnalysisProvider.js +3 -1
  127. package/dist/application/binary/SessionProviderRouter.js +5 -2
  128. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +11 -1
  129. package/dist/application/binaryDiagnostics/PeResourcesService.js +3 -0
  130. package/dist/application/binaryDiagnostics/RecordedCrashService.js +14 -3
  131. package/dist/application/captures/PacketCaptureService.js +83 -0
  132. package/dist/application/closeOwnedWebResources.js +7 -0
  133. package/dist/application/electron/ElectronFusePort.js +1 -0
  134. package/dist/application/electron/ElectronFuseService.js +80 -0
  135. package/dist/application/evm/EvmInterfaceService.js +1 -0
  136. package/dist/application/flutter/DartAotInspection.js +26 -0
  137. package/dist/application/flutter/FlutterBuildAnalysisPort.js +1 -0
  138. package/dist/application/flutter/FlutterBuildAnalysisService.js +13 -0
  139. package/dist/application/frida/FridaInstrumentationPort.js +8 -0
  140. package/dist/application/frida/FridaInstrumentationService.js +310 -0
  141. package/dist/application/frida/fridaInputErrors.js +17 -0
  142. package/dist/application/go/GoBinaryPort.js +1 -0
  143. package/dist/application/go/GoBinaryService.js +80 -0
  144. package/dist/application/harmony/HarmonyApplicationService.js +17 -0
  145. package/dist/application/investigation/EvidenceLedger.js +40 -14
  146. package/dist/application/investigation/InvestigationRecords.js +12 -21
  147. package/dist/application/investigation/UnknownEvidence.js +22 -18
  148. package/dist/application/javascript/ElectronActiveObservationService.js +55 -25
  149. package/dist/application/javascript/ElectronBoundaryAnalysis.js +17 -3
  150. package/dist/application/javascript/ElectronBoundaryGraph.js +2 -0
  151. package/dist/application/javascript/ElectronBoundaryGraphCallPaths.js +144 -0
  152. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +26 -7
  153. package/dist/application/javascript/ElectronBoundaryGraphNative.js +1 -1
  154. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +47 -9
  155. package/dist/application/javascript/ElectronObservationService.js +0 -1
  156. package/dist/application/javascript/JavaScriptApplicationEvidence.js +15 -0
  157. package/dist/application/javascript/JavaScriptApplicationService.js +29 -14
  158. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +0 -1
  159. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +86 -34
  160. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +51 -21
  161. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +31 -7
  162. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +25 -4
  163. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +25 -14
  164. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +147 -41
  165. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +156 -7
  166. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +892 -181
  167. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +43 -30
  168. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +2 -0
  169. package/dist/application/javascript/JavaScriptModuleRelationships.js +33 -11
  170. package/dist/application/javascript/JavaScriptRecoveryService.js +29 -9
  171. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +2 -1
  172. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +0 -1
  173. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +42 -26
  174. package/dist/application/javascript/JavaScriptSemanticGraphElectronProjection.js +67 -0
  175. package/dist/application/javascript/JavaScriptSemanticTraceService.js +0 -1
  176. package/dist/application/managed/ManagedApplicationGraphService.js +0 -1
  177. package/dist/application/managed/ManagedMemberComparisonService.js +72 -54
  178. package/dist/application/managed/ManagedNativeVerificationService.js +0 -1
  179. package/dist/application/managed/ManagedReconstructionService.js +0 -1
  180. package/dist/application/native/NativeCallRoutes.js +54 -34
  181. package/dist/application/native/NativeDispatchMetadataInspection.js +6 -2
  182. package/dist/application/native/NativeUiActionTrace.js +35 -22
  183. package/dist/application/native/NativeValueTrace.js +57 -23
  184. package/dist/application/pcap/PcapAnalysisPort.js +1 -0
  185. package/dist/application/pcap/PcapAnalysisService.js +24 -0
  186. package/dist/application/process/ProcessCli.js +33 -13
  187. package/dist/application/reverse/ReverseEngineeringCommandPort.js +1 -0
  188. package/dist/application/reverse/ReverseEngineeringService.js +688 -0
  189. package/dist/application/rust/RustBinaryPort.js +1 -0
  190. package/dist/application/rust/RustBinaryService.js +80 -0
  191. package/dist/application/signals/SignalRecordingService.js +83 -0
  192. package/dist/application/sqlite/SqliteDatabaseCapability.js +30 -0
  193. package/dist/application/sqlite/SqliteDatabasePort.js +1 -0
  194. package/dist/application/sqlite/SqliteDatabaseService.js +76 -0
  195. package/dist/application/wasm/WasmArtifactPort.js +1 -0
  196. package/dist/application/wasm/WasmArtifactService.js +77 -0
  197. package/dist/application/wasm/WasmInterfaceComparisonService.js +188 -0
  198. package/dist/artifacts/ArtifactHash.js +13 -2
  199. package/dist/artifacts/ArtifactPaths.js +4 -7
  200. package/dist/artifacts/ArtifactProvider.js +8 -4
  201. package/dist/artifacts/ArtifactReader.js +13 -1
  202. package/dist/artifacts/ArtifactResourceScope.js +12 -3
  203. package/dist/artifacts/AsarArtifactReader.js +177 -112
  204. package/dist/artifacts/AsarListing.js +78 -0
  205. package/dist/artifacts/DirectoryArtifactReader.js +94 -24
  206. package/dist/artifacts/MachOSliceArtifactReader.js +83 -10
  207. package/dist/artifacts/NativeDmgArtifactReader.js +161 -58
  208. package/dist/artifacts/OrderedReads.js +57 -0
  209. package/dist/artifacts/SafeOutputTree.js +19 -4
  210. package/dist/artifacts/ZipArtifactReader.js +117 -12
  211. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +77 -68
  212. package/dist/artifacts/apple/DylibResolutionReader.js +11 -5
  213. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +57 -21
  214. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +64 -12
  215. package/dist/artifacts/apple/KeyedArchiveReader.js +3 -2
  216. package/dist/artifacts/apple/MachoLoadCommandReader.js +62 -61
  217. package/dist/artifacts/apple/NibArchive.js +11 -4
  218. package/dist/artifacts/apple/PlistNumberLiterals.js +2 -2
  219. package/dist/artifacts/extraction/ArtifactExtraction.js +6 -7
  220. package/dist/artifacts/hostExecutableMarking.js +16 -0
  221. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +134 -34
  222. package/dist/artifacts/inventory/ArtifactInventory.js +2 -2
  223. package/dist/artifacts/inventory/classify.js +32 -15
  224. package/dist/artifacts/inventory/reader.js +36 -21
  225. package/dist/artifacts/inventory/scanCanonical.js +25 -18
  226. package/dist/artifacts/inventory/scanReader.js +36 -10
  227. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +163 -7
  228. package/dist/artifacts/readStableArtifact.js +28 -4
  229. package/dist/browser/BrowserProcessStartup.js +20 -9
  230. package/dist/browser/BrowserScenarioPartialObservation.js +60 -44
  231. package/dist/browser/BrowserScenarioSecrets.js +176 -46
  232. package/dist/browser/CdpBrowserProvider.js +70 -99
  233. package/dist/browser/CdpCaptureDocuments.js +231 -69
  234. package/dist/browser/CdpCaptureDomSvg.js +94 -61
  235. package/dist/browser/CdpCaptureEventBodyShapes.js +9 -5
  236. package/dist/browser/CdpCaptureEventHandlers.js +23 -12
  237. package/dist/browser/CdpCaptureEvents.js +49 -10
  238. package/dist/browser/CdpCaptureStorage.js +22 -5
  239. package/dist/browser/CdpCaptureStorageFingerprints.js +54 -11
  240. package/dist/browser/CdpCaptureValues.js +0 -1
  241. package/dist/browser/CdpConnection.js +3 -4
  242. package/dist/browser/CdpElectronInspection.js +14 -4
  243. package/dist/browser/CdpElectronProvider.js +7 -2
  244. package/dist/browser/CdpElectronScripts.js +2 -1
  245. package/dist/browser/CdpElectronWorkers.js +7 -2
  246. package/dist/browser/CdpEndpoint.js +143 -17
  247. package/dist/browser/CdpObservationSession.js +24 -8
  248. package/dist/browser/CdpPageCapture.js +66 -16
  249. package/dist/browser/CdpPageCaptureScripts.js +4 -3
  250. package/dist/browser/CdpPageCaptureWorkers.js +5 -1
  251. package/dist/browser/CdpSafeMetadata.js +9 -5
  252. package/dist/browser/CdpScreenshot.js +5 -14
  253. package/dist/browser/CdpSnapshotStrings.js +21 -0
  254. package/dist/browser/CdpTargetSession.js +29 -2
  255. package/dist/browser/CdpWebMcpDiscovery.js +23 -6
  256. package/dist/browser/PlaywrightBrowserScenarioProvider.js +4 -4
  257. package/dist/browser/PlaywrightElectronActiveActions.js +4 -4
  258. package/dist/browser/PlaywrightElectronActiveProjection.js +16 -4
  259. package/dist/browser/PlaywrightElectronActiveProvider.js +103 -30
  260. package/dist/browser/PlaywrightExecutionBoundary.js +2 -2
  261. package/dist/browser/PlaywrightScenarioBrowser.js +9 -6
  262. package/dist/browser/PlaywrightScenarioEvents.js +198 -36
  263. package/dist/browser/PlaywrightScenarioServiceWorkers.js +249 -0
  264. package/dist/browser/PlaywrightScenarioSession.js +61 -29
  265. package/dist/browser/WebSourceMapFetcher.js +163 -80
  266. package/dist/browser/assets/LocalWebScriptArtifacts.js +24 -3
  267. package/dist/browser/assets/PublishWebScripts.js +13 -2
  268. package/dist/browser/assets/ScenarioScriptCapture.js +2 -1
  269. package/dist/browser/assets/WebArtifactReads.js +11 -3
  270. package/dist/browser/assets/WebSourceLocationArtifacts.js +38 -3
  271. package/dist/browser/history/CaptureFailures.js +22 -8
  272. package/dist/browser/history/CaptureFormatError.js +2 -2
  273. package/dist/browser/history/{HarJson.js → CaptureJson.js} +14 -4
  274. package/dist/browser/history/CaptureRedaction.js +16 -3
  275. package/dist/browser/history/CaptureRelease.js +20 -2
  276. package/dist/browser/history/HarCapture.js +16 -23
  277. package/dist/browser/history/HarSchema.js +36 -36
  278. package/dist/browser/history/HistoricalCaptureDecoder.js +93 -25
  279. package/dist/browser/history/NodeCaptureAdapter.js +48 -0
  280. package/dist/browser/history/{HarCaptureProcess.js → NodeCaptureProcess.js} +18 -9
  281. package/dist/browser/history/QlogCapture.js +385 -0
  282. package/dist/browser/history/SazCapture.js +130 -0
  283. package/dist/browser/history/SazHttp.js +61 -0
  284. package/dist/browser/history/SazMetadata.js +92 -0
  285. package/dist/browser/history/SazProjection.js +90 -0
  286. package/dist/browser/modules/NativeModuleResolver.js +177 -110
  287. package/dist/browser/modules/WebModuleArtifacts.js +40 -3
  288. package/dist/browser/network/PlaywrightNetworkContent.js +40 -5
  289. package/dist/browser/network/PlaywrightScenarioNetwork.js +125 -11
  290. package/dist/captures/TsharkCaptureProvider.js +370 -0
  291. package/dist/captures/parseFieldDiscovery.js +66 -0
  292. package/dist/captures/parsePacketOutput.js +21 -0
  293. package/dist/catalogIdentity.js +46 -35
  294. package/dist/cli/adbCommands.js +2 -2
  295. package/dist/cli/analysisViewCommands.js +1 -1
  296. package/dist/cli/androidCommands.js +11 -2
  297. package/dist/cli/apktoolCommands.js +10 -11
  298. package/dist/cli/applicationCommands.js +44 -17
  299. package/dist/cli/artifactCommands.js +1 -1
  300. package/dist/cli/binaryDiagnosticsCommands.js +14 -10
  301. package/dist/cli/browserAdvancedCommands.js +37 -24
  302. package/dist/cli/browserCommands.js +46 -29
  303. package/dist/cli/captureCommands.js +72 -0
  304. package/dist/cli/cliResultOutput.js +188 -0
  305. package/dist/cli/coreBinaryCommands.js +73 -27
  306. package/dist/cli/coreNativeCommands.js +53 -31
  307. package/dist/cli/cutterCommands.js +50 -0
  308. package/dist/cli/electronCommands.js +45 -3
  309. package/dist/cli/evmCommands.js +4 -5
  310. package/dist/cli/finishAnalysisCommand.js +44 -0
  311. package/dist/cli/firmwareCommands.js +14 -36
  312. package/dist/cli/flutterCommands.js +69 -0
  313. package/dist/cli/fridaCommands.js +211 -0
  314. package/dist/cli/goCommands.js +20 -0
  315. package/dist/cli/interactiveSetup.js +11 -1
  316. package/dist/cli/javascriptApplicationAnalysis.js +1 -1
  317. package/dist/cli/javascriptRecoveryCommands.js +7 -0
  318. package/dist/cli/jsonOutput.js +2 -2
  319. package/dist/cli/managedCommands.js +31 -3
  320. package/dist/cli/options.js +20 -2
  321. package/dist/cli/pcapCommands.js +47 -0
  322. package/dist/cli/processCommands.js +1 -1
  323. package/dist/cli/reverseEngineeringCommands.js +268 -0
  324. package/dist/cli/rustCommands.js +21 -0
  325. package/dist/cli/setupCommands.js +40 -12
  326. package/dist/cli/signalCommands.js +72 -0
  327. package/dist/cli/sqliteCommands.js +79 -0
  328. package/dist/cli/utilityCommands.js +116 -74
  329. package/dist/cli/wasmCommands.js +61 -0
  330. package/dist/cli/webModuleCommands.js +36 -32
  331. package/dist/cli/webNetworkCaptureCommands.js +8 -8
  332. package/dist/cli-runtime/AbortablePromise-BVBemxbD.js +123 -0
  333. package/dist/cli-runtime/AnalysisProvider-D0Us2OTk.js +27 -0
  334. package/dist/cli-runtime/AnalysisSnapshotCache-BXS0wRd2.js +710 -0
  335. package/dist/cli-runtime/ArtifactReader-BXkffc1D.js +55 -0
  336. package/dist/cli-runtime/ArtifactResourceScope-DQWTcUwE.js +114 -0
  337. package/dist/cli-runtime/AsarHeader-CnzOzYEH.js +31 -0
  338. package/dist/cli-runtime/BinarySessionStatus-DnMxMk-r.js +211 -0
  339. package/dist/cli-runtime/BinaryTargetResolver-CVIJ_s1A.js +1308 -0
  340. package/dist/cli-runtime/BoundedFileBytes-BU30odTm.js +39 -0
  341. package/dist/cli-runtime/CdpTargetSession-DGX5pV9w.js +650 -0
  342. package/dist/cli-runtime/ClientConfigPath-c6jr6INc.js +36 -0
  343. package/dist/cli-runtime/ClientConfigurationDocument-ffQ9X0Se.js +1957 -0
  344. package/dist/cli-runtime/ClientRegistrationStatus-DszCyPEU.js +509 -0
  345. package/dist/cli-runtime/CurrentEntrypointPath-D5FRNdkq.js +14 -0
  346. package/dist/cli-runtime/DirectAnalysis-BgvAtpN3.js +528 -0
  347. package/dist/cli-runtime/Doctor-DIpf_I7N.js +588 -0
  348. package/dist/cli-runtime/ElectronFileScope-dpHm2nrS.js +1054 -0
  349. package/dist/cli-runtime/ExecFileOutput-BEQs-lDD.js +117 -0
  350. package/dist/cli-runtime/IdaConfiguration-CtGP7EKo.js +1094 -0
  351. package/dist/cli-runtime/InterfaceBuilderDecodeBudget-D4omRUe4.js +279 -0
  352. package/dist/cli-runtime/InventoryProjectionEvidence-DIsI4DJ6.js +49 -0
  353. package/dist/cli-runtime/InvestigationProviders-DoQRIHii.js +117 -0
  354. package/dist/cli-runtime/JavaScriptApplicationEvidenceGraph-D5aI_FSJ.js +160 -0
  355. package/dist/cli-runtime/JavaScriptApplicationWorkflowEvidence-Bz4-V0Ct.js +75 -0
  356. package/dist/cli-runtime/JavaScriptWorkerMemoryLimit-B1bwMM1a.js +86 -0
  357. package/dist/cli-runtime/JebMcpEndpoint-DUytrn5G.js +428 -0
  358. package/dist/cli-runtime/JsonFiles-DQa1PRKy.js +708 -0
  359. package/dist/cli-runtime/MacCodeSignature-MgYbRK_H.js +24 -0
  360. package/dist/cli-runtime/MacHopperPaths-CwL5lYPX.js +434 -0
  361. package/dist/cli-runtime/MachoLoadCommandReader-C7e074Ze.js +510 -0
  362. package/dist/cli-runtime/ManagedSnapshot-rqyBHcdL.js +4185 -0
  363. package/dist/cli-runtime/OwnedCommand-Cj9GhmPR.js +112 -0
  364. package/dist/cli-runtime/PrivateRuntimeRoot-DAy0PiBM.js +263 -0
  365. package/dist/cli-runtime/ProcessOwnership-DXC5-UWt.js +1378 -0
  366. package/dist/cli-runtime/ProviderDeadline-8m2pFRDc.js +122 -0
  367. package/dist/cli-runtime/RegularFile-B_6KPCNQ.js +139 -0
  368. package/dist/cli-runtime/RegularFileRead-DVlC5faM.js +125 -0
  369. package/dist/cli-runtime/SafeOutputTree-D6U15GXd.js +524 -0
  370. package/dist/cli-runtime/SetupHost-FkYWswsq.js +1098 -0
  371. package/dist/cli-runtime/SupportedClients-DaX6Lt2d.js +1049 -0
  372. package/dist/cli-runtime/UninstallFailure-1blyKXHE.js +22 -0
  373. package/dist/cli-runtime/Update-CbTC_eg1.js +143 -0
  374. package/dist/cli-runtime/UpdateFailure-BcFNxEZZ.js +24 -0
  375. package/dist/cli-runtime/ZipArtifactReader-B8ZgNe4D.js +248 -0
  376. package/dist/cli-runtime/analysisErrorCleanup-Do6YeeoD.js +32 -0
  377. package/dist/cli-runtime/analysisErrorPresentation-DGt7TdsH.js +497 -0
  378. package/dist/cli-runtime/appleArchiveFormat-tVoI2ykA.js +263 -0
  379. package/dist/cli-runtime/application__DirectAnalysisStatus-DpOejOf0.js +150 -0
  380. package/dist/cli-runtime/application__EnhancedTools-oFE2bOjs.js +1787 -0
  381. package/dist/cli-runtime/application__FunctionAnalysisEvidence-B6osuhvW.js +41 -0
  382. package/dist/cli-runtime/application__ReconstructionCoverageService-DN3wTFQj.js +32 -0
  383. package/dist/cli-runtime/application__ReconstructionObligationLedgerService-CKcTppX9.js +815 -0
  384. package/dist/cli-runtime/application__Setup-XpMaRNjy.js +514 -0
  385. package/dist/cli-runtime/application__Uninstall-_23pU2yB.js +427 -0
  386. package/dist/cli-runtime/application__UpdateRuntime-DPvY8ohd.js +345 -0
  387. package/dist/cli-runtime/application__android__AndroidApplicationService-CFgIFPM4.js +31 -0
  388. package/dist/cli-runtime/application__apple__AppleApplicationService-Db6QCsun.js +31 -0
  389. package/dist/cli-runtime/application__harmony__HarmonyApplicationService-CFjocHoK.js +31 -0
  390. package/dist/cli-runtime/application__javascript__ElectronActiveObservationService-CmVDUI_Z.js +118 -0
  391. package/dist/cli-runtime/application__javascript__ElectronObservationService-DEsR8KDN.js +63 -0
  392. package/dist/cli-runtime/application__javascript__JavaScriptApplicationService-CCkp8KBh.js +11450 -0
  393. package/dist/cli-runtime/application__javascript__JavaScriptApplicationWorkflowService-lPy0tzr3.js +2329 -0
  394. package/dist/cli-runtime/application__javascript__JavaScriptRuntimeReconciliationService-DWleA8K9.js +88 -0
  395. package/dist/cli-runtime/application__javascript__JavaScriptSemanticTraceService-DkALH4rL.js +299 -0
  396. package/dist/cli-runtime/artifactOperationError-B7n03FbD.js +27 -0
  397. package/dist/cli-runtime/artifacts__ArtifactProvider-zXI0QjSL.js +2187 -0
  398. package/dist/cli-runtime/binary-BVOr2mgE.js +14206 -0
  399. package/dist/cli-runtime/browserObservationError-Dx6xRTjb.js +40 -0
  400. package/dist/cli-runtime/catalogIdentity-DLoXgfIR.js +933 -0
  401. package/dist/cli-runtime/cli.js +41848 -0
  402. package/dist/cli-runtime/cliOutput-BC1BdAcB.js +122 -0
  403. package/dist/cli-runtime/cliOutput.js +5 -0
  404. package/dist/cli-runtime/cliResultOutput-DsRMI8CJ.js +780 -0
  405. package/dist/cli-runtime/cliResultOutput.js +5 -0
  406. package/dist/cli-runtime/composition__browserScenario-DHXC1a8n.js +2927 -0
  407. package/dist/cli-runtime/composition__electronObservation-GecK2EID.js +555 -0
  408. package/dist/cli-runtime/composition__electronScenario-CEZnVrAL.js +653 -0
  409. package/dist/cli-runtime/cutterToolContracts-TZH9EHr5.js +5134 -0
  410. package/dist/cli-runtime/doctorRuntime-BE5ZX8it.js +258 -0
  411. package/dist/cli-runtime/dotnet__ManagedStaticProvider-C8_yZCDc.js +5 -0
  412. package/dist/cli-runtime/errorSchemas-CTRmvMl3.js +601 -0
  413. package/dist/cli-runtime/javascriptApplicationAnalysis-HgMzVMQw.js +2068 -0
  414. package/dist/cli-runtime/javascriptExportReturnShapeProjection-Dg00g35t.js +78 -0
  415. package/dist/cli-runtime/javascriptExportShapeComparisonSchemas-BYnoIqIk.js +1242 -0
  416. package/dist/cli-runtime/javascriptRuntimeReconciliation-DNjDoL3S.js +1507 -0
  417. package/dist/cli-runtime/javascriptRuntimeReconciliationSchemas-BWpGWNcI.js +247 -0
  418. package/dist/cli-runtime/javascriptSemanticTraceSchemas-BTCNcvbc.js +126 -0
  419. package/dist/cli-runtime/lipo-DSWP6fv-.js +396 -0
  420. package/dist/cli-runtime/logger-CQQCI4a2.js +48 -0
  421. package/dist/cli-runtime/machoContainer-C8BIkkq3.js +172 -0
  422. package/dist/cli-runtime/managedApplicationGraph-B08jb3jq.js +1130 -0
  423. package/dist/cli-runtime/managedToolContracts-D60QmIYj.js +99 -0
  424. package/dist/cli-runtime/mcpDoctor.js +359 -0
  425. package/dist/cli-runtime/mcpStartupPolicy-CVVSOmRc.js +21 -0
  426. package/dist/cli-runtime/native__NativeMacOSProvider-YBTvUeJO.js +4875 -0
  427. package/dist/cli-runtime/officialToolContracts-CCFF0an9.js +1501 -0
  428. package/dist/cli-runtime/propertyListKeys-G8e74YWb.js +248 -0
  429. package/dist/cli-runtime/providerAdapterError-DAjhICdr.js +25 -0
  430. package/dist/cli-runtime/providerCleanupError-Ceq8f0wK.js +27 -0
  431. package/dist/cli-runtime/providerIdentities-Ao1XTvwx.js +31 -0
  432. package/dist/cli-runtime/providerStartupTimeout-B2tF2LtZ.js +17 -0
  433. package/dist/cli-runtime/readFileHandleChunks-dp60iZ6v.js +38 -0
  434. package/dist/cli-runtime/reconstructionObligationLedgerSchemas-Bao0xMr-.js +19478 -0
  435. package/dist/cli-runtime/rolldown-runtime-DXoylpqc.js +121 -0
  436. package/dist/cli-runtime/runtimeVersion-CMGd0bDu.js +23 -0
  437. package/dist/cli-runtime/safeJson-DKKACtdy.js +25 -0
  438. package/dist/cli-runtime/scanCanonical-KP4T9jSl.js +2724 -0
  439. package/dist/cli-runtime/snapshotEnvironment-D_tWyOub.js +813 -0
  440. package/dist/cli-runtime/toolContracts-D2FOG_Nb.js +3721 -0
  441. package/dist/cli-runtime/toolOutputSchemaGroups-DRiYs1je.js +12070 -0
  442. package/dist/cli-runtime/workflowInputError-n8Oo-bLA.js +26 -0
  443. package/dist/cli.js +38 -5
  444. package/dist/cliBrowserScenarioCommands.js +39 -4
  445. package/dist/cliCommandNames.js +48 -0
  446. package/dist/cliEvidenceCommands.js +0 -1
  447. package/dist/cliJavaScriptRuntimeCommands.js +16 -14
  448. package/dist/cliJsonInput.js +12 -4
  449. package/dist/cliLogging.js +50 -14
  450. package/dist/cliObservationOptions.js +6 -0
  451. package/dist/cliOutput.js +38 -5
  452. package/dist/composition/binary.js +4 -0
  453. package/dist/composition/captures.js +3 -0
  454. package/dist/composition/directAnalysis.js +28 -11
  455. package/dist/composition/electronFuses.js +4 -0
  456. package/dist/composition/evm.js +12 -0
  457. package/dist/composition/flutter.js +3 -0
  458. package/dist/composition/go.js +4 -0
  459. package/dist/composition/javascriptAnalysisWorkerProcess.js +5 -4
  460. package/dist/composition/jeb.js +33 -4
  461. package/dist/composition/pcap.js +3 -0
  462. package/dist/composition/resolveWindowsProviderExecutable.js +61 -0
  463. package/dist/composition/reverseEngineering.js +29 -0
  464. package/dist/composition/rust.js +4 -0
  465. package/dist/composition/signals.js +3 -0
  466. package/dist/composition/sqlite.js +4 -0
  467. package/dist/composition/wasm.js +22 -0
  468. package/dist/composition/webNetworkCaptures.js +7 -2
  469. package/dist/config/environment.js +45 -4
  470. package/dist/config/ghidraDisabledAnalyzers.js +25 -0
  471. package/dist/config/homeDirectory.js +9 -6
  472. package/dist/config/mcpInputSchemaProfile.js +4 -0
  473. package/dist/config/mcpOutputSchemaProfile.js +22 -0
  474. package/dist/config/parseConfig.js +21 -31
  475. package/dist/config/parsers.js +4 -3
  476. package/dist/config/{ghidraStartupTimeout.js → providerStartupTimeout.js} +7 -3
  477. package/dist/contracts/adb/adbToolContracts.js +7 -7
  478. package/dist/contracts/analysisDetail.js +6 -3
  479. package/dist/contracts/analysisViewApiSurfaceExample.js +68 -0
  480. package/dist/contracts/analysisViewToolContracts.js +24 -3
  481. package/dist/contracts/android/androidToolContracts.js +17 -8
  482. package/dist/contracts/applicationToolContracts.js +17 -2
  483. package/dist/contracts/artifactToolContracts.js +14 -2
  484. package/dist/contracts/browserToolContracts.js +1 -0
  485. package/dist/contracts/captures/captureToolContracts.js +42 -0
  486. package/dist/contracts/compactInputSchema.js +26 -6
  487. package/dist/contracts/cutterToolContracts.js +84 -0
  488. package/dist/contracts/enhancedToolContracts.js +2 -2
  489. package/dist/contracts/evm/evmToolContracts.js +30 -15
  490. package/dist/contracts/firmware/firmwareToolContracts.js +1 -1
  491. package/dist/contracts/flutter/flutterToolContracts.js +47 -0
  492. package/dist/contracts/fridaRemoteAddress.js +23 -0
  493. package/dist/contracts/fridaToolContracts.js +273 -0
  494. package/dist/contracts/functionComparisonExample.js +12 -1
  495. package/dist/contracts/gdbToolContracts.js +103 -0
  496. package/dist/contracts/go/goToolContracts.js +20 -0
  497. package/dist/contracts/hopperMemoryContracts.js +15 -0
  498. package/dist/contracts/inputSchemaPresentation.js +81 -14
  499. package/dist/contracts/investigationExamples.js +1 -0
  500. package/dist/contracts/javascript/electronToolContracts.js +27 -2
  501. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +13 -1
  502. package/dist/contracts/managed/managedToolContracts.js +43 -4
  503. package/dist/contracts/managed/managedWorkflowExamples.js +7 -1
  504. package/dist/contracts/managed/managedWorkflowToolContracts.js +4 -30
  505. package/dist/contracts/mobileApplicationGraphExamples.js +12 -0
  506. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +3 -2
  507. package/dist/contracts/native/nativeToolContracts.js +10 -6
  508. package/dist/contracts/officialToolContracts.js +5 -5
  509. package/dist/contracts/pcap/pcapToolContracts.js +33 -0
  510. package/dist/contracts/providerSelection.js +1 -0
  511. package/dist/contracts/reconstructionReadinessExample.js +126 -119
  512. package/dist/contracts/reverseEngineeringToolContracts.js +52 -0
  513. package/dist/contracts/rizinDebugToolContracts.js +96 -0
  514. package/dist/contracts/rust/rustToolContracts.js +20 -0
  515. package/dist/contracts/sessionLifecycleInputs.js +34 -2
  516. package/dist/contracts/sessionToolContracts.js +2 -2
  517. package/dist/contracts/sessionToolSchemas.js +14 -0
  518. package/dist/contracts/signals/signalToolContracts.js +40 -0
  519. package/dist/contracts/sqlite/sqliteToolContracts.js +36 -0
  520. package/dist/contracts/toolContractExamples.js +29 -0
  521. package/dist/contracts/toolContractTypes.js +2 -0
  522. package/dist/contracts/toolContracts.js +26 -0
  523. package/dist/contracts/toolEffects.js +247 -8
  524. package/dist/contracts/toolOutputSchemaGroups.js +75 -32
  525. package/dist/contracts/toolOutputSchemaPrimitives.js +111 -10
  526. package/dist/contracts/toolSchemaMetadata.js +16 -2
  527. package/dist/contracts/unknownContractExamples.js +1 -1
  528. package/dist/contracts/wasm/wasmComparisonContracts.js +52 -0
  529. package/dist/contracts/wasm/wasmToolContracts.js +33 -0
  530. package/dist/contracts/webNetworkCaptureToolContracts.js +15 -4
  531. package/dist/cutter/CutterBridgeClient.js +621 -0
  532. package/dist/cutter/CutterBridgeService.js +139 -0
  533. package/dist/doctorRuntime.js +20 -8
  534. package/dist/domain/adb/adbDeviceAnalysis.js +26 -4
  535. package/dist/domain/analysisErrorBase.js +20 -0
  536. package/dist/domain/analysisErrorCleanup.js +1 -1
  537. package/dist/domain/analysisErrorCore.js +19 -0
  538. package/dist/domain/analysisErrorPresentation.js +58 -17
  539. package/dist/domain/analysisErrorProjection.js +31 -12
  540. package/dist/domain/analysisProfile.js +7 -3
  541. package/dist/domain/analysisSnapshot.js +311 -184
  542. package/dist/domain/analysisView/WebNetworkApiSurfaceAccumulator.js +414 -0
  543. package/dist/domain/analysisView/analysisView.js +366 -44
  544. package/dist/domain/analysisView/analysisViewCoverage.js +32 -0
  545. package/dist/domain/analysisView/analysisViewErrors.js +4 -0
  546. package/dist/domain/analysisView/analysisViewParent.js +12 -0
  547. package/dist/domain/analysisView/analysisViewText.js +29 -0
  548. package/dist/domain/analysisView/androidPackageView.js +102 -0
  549. package/dist/domain/analysisView/artifactInventoryView.js +140 -0
  550. package/dist/domain/analysisView/binaryLayoutView.js +11 -4
  551. package/dist/domain/analysisView/dartAotView.js +93 -0
  552. package/dist/domain/analysisView/evmInterfaceView.js +105 -0
  553. package/dist/domain/analysisView/interfaceBuilderView.js +182 -0
  554. package/dist/domain/analysisView/javascriptApplicationView.js +29 -28
  555. package/dist/domain/analysisView/machoView.js +186 -0
  556. package/dist/domain/analysisView/managedArtifactView.js +108 -0
  557. package/dist/domain/analysisView/managedMemberView.js +209 -0
  558. package/dist/domain/analysisView/nativeFunctionView.js +20 -25
  559. package/dist/domain/analysisView/pcapCaptureView.js +264 -0
  560. package/dist/domain/analysisView/qlogCaptureView.js +198 -0
  561. package/dist/domain/analysisView/wasmArtifactView.js +162 -0
  562. package/dist/domain/analysisView/webNetworkApiSurfaceView.js +123 -0
  563. package/dist/domain/analysisView/webNetworkCaptureView.js +388 -0
  564. package/dist/domain/android/androidAnalysis.js +36 -2
  565. package/dist/domain/android/androidApplication.js +32 -60
  566. package/dist/domain/apktool/apktoolResourceAnalysis.js +19 -7
  567. package/dist/domain/apple/appleApplication.js +31 -29
  568. package/dist/domain/apple/appleArchiveFormat.js +184 -0
  569. package/dist/domain/apple/appleAssetCatalog.js +15 -0
  570. package/dist/domain/apple/appleBundleAnatomy.js +1 -1
  571. package/dist/domain/apple/dyldPaths.js +9 -2
  572. package/dist/domain/apple/dylibResolution.js +19 -9
  573. package/dist/domain/apple/dylibResolutionFindings.js +8 -9
  574. package/dist/domain/apple/interfaceBuilderGraph.js +50 -26
  575. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +28 -8
  576. package/dist/domain/apple/machoContainer.js +120 -8
  577. package/dist/domain/apple/machoCpuIdentity.js +4 -0
  578. package/dist/domain/apple/plistValue.js +6 -1
  579. package/dist/domain/artifactComparison.js +109 -32
  580. package/dist/domain/artifactDecompressionBudget.js +26 -0
  581. package/dist/domain/artifactGraph.js +23 -6
  582. package/dist/domain/artifactIdentity.js +4 -1
  583. package/dist/domain/artifactInspection.js +44 -2
  584. package/dist/domain/artifactInventoryEvidence.js +137 -39
  585. package/dist/domain/binaryTarget.js +251 -94
  586. package/dist/domain/binaryTargetTypes.js +14 -1
  587. package/dist/domain/browserNetworkEvidence.js +4 -0
  588. package/dist/domain/browserObservation.js +88 -29
  589. package/dist/domain/browserObservationSchemas.js +4 -1
  590. package/dist/domain/browserScenarioCapture.js +2 -1
  591. package/dist/domain/browserScenarioCaptureValues.js +26 -2
  592. package/dist/domain/browserScenarioDiff.js +120 -11
  593. package/dist/domain/browserScenarioDiffEvidence.js +46 -13
  594. package/dist/domain/browserScenarioDiffValues.js +10 -3
  595. package/dist/domain/browserScenarioNetworkComparison.js +158 -0
  596. package/dist/domain/browserScenarioNormalization.js +10 -13
  597. package/dist/domain/browserScenarioValues.js +2 -12
  598. package/dist/domain/browserSession.js +2 -2
  599. package/dist/domain/bundleComparison.js +1 -5
  600. package/dist/domain/callPath.js +40 -3
  601. package/dist/domain/captures/packetCapture.js +138 -0
  602. package/dist/domain/captures/packetFields.js +81 -0
  603. package/dist/domain/changedBehavior.js +43 -41
  604. package/dist/domain/comparisonSourceEvidence.js +6 -0
  605. package/dist/domain/dosCom.js +2 -2
  606. package/dist/domain/dosMz.js +52 -14
  607. package/dist/domain/electron/electronFuses.js +360 -0
  608. package/dist/domain/elfFixedHeader.js +42 -0
  609. package/dist/domain/evidence.js +103 -38
  610. package/dist/domain/evidenceBundle.js +58 -20
  611. package/dist/domain/evidenceErrors.js +5 -0
  612. package/dist/domain/evm/evmInterface.js +18 -4
  613. package/dist/domain/evm/solidityMetadata.js +70 -0
  614. package/dist/domain/explicitSensitiveFailure.js +42 -24
  615. package/dist/domain/firmware/firmwareAnalysis.js +29 -0
  616. package/dist/domain/flutter/flutterBuildAnalysis.js +141 -0
  617. package/dist/domain/functionCallCoverage.js +60 -0
  618. package/dist/domain/functionComparisonDimensions.js +101 -10
  619. package/dist/domain/functionComparisonNormalization.js +66 -10
  620. package/dist/domain/functionComparisonResults.js +7 -6
  621. package/dist/domain/functionComparisonSchemas.js +14 -3
  622. package/dist/domain/functionDossierEvidence.js +3 -0
  623. package/dist/domain/go/goBinary.js +96 -0
  624. package/dist/domain/harmony/harmonyApplication.js +156 -0
  625. package/dist/domain/hopperErrors.js +15 -16
  626. package/dist/domain/hopperPublisher.js +12 -0
  627. package/dist/domain/hopperValues.js +112 -34
  628. package/dist/domain/javascript/electronObservation.js +4 -1
  629. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +15 -14
  630. package/dist/domain/javascript/electronStaticAnalysisIpc.js +3 -1
  631. package/dist/domain/javascript/electronStaticAnalysisNative.js +19 -5
  632. package/dist/domain/javascript/electronStaticAnalysisValues.js +14 -8
  633. package/dist/domain/javascript/electronWrappedCallPaths.js +498 -0
  634. package/dist/domain/javascript/htmlArtifactReferences.js +94 -4
  635. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +21 -1
  636. package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -0
  637. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +7 -2
  638. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +1 -1
  639. package/dist/domain/javascript/javascriptApplicationGraph.js +17 -1
  640. package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +1 -0
  641. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +8 -0
  642. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +31 -18
  643. package/dist/domain/javascript/javascriptArtifactFiles.js +2 -1
  644. package/dist/domain/javascript/javascriptAstFingerprint.js +51 -17
  645. package/dist/domain/javascript/javascriptAstValues.js +52 -3
  646. package/dist/domain/javascript/javascriptBootstrap.js +94 -0
  647. package/dist/domain/javascript/javascriptBootstrapIntegrity.js +372 -0
  648. package/dist/domain/javascript/javascriptBuiltinResourceMethods.js +8 -0
  649. package/dist/domain/javascript/javascriptBundledRequireOrigin.js +291 -0
  650. package/dist/domain/javascript/javascriptContextBridgeExposure.js +23 -0
  651. package/dist/domain/javascript/javascriptElectronMemberWrites.js +86 -22
  652. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +6 -5
  653. package/dist/domain/javascript/javascriptExportShapeVariants.js +1 -1
  654. package/dist/domain/javascript/javascriptFeatureSeed.js +33 -16
  655. package/dist/domain/javascript/javascriptFeatureTrace.js +9 -3
  656. package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +42 -11
  657. package/dist/domain/javascript/javascriptIntrinsicInvocation.js +132 -0
  658. package/dist/domain/javascript/javascriptModuleDeclaration.js +28 -0
  659. package/dist/domain/javascript/javascriptModuleInterop.js +618 -0
  660. package/dist/domain/javascript/javascriptModuleResolutionMode.js +18 -0
  661. package/dist/domain/javascript/javascriptModuleSpecifier.js +5 -0
  662. package/dist/domain/javascript/javascriptNativeHandoff.js +0 -1
  663. package/dist/domain/javascript/javascriptPackageImportAliases.js +58 -0
  664. package/dist/domain/javascript/javascriptRecovery.js +12 -5
  665. package/dist/domain/javascript/javascriptRpcEndpoints.js +119 -41
  666. package/dist/domain/javascript/javascriptRuntimeLoadState.js +11 -0
  667. package/dist/domain/javascript/javascriptRuntimeObservation.js +4 -1
  668. package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +10 -4
  669. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +15 -2
  670. package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +0 -1
  671. package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +5 -4
  672. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +113 -11
  673. package/dist/domain/javascript/javascriptSemanticAmbientWrites.js +251 -0
  674. package/dist/domain/javascript/javascriptSemanticAnalysis.js +340 -108
  675. package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +17 -34
  676. package/dist/domain/javascript/javascriptSemanticCallResolution.js +4 -3
  677. package/dist/domain/javascript/javascriptSemanticCallableStack.js +52 -0
  678. package/dist/domain/javascript/javascriptSemanticCalls.js +6 -11
  679. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +42 -55
  680. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +428 -32
  681. package/dist/domain/javascript/javascriptSemanticDataEffects.js +14 -20
  682. package/dist/domain/javascript/javascriptSemanticDependencies.js +69 -0
  683. package/dist/domain/javascript/javascriptSemanticFingerprints.js +11 -14
  684. package/dist/domain/javascript/javascriptSemanticGraph.js +5 -1
  685. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +0 -1
  686. package/dist/domain/javascript/javascriptSemanticIterationSources.js +2 -2
  687. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +224 -91
  688. package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +199 -3
  689. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +333 -43
  690. package/dist/domain/javascript/javascriptSemanticObjects.js +20 -16
  691. package/dist/domain/javascript/javascriptSemanticProjection.js +151 -43
  692. package/dist/domain/javascript/javascriptSemanticPromises.js +6 -9
  693. package/dist/domain/javascript/javascriptSemanticProvenance.js +5 -1
  694. package/dist/domain/javascript/javascriptSemanticQuery.js +7 -2
  695. package/dist/domain/javascript/javascriptSemanticReferenceSources.js +25 -0
  696. package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +331 -8
  697. package/dist/domain/javascript/javascriptSemanticResources.js +6 -40
  698. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +14 -0
  699. package/dist/domain/javascript/javascriptSemanticReturns.js +37 -30
  700. package/dist/domain/javascript/javascriptSemanticState.js +39 -2
  701. package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -4
  702. package/dist/domain/javascript/javascriptSemanticValues.js +227 -30
  703. package/dist/domain/javascript/javascriptSourceMapPaths.js +44 -17
  704. package/dist/domain/javascript/javascriptSourceParser.js +72 -3
  705. package/dist/domain/javascript/javascriptSourceSelection.js +11 -0
  706. package/dist/domain/javascript/javascriptStaticAnalysis.js +51 -17
  707. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +97 -23
  708. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +224 -44
  709. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +166 -56
  710. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  711. package/dist/domain/javascript/javascriptStaticAnalysisTypes.js +2 -1
  712. package/dist/domain/javascript/javascriptSymbolicBindings.js +836 -0
  713. package/dist/domain/javascript/javascriptSymbolicControlFlow.js +40 -0
  714. package/dist/domain/javascript/javascriptSymbolicValues.js +34 -0
  715. package/dist/domain/javascript/sourceToBundleComparison.js +3 -1
  716. package/dist/domain/javascript/sourceToBundleComparisonSchemas.js +2 -0
  717. package/dist/domain/javascript/sourceToBundleSignals.js +47 -13
  718. package/dist/domain/jsonValue.js +37 -12
  719. package/dist/domain/localPath.js +6 -3
  720. package/dist/domain/managed/managedApplicationGraph.js +5 -0
  721. package/dist/domain/managed/managedApplicationGraphCoverage.js +6 -2
  722. package/dist/domain/managed/managedApplicationGraphNodes.js +0 -1
  723. package/dist/domain/managed/managedArtifact.js +51 -1
  724. package/dist/domain/managed/managedInspectionEvidence.js +5 -6
  725. package/dist/domain/managed/managedMemberComparison.js +3 -0
  726. package/dist/domain/managed/managedMemberComparisonCoverage.js +23 -3
  727. package/dist/domain/managed/managedMemberComparisonItems.js +23 -19
  728. package/dist/domain/managed/managedMemberComparisonMatch.js +209 -18
  729. package/dist/domain/managed/managedNativeVerificationMatch.js +49 -26
  730. package/dist/domain/managed/managedNativeVerificationSchemas.js +13 -2
  731. package/dist/domain/managed/managedReconstruction.js +5 -8
  732. package/dist/domain/mobileApplicationGraphProjection.js +80 -0
  733. package/dist/domain/native/addressCoordinate.js +11 -0
  734. package/dist/domain/native/binaryLayout.js +2 -4
  735. package/dist/domain/native/bytePattern.js +100 -0
  736. package/dist/domain/native/nativeAotPe.js +2 -2
  737. package/dist/domain/native/nativeInspection.js +38 -4
  738. package/dist/domain/native/nativeInstruction.js +17 -2
  739. package/dist/domain/native/nativeInvestigationGraph.js +9 -5
  740. package/dist/domain/native/nativeLoadImage.js +19 -1
  741. package/dist/domain/native/nativeUiObservation.js +5 -6
  742. package/dist/domain/native/objcSwiftMetadata.js +4 -1
  743. package/dist/domain/native/peResources.js +8 -2
  744. package/dist/domain/native/recordedCrash.js +79 -10
  745. package/dist/domain/offsetDateTime.js +60 -0
  746. package/dist/domain/pcap/pcapAnalysis.js +91 -0
  747. package/dist/domain/pcap/pcapEvidence.js +15 -0
  748. package/dist/domain/peMachine.js +36 -0
  749. package/dist/domain/pngHeader.js +18 -0
  750. package/dist/domain/process/processCaptureCoverage.js +26 -3
  751. package/dist/domain/process/processCaptureExample.js +2 -0
  752. package/dist/domain/process/processCaptureValidation.js +33 -8
  753. package/dist/domain/process/processComparison.js +41 -13
  754. package/dist/domain/process/processScenario.js +7 -0
  755. package/dist/domain/process/processTraceEvaluation.js +54 -50
  756. package/dist/domain/process/processTraceSpecification.js +243 -89
  757. package/dist/domain/propertyListKeys.js +211 -11
  758. package/dist/domain/propertyListXmlText.js +20 -4
  759. package/dist/domain/providerAdapterError.js +0 -5
  760. package/dist/domain/providerConfigurationRefusal.js +12 -0
  761. package/dist/domain/providerSelectionError.js +2 -1
  762. package/dist/domain/qlogCapture.js +62 -0
  763. package/dist/domain/rawBinary.js +96 -0
  764. package/dist/domain/reconstructionCoverage.js +5 -1
  765. package/dist/domain/reconstructionCoverageEvaluation.js +18 -15
  766. package/dist/domain/reconstructionCoverageVerifierResults.js +35 -0
  767. package/dist/domain/reconstructionObligationLedgerIntegrity.js +114 -0
  768. package/dist/domain/reconstructionObligationLedgerSchemas.js +104 -1
  769. package/dist/domain/reconstructionReadiness.js +4 -8
  770. package/dist/domain/reconstructionReadinessJourneyFindings.js +4 -1
  771. package/dist/domain/reconstructionUnknowns.js +9 -1
  772. package/dist/domain/reconstructionVerification.js +54 -25
  773. package/dist/domain/recordedTransportUrl.js +59 -0
  774. package/dist/domain/referenceSourceClassification.js +27 -23
  775. package/dist/domain/referenceSourceGraph.js +51 -13
  776. package/dist/domain/referenceSourceImportParsing.js +23 -13
  777. package/dist/domain/referenceSourcePathIdentity.js +11 -1
  778. package/dist/domain/referenceSourceRequireBindings.js +5 -12
  779. package/dist/domain/referenceSourceSummary.js +92 -0
  780. package/dist/domain/relationshipCoverage.js +44 -0
  781. package/dist/domain/residualUnknown.js +93 -26
  782. package/dist/domain/reverseEngineering.js +31 -0
  783. package/dist/domain/runtimeVersion.js +8 -0
  784. package/dist/domain/rust/rustBinary.js +200 -0
  785. package/dist/domain/signals/annotationTextWindow.js +31 -0
  786. package/dist/domain/signals/signalDecoders.js +69 -0
  787. package/dist/domain/signals/signalRecording.js +115 -0
  788. package/dist/domain/sourceMapContents.js +10 -3
  789. package/dist/domain/sourceMapEnvelope.js +17 -11
  790. package/dist/domain/sqlite/sqliteDatabase.js +188 -0
  791. package/dist/domain/staticRuntimeCorrelation.js +7 -9
  792. package/dist/domain/swiftSymbolClassification.js +17 -0
  793. package/dist/domain/symbolAnalysis.js +16 -4
  794. package/dist/domain/urlComponents.js +6 -0
  795. package/dist/domain/wasm/wasmArtifact.js +119 -0
  796. package/dist/domain/wasm/wasmInterface.js +89 -0
  797. package/dist/domain/webBundleAnalysis.js +14 -3
  798. package/dist/domain/webBundleAnalyzerAst.js +7 -2
  799. package/dist/domain/webBundleAnalyzerInspection.js +54 -38
  800. package/dist/domain/webBundleAnalyzerResult.js +18 -6
  801. package/dist/domain/webCaptureDiff.js +140 -39
  802. package/dist/domain/webCaptureFrameComparison.js +49 -0
  803. package/dist/domain/webMcpDiscovery.js +5 -2
  804. package/dist/domain/webModuleImports.js +22 -27
  805. package/dist/domain/webModuleTrace.js +3 -8
  806. package/dist/domain/webNetworkCapture.js +101 -39
  807. package/dist/domain/webNetworkCaptureCoordinates.js +21 -0
  808. package/dist/domain/webRuntime.js +0 -1
  809. package/dist/domain/webScreenshot.js +2 -2
  810. package/dist/domain/webScriptArtifacts.js +2 -4
  811. package/dist/domain/webScriptExport.js +6 -8
  812. package/dist/domain/webScriptExportPlan.js +2 -2
  813. package/dist/domain/webSourceLocation.js +20 -9
  814. package/dist/domain/zipPackageFormat.js +29 -3
  815. package/dist/dotnet/ManagedArtifactInspector.js +27 -12
  816. package/dist/dotnet/ManagedDecodeBudget.js +66 -8
  817. package/dist/dotnet/ManagedMemberInspector.js +101 -21
  818. package/dist/dotnet/ManagedMemberInspectorCore.js +356 -140
  819. package/dist/dotnet/ManagedMemberInstructionDecoder.js +109 -37
  820. package/dist/dotnet/ManagedMemberOwnership.js +65 -0
  821. package/dist/dotnet/ManagedMemberPointers.js +69 -0
  822. package/dist/dotnet/ManagedMemberRows.js +179 -46
  823. package/dist/dotnet/ManagedMetadataHeaps.js +110 -24
  824. package/dist/dotnet/ManagedMetadataInventory.js +5 -5
  825. package/dist/dotnet/ManagedMetadataInventoryRows.js +36 -52
  826. package/dist/dotnet/ManagedMetadataLayout.js +9 -1
  827. package/dist/dotnet/ManagedMetadataRowSizes.js +1 -1
  828. package/dist/dotnet/ManagedMethodBodyReader.js +29 -11
  829. package/dist/dotnet/ManagedMethodSpecs.js +78 -0
  830. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +2 -2
  831. package/dist/dotnet/ManagedNativeBoundaryInspector.js +6 -13
  832. package/dist/dotnet/ManagedPeReader.js +55 -27
  833. package/dist/dotnet/ManagedReaderFailure.js +9 -0
  834. package/dist/dotnet/ManagedSnapshot.js +88 -0
  835. package/dist/dotnet/ManagedStaticProvider.js +55 -64
  836. package/dist/dotnet/ManagedTypeMemberLists.js +105 -0
  837. package/dist/dotnet/ManagedTypeNames.js +98 -0
  838. package/dist/dotnet/ManagedUserStrings.js +75 -0
  839. package/dist/electron/ElectronFusePath.js +247 -0
  840. package/dist/electron/ElectronFuseProvider.js +113 -0
  841. package/dist/electron/ElectronFuseReader.js +317 -0
  842. package/dist/evaluation/AgentEvaluationFixtures.js +194 -11
  843. package/dist/evaluation/CodexAgentEval.js +19 -40
  844. package/dist/evaluation/KnownAnswerEvaluation.js +126 -57
  845. package/dist/evm/EvmoleFailures.js +19 -14
  846. package/dist/evm/EvmoleInterfaceAdapter.js +5 -1
  847. package/dist/evm/EvmoleInterfaceProvider.js +141 -31
  848. package/dist/evm/EvmoleInterfaceWorker.js +2 -0
  849. package/dist/evm/SolidityMetadata.js +139 -0
  850. package/dist/filesystem/OwnedStagedOutput.js +138 -0
  851. package/dist/filesystem/RegularFile.js +48 -4
  852. package/dist/filesystem/readFileHandleChunks.js +17 -8
  853. package/dist/firmware/FirmwareCommand.js +2 -2
  854. package/dist/firmware/FirmwareFiles.js +8 -12
  855. package/dist/firmware/FirmwareProvider.js +2 -0
  856. package/dist/firmware/FirmwarePublication.js +218 -1
  857. package/dist/firmware/FirmwareReports.js +202 -12
  858. package/dist/flutter/DartElf.js +418 -0
  859. package/dist/flutter/ElfBuildId.js +137 -0
  860. package/dist/flutter/ElfLoadMap.js +91 -0
  861. package/dist/flutter/FlutterBuildProvider.js +826 -0
  862. package/dist/flutter/FlutterPayloadScan.js +180 -0
  863. package/dist/frida/FridaInstrumentationManager.js +1104 -0
  864. package/dist/gdb/GdbSessionManager.js +1451 -0
  865. package/dist/generatedPackageMetadata.js +2 -2
  866. package/dist/ghidra/GhidraAnalysisProfile.js +130 -12
  867. package/dist/ghidra/GhidraClient.js +195 -88
  868. package/dist/ghidra/GhidraDiagnostics.js +7 -0
  869. package/dist/ghidra/GhidraDoctor.js +15 -12
  870. package/dist/ghidra/GhidraFunctionValues.js +49 -2
  871. package/dist/ghidra/GhidraInstallation.js +215 -19
  872. package/dist/ghidra/GhidraInstallationPolicy.js +79 -29
  873. package/dist/ghidra/GhidraInventoryValues.js +30 -0
  874. package/dist/ghidra/GhidraJavaLaunch.js +91 -10
  875. package/dist/ghidra/GhidraJavaProperties.js +117 -0
  876. package/dist/ghidra/GhidraLanguageCatalog.js +74 -4
  877. package/dist/ghidra/GhidraLauncher.js +234 -57
  878. package/dist/ghidra/GhidraLoadImageAttest.js +28 -8
  879. package/dist/ghidra/GhidraLoadImageValues.js +72 -0
  880. package/dist/ghidra/GhidraMipsProfile.js +250 -14
  881. package/dist/ghidra/GhidraPeProfile.js +21 -0
  882. package/dist/ghidra/GhidraPowerPcProfile.js +51 -0
  883. package/dist/ghidra/GhidraProvider.js +54 -16
  884. package/dist/ghidra/GhidraProviderCapabilities.js +13 -12
  885. package/dist/ghidra/GhidraProviderClient.js +260 -57
  886. package/dist/ghidra/GhidraPspExtension.js +140 -0
  887. package/dist/ghidra/GhidraPspProfile.js +59 -0
  888. package/dist/ghidra/GhidraRawBinaryLanguage.js +40 -0
  889. package/dist/ghidra/GhidraRiscvProfile.js +100 -0
  890. package/dist/ghidra/GhidraSessionError.js +155 -11
  891. package/dist/ghidra/GhidraSessionValues.js +66 -0
  892. package/dist/ghidra/GhidraTransport.js +2 -1
  893. package/dist/go/GoBinaryContainer.js +140 -0
  894. package/dist/go/GoBinaryImage.js +210 -0
  895. package/dist/go/GoBinaryProvider.js +151 -0
  896. package/dist/go/GoElfImage.js +211 -0
  897. package/dist/go/GoMachoImage.js +164 -0
  898. package/dist/go/GoModuleText.js +217 -0
  899. package/dist/go/GoPeImage.js +124 -0
  900. package/dist/hopper/BridgeLauncher.js +35 -2
  901. package/dist/hopper/HopperAnalysisProfile.js +21 -11
  902. package/dist/hopper/HopperCleanup.js +15 -3
  903. package/dist/hopper/HopperClient.js +188 -36
  904. package/dist/hopper/HopperMacPublisher.js +29 -0
  905. package/dist/hopper/HopperMachOImage.js +61 -29
  906. package/dist/hopper/HopperProcessDiagnostic.js +27 -0
  907. package/dist/hopper/HopperProvider.js +59 -28
  908. package/dist/hopper/HopperProviderCapabilities.js +7 -3
  909. package/dist/hopper/HopperRequestQueue.js +17 -5
  910. package/dist/hopper/HopperSessionValues.js +10 -1
  911. package/dist/hopper/HopperTargetLease.js +66 -19
  912. package/dist/ida/IdaBusyHealth.js +44 -0
  913. package/dist/ida/IdaCallGraph.js +134 -0
  914. package/dist/ida/IdaConfiguration.js +7 -2
  915. package/dist/ida/IdaDiagnosticRedactor.js +199 -0
  916. package/dist/ida/IdaDiagnosticWriter.js +62 -0
  917. package/dist/ida/IdaDoctor.js +7 -5
  918. package/dist/ida/IdaJsonDiagnostic.js +138 -0
  919. package/dist/ida/IdaMcpConnection.js +297 -27
  920. package/dist/ida/IdaNativeProtocol.js +93 -0
  921. package/dist/ida/IdaOperationRunner.js +246 -43
  922. package/dist/ida/IdaProtocolValues.js +86 -4
  923. package/dist/ida/IdaProvider.js +29 -10
  924. package/dist/ida/IdaProviderCapabilities.js +37 -8
  925. package/dist/ida/IdaSessionClient.js +331 -54
  926. package/dist/ida/IdaWorkspace.js +54 -6
  927. package/dist/inspector/V8InspectorCaptureProjection.js +7 -2
  928. package/dist/inspector/V8InspectorEndpoint.js +15 -13
  929. package/dist/inspector/V8InspectorProvider.js +41 -7
  930. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +19 -8
  931. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +103 -29
  932. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +6 -4
  933. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +78 -9
  934. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +15 -5
  935. package/dist/javascript/recovery/RecoveryFiles.js +51 -6
  936. package/dist/javascript/recovery/WakaruExecution.js +19 -11
  937. package/dist/javascript/recovery/WakaruProvider.js +12 -9
  938. package/dist/javascript/recovery/WakaruPublication.js +24 -10
  939. package/dist/javascript/recovery/WakaruRelease.js +1 -1
  940. package/dist/javascript/recovery/WakaruReport.js +3 -2
  941. package/dist/javascript/sourceMaps/DecodedSourceMap.js +2 -16
  942. package/dist/javascript/sourceMaps/SourceMapCommand.js +22 -4
  943. package/dist/javascript/sourceMaps/SourceMapDecoder.js +22 -4
  944. package/dist/javascript/sourceMaps/SourceMapFormat.js +25 -38
  945. package/dist/javascript/sourceMaps/TraceSourceMap.js +34 -6
  946. package/dist/jeb/JebMcpConnection.js +19 -12
  947. package/dist/jeb/JebMcpEndpoint.js +6 -1
  948. package/dist/jeb/JebProvider.js +5 -7
  949. package/dist/logger.js +14 -1
  950. package/dist/main/shutdown.js +3 -0
  951. package/dist/main/transport.js +48 -4
  952. package/dist/main.js +14 -3
  953. package/dist/mcp/AnalysisSnapshotFiles-BAbiJQOc.js +1412 -0
  954. package/dist/mcp/ArtifactProvider-DViCU_rn.js +2183 -0
  955. package/dist/mcp/ArtifactProviderMetadata-b7pOK5_t.js +76 -0
  956. package/dist/mcp/ArtifactReader-OyM03Gjn.js +55 -0
  957. package/dist/mcp/ArtifactResourceScope-P3tq5z8Z.js +162 -0
  958. package/dist/mcp/AsarHeader-WsPgoooH.js +31 -0
  959. package/dist/mcp/BinarySessionStatus-B4P9gf-S.js +212 -0
  960. package/dist/mcp/BinaryTargetResolver-BMaE_0H1.js +1427 -0
  961. package/dist/mcp/BoundedFileBytes-DuczXiQZ.js +68 -0
  962. package/dist/mcp/CdpCaptureDocuments-HDiF2O7k.js +746 -0
  963. package/dist/mcp/CdpCaptureValues-M-j6CIh1.js +90 -0
  964. package/dist/mcp/CdpConnection-BpDfz4MK.js +570 -0
  965. package/dist/mcp/CdpOptionalCommand-BPjRD9Kz.js +120 -0
  966. package/dist/mcp/CdpTargetSession-BsPoKhEU.js +86 -0
  967. package/dist/mcp/DirectAnalysis-DrafbXke.js +409 -0
  968. package/dist/mcp/DirectAnalysisStatus-CjjeDLzW.js +44 -0
  969. package/dist/mcp/ElectronFileScope-BPG_YoyU.js +110 -0
  970. package/dist/mcp/InterfaceBuilderDecodeBudget-5F2AkxJT.js +652 -0
  971. package/dist/mcp/ManagedStaticProvider-BthZbKyZ.js +5028 -0
  972. package/dist/mcp/NativeMacOSProvider-Bh79k8dI.js +4867 -0
  973. package/dist/mcp/NativeMacOSProviderMetadata-N1lPOaY_.js +307 -0
  974. package/dist/mcp/ProcedureAddressResolution-CQpuwm1h.js +19 -0
  975. package/dist/mcp/ProcessOwnership-Bl_3ejLe.js +1502 -0
  976. package/dist/mcp/ProviderDeadline-DskQ94YD.js +932 -0
  977. package/dist/mcp/WorkflowEvidence-umWrB_wm.js +111 -0
  978. package/dist/mcp/analysisErrorCore-DXRTvF_m.js +235 -0
  979. package/dist/mcp/analysisErrorProjection-BN0EPM-3.js +892 -0
  980. package/dist/mcp/artifactOperationError-CkHMMaf7.js +27 -0
  981. package/dist/mcp/artifactToolContracts-Di4qZlEt.js +72 -0
  982. package/dist/mcp/browserObservation-C0s4i8UI.js +4468 -0
  983. package/dist/mcp/browserObservationError-CyLugqX4.js +40 -0
  984. package/dist/mcp/browserObservationSchemas-tgqjH7aA.js +573 -0
  985. package/dist/mcp/browserScenario-CAQ8Fns9.js +2929 -0
  986. package/dist/mcp/browserScenarioCapture-CTNFN-FI.js +479 -0
  987. package/dist/mcp/canonicalDigest-Bi_0_zGi.js +71 -0
  988. package/dist/mcp/digests-BFoWUT_-.js +223 -0
  989. package/dist/mcp/electronActiveObservation-lDvQTMR0.js +226 -0
  990. package/dist/mcp/electronObservation-DFOFEood.js +112 -0
  991. package/dist/mcp/electronObservation-i7LcILQ-.js +562 -0
  992. package/dist/mcp/electronScenario-nCzE6IfJ.js +653 -0
  993. package/dist/mcp/emptyArraySchema-tL6Qymyd.js +140 -0
  994. package/dist/mcp/enhancedInputs-DgdEnzHy.js +56 -0
  995. package/dist/mcp/javascriptRuntimeObservation-61NhCf7H.js +690 -0
  996. package/dist/mcp/javascriptRuntimeObservation-PIUoLfX6.js +121 -0
  997. package/dist/mcp/jsonSerialization-V-wWiFRE.js +152 -0
  998. package/dist/mcp/lipo-Bnkoq_6W.js +502 -0
  999. package/dist/mcp/localPath-AxvW9aPe.js +19 -0
  1000. package/dist/mcp/logger-BQY5ulYv.js +48 -0
  1001. package/dist/mcp/main-kBXHZ8S5.js +69390 -0
  1002. package/dist/mcp/main.js +6 -0
  1003. package/dist/mcp/managedToolContracts-CK--I_s7.js +101 -0
  1004. package/dist/mcp/nativeValueTrace-DR9UE62L.js +3439 -0
  1005. package/dist/mcp/officialToolContracts-B67NJ2tC.js +1413 -0
  1006. package/dist/mcp/pngHeader-DQ-ObyY2.js +147 -0
  1007. package/dist/mcp/propertyListKeys-DD25WsjI.js +553 -0
  1008. package/dist/mcp/providerAdapterError-sDxToNal.js +25 -0
  1009. package/dist/mcp/providerIdentities--ptAh481.js +31 -0
  1010. package/dist/mcp/providerIdentity-BCQ5n5tw.js +16 -0
  1011. package/dist/mcp/providerOperationHealth-CTYa3iLf.js +48 -0
  1012. package/dist/mcp/rolldown-runtime-BjeaiXFo.js +121 -0
  1013. package/dist/mcp/safeJson-NeGfpkrI.js +25 -0
  1014. package/dist/mcp/scanCanonical-CRXSpule.js +3982 -0
  1015. package/dist/mcp/serverIdentity-Cio4iFV3.js +1328 -0
  1016. package/dist/mcp/sourceMapEnvelope-C0uJlrOh.js +94 -0
  1017. package/dist/mcp/toolContracts-BW05wpcr.js +12200 -0
  1018. package/dist/mcp/toolOutputSchemaGroups-ColvNZ1r.js +17533 -0
  1019. package/dist/mcp/unicodeCodePointOrder-BezCbTpg.js +26 -0
  1020. package/dist/mcp/webContentArtifact-Dzjc1z-R.js +284 -0
  1021. package/dist/mcp/webRuntime-K__NYzXm.js +74 -0
  1022. package/dist/mcp/webSourceLocation-DbMAT2J9.js +11130 -0
  1023. package/dist/mcpDoctor.js +93 -70
  1024. package/dist/mcpStartupPolicy.js +3 -0
  1025. package/dist/native/AppleDispatchCoverage.js +57 -17
  1026. package/dist/native/AppleDispatchMetadata.js +6 -2
  1027. package/dist/native/AppleMachoFixups.js +188 -25
  1028. package/dist/native/AppleMachoSelection.js +30 -23
  1029. package/dist/native/AppleObjcCategories.js +1 -2
  1030. package/dist/native/AppleObjcDispatchFacets.js +76 -7
  1031. package/dist/native/CommandRunner.js +142 -32
  1032. package/dist/native/LldbCallTracer.js +5 -3
  1033. package/dist/native/MachoArchitectureSelection.js +50 -0
  1034. package/dist/native/NativeCallObservation.js +2 -1
  1035. package/dist/native/NativeMacOSProvider.js +90 -29
  1036. package/dist/native/NativeMachoInspection.js +136 -76
  1037. package/dist/native/NativeUiObservation.js +2 -2
  1038. package/dist/native/SignatureTargetBinding.js +118 -55
  1039. package/dist/native/parsers/codesign.js +27 -10
  1040. package/dist/native/parsers/demangle.js +7 -1
  1041. package/dist/native/parsers/dyldInfo.js +73 -4
  1042. package/dist/native/parsers/lipo.js +53 -19
  1043. package/dist/native/parsers/machoUuid.js +150 -0
  1044. package/dist/native/parsers/otool.js +232 -29
  1045. package/dist/native/pe/PeResourcesProvider.js +20 -6
  1046. package/dist/native/pwndbg/PwndbgCoreContext.js +20 -20
  1047. package/dist/native/pwntools/PwntoolsDecoder.js +264 -40
  1048. package/dist/native/pwntools/PwntoolsFailures.js +2 -1
  1049. package/dist/native/pwntools/PwntoolsInputLimit.js +27 -0
  1050. package/dist/native/pwntools/PwntoolsRecordedCrashProvider.js +27 -15
  1051. package/dist/native/pwntools/PwntoolsResourceLimits.js +3 -3
  1052. package/dist/native/pwntools/RecordedCrashSourceBindings.js +12 -8
  1053. package/dist/native/pwntools/RecordedCrashStructureBindings.js +3 -1
  1054. package/dist/objdump/ObjdumpCommand.js +21 -0
  1055. package/dist/pcap/PcapCommand.js +146 -0
  1056. package/dist/pcap/PcapConfiguration.js +93 -0
  1057. package/dist/pcap/PcapNativeBound.js +58 -0
  1058. package/dist/pcap/PcapOutput.js +240 -0
  1059. package/dist/pcap/PcapProvider.js +424 -0
  1060. package/dist/pcap/PcapSnapshot.js +171 -0
  1061. package/dist/process/ArtifactAnalysisResources.js +213 -0
  1062. package/dist/process/CurrentEntrypointPath.js +6 -0
  1063. package/dist/process/DarwinProcessRunTokenReader.js +117 -13
  1064. package/dist/process/ExecFileBoundedOutput.js +44 -0
  1065. package/dist/process/ExecFileOutput.js +30 -6
  1066. package/dist/process/JavaScriptWorkerMemoryLimit.js +25 -0
  1067. package/dist/process/LinuxResourceLimits.js +80 -0
  1068. package/dist/process/MacCodeSignature.js +3 -0
  1069. package/dist/process/OwnedCommand.js +37 -13
  1070. package/dist/process/PrivateRuntimeRoot.js +9 -19
  1071. package/dist/process/PrivateRuntimeRootUnavailableError.js +10 -0
  1072. package/dist/process/ProcessOwnership.js +70 -17
  1073. package/dist/process/ProcessOwnershipObservation.js +35 -4
  1074. package/dist/process/ProviderDeadline.js +58 -12
  1075. package/dist/process/ProviderProcess.js +108 -11
  1076. package/dist/process/WindowsAuthority.js +48 -39
  1077. package/dist/process/WindowsBatchCommand.js +46 -0
  1078. package/dist/process/boundedUtf8Text.js +13 -0
  1079. package/dist/process/capture/FilesystemSnapshot.js +60 -9
  1080. package/dist/process/capture/ProcessCaptureClock.js +2 -0
  1081. package/dist/process/capture/ProcessCaptureError.js +22 -3
  1082. package/dist/process/capture/ProcessCaptureJournal.js +2 -1
  1083. package/dist/process/capture/ProcessCaptureLifecycle.js +87 -36
  1084. package/dist/process/capture/ProcessCaptureProgress.js +2 -1
  1085. package/dist/process/capture/ProcessHarness.js +17 -14
  1086. package/dist/process/capture/ProcessNormalization.js +278 -36
  1087. package/dist/process/capture/ProcessSampling.js +3 -2
  1088. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +13 -13
  1089. package/dist/process/capture/TerminalRenderer.js +31 -10
  1090. package/dist/process/ownedDebuggerSession.js +203 -0
  1091. package/dist/reference/ReferenceSourceReader.js +0 -1
  1092. package/dist/reference/ReferenceSourceReaderEntries.js +68 -54
  1093. package/dist/reference/ReferenceSourceReaderErrors.js +5 -1
  1094. package/dist/reference/ReferenceSourceReaderFile.js +0 -1
  1095. package/dist/reference/ReferenceSourceReaderTypes.js +1 -2
  1096. package/dist/reference/ReferenceSourceReaderValidate.js +0 -1
  1097. package/dist/rizin/RizinCommand.js +14 -0
  1098. package/dist/rizin/RizinDebugSessionManager.js +1072 -0
  1099. package/dist/rust/RustAuditableReader.js +309 -0
  1100. package/dist/rust/RustBinaryImage.js +116 -0
  1101. package/dist/rust/RustBinaryProvider.js +162 -0
  1102. package/dist/server/EvidenceMcpServer.js +160 -37
  1103. package/dist/server/admittedToolOperation.js +7 -2
  1104. package/dist/server/contractToolHandler.js +8 -1
  1105. package/dist/server/createServer.js +157 -27
  1106. package/dist/server/externalMutationAdmission.js +50 -0
  1107. package/dist/server/mcpProgress.js +4 -2
  1108. package/dist/server/promptCompletion.js +19 -6
  1109. package/dist/server/providerEnvironment.js +3 -0
  1110. package/dist/server/registerAnalysisViewTool.js +6 -2
  1111. package/dist/server/registerAndroidTools.js +22 -4
  1112. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +8 -1
  1113. package/dist/server/registerArtifactTools.js +21 -1
  1114. package/dist/server/registerBrowserTools.js +2 -4
  1115. package/dist/server/registerBundleComparisonTool.js +4 -4
  1116. package/dist/server/registerCaptureTools.js +12 -0
  1117. package/dist/server/registerCutterTools.js +33 -0
  1118. package/dist/server/registerElectronTools.js +12 -9
  1119. package/dist/server/registerEnhancedTools.js +7 -6
  1120. package/dist/server/registerEvidenceTools.js +14 -10
  1121. package/dist/server/registerEvmTools.js +22 -4
  1122. package/dist/server/registerFlutterTools.js +17 -0
  1123. package/dist/server/registerFridaTools.js +205 -0
  1124. package/dist/server/registerFunctionComparisonTool.js +29 -9
  1125. package/dist/server/registerGdbTools.js +64 -0
  1126. package/dist/server/registerGoTools.js +9 -0
  1127. package/dist/server/registerInvestigationTools/helpers.js +2 -2
  1128. package/dist/server/registerInvestigationTools.js +12 -8
  1129. package/dist/server/registerJavaScriptRuntimeObservationTools.js +1 -5
  1130. package/dist/server/registerManagedTools.js +11 -1
  1131. package/dist/server/registerNativeTools.js +14 -0
  1132. package/dist/server/registerOfficialTools.js +5 -0
  1133. package/dist/server/registerPcapTools.js +35 -0
  1134. package/dist/server/registerProcessComparisonTool.js +9 -2
  1135. package/dist/server/registerReverseEngineeringTools.js +86 -0
  1136. package/dist/server/registerRizinDebugTools.js +53 -0
  1137. package/dist/server/registerRustTools.js +9 -0
  1138. package/dist/server/registerSessionRecordTools.js +19 -13
  1139. package/dist/server/registerSessionStatusTool.js +22 -4
  1140. package/dist/server/registerSessionTools.js +29 -16
  1141. package/dist/server/registerSignalTools.js +12 -0
  1142. package/dist/server/registerSqliteTools.js +9 -0
  1143. package/dist/server/registerWasmTools.js +46 -0
  1144. package/dist/server/registerWebNetworkCaptureTool.js +24 -10
  1145. package/dist/server/retainedSummaryDelivery.js +28 -0
  1146. package/dist/server/sessionAvailabilityPolicy.js +3 -0
  1147. package/dist/server/toolRegistrationOptions.js +8 -0
  1148. package/dist/server/toolResult.js +52 -19
  1149. package/dist/server/toolResultEncoding.js +36 -3
  1150. package/dist/serverIdentity.js +17 -8
  1151. package/dist/signals/SigrokRecordingProvider.js +339 -0
  1152. package/dist/signals/parseDecoderDiscovery.js +65 -0
  1153. package/dist/sqlite/SqliteDatabaseFailures.js +134 -0
  1154. package/dist/sqlite/SqliteDatabaseInspection.js +421 -0
  1155. package/dist/sqlite/SqliteDatabaseLimits.js +16 -0
  1156. package/dist/sqlite/SqliteDatabaseProvider.js +295 -0
  1157. package/dist/sqlite/SqliteDatabaseSnapshot.js +156 -0
  1158. package/dist/sqlite/SqliteDatabaseWorker.js +46 -0
  1159. package/dist/sqlite/SqliteDatabaseWorkerExecution.js +112 -0
  1160. package/dist/wasm/WabtArtifactProvider.js +336 -0
  1161. package/dist/wasm/WabtFailures.js +101 -0
  1162. package/dist/wasm/WabtInterface.js +309 -0
  1163. package/dist/wasm/WabtOutput.js +60 -0
  1164. package/dist/wasm/WabtRelease.js +12 -0
  1165. package/dist/wasm/WabtString.js +48 -0
  1166. package/dist/wasm/WabtWat.js +147 -0
  1167. package/dist/wasm/WasmGlueAdapter.js +53 -0
  1168. package/dist/wasm/WasmInterfaceBudget.js +11 -0
  1169. package/dist/windows/WindowsNativeLoader.js +37 -7
  1170. package/dist/windows/WindowsOwnedProcess.js +150 -17
  1171. package/dist/windows/WindowsPrivateRuntime.js +22 -1
  1172. package/install.sh +157 -98
  1173. package/licenses/Apache-2.0.txt +202 -0
  1174. package/licenses/GCC-Runtime-Library-Exception-3.1.txt +73 -0
  1175. package/licenses/GPL-3.0.txt +674 -0
  1176. package/licenses/LGPL-2.0.txt +480 -0
  1177. package/licenses/MIT-template.txt +18 -0
  1178. package/licenses/MinGW-w64-runtime.txt +240 -0
  1179. package/licenses/Node-22.19.0-LICENSE.txt +2666 -0
  1180. package/licenses/README.md +68 -0
  1181. package/licenses/cfworker-MIT.txt +21 -0
  1182. package/licenses/dotnet-runtime-MIT.txt +23 -0
  1183. package/licenses/frida-17.23.2-COPYING.txt +50 -0
  1184. package/licenses/ghidra-12.1.4-DISCLAIMER.txt +13 -0
  1185. package/licenses/ghidra-12.1.4-LICENSE.txt +201 -0
  1186. package/licenses/ghidra-12.1.4-NOTICE.txt +49 -0
  1187. package/licenses/npm-dependencies.txt +3612 -0
  1188. package/licenses/npm-runtime-notices.txt +8548 -0
  1189. package/licenses/upstream-sources.json +72 -0
  1190. package/licenses/xterm-MIT.txt +21 -0
  1191. package/native/windows/README.md +92 -11
  1192. package/native/windows/build/manifest.json +2 -2
  1193. package/native/windows/build/rea-windows-x64.node +0 -0
  1194. package/package.json +89 -22
  1195. package/scripts/electron-active-hook.cjs +4 -1
  1196. package/scripts/hopper-demo-x11.py +53 -3
  1197. package/scripts/prepack.mjs +5 -0
  1198. package/scripts/rea-android-workspace-guardian.mjs +46 -0
  1199. package/scripts/rea.mjs +28 -12
  1200. package/scripts/verify-windows-native-artifact.mjs +2 -2
  1201. package/skills/reverse-engineer-anything/SKILL.md +131 -10
  1202. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +10 -10
  1203. package/skills/reverse-engineer-anything/references/evidence-workflows.md +23 -0
  1204. package/skills/reverse-engineer-anything/references/javascript-applications.md +28 -2
  1205. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +125 -15
  1206. package/skills/reverse-engineer-anything/references/runtime-observation.md +57 -7
  1207. package/third_party/README.md +1 -1
  1208. package/third_party/wabt/README.md +24 -0
  1209. package/dist/browser/history/HarCaptureAdapter.js +0 -20
  1210. package/dist/cli/streamedJsonOutput.js +0 -135
  1211. /package/dist/{application/binary → process}/AbortablePromise.js +0 -0
@@ -5,14 +5,18 @@ import java.io.BufferedReader;
5
5
  import java.io.BufferedWriter;
6
6
  import java.io.ByteArrayOutputStream;
7
7
  import java.io.IOException;
8
+ import java.io.InputStream;
8
9
  import java.math.BigInteger;
9
10
  import java.net.InetAddress;
10
11
  import java.net.InetSocketAddress;
12
+ import java.net.SocketTimeoutException;
11
13
  import java.net.StandardProtocolFamily;
12
14
  import java.net.UnixDomainSocketAddress;
13
15
  import java.nio.channels.Channels;
14
16
  import java.nio.channels.ServerSocketChannel;
15
17
  import java.nio.channels.SocketChannel;
18
+ import java.nio.ByteBuffer;
19
+ import java.nio.charset.CharacterCodingException;
16
20
  import java.nio.charset.StandardCharsets;
17
21
  import java.nio.file.AtomicMoveNotSupportedException;
18
22
  import java.nio.file.Files;
@@ -22,8 +26,11 @@ import java.nio.file.StandardCopyOption;
22
26
  import java.nio.file.StandardOpenOption;
23
27
  import java.nio.file.attribute.PosixFilePermissions;
24
28
  import java.security.MessageDigest;
29
+ import java.util.ArrayDeque;
25
30
  import java.util.ArrayList;
31
+ import java.util.Arrays;
26
32
  import java.util.Comparator;
33
+ import java.util.HashMap;
27
34
  import java.util.HashSet;
28
35
  import java.util.IdentityHashMap;
29
36
  import java.util.Iterator;
@@ -52,6 +59,8 @@ import ghidra.app.decompiler.DecompiledFunction;
52
59
  import ghidra.app.decompiler.ClangCaseToken;
53
60
  import ghidra.app.decompiler.ClangNode;
54
61
  import ghidra.framework.Application;
62
+ import ghidra.app.util.bin.format.pdb.PdbParserConstants;
63
+ import ghidra.framework.options.Options;
55
64
  import ghidra.program.model.address.Address;
56
65
  import ghidra.program.model.address.AddressIterator;
57
66
  import ghidra.program.model.address.AddressSet;
@@ -74,6 +83,7 @@ import ghidra.program.model.listing.Function;
74
83
  import ghidra.program.model.listing.FunctionIterator;
75
84
  import ghidra.program.model.listing.Instruction;
76
85
  import ghidra.program.model.listing.InstructionIterator;
86
+ import ghidra.program.model.listing.Listing;
77
87
  import ghidra.program.model.listing.Variable;
78
88
  import ghidra.program.model.mem.MemoryBlock;
79
89
  import ghidra.program.model.mem.MemoryBlockSourceInfo;
@@ -82,6 +92,7 @@ import ghidra.program.model.address.SegmentedAddress;
82
92
  import ghidra.program.model.reloc.Relocation;
83
93
  import java.io.ByteArrayOutputStream;
84
94
  import ghidra.program.model.symbol.Namespace;
95
+ import ghidra.program.model.symbol.FlowType;
85
96
  import ghidra.program.model.symbol.RefType;
86
97
  import ghidra.program.model.symbol.Reference;
87
98
  import ghidra.program.model.symbol.ReferenceIterator;
@@ -100,12 +111,19 @@ import ghidra.program.model.pcode.PcodeBlock;
100
111
  import ghidra.program.model.pcode.PcodeBlockBasic;
101
112
  import ghidra.program.model.pcode.Varnode;
102
113
  import ghidra.program.model.pcode.VarnodeAST;
114
+ import ghidra.program.util.ContextEvaluatorAdapter;
115
+ import ghidra.program.util.SymbolicPropogator;
116
+ import ghidra.program.util.VarnodeContext;
103
117
 
104
118
  public final class ReaGhidraBridge extends HeadlessScript {
119
+ // At most 24 KiB after worst-case JSON escaping (six bytes per UTF-16 unit).
120
+ private static final int PDB_ATTRIBUTE_UTF16_BUDGET = 4096;
105
121
  private static final int MAX_HIGH_PCODE_OPS = 3000;
106
122
  private static final int MAX_HIGH_PCODE_INPUTS_PER_OP = 64;
107
123
  private static final int MAX_HIGH_PCODE_DEF_USE_EDGES = 12000;
108
124
  private static final Gson GSON = new GsonBuilder().serializeNulls().create();
125
+ private final Map<FileBytes, Boolean> targetSourceIdentity = new IdentityHashMap<>();
126
+ private String admittedTargetSha256;
109
127
  private static final Set<String> DESCRIPTOR_KEYS = Set.of(
110
128
  "transport",
111
129
  "endpoint_path",
@@ -127,6 +145,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
127
145
  "set_addresses_names",
128
146
  "inspect_native_load_image",
129
147
  "read_bytes",
148
+ "search_bytes",
130
149
  "address_to_file_offset",
131
150
  "ping",
132
151
  "shutdown",
@@ -182,10 +201,17 @@ public final class ReaGhidraBridge extends HeadlessScript {
182
201
  }
183
202
  sessionDefaultAddressSpace =
184
203
  currentProgram.getAddressFactory().getDefaultAddressSpace();
185
- if (currentProgram.getExecutableFormat().equals("Raw Binary") &&
186
- !currentProgram.getOptions(ghidra.program.model.listing.Program.PROGRAM_INFO)
187
- .getBoolean("REA DOS COM prepared", false)) {
188
- throw new IllegalStateException("REA DOS COM entry/context preparation failed");
204
+ if (currentProgram.getExecutableFormat().equals("Raw Binary")) {
205
+ boolean dosCom = currentProgram.getLanguageID().getIdAsString()
206
+ .equals("x86:LE:16:Real Mode");
207
+ String preparation = dosCom ? "REA DOS COM prepared" : "REA raw binary prepared";
208
+ if (!currentProgram.getOptions(ghidra.program.model.listing.Program.PROGRAM_INFO)
209
+ .getBoolean(preparation, false)) {
210
+ throw new IllegalStateException(
211
+ dosCom ? "REA DOS COM entry/context preparation failed" :
212
+ "REA raw binary entry preparation failed"
213
+ );
214
+ }
189
215
  }
190
216
  if (!Application.getApplicationVersion().equals(descriptor.providerVersion)) {
191
217
  throw new IllegalStateException("Ghidra provider version does not match the session");
@@ -200,6 +226,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
200
226
  "Ghidra imported-byte digest does not match the admitted target"
201
227
  );
202
228
  }
229
+ admittedTargetSha256 = descriptor.targetSha256;
203
230
  // GhidraScript wraps run() in a transaction. End it before serving so
204
231
  // each edit owns a real outer transaction and can roll back immediately.
205
232
  end(true);
@@ -273,7 +300,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
273
300
  Files.move(pendingPath, endpointPath);
274
301
  }
275
302
  }
276
- acceptClient(server, descriptor);
303
+ acceptAuthenticatedLoopbackClient(server, descriptor);
277
304
  }
278
305
  finally {
279
306
  Files.deleteIfExists(pendingPath);
@@ -285,6 +312,50 @@ public final class ReaGhidraBridge extends HeadlessScript {
285
312
  return System.getProperty("os.name", "").startsWith("Windows");
286
313
  }
287
314
 
315
+ private static String readLoopbackHandshake(
316
+ SocketChannel client, int maxBytes, long timeoutMillis) throws IOException {
317
+ long deadline = System.nanoTime() + timeoutMillis * 1_000_000L;
318
+ InputStream input = client.socket().getInputStream();
319
+ ByteArrayOutputStream bytes = new ByteArrayOutputStream();
320
+ while (true) {
321
+ long remaining = deadline - System.nanoTime();
322
+ if (remaining <= 0) throw new SocketTimeoutException("Bridge authentication timed out");
323
+ client.socket().setSoTimeout((int) Math.max(1,
324
+ Math.min(Integer.MAX_VALUE, (remaining + 999_999L) / 1_000_000L)));
325
+ int value = input.read();
326
+ if (value == -1) return null;
327
+ if (value == '\n') return bytes.toString(StandardCharsets.UTF_8);
328
+ if (bytes.size() == maxBytes) throw new IOException("Bridge authentication frame is too large");
329
+ bytes.write(value);
330
+ }
331
+ }
332
+
333
+ private void acceptAuthenticatedLoopbackClient(
334
+ ServerSocketChannel server, SessionDescriptor descriptor) throws Exception {
335
+ while (true) {
336
+ try (SocketChannel client = server.accept()) {
337
+ Request first;
338
+ try {
339
+ String line = readLoopbackHandshake(client, 64 * 1024, 1_000);
340
+ if (line == null) continue;
341
+ first = parseRequest(line, descriptor.token);
342
+ }
343
+ catch (IOException | RuntimeException rejected) {
344
+ // A rejected unauthenticated peer cannot consume the bridge session.
345
+ continue;
346
+ }
347
+ client.socket().setSoTimeout(0);
348
+ try (BufferedReader reader = new BufferedReader(
349
+ Channels.newReader(client, StandardCharsets.UTF_8));
350
+ BufferedWriter writer = new BufferedWriter(
351
+ Channels.newWriter(client, StandardCharsets.UTF_8))) {
352
+ serveClient(descriptor, reader, writer, first);
353
+ }
354
+ return;
355
+ }
356
+ }
357
+ }
358
+
288
359
  private void acceptClient(
289
360
  ServerSocketChannel server,
290
361
  SessionDescriptor descriptor) throws Exception {
@@ -295,26 +366,28 @@ public final class ReaGhidraBridge extends HeadlessScript {
295
366
  BufferedWriter writer = new BufferedWriter(
296
367
  Channels.newWriter(client, StandardCharsets.UTF_8)
297
368
  )) {
298
- serveClient(descriptor, reader, writer);
369
+ serveClient(descriptor, reader, writer, null);
299
370
  }
300
371
  }
301
372
 
302
373
  private void serveClient(
303
374
  SessionDescriptor descriptor,
304
375
  BufferedReader reader,
305
- BufferedWriter writer) throws Exception {
376
+ BufferedWriter writer,
377
+ Request first) throws Exception {
306
378
  while (true) {
307
- String line = reader.readLine();
308
- if (line == null) {
309
- return;
310
- }
311
- Request request;
312
- try {
313
- request = parseRequest(line, descriptor.token);
314
- }
315
- catch (RuntimeException exception) {
316
- writeFailure(writer, 1, "invalid_request", "Bridge request is invalid");
317
- return;
379
+ Request request = first;
380
+ first = null;
381
+ if (request == null) {
382
+ String line = reader.readLine();
383
+ if (line == null) return;
384
+ try {
385
+ request = parseRequest(line, descriptor.token);
386
+ }
387
+ catch (RuntimeException exception) {
388
+ writeFailure(writer, 1, "invalid_request", "Bridge request is invalid");
389
+ return;
390
+ }
318
391
  }
319
392
  try {
320
393
  if (request.method.equals("shutdown")) {
@@ -356,6 +429,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
356
429
  return switch (request.method) {
357
430
  case "inspect_native_load_image" -> inspectNativeLoadImage(request.params);
358
431
  case "read_bytes" -> readMemoryBytes(request.params);
432
+ case "search_bytes" -> searchMemoryBytes(request.params, descriptor);
359
433
  case "address_to_file_offset" -> addressToFileOffset(request.params);
360
434
  case "address_name" -> addressName(request.params);
361
435
  case "list_documents" -> listDocuments(request.params);
@@ -375,12 +449,14 @@ public final class ReaGhidraBridge extends HeadlessScript {
375
449
  case "search_procedures" -> search(request.params, true);
376
450
  case "search_strings" -> search(request.params, false);
377
451
  case "inspect_native_data_type" -> inspectNativeDataType(request.params);
378
- case "inspect_native_instruction" -> inspectNativeInstruction(request.params);
452
+ case "inspect_native_instruction" -> inspectNativeInstruction(request.params, true);
379
453
  case "resolve_native_call_targets" -> resolveNativeCallTargets(request.params);
380
454
  case "xrefs" -> xrefs(request.params);
381
455
  case "analyze_function" -> {
382
456
  FunctionAnalysisObservation observation = analyzeFunctionObservation(request.params);
383
- yield functionObservation(observation.dossier(), observation.limitations());
457
+ JsonObject result = functionObservation(observation.dossier(), observation.limitations());
458
+ result.add("relationship_coverage", observation.relationshipCoverage());
459
+ yield result;
384
460
  }
385
461
  case "set_address_name", "set_addresses_names" -> {
386
462
  if (!descriptor.transport.equals("unix-socket"))
@@ -436,6 +512,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
436
512
  .toArray(String[]::new)
437
513
  ));
438
514
  result.add("target", target);
515
+ result.add("pdb", pdbObservation());
439
516
  JsonArray extensions = analysisExtensions.reports();
440
517
  if (extensions.size() > 0) result.add("analysis_extensions", extensions);
441
518
  // Written by ReaGhidraApplySeeds before auto-analysis; REA checks it
@@ -443,9 +520,49 @@ public final class ReaGhidraBridge extends HeadlessScript {
443
520
  String seeds = currentProgram.getOptions(ghidra.program.model.listing.Program.PROGRAM_INFO)
444
521
  .getString("REA analysis seeds", null);
445
522
  if (seeds != null) result.add("analysis_seeds", JsonParser.parseString(seeds));
523
+ // Written by ReaGhidraMipsSoftFloat after analysis; REA requires it
524
+ // exactly when the committed profile declares soft-float storage.
525
+ String softFloat = currentProgram.getOptions(ghidra.program.model.listing.Program.PROGRAM_INFO)
526
+ .getString("REA MIPS soft-float storage", null);
527
+ if (softFloat != null) result.add("mips_soft_float_storage", JsonParser.parseString(softFloat));
446
528
  return result;
447
529
  }
448
530
 
531
+ /** Read loader/analyzer-owned facts without searching for or applying companions. */
532
+ private JsonObject pdbObservation() {
533
+ Options info = currentProgram.getOptions(ghidra.program.model.listing.Program.PROGRAM_INFO);
534
+ JsonObject pdb = new JsonObject();
535
+ String[] names = {"file", "guid", "age", "signature", "version"};
536
+ String[] attributes = {
537
+ PdbParserConstants.PDB_FILE, PdbParserConstants.PDB_GUID,
538
+ PdbParserConstants.PDB_AGE, PdbParserConstants.PDB_SIGNATURE,
539
+ PdbParserConstants.PDB_VERSION
540
+ };
541
+ int remaining = PDB_ATTRIBUTE_UTF16_BUDGET;
542
+ JsonArray omitted = new JsonArray();
543
+ for (int index = 0; index < names.length; index++) {
544
+ String value = info.getString(attributes[index], null);
545
+ if (value != null && value.length() > remaining) {
546
+ omitted.add(names[index]);
547
+ pdb.add(names[index], JsonNull.INSTANCE);
548
+ } else {
549
+ pdb.addProperty(names[index], value);
550
+ if (value != null) remaining -= value.length();
551
+ }
552
+ }
553
+ if (omitted.size() > 0) {
554
+ JsonObject limit = new JsonObject();
555
+ limit.addProperty("utf16_budget", PDB_ATTRIBUTE_UTF16_BUDGET);
556
+ limit.add("omitted_attributes", omitted);
557
+ pdb.add("resource_limit", limit);
558
+ }
559
+ if (info.contains(PdbParserConstants.PDB_LOADED))
560
+ pdb.addProperty("loaded", info.getBoolean(PdbParserConstants.PDB_LOADED, false));
561
+ else
562
+ pdb.add("loaded", JsonNull.INSTANCE);
563
+ return pdb;
564
+ }
565
+
449
566
  private static String bytesHex(byte[] bytes) {
450
567
  return java.util.HexFormat.of().formatHex(bytes);
451
568
  }
@@ -621,24 +738,173 @@ public final class ReaGhidraBridge extends HeadlessScript {
621
738
  return result;
622
739
  }
623
740
 
624
- private JsonObject addressToFileOffset(JsonObject params) {
741
+ private JsonObject searchMemoryBytes(JsonObject params, SessionDescriptor descriptor) throws Exception {
742
+ // mask, start, end, and cursor are omitted when absent; JSON encoding drops those keys.
743
+ Set<String> keys = params.keySet();
744
+ if (!keys.containsAll(Set.of("document", "pattern", "limit")) ||
745
+ !Set.of("document", "pattern", "mask", "start", "end", "limit", "cursor").containsAll(keys))
746
+ throw new RequestFailure("invalid_request", "Bridge request fields are invalid");
747
+ requireDocument(params);
748
+ // Public input validation owns the grammar; validate again at the socket boundary.
749
+ String pattern = requireString(params, "pattern").replaceAll("[\\s\\p{Z}\\uFEFF]", "");
750
+ String mask = params.has("mask") ? requireString(params, "mask") : null;
751
+ if (mask != null) mask = mask.replaceAll("[\\s\\p{Z}\\uFEFF]", "");
752
+ if (pattern.isEmpty() || pattern.length() % 2 != 0 ||
753
+ (mask != null && mask.length() != pattern.length()))
754
+ throw new RequestFailure("invalid_request", "Mask length must equal a nonempty byte pattern length");
755
+ byte[] bytes = new byte[pattern.length() / 2];
756
+ byte[] masks = new byte[bytes.length];
757
+ boolean constrained = false;
758
+ for (int index = 0; index < bytes.length; index++) {
759
+ monitor.checkCancelled();
760
+ String pair = pattern.substring(index * 2, index * 2 + 2);
761
+ if ((!pair.equals("??") && !isHexadecimal(pair, 0, 2)) ||
762
+ (mask != null && !isHexadecimal(mask, index * 2, index * 2 + 2)))
763
+ throw new RequestFailure("invalid_request", "Use hexadecimal byte pairs or ?? wildcards");
764
+ int selected = mask == null ? 255 : Integer.parseInt(mask.substring(index * 2, index * 2 + 2), 16);
765
+ bytes[index] = (byte) (pair.equals("??") ? 0 : Integer.parseInt(pair, 16));
766
+ masks[index] = (byte) (pair.equals("??") ? 0 : selected);
767
+ constrained |= masks[index] != 0;
768
+ }
769
+ if (!constrained) throw new RequestFailure("invalid_request", "Pattern must constrain at least one bit");
770
+ int limit = requireBoundedInteger(params, "limit", 1, 1000);
771
+ Address start = params.has("start") ? requireAddress(params, "start") : null;
772
+ Address end = params.has("end") ? requireAddress(params, "end") : null;
773
+ if (start != null && end != null &&
774
+ (!start.getAddressSpace().equals(end.getAddressSpace()) || start.compareTo(end) > 0))
775
+ throw new RequestFailure("invalid_request", "Search bounds must be ordered in one address space");
776
+ JsonArray identity = new JsonArray();
777
+ for (String value : new String[] { descriptor.targetSha256, descriptor.profileDigest,
778
+ bytesHex(bytes), bytesHex(masks), start == null ? "" : canonicalAddress(start),
779
+ end == null ? "" : canonicalAddress(end), optionalString(params, "document") }) identity.add(value);
780
+ String binding = bytesHex(MessageDigest.getInstance("SHA-256").digest(identity.toString().getBytes(StandardCharsets.UTF_8)));
781
+ String cursor = params.has("cursor") ? requireString(params, "cursor") : null;
782
+ Address resume = null;
783
+ if (cursor != null) {
784
+ if (!cursor.startsWith(binding + ":"))
785
+ throw new RequestFailure("invalid_request", "Byte search cursor does not match the target and query");
786
+ resume = parseReaAddress(cursor.substring(binding.length() + 1));
787
+ MemoryBlock resumedBlock = currentProgram.getMemory().getBlock(resume);
788
+ Address bound = start == null ? end : start;
789
+ if (resumedBlock == null || !resumedBlock.isInitialized() ||
790
+ (bound != null && !bound.getAddressSpace().equals(resume.getAddressSpace())) ||
791
+ (start != null && resume.compareTo(start) < 0) ||
792
+ (end != null && resume.compareTo(end) > 0))
793
+ throw new RequestFailure("invalid_request", "Byte search cursor lies outside initialized query memory");
794
+ }
795
+ List<MemoryBlock> ordered = new ArrayList<>(List.of(currentProgram.getMemory().getBlocks()));
796
+ ordered.sort(Comparator.comparing(MemoryBlock::getStart));
797
+ JsonArray matches = new JsonArray();
798
+ JsonArray blocks = new JsonArray();
799
+ JsonArray skipped = new JsonArray();
800
+ JsonArray notLoaded = new JsonArray();
801
+ long covered = 0;
802
+ String next = null;
803
+ for (MemoryBlock block : ordered) {
804
+ monitor.checkCancelled();
805
+ Address low = block.getStart();
806
+ Address high = block.getEnd();
807
+ Address bound = start == null ? end : start;
808
+ if (bound != null && !bound.getAddressSpace().equals(low.getAddressSpace())) continue;
809
+ // Without bounds, search loaded memory only. Non-loaded file parts
810
+ // (such as .symtab) and overlays stay reachable through explicit bounds.
811
+ if (bound == null && (!block.isLoaded() || block.isOverlay())) {
812
+ notLoaded.add(byteSearchCoverage(block, low, high));
813
+ continue;
814
+ }
815
+ if (start != null && low.compareTo(start) < 0) low = start;
816
+ if (end != null && high.compareTo(end) > 0) high = end;
817
+ if (low.compareTo(high) > 0) continue;
818
+ if (!block.isInitialized()) {
819
+ skipped.add(byteSearchCoverage(block, low, high));
820
+ continue;
821
+ }
822
+ if (next != null) continue;
823
+ if (resume != null && low.compareTo(resume) < 0) low = resume;
824
+ if (low.compareTo(high) > 0 || !low.getAddressSpace().equals(high.getAddressSpace())) continue;
825
+ Address at = low;
826
+ Address examinedEnd = high;
827
+ while (at != null && at.compareTo(high) <= 0 && high.subtract(at) >= bytes.length - 1L) {
828
+ monitor.checkCancelled();
829
+ // Ghidra's end address bounds candidate starts, not the final matched byte.
830
+ Address found = currentProgram.getMemory().findBytes(at, high.subtract(bytes.length - 1L), bytes, masks, true, monitor);
831
+ monitor.checkCancelled();
832
+ if (found == null || high.subtract(found) < bytes.length - 1L) break;
833
+ if (matches.size() == limit) {
834
+ next = binding + ":" + canonicalAddress(found);
835
+ examinedEnd = found.addNoWrap(bytes.length - 1L);
836
+ break;
837
+ }
838
+ JsonObject match = new JsonObject();
839
+ match.addProperty("address", canonicalAddress(found));
840
+ match.addProperty("segment", block.getName());
841
+ Long offset = targetFileOffset(block, found).offset();
842
+ match.add("file_offset", offset == null ? JsonNull.INSTANCE : GSON.toJsonTree(offset));
843
+ Function function = currentProgram.getFunctionManager().getFunctionContaining(found);
844
+ JsonObject procedure = new JsonObject();
845
+ if (function != null) {
846
+ procedure.addProperty("address", canonicalAddress(function.getEntryPoint()));
847
+ procedure.addProperty("name", function.getName(true));
848
+ }
849
+ match.add("procedure", function == null ? JsonNull.INSTANCE : procedure);
850
+ matches.add(match);
851
+ at = found.next();
852
+ }
853
+ JsonObject coverage = byteSearchCoverage(block, low, examinedEnd);
854
+ covered = Math.addExact(covered, coverage.get("bytes").getAsLong());
855
+ blocks.add(coverage);
856
+ }
857
+ JsonObject searched = new JsonObject();
858
+ searched.add("blocks", blocks);
859
+ searched.addProperty("bytes", covered);
860
+ searched.add("skipped_uninitialized", skipped);
861
+ searched.add("skipped_not_loaded", notLoaded);
862
+ JsonObject result = new JsonObject();
863
+ result.add("matches", matches);
864
+ result.add("searched", searched);
865
+ result.addProperty("complete", next == null);
866
+ result.add("next_cursor", next == null ? JsonNull.INSTANCE : GSON.toJsonTree(next));
867
+ return result;
868
+ }
869
+
870
+ private static JsonObject byteSearchCoverage(MemoryBlock block, Address low, Address high) {
871
+ JsonObject result = new JsonObject();
872
+ result.addProperty("segment", block.getName());
873
+ result.addProperty("start", canonicalAddress(low));
874
+ result.addProperty("end", canonicalAddress(high));
875
+ result.addProperty("bytes", high.subtract(low) + 1);
876
+ return result;
877
+ }
878
+
879
+ private record TargetFileOffset(Long offset, int mappings) {}
880
+
881
+ private TargetFileOffset targetFileOffset(MemoryBlock block, Address address) throws Exception {
882
+ Long offset = null;
883
+ int mappings = 0;
884
+ for (MemoryBlockSourceInfo source : block.getSourceInfos()) {
885
+ if (!source.contains(address) || source.getFileBytes().isEmpty() ||
886
+ !isTargetSource(source.getFileBytes().get())) continue;
887
+ long candidate = source.getFileBytesOffset(address);
888
+ if (candidate < 0) continue;
889
+ offset = candidate;
890
+ mappings++;
891
+ }
892
+ return new TargetFileOffset(mappings == 1 && offset <= 9007199254740991L ? offset : null, mappings);
893
+ }
894
+
895
+ private JsonObject addressToFileOffset(JsonObject params) throws Exception {
625
896
  requireKeys(params, Set.of("document", "address"));
626
897
  requireDocument(params);
627
898
  Address address = requireAddress(params, "address");
628
899
  MemoryBlock block = currentProgram.getMemory().getBlock(address);
629
900
  if (block == null || !block.isInitialized())
630
901
  throw new RequestFailure("invalid_request", "Address has no initialized file-backed memory: " + canonicalAddress(address));
631
- Long fileOffset = null;
632
- int mappings = 0;
633
- for (MemoryBlockSourceInfo source : block.getSourceInfos()) {
634
- if (!source.contains(address) || source.getFileBytes().isEmpty()) continue;
635
- long offset = source.getFileBytesOffset(address);
636
- if (offset < 0) continue;
637
- fileOffset = offset;
638
- mappings++;
639
- }
640
- if (mappings != 1)
641
- throw new RequestFailure("invalid_request", "Address has " + mappings + " authoritative source mappings: " + canonicalAddress(address));
902
+ TargetFileOffset mapping = targetFileOffset(block, address);
903
+ if (mapping.mappings() != 1)
904
+ throw new RequestFailure("invalid_request", "Address has " + mapping.mappings() + " authoritative target-file mappings: " + canonicalAddress(address));
905
+ Long fileOffset = mapping.offset();
906
+ if (fileOffset == null)
907
+ throw new RequestFailure("invalid_request", "Address lacks a safe file offset: " + canonicalAddress(address));
642
908
  JsonObject result = new JsonObject();
643
909
  result.addProperty("address", canonicalAddress(address));
644
910
  result.addProperty("file_offset", fileOffset);
@@ -661,14 +927,97 @@ public final class ReaGhidraBridge extends HeadlessScript {
661
927
  private JsonElement procedurePseudocode(JsonObject params) throws Exception {
662
928
  requireKeys(params, Set.of("document", "procedure"));
663
929
  requireDocument(params);
664
- Function function = resolveProcedure(requireString(params, "procedure"));
665
- String value = decompiledText(decompile(function));
666
- return functionObservation(
667
- value == null ? JsonNull.INSTANCE : GSON.toJsonTree(value),
668
- noReturnCallLimitations(
669
- currentProgram.getListing().getInstructions(function.getBody(), true)
670
- )
671
- );
930
+ String selector = requireString(params, "procedure");
931
+ JsonObject selection = new JsonObject();
932
+ Function function = resolveDecompileProcedure(selector, selection);
933
+ try {
934
+ String value = decompiledText(decompile(function));
935
+ JsonObject result = functionObservation(
936
+ value == null ? JsonNull.INSTANCE : GSON.toJsonTree(value),
937
+ noReturnCallLimitations(
938
+ function,
939
+ currentProgram.getListing().getInstructions(function.getBody(), true)
940
+ )
941
+ );
942
+ if (selection.size() > 0) result.add("selection", selection);
943
+ return result;
944
+ } catch (RequestFailure failure) {
945
+ if (selection.size() == 0) throw failure;
946
+ // Preserve completed resolution facts without changing the backend's
947
+ // failure code or suggesting that the successful mapping was invalid.
948
+ throw new RequestFailure(failure.code, "Selector " + selector +
949
+ " mapped to analysis address " + selection.get("mapped_address").getAsString() +
950
+ " and procedure " + canonicalAddress(function.getEntryPoint()) +
951
+ "; " + failure.getMessage());
952
+ }
953
+ }
954
+
955
+ private Function resolveDecompileProcedure(String selector, JsonObject selection) throws Exception {
956
+ String prefix = "file-offset:";
957
+ boolean explicitOffset = selector.startsWith(prefix);
958
+ if (!explicitOffset) {
959
+ try {
960
+ return resolveProcedure(selector);
961
+ } catch (RequestFailure failure) {
962
+ // Existing names/addresses win. Only an unresolved numeric input
963
+ // can fall back to source coordinates; ambiguity never falls back.
964
+ if (!failure.code.equals("not_found") || !selector.matches("0x[0-9a-fA-F]+"))
965
+ throw failure;
966
+ }
967
+ }
968
+ String coordinate = explicitOffset ? selector.substring(prefix.length()) : selector;
969
+ if (!coordinate.matches("0x[0-9a-fA-F]+"))
970
+ throw new RequestFailure("invalid_request", "File offsets require hexadecimal file-offset:0x... syntax");
971
+ BigInteger parsed = new BigInteger(coordinate.substring(2), 16);
972
+ if (parsed.compareTo(BigInteger.valueOf(9007199254740991L)) > 0)
973
+ throw new RequestFailure("invalid_request", "File offset exceeds the exact JSON integer range");
974
+ long offset = parsed.longValueExact();
975
+ monitor.checkCancelled();
976
+ // Ghidra's convenience lookup spans every FileBytes and uses coordinates
977
+ // local to each object. Only a complete, digest-matched target source
978
+ // establishes that the caller's offset belongs to the admitted file.
979
+ Set<Address> mappedAddresses = new java.util.LinkedHashSet<>();
980
+ for (MemoryBlock block : currentProgram.getMemory().getBlocks()) {
981
+ for (MemoryBlockSourceInfo source : block.getSourceInfos()) {
982
+ monitor.checkCancelled();
983
+ FileBytes backing = source.getFileBytes().orElse(null);
984
+ if (backing == null || !isTargetSource(backing)) continue;
985
+ Address mapped = source.locateAddressForFileOffset(offset);
986
+ if (mapped != null) mappedAddresses.add(mapped);
987
+ }
988
+ }
989
+ List<Address> candidates = new ArrayList<>(mappedAddresses);
990
+ if (candidates.size() > 1)
991
+ throw new RequestFailure("ambiguous", "File offset " + coordinate +
992
+ " has multiple loaded mappings: " + candidates.stream().map(ReaGhidraBridge::canonicalAddress).toList() +
993
+ "; select an explicit analysis address");
994
+ if (candidates.isEmpty())
995
+ throw new RequestFailure("not_found", "File offset " + coordinate +
996
+ " has no loaded source mapping for the admitted target file; Ghidra image base: " + canonicalAddress(currentProgram.getImageBase()) +
997
+ ". Inspect mappings with rea inspect-native-load-image <path> --provider ghidra --json or MCP inspect_native_load_image.");
998
+ Address mapped = candidates.get(0);
999
+ Function function = functionAtOrContaining(mapped);
1000
+ if (function == null)
1001
+ throw new RequestFailure("not_found", "File offset " + coordinate +
1002
+ " maps to analysis address " + canonicalAddress(mapped) +
1003
+ ", but no procedure starts at or contains that address in the current Ghidra analysis. " +
1004
+ "Choose an observed procedure with CLI rea search <path> . --kind procedures --mode regex --provider ghidra --json or MCP list_procedures.");
1005
+ selection.addProperty("file_offset", offset);
1006
+ selection.addProperty("mapped_address", canonicalAddress(mapped));
1007
+ selection.addProperty("procedure_address", canonicalAddress(function.getEntryPoint()));
1008
+ return function;
1009
+ }
1010
+
1011
+ private boolean isTargetSource(FileBytes source) throws Exception {
1012
+ Boolean observed = targetSourceIdentity.get(source);
1013
+ if (observed != null) return observed;
1014
+ // Original FileBytes are immutable even when analysis memory is edited.
1015
+ // Partial/auxiliary sources remain inspectable but cannot establish an
1016
+ // original-target offset from their object-local coordinates alone.
1017
+ boolean matched = source.getFileOffset() == 0 &&
1018
+ constantTimeEquals(hashFileBytes(source, false), admittedTargetSha256);
1019
+ targetSourceIdentity.put(source, matched);
1020
+ return matched;
672
1021
  }
673
1022
 
674
1023
  private JsonElement procedureAssembly(JsonObject params) throws Exception {
@@ -678,7 +1027,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
678
1027
  InstructionScan scan = scanInstructions(function, Integer.MAX_VALUE);
679
1028
  return functionObservation(
680
1029
  GSON.toJsonTree(renderAssembly(scan.instructions)),
681
- noReturnCallLimitations(scan.instructions)
1030
+ noReturnCallLimitations(function, scan.instructions)
682
1031
  );
683
1032
  }
684
1033
 
@@ -697,7 +1046,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
697
1046
  limitations.add(
698
1047
  "The fast path does not invoke the decompiler or scan whole-program names and strings."
699
1048
  );
700
- List<String> boundaryLimitations = noReturnCallLimitations(scan.instructions);
1049
+ List<String> boundaryLimitations = noReturnCallLimitations(function, scan.instructions);
701
1050
  for (String limitation : boundaryLimitations) limitations.add(limitation);
702
1051
  JsonObject result = new JsonObject();
703
1052
  result.add("procedure", procedureIdentity(function));
@@ -706,7 +1055,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
706
1055
  return functionObservation(result, boundaryLimitations);
707
1056
  }
708
1057
 
709
- private JsonArray procedureCalls(JsonObject params, boolean callers) throws Exception {
1058
+ private JsonObject procedureCalls(JsonObject params, boolean callers) throws Exception {
710
1059
  requireKeys(params, Set.of("document", "procedure"));
711
1060
  requireDocument(params);
712
1061
  Function function = resolveProcedure(requireString(params, "procedure"));
@@ -719,7 +1068,19 @@ public final class ReaGhidraBridge extends HeadlessScript {
719
1068
  for (Function item : ordered) {
720
1069
  result.add(canonicalAddress(item.getEntryPoint()));
721
1070
  }
722
- return result;
1071
+ if (callers) {
1072
+ JsonObject observation = functionObservation(result, noReturnCallLimitations(function,
1073
+ currentProgram.getListing().getInstructions(function.getBody(), true)
1074
+ ));
1075
+ observation.add("relationship_coverage", callRelationshipCoverage(null,
1076
+ unrepresentedIncomingCalls(function, observed)));
1077
+ monitor.checkCancelled();
1078
+ return observation;
1079
+ }
1080
+ CallBoundaryObservation calls = callBoundaryObservation(
1081
+ function, currentProgram.getListing().getInstructions(function.getBody(), true), observed, false, null
1082
+ );
1083
+ return callRelationshipObservation(result, calls);
723
1084
  }
724
1085
 
725
1086
  private JsonObject procedureInfo(JsonObject params) throws Exception {
@@ -739,6 +1100,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
739
1100
  return functionObservation(
740
1101
  result,
741
1102
  noReturnCallLimitations(
1103
+ function,
742
1104
  currentProgram.getListing().getInstructions(function.getBody(), true)
743
1105
  )
744
1106
  );
@@ -769,18 +1131,10 @@ public final class ReaGhidraBridge extends HeadlessScript {
769
1131
  result.addProperty("direction", direction);
770
1132
  result.add("references", edges);
771
1133
  result.addProperty("reference_kinds_available", true);
772
- JsonArray unresolvedCalls = new JsonArray();
773
- if (direction.equals("outgoing")) for (Instruction instruction : scanInstructions(function, Integer.MAX_VALUE).instructions) {
774
- if (!instruction.getFlowType().isCall()) continue;
775
- boolean resolved = false;
776
- for (Reference reference : instruction.getReferencesFrom()) if (reference.getReferenceType().isCall()) resolved = true;
777
- if (!resolved) {
778
- JsonObject site = new JsonObject();
779
- site.addProperty("address", canonicalAddress(instruction.getAddress()));
780
- site.addProperty("reason", "Instruction decoder identifies a call but ReferenceManager supplies no call destination");
781
- unresolvedCalls.add(site);
782
- }
783
- }
1134
+ JsonArray unresolvedCalls = direction.equals("outgoing")
1135
+ ? callBoundaryObservation(
1136
+ function, currentProgram.getListing().getInstructions(function.getBody(), true), null, true, references
1137
+ ).unresolvedCalls() : new JsonArray();
784
1138
  result.add("unresolved_calls", unresolvedCalls);
785
1139
  return result;
786
1140
  }
@@ -885,7 +1239,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
885
1239
  return item;
886
1240
  }
887
1241
 
888
- private JsonObject inspectNativeInstruction(JsonObject params) throws Exception {
1242
+ private JsonObject inspectNativeInstruction(JsonObject params, boolean includeIncoming) throws Exception {
889
1243
  requireKeys(params, Set.of("document", "address"));
890
1244
  requireDocument(params);
891
1245
  Address address = requireAddress(params, "address");
@@ -896,6 +1250,19 @@ public final class ReaGhidraBridge extends HeadlessScript {
896
1250
  result.add("procedure", function == null ? JsonNull.INSTANCE : GSON.toJsonTree(canonicalAddress(function.getEntryPoint())));
897
1251
  result.addProperty("architecture", currentProgram.getLanguageID().getIdAsString());
898
1252
  result.addProperty("mode", currentProgram.getLanguage().getLanguageDescription().getVariant());
1253
+ if (currentProgram.getLanguageID().getIdAsString().startsWith("MIPS:")) {
1254
+ JsonArray decoderContext = new JsonArray();
1255
+ var modeRegister = currentProgram.getRegister("ISA_MODE");
1256
+ if (modeRegister != null) {
1257
+ var modeValue = currentProgram.getProgramContext().getValue(modeRegister, address, false);
1258
+ JsonObject context = new JsonObject();
1259
+ context.addProperty("register", modeRegister.getName());
1260
+ context.add("value", modeValue == null ? JsonNull.INSTANCE : GSON.toJsonTree(modeValue.toString()));
1261
+ context.addProperty("source", "ghidra-program-context");
1262
+ decoderContext.add(context);
1263
+ }
1264
+ result.add("decoder_context", decoderContext);
1265
+ }
899
1266
  JsonArray operands = new JsonArray();
900
1267
  JsonArray references = new JsonArray();
901
1268
  JsonArray destinations = new JsonArray();
@@ -968,6 +1335,19 @@ public final class ReaGhidraBridge extends HeadlessScript {
968
1335
  result.add("operands", operands);
969
1336
  result.add("flow", flow);
970
1337
  result.add("references", references);
1338
+ if (includeIncoming) {
1339
+ TreeMap<String, Reference> incoming = new TreeMap<>();
1340
+ ReferenceIterator incomingIterator = currentProgram.getReferenceManager().getReferencesTo(address);
1341
+ while (incomingIterator.hasNext()) {
1342
+ monitor.checkCancelled();
1343
+ addReference(incoming, incomingIterator.next());
1344
+ }
1345
+ List<Reference> orderedIncoming = new ArrayList<>(incoming.values());
1346
+ orderedIncoming.sort(REFERENCE_ORDER);
1347
+ JsonArray incomingReferences = new JsonArray();
1348
+ for (Reference reference : orderedIncoming) incomingReferences.add(instructionReference(reference));
1349
+ result.add("incoming_references", incomingReferences);
1350
+ }
971
1351
  List<String> limitations = new ArrayList<>(List.of("Operand components are Ghidra Listing decoder tokens; effective memory base/index/displacement roles and per-instruction context mode are unavailable. The mode field is the program language variant."));
972
1352
  if (flow.get("kind").getAsString().equals("terminal")) limitations.add("No RETURN operation was observed in the provider's instruction p-code; terminal classification remains generic.");
973
1353
  result.add("limitations", GSON.toJsonTree(limitations));
@@ -975,7 +1355,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
975
1355
  }
976
1356
 
977
1357
  private JsonObject resolveNativeCallTargets(JsonObject params) throws Exception {
978
- JsonObject instruction = inspectNativeInstruction(params);
1358
+ JsonObject instruction = inspectNativeInstruction(params, false);
979
1359
  JsonObject result = new JsonObject();
980
1360
  result.add("call_site", instruction.get("address"));
981
1361
  result.add("procedure", instruction.get("procedure"));
@@ -1162,19 +1542,28 @@ public final class ReaGhidraBridge extends HeadlessScript {
1162
1542
  InstructionScan scan = scanInstructions(function, Integer.MAX_VALUE);
1163
1543
  DecompileResults decompilation = decompile(function);
1164
1544
  String pseudocode = decompiledText(decompilation);
1545
+ JsonObject availability = new JsonObject();
1546
+ availability.add("pseudocode", facetAvailability(
1547
+ pseudocode != null,
1548
+ function.isExternal() ? "Ghidra does not decompile external functions."
1549
+ : function.getBody().isEmpty() ? "Ghidra has no function body to decompile."
1550
+ : "Ghidra completed decompilation without returning pseudocode."
1551
+ ));
1165
1552
  if (pseudocode == null) {
1166
1553
  pseudocode = "";
1167
1554
  }
1168
- List<Reference> incomingReferences = collectReferences(function, "incoming")
1169
- .stream()
1555
+ List<Reference> bodyIncoming = collectReferences(function, "incoming");
1556
+ List<Reference> incomingReferences = bodyIncoming.stream()
1170
1557
  .filter(reference -> !function.getBody().contains(reference.getFromAddress()))
1171
1558
  .toList();
1172
1559
  List<Reference> outgoingReferences = collectReferences(function, "outgoing");
1173
1560
  JsonArray incoming = referenceEdges(incomingReferences);
1174
1561
  JsonArray outgoing = referenceEdges(outgoingReferences);
1175
- JsonArray comments = comments(scan.instructions);
1176
- JsonArray callers = procedureIdentities(function.getCallingFunctions(monitor));
1177
- JsonArray callees = procedureIdentities(function.getCalledFunctions(monitor));
1562
+ JsonArray comments = comments(function);
1563
+ Set<Function> callerFunctions = function.getCallingFunctions(monitor);
1564
+ JsonArray callers = procedureIdentities(callerFunctions);
1565
+ Set<Function> calleeFunctions = function.getCalledFunctions(monitor);
1566
+ JsonArray callees = procedureIdentities(calleeFunctions);
1178
1567
  JsonArray referencedStrings = referencedStrings(outgoingReferences);
1179
1568
  JsonArray referencedNames = referencedNames(outgoingReferences);
1180
1569
  JsonArray blocks = basicBlockValues(function);
@@ -1195,12 +1584,28 @@ public final class ReaGhidraBridge extends HeadlessScript {
1195
1584
  result.add("outgoing_references", outgoing);
1196
1585
  result.add("referenced_strings", referencedStrings);
1197
1586
  result.add("referenced_names", referencedNames);
1587
+ boolean swift = swiftProgram();
1588
+ boolean aarch64 = currentProgram.getLanguageID().getIdAsString().startsWith("AARCH64:");
1589
+ SwiftStringLiteralDecode swiftLiterals = swift && aarch64 ? swiftStringLiterals(function) : null;
1590
+ if (swiftLiterals != null) {
1591
+ result.add("swift_string_literals", swiftLiterals.literals());
1592
+ result.add("swift_string_literal_omissions", swiftLiterals.omissions());
1593
+ }
1198
1594
  result.add("basic_blocks", blocks);
1199
1595
  result.add(
1200
1596
  "native_api",
1201
1597
  nativeApiBoundary(function, decompilation)
1202
1598
  );
1203
1599
  result.add("native_value_flow", nativeValueFlow(decompilation));
1600
+ // Successful full queries distinguish collected empty sets from missing facts.
1601
+ // Availability does not claim that Ghidra resolved every runtime relationship.
1602
+ for (String facet : List.of("comments", "callers", "callees", "references", "strings_names", "cfg")) {
1603
+ availability.add(facet, facetAvailability(true, null));
1604
+ }
1605
+ availability.add("assembly", facetAvailability(
1606
+ !scan.truncated(), "The function instruction scan was truncated."
1607
+ ));
1608
+ result.add("facet_availability", availability);
1204
1609
  JsonArray limitations = new JsonArray();
1205
1610
  limitations.add(
1206
1611
  "Unresolved computed or indirect flows without target addresses are not represented as reference edges."
@@ -1214,8 +1619,24 @@ public final class ReaGhidraBridge extends HeadlessScript {
1214
1619
  limitations.add(
1215
1620
  "Synthetic Ghidra entry-point references without actionable memory sources are omitted."
1216
1621
  );
1217
- List<String> boundaryLimitations = noReturnCallLimitations(scan.instructions);
1218
- for (String limitation : boundaryLimitations) {
1622
+ if (swift && aarch64) {
1623
+ limitations.add(
1624
+ "Swift String literals are decoded from constant register pairs at calls, returns and paired stores. Literals stored one word at a time, chosen by conditional selects, or built at runtime are not reported; candidate pairs at unresolved jumps are retained as unknown omissions."
1625
+ );
1626
+ if (swiftLiterals.omissions().size() > 0) {
1627
+ limitations.add(
1628
+ "Swift String literal records listed in swift_string_literal_omissions could not be retained or decoded within this dossier's remaining heap budget; later symbolic flows remain unexamined."
1629
+ );
1630
+ }
1631
+ } else if (swift) {
1632
+ limitations.add(
1633
+ "Swift String literal decoding is implemented for AArch64 register pairs only; no Swift literals were decoded for this architecture."
1634
+ );
1635
+ }
1636
+ CallBoundaryObservation calls = callBoundaryObservation(
1637
+ function, scan.instructions, calleeFunctions, true, outgoingReferences);
1638
+ result.add("unresolved_calls", calls.unresolvedCalls());
1639
+ for (String limitation : calls.limitations()) {
1219
1640
  limitations.add(limitation);
1220
1641
  }
1221
1642
  if (decompilation != null && decompilation.getErrorMessage() != null &&
@@ -1223,7 +1644,14 @@ public final class ReaGhidraBridge extends HeadlessScript {
1223
1644
  limitations.add("Ghidra decompiler diagnostic: " + decompilation.getErrorMessage());
1224
1645
  }
1225
1646
  result.add("limitations", limitations);
1226
- return new FunctionAnalysisObservation(result, boundaryLimitations);
1647
+ monitor.checkCancelled();
1648
+ int missingCallers = 0;
1649
+ for (Reference reference : bodyIncoming) {
1650
+ monitor.checkCancelled();
1651
+ if (unrepresentedCaller(reference, callerFunctions)) missingCallers++;
1652
+ }
1653
+ return new FunctionAnalysisObservation(result, calls.limitations(),
1654
+ callRelationshipCoverage(calls, missingCallers));
1227
1655
  }
1228
1656
 
1229
1657
  private JsonObject nativeValueFlow(DecompileResults decompilation) throws Exception {
@@ -1795,14 +2223,25 @@ public final class ReaGhidraBridge extends HeadlessScript {
1795
2223
  Address address = explicitAddress ? parseReaAddress(value) : tryParseAddress(value);
1796
2224
  if (address == null)
1797
2225
  throw new RequestFailure("not_found", "Unknown Ghidra procedure name or address: " + value);
1798
- Function function = currentProgram.getFunctionManager().getFunctionAt(address);
1799
- if (function == null && address.isMemoryAddress())
1800
- function = currentProgram.getFunctionManager().getFunctionContaining(address);
2226
+ Function function = functionAtOrContaining(address);
1801
2227
  if (function == null)
1802
- throw new RequestFailure("not_found", "No procedure exists at the requested address: " + value);
2228
+ // Other procedure operations retain their analysis-address semantics.
2229
+ throw new RequestFailure("not_found", "No procedure exists at the requested address: " + value +
2230
+ "; Ghidra image base: " + canonicalAddress(currentProgram.getImageBase()) +
2231
+ ". Choose an observed analysis address. CLI: rea search <path> . --kind procedures --mode regex --provider ghidra --json; " +
2232
+ "MCP: list_procedures. Inspect the loaded base and source mappings with CLI rea analyze <path> --provider ghidra --json " +
2233
+ "and rea inspect-native-load-image <path> --provider ghidra --json, or MCP binary_overview and inspect_native_load_image. " +
2234
+ "Repeat the original target options. For decompile, select source coordinates explicitly with --file-offset=0x... or MCP procedure file-offset:0x....");
1803
2235
  return function;
1804
2236
  }
1805
2237
 
2238
+ private Function functionAtOrContaining(Address address) {
2239
+ Function function = currentProgram.getFunctionManager().getFunctionAt(address);
2240
+ return function == null && address.isMemoryAddress()
2241
+ ? currentProgram.getFunctionManager().getFunctionContaining(address)
2242
+ : function;
2243
+ }
2244
+
1806
2245
  private JsonObject nativeApiBoundary(
1807
2246
  Function function,
1808
2247
  DecompileResults decompilation
@@ -2916,52 +3355,274 @@ public final class ReaGhidraBridge extends HeadlessScript {
2916
3355
  return result;
2917
3356
  }
2918
3357
 
2919
- private List<String> noReturnCallLimitations(Iterable<Instruction> instructions)
3358
+ private static JsonObject facetAvailability(boolean available, String reason) {
3359
+ JsonObject result = new JsonObject();
3360
+ result.addProperty("available", available);
3361
+ if (!available) result.addProperty("reason", reason);
3362
+ return result;
3363
+ }
3364
+
3365
+ private JsonObject callRelationshipObservation(JsonElement value, CallBoundaryObservation calls)
3366
+ throws Exception {
3367
+ monitor.checkCancelled();
3368
+ JsonObject result = functionObservation(value, calls.limitations());
3369
+ result.add("relationship_coverage", callRelationshipCoverage(calls, null));
3370
+ return result;
3371
+ }
3372
+
3373
+ private static JsonObject callRelationshipCoverage(
3374
+ CallBoundaryObservation calls, Integer missingCallers) {
3375
+ JsonObject coverage = completeResolvedCallCoverage();
3376
+ Integer omitted = calls == null ? null : calls.unrepresentedCalleeCalls();
3377
+ JsonArray directions = new JsonArray();
3378
+ if (missingCallers != null && missingCallers > 0) directions.add("callers");
3379
+ String callerLimitation = missingCallers != null && missingCallers > 0
3380
+ ? "Ghidra's caller inventory omits sources of " + missingCallers +
3381
+ " call reference(s) into this function's body." : null;
3382
+ if ((calls != null && omitted == null) || (calls == null && missingCallers == null)) {
3383
+ coverage.addProperty("status", "unknown");
3384
+ String reason = calls == null ? "No call inventory was examined."
3385
+ : "The callee inventory was not examined alongside decoded call targets.";
3386
+ coverage.addProperty("reason", reason + (callerLimitation == null ? "" : " " + callerLimitation));
3387
+ if (calls == null && missingCallers == null) directions.add("callers");
3388
+ directions.add("callees");
3389
+ coverage.add("limited_directions", directions);
3390
+ return coverage;
3391
+ }
3392
+ JsonArray limitations = new JsonArray();
3393
+ if (callerLimitation != null) limitations.add(callerLimitation);
3394
+ if (omitted != null && omitted > 0) {
3395
+ limitations.add("Ghidra's callee inventory omits targets of " + omitted +
3396
+ " call reference(s) or decoded call(s) without destinations.");
3397
+ directions.add("callees");
3398
+ }
3399
+ if (!limitations.isEmpty()) {
3400
+ coverage.addProperty("status", "partial");
3401
+ coverage.add("limitations", limitations);
3402
+ coverage.add("limited_directions", directions);
3403
+ }
3404
+ return coverage;
3405
+ }
3406
+
3407
+ private static JsonObject completeResolvedCallCoverage() {
3408
+ JsonObject coverage = new JsonObject();
3409
+ coverage.addProperty("status", "complete");
3410
+ JsonArray diagnostics = new JsonArray();
3411
+ diagnostics.add(
3412
+ "Only resolved Ghidra call references are returned; unresolved computed or indirect calls remain unknown, while function classifications distinguish thunks and externals."
3413
+ );
3414
+ coverage.add("diagnostics", diagnostics);
3415
+ return coverage;
3416
+ }
3417
+
3418
+ private boolean unrepresentedCaller(Reference reference, Set<Function> callers) {
3419
+ if (!reference.getReferenceType().isCall()) return false;
3420
+ Function caller = containingFunction(reference.getFromAddress());
3421
+ return caller == null || !callers.contains(caller);
3422
+ }
3423
+
3424
+ private int unrepresentedIncomingCalls(Function function, Set<Function> callers)
3425
+ throws Exception {
3426
+ int[] omitted = { 0 };
3427
+ visitReferences(function, "incoming", reference -> {
3428
+ if (unrepresentedCaller(reference, callers)) omitted[0]++;
3429
+ });
3430
+ return omitted[0];
3431
+ }
3432
+
3433
+ private List<String> noReturnCallLimitations(
3434
+ Function function, Iterable<Instruction> instructions)
2920
3435
  throws Exception {
2921
3436
  List<String> limitations = new ArrayList<>();
3437
+ Instruction beforePrevious = null;
3438
+ Instruction previous = null;
2922
3439
  for (Instruction instruction : instructions) {
2923
3440
  monitor.checkCancelled();
2924
- if (!instruction.getFlowType().isCall() || !instruction.getFlowType().isTerminal()) {
2925
- continue;
3441
+ String limitation = terminalCallLimitation(instruction);
3442
+ if (limitation != null) limitations.add(limitation);
3443
+ if (beforePrevious != null && previous != null) {
3444
+ String seh = borlandSehHandlerLimitation(
3445
+ function, beforePrevious, previous, instruction);
3446
+ if (seh != null) limitations.add(seh);
2926
3447
  }
2927
- Address[] destinations = instruction.getFlows();
2928
- StringBuilder limitation = new StringBuilder();
2929
- limitation.append("Ghidra Listing reports a terminal call at ")
2930
- .append(canonicalAddress(instruction.getAddress()));
2931
- if (destinations.length == 0) {
2932
- limitation.append(" with no resolved callee; its no-return basis is unknown.");
3448
+ beforePrevious = previous;
3449
+ previous = instruction;
3450
+ }
3451
+ return limitations;
3452
+ }
3453
+
3454
+ private CallBoundaryObservation callBoundaryObservation(
3455
+ Function function, Iterable<Instruction> instructions, Set<Function> returnedCallees,
3456
+ boolean includeUnresolvedSites, List<Reference> observedReferences)
3457
+ throws Exception {
3458
+ List<String> limitations = new ArrayList<>();
3459
+ CallBoundaryReferences calls = new CallBoundaryReferences(returnedCallees, includeUnresolvedSites);
3460
+ Instruction beforePrevious = null;
3461
+ Instruction previous = null;
3462
+ if (observedReferences == null) visitReferences(function, "outgoing", calls::observe);
3463
+ else for (Reference reference : observedReferences) {
3464
+ monitor.checkCancelled();
3465
+ calls.observe(reference);
3466
+ }
3467
+ for (Instruction instruction : instructions) {
3468
+ monitor.checkCancelled();
3469
+ String limitation = terminalCallLimitation(instruction);
3470
+ if (limitation != null) limitations.add(limitation);
3471
+ if (beforePrevious != null && previous != null) {
3472
+ String seh = borlandSehHandlerLimitation(
3473
+ function, beforePrevious, previous, instruction);
3474
+ if (seh != null) limitations.add(seh);
2933
3475
  }
2934
- else {
2935
- limitation.append(" to ");
2936
- for (int index = 0; index < destinations.length; index++) {
2937
- if (index > 0) limitation.append(", ");
2938
- Address destination = destinations[index];
2939
- limitation.append(canonicalAddress(destination));
2940
- Function target = currentProgram.getFunctionManager().getFunctionAt(destination);
2941
- if (target == null) {
2942
- limitation.append(" (callee identity unknown)");
2943
- }
2944
- else {
2945
- limitation.append(" ").append(procedureName(target));
2946
- limitation.append(" (external=").append(target.isExternal());
2947
- limitation.append(", thunk=").append(target.isThunk());
2948
- limitation.append(", hasNoReturn=").append(target.hasNoReturn()).append(")");
2949
- }
2950
- }
2951
- limitation.append("; fallthrough is excluded by Ghidra's flow model.");
2952
- Function target = destinations.length == 1
2953
- ? currentProgram.getFunctionManager().getFunctionAt(destinations[0])
2954
- : null;
2955
- if (target != null && target.hasNoReturn()) {
2956
- limitation.append(" This records Ghidra's FunctionManager flag, not an independent verification that the callee cannot return.");
3476
+ beforePrevious = previous;
3477
+ previous = instruction;
3478
+ if (!instruction.getFlowType().isCall()) continue;
3479
+ boolean destination = false;
3480
+ for (Reference reference : instruction.getReferencesFrom()) {
3481
+ if (!reference.getReferenceType().isCall()) continue;
3482
+ destination = true;
3483
+ break;
3484
+ }
3485
+ if (!destination) {
3486
+ calls.unrepresented++;
3487
+ calls.unresolved(instruction.getAddress(),
3488
+ "Instruction decoder identifies a call but ReferenceManager supplies no call destination");
3489
+ }
3490
+ }
3491
+ return new CallBoundaryObservation(List.copyOf(limitations),
3492
+ returnedCallees == null ? null : calls.unrepresented, calls.unresolvedCalls());
3493
+ }
3494
+
3495
+ private String borlandSehHandlerLimitation(
3496
+ Function function, Instruction handlerPush, Instruction framePush,
3497
+ Instruction frameLink) {
3498
+ if (!immediatelyPrecedes(handlerPush, framePush) ||
3499
+ !immediatelyPrecedes(framePush, frameLink) ||
3500
+ !handlerPush.getMnemonicString().equalsIgnoreCase("PUSH") ||
3501
+ handlerPush.getNumOperands() != 1 ||
3502
+ !framePush.getMnemonicString().equalsIgnoreCase("PUSH") ||
3503
+ framePush.getNumOperands() != 1 ||
3504
+ !frameLink.getMnemonicString().equalsIgnoreCase("MOV") ||
3505
+ frameLink.getNumOperands() != 2 ||
3506
+ !sameFsMemoryOperand(framePush, frameLink) ||
3507
+ !hasRegisterOperand(frameLink, 1, "ESP"))
3508
+ return null;
3509
+ Object[] handlerOperand = handlerPush.getOpObjects(0);
3510
+ if (handlerOperand.length != 1 || !(handlerOperand[0] instanceof Scalar scalar) ||
3511
+ scalar.bitLength() != 32)
3512
+ return null;
3513
+ Address handler = currentProgram.getAddressFactory().getDefaultAddressSpace()
3514
+ .getAddress(scalar.getUnsignedValue());
3515
+ if (function.getBody().contains(handler)) return null;
3516
+ return "Ghidra Listing shows a Borland/Delphi-style SEH frame registration at " +
3517
+ canonicalAddress(frameLink.getAddress()) + " (push " + canonicalAddress(handler) +
3518
+ " followed by fs-segment stack chaining); handler " + canonicalAddress(handler) +
3519
+ " lies outside this procedure's body, so callees, strings, and cross-references may omit the handler region.";
3520
+ }
3521
+
3522
+ private static boolean immediatelyPrecedes(Instruction first, Instruction second) {
3523
+ Address fallThrough = first.getFallThrough();
3524
+ return fallThrough != null && fallThrough.equals(second.getAddress());
3525
+ }
3526
+
3527
+ private static boolean sameFsMemoryOperand(Instruction first, Instruction second) {
3528
+ String firstOperand = normalizedFsMemoryOperand(first);
3529
+ String secondOperand = normalizedFsMemoryOperand(second);
3530
+ return firstOperand != null && firstOperand.equalsIgnoreCase(secondOperand);
3531
+ }
3532
+
3533
+ private static String normalizedFsMemoryOperand(Instruction instruction) {
3534
+ String representation = instruction.getDefaultOperandRepresentation(0);
3535
+ representation = representation.replaceAll("(?i)\\b(?:byte|word|dword|qword)\\s+ptr\\s+", "")
3536
+ .replaceAll("\\s+", "");
3537
+ return representation.regionMatches(true, 0, "fs:", 0, 3) &&
3538
+ representation.indexOf('[') >= 0 ? representation : null;
3539
+ }
3540
+
3541
+ private static boolean hasRegisterOperand(
3542
+ Instruction instruction, int operand, String name) {
3543
+ for (Object object : instruction.getOpObjects(operand)) {
3544
+ if (object instanceof Register register && register.getName().equalsIgnoreCase(name))
3545
+ return true;
3546
+ }
3547
+ return false;
3548
+ }
3549
+
3550
+ private final class CallBoundaryReferences {
3551
+ private final Set<Function> returnedCallees;
3552
+ private final TreeMap<Address, String> unresolved;
3553
+ private int unrepresented;
3554
+
3555
+ CallBoundaryReferences(Set<Function> returnedCallees, boolean includeUnresolvedSites) {
3556
+ this.returnedCallees = returnedCallees;
3557
+ unresolved = includeUnresolvedSites ? new TreeMap<>() : null;
3558
+ }
3559
+
3560
+ void observe(Reference reference) {
3561
+ if (!reference.getReferenceType().isCall()) return;
3562
+ // Reference identity follows the same containing-function owner as referenceEdge.
3563
+ Function target = containingFunction(reference.getToAddress());
3564
+ if (returnedCallees != null && (target == null || !returnedCallees.contains(target)))
3565
+ unrepresented++;
3566
+ if (target == null) unresolved(reference.getFromAddress(),
3567
+ "A call destination has no known containing Ghidra procedure");
3568
+ }
3569
+
3570
+ void unresolved(Address address, String reason) {
3571
+ if (unresolved != null) unresolved.put(address, reason);
3572
+ }
3573
+
3574
+ JsonArray unresolvedCalls() {
3575
+ if (unresolved == null) return null;
3576
+ JsonArray result = new JsonArray();
3577
+ for (var item : unresolved.entrySet()) {
3578
+ JsonObject site = new JsonObject();
3579
+ site.addProperty("address", canonicalAddress(item.getKey()));
3580
+ site.addProperty("reason", item.getValue());
3581
+ result.add(site);
3582
+ }
3583
+ return result;
3584
+ }
3585
+ }
3586
+
3587
+ private String terminalCallLimitation(Instruction instruction) {
3588
+ if (!instruction.getFlowType().isCall() || !instruction.getFlowType().isTerminal())
3589
+ return null;
3590
+ Address[] destinations = instruction.getFlows();
3591
+ StringBuilder limitation = new StringBuilder();
3592
+ limitation.append("Ghidra Listing reports a terminal call at ")
3593
+ .append(canonicalAddress(instruction.getAddress()));
3594
+ if (destinations.length == 0) {
3595
+ limitation.append(" with no resolved callee; its no-return basis is unknown.");
3596
+ }
3597
+ else {
3598
+ limitation.append(" to ");
3599
+ for (int index = 0; index < destinations.length; index++) {
3600
+ if (index > 0) limitation.append(", ");
3601
+ Address destination = destinations[index];
3602
+ limitation.append(canonicalAddress(destination));
3603
+ Function target = currentProgram.getFunctionManager().getFunctionAt(destination);
3604
+ if (target == null) {
3605
+ limitation.append(" (callee identity unknown)");
2957
3606
  }
2958
3607
  else {
2959
- limitation.append(" The reason for the terminal flow is not established by this observation.");
3608
+ limitation.append(" ").append(procedureName(target));
3609
+ limitation.append(" (external=").append(target.isExternal());
3610
+ limitation.append(", thunk=").append(target.isThunk());
3611
+ limitation.append(", hasNoReturn=").append(target.hasNoReturn()).append(")");
2960
3612
  }
2961
3613
  }
2962
- limitations.add(limitation.toString());
3614
+ limitation.append("; fallthrough is excluded by Ghidra's flow model.");
3615
+ Function target = destinations.length == 1
3616
+ ? currentProgram.getFunctionManager().getFunctionAt(destinations[0])
3617
+ : null;
3618
+ if (target != null && target.hasNoReturn()) {
3619
+ limitation.append(" This records Ghidra's FunctionManager flag, not an independent verification that the callee cannot return.");
3620
+ }
3621
+ else {
3622
+ limitation.append(" The reason for the terminal flow is not established by this observation.");
3623
+ }
2963
3624
  }
2964
- return limitations;
3625
+ return limitation.toString();
2965
3626
  }
2966
3627
 
2967
3628
  private static String renderAssembly(List<Instruction> instructions) {
@@ -2987,15 +3648,27 @@ public final class ReaGhidraBridge extends HeadlessScript {
2987
3648
  private List<Reference> collectReferences(
2988
3649
  Function function,
2989
3650
  String direction) throws Exception {
3651
+ TreeMap<String, Reference> observed = new TreeMap<>();
3652
+ visitReferences(function, direction, reference -> addReference(observed, reference));
3653
+ List<Reference> result = new ArrayList<>(observed.values());
3654
+ result.sort(REFERENCE_ORDER);
3655
+ return result;
3656
+ }
3657
+
3658
+ @FunctionalInterface
3659
+ private interface ReferenceVisitor {
3660
+ void accept(Reference reference) throws Exception;
3661
+ }
3662
+
3663
+ private void visitReferences(Function function, String direction, ReferenceVisitor visitor)
3664
+ throws Exception {
2990
3665
  // References can target instruction interiors or originate in embedded
2991
3666
  // data. Use actual body ownership, including an external's exact entry.
2992
- AddressSet scope = new AddressSet(function.getBody());
2993
- scope.add(function.getEntryPoint());
3667
+ AddressSet scope = functionObservationScope(function);
2994
3668
  boolean outgoing = direction.equals("outgoing");
2995
3669
  AddressIterator addresses = outgoing
2996
3670
  ? currentProgram.getReferenceManager().getReferenceSourceIterator(scope, true)
2997
3671
  : currentProgram.getReferenceManager().getReferenceDestinationIterator(scope, true);
2998
- TreeMap<String, Reference> observed = new TreeMap<>();
2999
3672
  while (addresses.hasNext()) {
3000
3673
  monitor.checkCancelled();
3001
3674
  Address address = addresses.next();
@@ -3003,7 +3676,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
3003
3676
  for (Reference reference : currentProgram.getReferenceManager()
3004
3677
  .getReferencesFrom(address)) {
3005
3678
  monitor.checkCancelled();
3006
- addReference(observed, reference);
3679
+ if (!reference.isEntryPointReference()) visitor.accept(reference);
3007
3680
  }
3008
3681
  }
3009
3682
  else {
@@ -3011,19 +3684,14 @@ public final class ReaGhidraBridge extends HeadlessScript {
3011
3684
  .getReferencesTo(address);
3012
3685
  while (iterator.hasNext()) {
3013
3686
  monitor.checkCancelled();
3014
- addReference(observed, iterator.next());
3687
+ Reference reference = iterator.next();
3688
+ if (!reference.isEntryPointReference()) visitor.accept(reference);
3015
3689
  }
3016
3690
  }
3017
3691
  }
3018
- List<Reference> result = new ArrayList<>(observed.values());
3019
- result.sort(REFERENCE_ORDER);
3020
- return result;
3021
3692
  }
3022
3693
 
3023
3694
  private static void addReference(TreeMap<String, Reference> observed, Reference reference) {
3024
- if (reference.isEntryPointReference()) {
3025
- return;
3026
- }
3027
3695
  String key = canonicalAddress(reference.getFromAddress()) + "\u0000" +
3028
3696
  canonicalAddress(reference.getToAddress()) + "\u0000" +
3029
3697
  reference.getReferenceType().getName() + "\u0000" +
@@ -3032,6 +3700,12 @@ public final class ReaGhidraBridge extends HeadlessScript {
3032
3700
  observed.putIfAbsent(key, reference);
3033
3701
  }
3034
3702
 
3703
+ private static AddressSet functionObservationScope(Function function) {
3704
+ AddressSet scope = new AddressSet(function.getBody());
3705
+ scope.add(function.getEntryPoint());
3706
+ return scope;
3707
+ }
3708
+
3035
3709
  private JsonArray referenceEdges(List<Reference> references) {
3036
3710
  JsonArray result = new JsonArray();
3037
3711
  for (Reference reference : references) {
@@ -3185,23 +3859,28 @@ public final class ReaGhidraBridge extends HeadlessScript {
3185
3859
  return result;
3186
3860
  }
3187
3861
 
3188
- private static JsonArray comments(List<Instruction> instructions) {
3862
+ private JsonArray comments(Function function) throws Exception {
3863
+ Listing listing = currentProgram.getListing();
3864
+ AddressSet scope = functionObservationScope(function);
3865
+ AddressIterator addresses = listing.getCommentAddressIterator(scope, true);
3189
3866
  TreeMap<String, JsonObject> observed = new TreeMap<>();
3190
- for (Instruction instruction : instructions) {
3867
+ while (addresses.hasNext()) {
3868
+ monitor.checkCancelled();
3869
+ Address address = addresses.next();
3191
3870
  for (CommentType type : CommentType.values()) {
3192
- String text = instruction.getComment(type);
3871
+ String text = listing.getComment(type, address);
3193
3872
  if (text == null || text.isEmpty()) {
3194
3873
  continue;
3195
3874
  }
3196
3875
  String kind = type == CommentType.EOL ? "inline" : "comment";
3197
3876
  JsonObject item = new JsonObject();
3198
- item.addProperty("address", canonicalAddress(instruction.getAddress()));
3877
+ item.addProperty("address", canonicalAddress(address));
3199
3878
  item.addProperty("kind", kind);
3200
3879
  item.addProperty("text", text);
3201
- String key = canonicalAddress(instruction.getAddress()) + "\u0000" +
3880
+ String key = canonicalAddress(address) + "\u0000" +
3202
3881
  kind + "\u0000" + type.name() + "\u0000" + text;
3203
3882
  observed.put(key, item);
3204
- }
3883
+ }
3205
3884
  }
3206
3885
  JsonArray result = new JsonArray();
3207
3886
  observed.values().forEach(result::add);
@@ -3256,6 +3935,376 @@ public final class ReaGhidraBridge extends HeadlessScript {
3256
3935
  return result;
3257
3936
  }
3258
3937
 
3938
+ private boolean swiftProgram() {
3939
+ for (MemoryBlock block : currentProgram.getMemory().getBlocks()) {
3940
+ String name = block.getName();
3941
+ if (name.startsWith("__swift5_") || name.startsWith("swift5_")) return true;
3942
+ }
3943
+ return false;
3944
+ }
3945
+
3946
+ /**
3947
+ * Swift passes a String as two words: small literals carry their bytes in the words and
3948
+ * immortal large literals carry their count and a biased pointer to the bytes. Ghidra keeps
3949
+ * neither as a data reference, so decode constant pairs where Swift consumes them: argument
3950
+ * and return registers at calls, tail calls and returns, and both registers of one STP.
3951
+ * The canonical empty string is a small literal with a zero count.
3952
+ */
3953
+ private SwiftStringLiteralDecode swiftStringLiterals(Function function) throws Exception {
3954
+ return swiftStringLiterals(function, new SwiftLiteralBudget());
3955
+ }
3956
+
3957
+ // An explicit budget makes capacity omissions deterministic in producer tests.
3958
+ private SwiftStringLiteralDecode swiftStringLiterals(
3959
+ Function function,
3960
+ SwiftLiteralBudget budget
3961
+ ) throws Exception {
3962
+ Register[] registers = new Register[31];
3963
+ for (int index = 0; index < registers.length; index++) {
3964
+ registers[index] = currentProgram.getRegister("x" + index);
3965
+ }
3966
+ TreeMap<String, JsonObject> observed = new TreeMap<>();
3967
+ TreeMap<String, JsonObject> omitted = new TreeMap<>();
3968
+ Map<String, Boolean> selectedValues = new HashMap<>();
3969
+ SymbolicPropogator propagator = new SymbolicPropogator(currentProgram, false);
3970
+ propagator.flowConstants(function.getEntryPoint(), function.getBody(), new ContextEvaluatorAdapter() {
3971
+ @Override
3972
+ public boolean evaluateContextBefore(VarnodeContext context, Instruction instruction) {
3973
+ // Returning true ends only the current flow, so every queued flow checks the shared stop.
3974
+ if (budget.stopped()) return true;
3975
+ FlowType flow = instruction.getFlowType();
3976
+ Address[] flowTargets = instruction.getFlows();
3977
+ boolean unresolvedJump = flow.isJump() && !flow.isConditional() && flowTargets.length == 0;
3978
+ for (Register[] pair : swiftStringPairs(function, instruction, registers)) {
3979
+ Long word = registerConstant(context, pair[0]);
3980
+ Long object = registerConstant(context, pair[1]);
3981
+ if (word == null || object == null) continue;
3982
+ SwiftLiteralLayout layout = swiftLiteralLayout(word, object);
3983
+ if (layout == null) continue;
3984
+ // A selected word can combine with a path-dependent ordinary move. Cache the
3985
+ // provenance question per site/register, charging retained cache state to the
3986
+ // same dossier budget before allocating it.
3987
+ boolean selected = false;
3988
+ boolean provenanceOverCapacity = false;
3989
+ for (Register register : pair) {
3990
+ String provenanceKey = canonicalAddress(instruction.getAddress()) + "\u0000" +
3991
+ register.getBaseRegister().getName();
3992
+ Boolean value = selectedValues.get(provenanceKey);
3993
+ if (value == null) {
3994
+ if (!budget.takeState()) {
3995
+ provenanceOverCapacity = true;
3996
+ break;
3997
+ }
3998
+ value = selectedValue(function, instruction, register);
3999
+ selectedValues.put(provenanceKey, value);
4000
+ }
4001
+ if (value) {
4002
+ selected = true;
4003
+ break;
4004
+ }
4005
+ }
4006
+ if (selected) continue;
4007
+ // Forks can reach one site with different constants, so the words are part of the key.
4008
+ String key = canonicalAddress(instruction.getAddress()) + "\u0000" + pair[0].getName() +
4009
+ "\u0000" + pair[1].getName() + "\u0000" + Long.toUnsignedString(word, 16) +
4010
+ "\u0000" + Long.toUnsignedString(object, 16);
4011
+ if (observed.containsKey(key) || omitted.containsKey(key)) continue;
4012
+ // Every record draws on the budget; the first one that does not fit is kept as an
4013
+ // omission and decoding stops, so later sites are never examined.
4014
+ String value = layout.smallValue();
4015
+ boolean overCapacity = provenanceOverCapacity || !budget.take(layout.byteLength());
4016
+ if (!overCapacity && value == null) {
4017
+ try {
4018
+ value = swiftLargeLiteralText(layout);
4019
+ } catch (OutOfMemoryError exhausted) {
4020
+ overCapacity = true;
4021
+ }
4022
+ }
4023
+ if (value == null && !overCapacity) continue;
4024
+ JsonObject item = overCapacity
4025
+ ? swiftStringOmission(layout, word, object)
4026
+ : swiftStringItem(value, layout, word, object);
4027
+ if (unresolvedJump && !overCapacity)
4028
+ item = swiftStringOmission(layout, word, object, "unresolved_jump");
4029
+ item.addProperty("source_address", canonicalAddress(instruction.getAddress()));
4030
+ JsonArray pairRegisters = new JsonArray();
4031
+ pairRegisters.add(pair[0].getName());
4032
+ pairRegisters.add(pair[1].getName());
4033
+ item.add("registers", pairRegisters);
4034
+ (overCapacity || unresolvedJump ? omitted : observed).put(key, item);
4035
+ if (overCapacity) {
4036
+ budget.stop();
4037
+ return true;
4038
+ }
4039
+ }
4040
+ return false;
4041
+ }
4042
+ }, false, monitor);
4043
+ JsonArray literals = new JsonArray();
4044
+ observed.values().forEach(literals::add);
4045
+ JsonArray omissions = new JsonArray();
4046
+ omitted.values().forEach(omissions::add);
4047
+ return new SwiftStringLiteralDecode(literals, omissions);
4048
+ }
4049
+
4050
+ private static List<Register[]> swiftStringPairs(
4051
+ Function function,
4052
+ Instruction instruction,
4053
+ Register[] registers
4054
+ ) {
4055
+ List<Register[]> pairs = new ArrayList<>();
4056
+ if (instruction.getMnemonicString().equals("stp")) {
4057
+ Register first = instruction.getRegister(0);
4058
+ Register second = instruction.getRegister(1);
4059
+ if (first != null && second != null && first.getBitLength() == 64 && second.getBitLength() == 64) {
4060
+ pairs.add(new Register[] {first, second});
4061
+ }
4062
+ return pairs;
4063
+ }
4064
+ FlowType flow = instruction.getFlowType();
4065
+ boolean returns = false;
4066
+ for (PcodeOp operation : instruction.getPcode()) {
4067
+ if (operation.getOpcode() == PcodeOp.RETURN) returns = true;
4068
+ }
4069
+ // A jump is a proven tail call only when it has resolved targets and all leave the
4070
+ // body. For unresolved targetless jumps, candidate literals remain unknown omissions.
4071
+ Address[] targets = instruction.getFlows();
4072
+ boolean tailCall = flow.isJump() && !flow.isConditional() && targets.length > 0 &&
4073
+ Arrays.stream(targets).allMatch(target -> !function.getBody().contains(target));
4074
+ boolean unresolvedJump = flow.isJump() && !flow.isConditional() && targets.length == 0;
4075
+ if (!flow.isCall() && !returns && !tailCall && !unresolvedJump) return pairs;
4076
+ // A String occupies two consecutive registers among x0-x7, or x0 and x1 when returned.
4077
+ int lastFirstRegister = returns ? 0 : 6;
4078
+ for (int index = 0; index <= lastFirstRegister; index++) {
4079
+ pairs.add(new Register[] {registers[index], registers[index + 1]});
4080
+ }
4081
+ return pairs;
4082
+ }
4083
+
4084
+ private static Long registerConstant(VarnodeContext context, Register register) {
4085
+ Varnode value = context.getRegisterVarnodeValue(register);
4086
+ return value != null && context.isConstant(value) ? value.getOffset() : null;
4087
+ }
4088
+
4089
+ // Search every predecessor path for the reaching definitions, following register copies,
4090
+ // since a select copied into an argument register or defined before a branch forks just as
4091
+ // independently as one written there directly.
4092
+ private boolean selectedValue(Function function, Instruction use, Register register) {
4093
+ ArrayDeque<Instruction> instructions = new ArrayDeque<>();
4094
+ ArrayDeque<Register> targets = new ArrayDeque<>();
4095
+ Set<String> visited = new HashSet<>();
4096
+ for (Instruction predecessor : predecessors(function, use)) {
4097
+ instructions.push(predecessor);
4098
+ targets.push(register.getBaseRegister());
4099
+ }
4100
+ while (!instructions.isEmpty()) {
4101
+ Instruction instruction = instructions.pop();
4102
+ Register target = targets.pop();
4103
+ if (!visited.add(canonicalAddress(instruction.getAddress()) + "\u0000" + target.getName())) continue;
4104
+ boolean defines = false;
4105
+ for (Object result : instruction.getResultObjects()) {
4106
+ if (result instanceof Register written && written.getBaseRegister().equals(target)) defines = true;
4107
+ }
4108
+ Register next = target;
4109
+ if (defines) {
4110
+ PcodeOp[] operations = instruction.getPcode();
4111
+ for (PcodeOp operation : operations) {
4112
+ if (operation.getOpcode() == PcodeOp.CBRANCH && operation.getInput(0).isConstant()) return true;
4113
+ }
4114
+ Register source = copiedRegister(operations);
4115
+ if (source == null) continue;
4116
+ next = source.getBaseRegister();
4117
+ }
4118
+ for (Instruction predecessor : predecessors(function, instruction)) {
4119
+ instructions.push(predecessor);
4120
+ targets.push(next);
4121
+ }
4122
+ }
4123
+ return false;
4124
+ }
4125
+
4126
+ private List<Instruction> predecessors(Function function, Instruction instruction) {
4127
+ List<Instruction> result = new ArrayList<>();
4128
+ Address from = instruction.getFallFrom();
4129
+ if (from != null) {
4130
+ Instruction previous = currentProgram.getListing().getInstructionAt(from);
4131
+ if (previous != null) result.add(previous);
4132
+ }
4133
+ for (Reference reference : currentProgram.getReferenceManager().getReferencesTo(instruction.getAddress())) {
4134
+ if (!reference.getReferenceType().isFlow() || reference.getReferenceType().isCall()) continue;
4135
+ if (!function.getBody().contains(reference.getFromAddress())) continue;
4136
+ Instruction source = currentProgram.getListing().getInstructionAt(reference.getFromAddress());
4137
+ if (source != null) result.add(source);
4138
+ }
4139
+ return result;
4140
+ }
4141
+
4142
+ private Register copiedRegister(PcodeOp[] operations) {
4143
+ if (operations.length != 1) return null;
4144
+ int opcode = operations[0].getOpcode();
4145
+ Varnode input = operations[0].getInput(0);
4146
+ if ((opcode != PcodeOp.COPY && opcode != PcodeOp.INT_ZEXT) || input == null || !input.isRegister()) return null;
4147
+ return currentProgram.getRegister(input);
4148
+ }
4149
+
4150
+ /** Validate the ABI layout of a pair; a small literal is decoded here, a large one only located. */
4151
+ private SwiftLiteralLayout swiftLiteralLayout(long word, long object) {
4152
+ int discriminator = (int) (object >>> 60);
4153
+ if (discriminator == 0xE || discriminator == 0xA) {
4154
+ int count = (int) ((object >>> 56) & 0xF);
4155
+ byte[] bytes = new byte[15];
4156
+ for (int index = 0; index < 8; index++) bytes[index] = (byte) (word >>> (8 * index));
4157
+ for (int index = 0; index < 7; index++) bytes[8 + index] = (byte) (object >>> (8 * index));
4158
+ for (int index = count; index < bytes.length; index++) {
4159
+ if (bytes[index] != 0) return null;
4160
+ }
4161
+ // Count zero is the canonical empty string (object 0xE000000000000000, word 0).
4162
+ String value = swiftStringText(bytes, count, discriminator == 0xE);
4163
+ return value == null ? null : new SwiftLiteralLayout("small", null, count, true, value);
4164
+ }
4165
+ int flags = (int) (word >>> 60);
4166
+ long count = word & 0xFFFFFFFFFFFFL;
4167
+ // Immortal literals: ASCII and NFC or neither, tail allocated, with a pointer biased by 32.
4168
+ if ((object >>> 56) != 0x80 || (flags != 0xD && flags != 0x1) || ((word >>> 48) & 0xFFF) != 0) {
4169
+ return null;
4170
+ }
4171
+ try {
4172
+ Address address = currentProgram.getAddressFactory().getDefaultAddressSpace()
4173
+ .getAddress((object & 0x00FFFFFFFFFFFFFFL) + 0x20);
4174
+ MemoryBlock block = currentProgram.getMemory().getBlock(address);
4175
+ // The bytes and their terminator must lie in one initialized, non-executable block,
4176
+ // and Java arrays bound one read.
4177
+ if (block == null || !block.isInitialized() || block.isExecute() ||
4178
+ count >= block.getEnd().subtract(address) + 1 || count >= Integer.MAX_VALUE) {
4179
+ return null;
4180
+ }
4181
+ return new SwiftLiteralLayout("large", address, count, flags == 0xD, null);
4182
+ } catch (Exception unaddressable) {
4183
+ return null;
4184
+ }
4185
+ }
4186
+
4187
+ private String swiftLargeLiteralText(SwiftLiteralLayout layout) {
4188
+ int count = (int) layout.byteLength();
4189
+ byte[] bytes = new byte[count + 1];
4190
+ try {
4191
+ if (currentProgram.getMemory().getBytes(layout.address(), bytes) != bytes.length) return null;
4192
+ } catch (Exception unreadable) {
4193
+ return null;
4194
+ }
4195
+ return bytes[count] == 0 ? swiftStringText(bytes, count, layout.ascii()) : null;
4196
+ }
4197
+
4198
+ /**
4199
+ * Every literal record of one dossier draws on half of the heap that was free when decoding
4200
+ * began. Text is charged at the worst case per UTF-8 byte: two bytes of UTF-16 text, then up
4201
+ * to six escaped JSON characters ("\\u0000") held as UTF-16 in Gson's growing writer buffer
4202
+ * (up to twice its length), again in the returned String, and once more as UTF-8 on the
4203
+ * socket. Each record also pays a fixed cost for its map key, JSON members, addresses, words
4204
+ * and their serialized form, so many empty or small literals are bounded too. Retained
4205
+ * provenance-cache entries draw on that same fixed-state allowance.
4206
+ */
4207
+ private static final class SwiftLiteralBudget {
4208
+ private static final long BYTES_PER_LITERAL_BYTE = 2 + 6 * 2 * 2 + 6 * 2 + 6;
4209
+ private static final long BYTES_PER_RECORD = 4096;
4210
+ private long remaining;
4211
+ private boolean stopped;
4212
+
4213
+ SwiftLiteralBudget() {
4214
+ Runtime runtime = Runtime.getRuntime();
4215
+ remaining = Math.max(0, (runtime.maxMemory() - runtime.totalMemory() + runtime.freeMemory()) / 2);
4216
+ }
4217
+
4218
+ SwiftLiteralBudget(long remaining) {
4219
+ if (remaining < 0) throw new IllegalArgumentException("Swift literal budget must be nonnegative");
4220
+ this.remaining = remaining;
4221
+ }
4222
+
4223
+ boolean takeState() {
4224
+ if (remaining < BYTES_PER_RECORD) return false;
4225
+ remaining -= BYTES_PER_RECORD;
4226
+ return true;
4227
+ }
4228
+
4229
+ boolean take(long bytes) {
4230
+ if (remaining < BYTES_PER_RECORD ||
4231
+ bytes > (remaining - BYTES_PER_RECORD) / BYTES_PER_LITERAL_BYTE) {
4232
+ return false;
4233
+ }
4234
+ remaining -= BYTES_PER_RECORD + bytes * BYTES_PER_LITERAL_BYTE;
4235
+ return true;
4236
+ }
4237
+
4238
+ void stop() {
4239
+ stopped = true;
4240
+ }
4241
+
4242
+ boolean stopped() {
4243
+ return stopped;
4244
+ }
4245
+ }
4246
+
4247
+ // Swift String values may contain any scalar, including controls; JSON escapes them.
4248
+ private static String swiftStringText(byte[] bytes, int length, boolean ascii) {
4249
+ if (length < 0 || length > bytes.length) return null;
4250
+ for (int index = 0; index < length; index++) {
4251
+ if (ascii && bytes[index] < 0) return null;
4252
+ }
4253
+ try {
4254
+ return StandardCharsets.UTF_8.newDecoder().decode(ByteBuffer.wrap(bytes, 0, length)).toString();
4255
+ } catch (CharacterCodingException invalid) {
4256
+ return null;
4257
+ }
4258
+ }
4259
+
4260
+ private static JsonObject swiftStringOmission(SwiftLiteralLayout layout, long word, long object) {
4261
+ return swiftStringOmission(layout, word, object, "capacity");
4262
+ }
4263
+
4264
+ private static JsonObject swiftStringOmission(
4265
+ SwiftLiteralLayout layout,
4266
+ long word,
4267
+ long object,
4268
+ String reason
4269
+ ) {
4270
+ JsonObject item = new JsonObject();
4271
+ item.addProperty("representation", layout.representation());
4272
+ if (layout.address() == null) {
4273
+ item.add("address", JsonNull.INSTANCE);
4274
+ } else {
4275
+ item.addProperty("address", canonicalAddress(layout.address()));
4276
+ }
4277
+ item.addProperty("byte_length", layout.byteLength());
4278
+ item.addProperty("reason", reason);
4279
+ item.add("words", swiftStringWords(word, object));
4280
+ return item;
4281
+ }
4282
+
4283
+ private static JsonObject swiftStringItem(
4284
+ String value,
4285
+ SwiftLiteralLayout layout,
4286
+ long word,
4287
+ long object
4288
+ ) {
4289
+ JsonObject item = new JsonObject();
4290
+ item.addProperty("value", value);
4291
+ item.addProperty("representation", layout.representation());
4292
+ if (layout.address() == null) {
4293
+ item.add("address", JsonNull.INSTANCE);
4294
+ } else {
4295
+ item.addProperty("address", canonicalAddress(layout.address()));
4296
+ }
4297
+ item.add("words", swiftStringWords(word, object));
4298
+ return item;
4299
+ }
4300
+
4301
+ private static JsonArray swiftStringWords(long word, long object) {
4302
+ JsonArray words = new JsonArray();
4303
+ words.add("0x" + Long.toUnsignedString(word, 16));
4304
+ words.add("0x" + Long.toUnsignedString(object, 16));
4305
+ return words;
4306
+ }
4307
+
3259
4308
  private static String exclusiveAddress(Address inclusive) {
3260
4309
  Address next = inclusive.next();
3261
4310
  if (next != null && next.getAddressSpace().equals(inclusive.getAddressSpace())) {
@@ -3794,7 +4843,16 @@ public final class ReaGhidraBridge extends HeadlessScript {
3794
4843
  private record InventoryItem(Address address, String value, JsonObject facts) {}
3795
4844
  private record AddressNameRequest(String inputAddress, Address address, String name) {}
3796
4845
  private record FunctionEntry(Function function, InventoryItem item) {}
3797
- private record FunctionAnalysisObservation(JsonObject dossier, List<String> limitations) {}
4846
+ private record FunctionAnalysisObservation(JsonObject dossier, List<String> limitations, JsonObject relationshipCoverage) {}
4847
+ private record CallBoundaryObservation(List<String> limitations, Integer unrepresentedCalleeCalls, JsonArray unresolvedCalls) {}
4848
+ private record SwiftStringLiteralDecode(JsonArray literals, JsonArray omissions) {}
4849
+ private record SwiftLiteralLayout(
4850
+ String representation,
4851
+ Address address,
4852
+ long byteLength,
4853
+ boolean ascii,
4854
+ String smallValue
4855
+ ) {}
3798
4856
  private record InstructionScan(List<Instruction> instructions, boolean truncated) {}
3799
4857
  private record SessionDescriptor(
3800
4858
  String transport,