rea-agents 6.0.0 → 6.2.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 (611) hide show
  1. package/README.md +26 -18
  2. package/bridge/android/ReaJadxBridge.java +14 -5
  3. package/bridge/ghidra/ReaGhidraBridge.java +205 -51
  4. package/bridge/hopper_bridge.py +314 -127
  5. package/bridge/mitmproxy/capture.py +0 -2
  6. package/bridge/native/rea_lldb_tracer.py +630 -94
  7. package/bridge/process/ProcessRunTokenReader.swift +39 -5
  8. package/bridge/pwntools/recorded_crash_impl.py +4 -0
  9. package/dist/android/JadxConfiguration.js +274 -31
  10. package/dist/android/JadxMcpTransport.js +18 -2
  11. package/dist/android/JadxProtocol.js +6 -0
  12. package/dist/android/JadxProvider.js +76 -37
  13. package/dist/android/JadxSession.js +23 -4
  14. package/dist/application/AnalysisContextQueries.js +8 -35
  15. package/dist/application/AnalysisDocument.js +32 -0
  16. package/dist/application/AppBundleExecutable.js +67 -21
  17. package/dist/application/BinaryTargetResolver.js +5 -3
  18. package/dist/application/BrowserEvidence.js +3 -8
  19. package/dist/application/BrowserScenarioEvidence.js +2 -18
  20. package/dist/application/CallPathTracing.js +19 -3
  21. package/dist/application/CapabilityInventory.js +48 -11
  22. package/dist/application/ClientConfigurationDocument.js +917 -8
  23. package/dist/application/ClientRegistrationIdentity.js +26 -5
  24. package/dist/application/ClientRegistrationStatus.js +29 -14
  25. package/dist/application/DirectAnalysis.js +56 -51
  26. package/dist/application/DirectAnalysisCleanup.js +72 -0
  27. package/dist/application/DirectAnalysisStatus.js +4 -5
  28. package/dist/application/Doctor.js +19 -21
  29. package/dist/application/DoctorDiagnostics.js +1 -2
  30. package/dist/application/DoctorScope.js +25 -13
  31. package/dist/application/EnhancedLiteralTracing.js +22 -25
  32. package/dist/application/EnhancedTools.js +64 -17
  33. package/dist/application/EvidenceBundleFiles.js +30 -13
  34. package/dist/application/FunctionAnalysisEvidence.js +2 -3
  35. package/dist/application/InventoryProjectionEvidence.js +4 -3
  36. package/dist/application/InvestigationProviders.js +11 -2
  37. package/dist/application/JsonFiles.js +83 -28
  38. package/dist/application/LinuxHopper.js +9 -6
  39. package/dist/application/MacHopper.js +15 -18
  40. package/dist/application/ProcedureAddressResolution.js +11 -0
  41. package/dist/application/RealHopperAssertions.js +0 -11
  42. package/dist/application/ReconstructionCoverageService.js +7 -4
  43. package/dist/application/ReconstructionObligationCandidates.js +1 -1
  44. package/dist/application/ReconstructionObligationLedgerService.js +4 -3
  45. package/dist/application/ReferenceSourceImportEntries.js +1 -1
  46. package/dist/application/Setup.js +21 -17
  47. package/dist/application/SetupClientConfiguration.js +10 -15
  48. package/dist/application/SetupHost.js +21 -29
  49. package/dist/application/SetupPlan.js +11 -9
  50. package/dist/application/SupportedClients.js +34 -1
  51. package/dist/application/Uninstall.js +82 -29
  52. package/dist/application/Update.js +18 -3
  53. package/dist/application/UpdateMaintenance.js +7 -5
  54. package/dist/application/UpdateRuntime.js +57 -36
  55. package/dist/application/WebModuleTraceService.js +4 -2
  56. package/dist/application/WebNetworkCaptureService.js +4 -2
  57. package/dist/application/WebRuntimeService.js +5 -3
  58. package/dist/application/WebScriptExportService.js +32 -6
  59. package/dist/application/WebSourceLocationService.js +4 -2
  60. package/dist/application/WorkflowEvidence.js +105 -0
  61. package/dist/application/XrefsAddressResolution.js +45 -0
  62. package/dist/application/analysisView/AnalysisViewService.js +76 -0
  63. package/dist/application/binary/AnalysisClientCleanup.js +30 -5
  64. package/dist/application/binary/AnalysisProviderEvaluation.js +22 -7
  65. package/dist/application/binary/AnalysisProviderRegistry.js +4 -6
  66. package/dist/application/binary/AnalysisSnapshotCache.js +13 -14
  67. package/dist/application/binary/BinarySession.js +161 -93
  68. package/dist/application/binary/BinarySessionComposition.js +1 -3
  69. package/dist/application/binary/BinarySessionExecution.js +3 -5
  70. package/dist/application/binary/BinarySessionOpen.js +4 -4
  71. package/dist/application/binary/BinarySessionRecords.js +26 -4
  72. package/dist/application/binary/BinarySessionStatus.js +18 -7
  73. package/dist/application/binary/CompositeProvider.js +16 -17
  74. package/dist/application/binary/LazyAnalysisProvider.js +8 -5
  75. package/dist/application/binary/SessionProviderRouter.js +27 -135
  76. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +4 -2
  77. package/dist/application/binaryDiagnostics/RecordedCrashService.js +4 -2
  78. package/dist/application/evm/EvmInterfaceService.js +4 -2
  79. package/dist/application/homebrew.js +48 -0
  80. package/dist/application/investigation/EvidenceLedger.js +21 -7
  81. package/dist/application/investigation/InvestigationRecords.js +8 -0
  82. package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
  83. package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
  84. package/dist/application/javascript/JavaScriptApplicationEvidence.js +21 -4
  85. package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
  86. package/dist/application/javascript/JavaScriptApplicationService.js +27 -15
  87. package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
  88. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +10 -7
  89. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +44 -10
  90. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
  91. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
  92. package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
  93. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
  94. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
  95. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +49 -19
  96. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +56 -8
  97. package/dist/application/javascript/JavaScriptModuleRelationships.js +38 -9
  98. package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
  99. package/dist/application/javascript/JavaScriptRuntimeObservationService.js +6 -4
  100. package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
  101. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
  102. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +63 -61
  103. package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
  104. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
  105. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
  106. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
  107. package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
  108. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +64 -19
  109. package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
  110. package/dist/application/managed/ManagedMemberComparisonService.js +9 -5
  111. package/dist/application/managed/ManagedNativeVerificationService.js +6 -4
  112. package/dist/application/managed/ManagedReconstructionService.js +4 -3
  113. package/dist/application/process/ProcessCli.js +25 -17
  114. package/dist/application/process/ProcessEvidence.js +4 -4
  115. package/dist/application/workflowInputError.js +18 -0
  116. package/dist/artifacts/ArtifactProvider.js +48 -13
  117. package/dist/artifacts/ArtifactReader.js +31 -0
  118. package/dist/artifacts/DirectoryArtifactReader.js +2 -1
  119. package/dist/artifacts/MachOSliceArtifactReader.js +106 -15
  120. package/dist/artifacts/NativeDmgArtifactReader.js +73 -21
  121. package/dist/artifacts/SafeOutputTree.js +16 -2
  122. package/dist/artifacts/ZipArtifactReader.js +11 -4
  123. package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +26 -5
  124. package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
  125. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
  126. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
  127. package/dist/artifacts/apple/KeyedArchiveReader.js +55 -23
  128. package/dist/artifacts/apple/MachoLoadCommandReader.js +92 -31
  129. package/dist/artifacts/apple/NibArchive.js +81 -14
  130. package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
  131. package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
  132. package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
  133. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +79 -68
  134. package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
  135. package/dist/artifacts/inventory/reader.js +3 -3
  136. package/dist/artifacts/inventory/scanCanonical.js +59 -38
  137. package/dist/artifacts/inventory/scanReader.js +5 -9
  138. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
  139. package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
  140. package/dist/browser/CdpBrowserProvider.js +2 -3
  141. package/dist/browser/CdpCaptureCompleteness.js +2 -0
  142. package/dist/browser/CdpCaptureEventHandlers.js +78 -15
  143. package/dist/browser/CdpCaptureEventTypes.js +5 -1
  144. package/dist/browser/CdpCaptureEvents.js +25 -1
  145. package/dist/browser/CdpCaptureValues.js +20 -0
  146. package/dist/browser/CdpConnection.js +30 -11
  147. package/dist/browser/CdpElectronProvider.js +0 -2
  148. package/dist/browser/CdpElectronScriptEvents.js +2 -8
  149. package/dist/browser/CdpElectronScripts.js +2 -3
  150. package/dist/browser/CdpOptionalCommand.js +2 -3
  151. package/dist/browser/CdpPageCapture.js +23 -1
  152. package/dist/browser/CdpPageCaptureScripts.js +2 -3
  153. package/dist/browser/CdpSafeMetadata.js +10 -10
  154. package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
  155. package/dist/browser/PlaywrightElectronActiveActions.js +34 -79
  156. package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
  157. package/dist/browser/PlaywrightElectronActiveProvider.js +133 -130
  158. package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
  159. package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
  160. package/dist/browser/PlaywrightScenarioEvents.js +1 -1
  161. package/dist/browser/PlaywrightScenarioSession.js +39 -22
  162. package/dist/browser/WebSourceMapFetcher.js +426 -72
  163. package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
  164. package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
  165. package/dist/browser/history/CaptureFailures.js +41 -1
  166. package/dist/browser/history/CaptureRelease.js +5 -0
  167. package/dist/browser/history/HarCaptureAdapter.js +3 -3
  168. package/dist/browser/history/HarJson.js +3 -2
  169. package/dist/browser/history/HistoricalCaptureDecoder.js +4 -2
  170. package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
  171. package/dist/catalogIdentity.js +0 -1
  172. package/dist/cli/analysisSelector.js +23 -0
  173. package/dist/cli/analysisViewCommands.js +36 -0
  174. package/dist/cli/applicationCommands.js +2 -3
  175. package/dist/cli/artifactCommands.js +11 -12
  176. package/dist/cli/coreAnalysisCommands.js +3 -3
  177. package/dist/cli/coreBinaryCommands.js +100 -37
  178. package/dist/cli/coreNativeCommands.js +9 -10
  179. package/dist/cli/electronCommands.js +10 -9
  180. package/dist/cli/interactiveSetup.js +6 -6
  181. package/dist/cli/javascriptApplicationAnalysis.js +7 -3
  182. package/dist/cli/jsonOutput.js +4 -99
  183. package/dist/cli/managedCommands.js +7 -8
  184. package/dist/cli/nativeCallCommands.js +3 -5
  185. package/dist/cli/omittableDefaults.js +50 -0
  186. package/dist/cli/processCommands.js +3 -2
  187. package/dist/cli/setupCommands.js +16 -15
  188. package/dist/cli/utilityCommands.js +9 -9
  189. package/dist/cli/webRuntimeCommands.js +8 -8
  190. package/dist/cli.js +18 -9
  191. package/dist/cliBrowserScenarioCommands.js +2 -2
  192. package/dist/cliCommandNames.js +1 -1
  193. package/dist/cliJsonInput.js +24 -5
  194. package/dist/cliOutput.js +0 -38
  195. package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
  196. package/dist/composition/binary.js +9 -9
  197. package/dist/composition/browserScenario.js +2 -1
  198. package/dist/composition/directAnalysis.js +20 -13
  199. package/dist/composition/electronScenario.js +1 -1
  200. package/dist/composition/optionalObservationProviders.js +12 -7
  201. package/dist/config/environment.js +10 -0
  202. package/dist/config/ghidraStartupTimeout.js +12 -0
  203. package/dist/config/homeDirectory.js +12 -0
  204. package/dist/config/mcpResponseBudget.js +30 -0
  205. package/dist/config/parseConfig.js +8 -3
  206. package/dist/config/parsers.js +19 -22
  207. package/dist/contracts/analysisViewToolContracts.js +56 -0
  208. package/dist/contracts/applicationToolContracts.js +5 -4
  209. package/dist/contracts/artifactComparisonExample.js +2 -2
  210. package/dist/contracts/artifactToolContracts.js +1 -1
  211. package/dist/contracts/browserScenarioToolContracts.js +1 -1
  212. package/dist/contracts/browserToolContracts.js +19 -15
  213. package/dist/contracts/enhancedInputs.js +7 -5
  214. package/dist/contracts/enhancedToolContracts.js +7 -6
  215. package/dist/contracts/evm/evmToolContracts.js +1 -1
  216. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  217. package/dist/contracts/hopperMemoryContracts.js +2 -5
  218. package/dist/contracts/inputSchemaPresentation.js +90 -0
  219. package/dist/contracts/investigationExamples.js +4 -3
  220. package/dist/contracts/javascript/electronToolContracts.js +2 -2
  221. package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
  222. package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
  223. package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
  224. package/dist/contracts/managed/managedToolContracts.js +7 -14
  225. package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
  226. package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
  227. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
  228. package/dist/contracts/native/nativeToolContracts.js +5 -3
  229. package/dist/contracts/officialToolContracts.js +16 -16
  230. package/dist/contracts/promptContracts.js +5 -5
  231. package/dist/contracts/providerSelection.js +1 -1
  232. package/dist/contracts/sessionLifecycleInputs.js +3 -7
  233. package/dist/contracts/sessionStatusContract.js +2 -4
  234. package/dist/contracts/sessionToolContracts.js +18 -8
  235. package/dist/contracts/sessionToolSchemas.js +3 -19
  236. package/dist/contracts/toolContractExamples.js +0 -1
  237. package/dist/contracts/toolContractHelpers.js +4 -1
  238. package/dist/contracts/toolContracts.js +2 -0
  239. package/dist/contracts/toolEffects.js +1 -1
  240. package/dist/contracts/toolOutputSchemaGroups.js +160 -115
  241. package/dist/contracts/toolOutputSchemaPrimitives.js +28 -20
  242. package/dist/contracts/toolSchemaMetadata.js +41 -33
  243. package/dist/contracts/webNetworkCaptureToolContracts.js +2 -2
  244. package/dist/contracts/webRuntimeToolContracts.js +1 -1
  245. package/dist/contracts/webScriptToolContracts.js +1 -1
  246. package/dist/doctorRuntime.js +7 -5
  247. package/dist/domain/analysisErrorBase.js +8 -3
  248. package/dist/domain/analysisErrorCore.js +6 -1
  249. package/dist/domain/analysisErrorPresentation.js +90 -20
  250. package/dist/domain/analysisErrorProjection.js +130 -32
  251. package/dist/domain/analysisSnapshot.js +29 -31
  252. package/dist/domain/analysisView/analysisView.js +243 -0
  253. package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
  254. package/dist/domain/analysisView/binaryLayoutView.js +159 -0
  255. package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
  256. package/dist/domain/android/androidAnalysis.js +2 -4
  257. package/dist/domain/android/androidApplication.js +18 -10
  258. package/dist/domain/apple/appleApplication.js +42 -15
  259. package/dist/domain/apple/dyldEnvironment.js +73 -0
  260. package/dist/domain/apple/dylibResolution.js +130 -12
  261. package/dist/domain/apple/dylibResolutionFindings.js +9 -7
  262. package/dist/domain/apple/interfaceBuilderGraph.js +25 -14
  263. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
  264. package/dist/domain/apple/keyedArchive.js +35 -3
  265. package/dist/domain/apple/machoContainer.js +54 -0
  266. package/dist/domain/apple/plistNumbers.js +76 -0
  267. package/dist/domain/artifactComparison.js +15 -6
  268. package/dist/domain/artifactGraph.js +16 -3
  269. package/dist/domain/artifactIdentity.js +29 -0
  270. package/dist/domain/artifactInventoryEvidence.js +28 -40
  271. package/dist/domain/artifactOperationError.js +3 -3
  272. package/dist/domain/artifactPartialObservation.js +1 -0
  273. package/dist/domain/artifactPathSyntax.js +49 -0
  274. package/dist/domain/binaryTarget.js +39 -13
  275. package/dist/domain/bridgeCandidateProjection.js +71 -0
  276. package/dist/domain/browserCaptureComparison.js +13 -49
  277. package/dist/domain/browserCompleteness.js +1 -0
  278. package/dist/domain/browserNetworkEvidence.js +10 -4
  279. package/dist/domain/browserObservation.js +0 -1
  280. package/dist/domain/browserObservationError.js +24 -5
  281. package/dist/domain/browserObservationSchemas.js +14 -3
  282. package/dist/domain/browserScenario.js +0 -1
  283. package/dist/domain/browserScenarioCapture.js +1 -2
  284. package/dist/domain/browserScenarioDiff.js +0 -2
  285. package/dist/domain/browserScenarioDiffEvidence.js +0 -12
  286. package/dist/domain/browserScenarioDiffValues.js +2 -2
  287. package/dist/domain/browserScenarioValues.js +5 -10
  288. package/dist/domain/bundleComparison.js +3 -2
  289. package/dist/domain/callPath.js +8 -9
  290. package/dist/domain/callPathSchemas.js +2 -2
  291. package/dist/domain/canonicalJsonDigestSteps.js +133 -0
  292. package/dist/domain/canonicalOrdering.js +9 -5
  293. package/dist/domain/changedBehavior.js +9 -9
  294. package/dist/domain/comparisonSourceEvidence.js +40 -0
  295. package/dist/domain/completionLedgerGeneration.js +2 -1
  296. package/dist/domain/configurationErrors.js +13 -1
  297. package/dist/domain/conformancePackage.js +4 -3
  298. package/dist/domain/evidence.js +65 -36
  299. package/dist/domain/evidenceBundle.js +47 -8
  300. package/dist/domain/evidenceCompletionLedger.js +2 -1
  301. package/dist/domain/evidenceErrors.js +12 -1
  302. package/dist/domain/explicitSensitiveFailure.js +17 -1
  303. package/dist/domain/firmware/firmwareAnalysis.js +6 -7
  304. package/dist/domain/functionComparison.js +4 -5
  305. package/dist/domain/functionComparisonDimensions.js +120 -87
  306. package/dist/domain/functionComparisonNormalization.js +23 -34
  307. package/dist/domain/functionComparisonResults.js +1 -4
  308. package/dist/domain/functionComparisonSchemas.js +2 -8
  309. package/dist/domain/functionDossierEvidence.js +2 -37
  310. package/dist/domain/hopperErrors.js +23 -2
  311. package/dist/domain/hopperValues.js +51 -8
  312. package/dist/domain/immutableJson.js +114 -0
  313. package/dist/domain/inputIssueProjection.js +3 -0
  314. package/dist/domain/javascript/electronActiveObservation.js +47 -64
  315. package/dist/domain/javascript/electronObservation.js +14 -3
  316. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
  317. package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
  318. package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
  319. package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
  320. package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
  321. package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
  322. package/dist/domain/javascript/javascriptApplicationGraph.js +39 -3
  323. package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
  324. package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
  325. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
  326. package/dist/domain/javascript/javascriptAstValues.js +20 -0
  327. package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
  328. package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
  329. package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
  330. package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
  331. package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
  332. package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
  333. package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
  334. package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
  335. package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
  336. package/dist/domain/javascript/javascriptRecovery.js +3 -8
  337. package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
  338. package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
  339. package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
  340. package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
  341. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
  342. package/dist/domain/javascript/javascriptSemanticAnalysis.js +106 -5
  343. package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
  344. package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
  345. package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
  346. package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
  347. package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
  348. package/dist/domain/javascript/javascriptSemanticDataEffects.js +23 -6
  349. package/dist/domain/javascript/javascriptSemanticGraph.js +98 -43
  350. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
  351. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
  352. package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
  353. package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
  354. package/dist/domain/javascript/javascriptSemanticPrimitives.js +18 -21
  355. package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
  356. package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
  357. package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
  358. package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
  359. package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
  360. package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
  361. package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
  362. package/dist/domain/javascript/javascriptSemanticValues.js +126 -61
  363. package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
  364. package/dist/domain/javascript/javascriptSourceParser.js +6 -2
  365. package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
  366. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
  367. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +16 -5
  368. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
  369. package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -17
  370. package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
  371. package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
  372. package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
  373. package/dist/domain/jsonSerialization.js +109 -0
  374. package/dist/domain/jsonValue.js +90 -6
  375. package/dist/domain/localPath.js +6 -0
  376. package/dist/domain/managed/managedApplicationGraph.js +10 -10
  377. package/dist/domain/managed/managedArtifact.js +6 -4
  378. package/dist/domain/managed/managedInspectionEvidence.js +16 -0
  379. package/dist/domain/managed/managedMemberComparison.js +2 -9
  380. package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
  381. package/dist/domain/managed/managedNativeVerification.js +3 -11
  382. package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
  383. package/dist/domain/native/binaryLayout.js +2 -3
  384. package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
  385. package/dist/domain/native/nativeApiBoundary.js +1 -1
  386. package/dist/domain/native/nativeCallObservation.js +37 -13
  387. package/dist/domain/native/nativeCallPartialObservation.js +33 -0
  388. package/dist/domain/native/nativeInstruction.js +7 -0
  389. package/dist/domain/native/recordedCrash.js +2 -3
  390. package/dist/domain/offsetDateTime.js +17 -0
  391. package/dist/domain/process/processCapture.js +21 -16
  392. package/dist/domain/process/processCaptureCoverage.js +67 -0
  393. package/dist/domain/process/processCaptureExample.js +2 -1
  394. package/dist/domain/process/processCaptureParsing.js +1 -34
  395. package/dist/domain/process/processCaptureValidation.js +81 -13
  396. package/dist/domain/process/processComparison.js +79 -26
  397. package/dist/domain/process/processObservation.js +10 -2
  398. package/dist/domain/process/processScenario.js +35 -12
  399. package/dist/domain/process/processTraceComparison.js +0 -2
  400. package/dist/domain/process/processTraceDimensionProjection.js +1 -1
  401. package/dist/domain/process/processTraceEvaluation.js +15 -11
  402. package/dist/domain/process/processTraceSpecification.js +3 -4
  403. package/dist/domain/propertyListKeys.js +1 -1
  404. package/dist/domain/propertyListXmlText.js +19 -0
  405. package/dist/domain/providerAdapterError.js +3 -1
  406. package/dist/domain/providerOperationHealth.js +54 -0
  407. package/dist/domain/reconstructionCoverage.js +5 -2
  408. package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
  409. package/dist/domain/reconstructionReadinessSchemas.js +2 -1
  410. package/dist/domain/reconstructionVerification.js +9 -46
  411. package/dist/domain/reconstructionVerificationSchemas.js +4 -3
  412. package/dist/domain/referenceSourceGraph.js +20 -21
  413. package/dist/domain/staticRuntimeCorrelation.js +8 -45
  414. package/dist/domain/stringPatterns.js +6 -0
  415. package/dist/domain/swiftSymbolClassification.js +61 -0
  416. package/dist/domain/symbolAnalysis.js +66 -18
  417. package/dist/domain/webBundleAnalysis.js +20 -8
  418. package/dist/domain/webBundleAnalyzerInspection.js +13 -8
  419. package/dist/domain/webBundleAnalyzerResult.js +41 -2
  420. package/dist/domain/webCaptureDiff.js +0 -1
  421. package/dist/domain/webCaptureDiffSchemas.js +6 -3
  422. package/dist/domain/webEventListeners.js +3 -2
  423. package/dist/domain/webExecution.js +3 -2
  424. package/dist/domain/webRuntime.js +19 -7
  425. package/dist/domain/webScriptExport.js +1 -1
  426. package/dist/domain/webSourceLocation.js +1 -0
  427. package/dist/dotnet/ManagedArtifactInspector.js +2 -19
  428. package/dist/dotnet/ManagedMemberInspector.js +12 -18
  429. package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
  430. package/dist/dotnet/ManagedMemberRows.js +75 -62
  431. package/dist/dotnet/ManagedMetadataInventory.js +16 -22
  432. package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
  433. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
  434. package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
  435. package/dist/dotnet/ManagedReaderFailure.js +16 -0
  436. package/dist/dotnet/ManagedStaticProvider.js +3 -5
  437. package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
  438. package/dist/evaluation/AgentEvaluationReport.js +28 -0
  439. package/dist/evaluation/CodexAgentEval.js +12 -8
  440. package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
  441. package/dist/evm/EvmoleInterfaceProvider.js +2 -1
  442. package/dist/firmware/FirmwareCommand.js +9 -5
  443. package/dist/firmware/FirmwareFiles.js +1 -1
  444. package/dist/firmware/FirmwareProvider.js +4 -4
  445. package/dist/generatedPackageMetadata.js +2 -2
  446. package/dist/ghidra/GhidraAnalysisProfile.js +7 -5
  447. package/dist/ghidra/GhidraClient.js +126 -34
  448. package/dist/ghidra/GhidraClientStartup.js +0 -2
  449. package/dist/ghidra/GhidraDiagnostics.js +7 -7
  450. package/dist/ghidra/GhidraDoctor.js +6 -5
  451. package/dist/ghidra/GhidraFunctionValues.js +13 -12
  452. package/dist/ghidra/GhidraInstallation.js +58 -33
  453. package/dist/ghidra/GhidraInventoryValues.js +14 -4
  454. package/dist/ghidra/GhidraJavaLaunch.js +66 -0
  455. package/dist/ghidra/GhidraLauncher.js +47 -22
  456. package/dist/ghidra/GhidraProvider.js +6 -2
  457. package/dist/ghidra/GhidraProviderCapabilities.js +20 -2
  458. package/dist/ghidra/GhidraProviderClient.js +36 -15
  459. package/dist/ghidra/GhidraSessionError.js +13 -7
  460. package/dist/ghidra/GhidraSessionRoot.js +39 -0
  461. package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
  462. package/dist/ghidra/GhidraTransport.js +20 -0
  463. package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
  464. package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
  465. package/dist/hopper/BridgeLauncher.js +65 -56
  466. package/dist/hopper/HopperAnalysisProfile.js +65 -12
  467. package/dist/hopper/HopperCleanup.js +63 -22
  468. package/dist/hopper/HopperClient.js +288 -59
  469. package/dist/hopper/HopperFileOffset.js +237 -0
  470. package/dist/hopper/HopperMachOImage.js +197 -0
  471. package/dist/hopper/HopperOperationStage.js +6 -0
  472. package/dist/hopper/HopperProvider.js +71 -19
  473. package/dist/hopper/HopperProviderCapabilities.js +19 -1
  474. package/dist/hopper/HopperRegexSearch.js +134 -0
  475. package/dist/hopper/HopperRegexWorker.js +27 -0
  476. package/dist/hopper/HopperRequestQueue.js +68 -19
  477. package/dist/hopper/HopperTargetLease.js +133 -49
  478. package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
  479. package/dist/ida/IdaConfiguration.js +8 -3
  480. package/dist/ida/IdaInput.js +1 -7
  481. package/dist/ida/IdaMcpConnection.js +8 -4
  482. package/dist/ida/IdaOperationRunner.js +3 -3
  483. package/dist/ida/IdaProvider.js +8 -12
  484. package/dist/ida/IdaSessionClient.js +20 -18
  485. package/dist/ida/IdaWorkspace.js +12 -13
  486. package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
  487. package/dist/inspector/V8InspectorCaptureProjection.js +9 -4
  488. package/dist/inspector/V8InspectorProvider.js +82 -36
  489. package/dist/javascript/recovery/WakaruCommand.js +7 -2
  490. package/dist/javascript/recovery/WakaruExecution.js +5 -2
  491. package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
  492. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -0
  493. package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
  494. package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
  495. package/dist/main/shutdown.js +11 -3
  496. package/dist/main/startup.js +9 -2
  497. package/dist/main/transport.js +22 -2
  498. package/dist/main.js +11 -18
  499. package/dist/mcpDoctor.js +62 -2
  500. package/dist/native/AppleDispatchCoverage.js +47 -6
  501. package/dist/native/AppleDispatchDecodeFacts.js +6 -0
  502. package/dist/native/AppleDispatchMetadata.js +6 -3
  503. package/dist/native/AppleMachoFixups.js +48 -24
  504. package/dist/native/AppleMachoSelection.js +48 -22
  505. package/dist/native/AppleObjcCategories.js +6 -2
  506. package/dist/native/AppleObjcDispatchFacets.js +5 -2
  507. package/dist/native/AppleObjcProperties.js +2 -1
  508. package/dist/native/AppleSwiftDispatchFacets.js +27 -21
  509. package/dist/native/AppleSwiftVtables.js +21 -15
  510. package/dist/native/CommandRunner.js +87 -88
  511. package/dist/native/LldbCallTracer.js +372 -103
  512. package/dist/native/LldbRetainedObservations.js +178 -0
  513. package/dist/native/NativeCallObservation.js +62 -3
  514. package/dist/native/NativeMacOSProvider.js +122 -31
  515. package/dist/native/NativeUiHelperRuntime.js +11 -2
  516. package/dist/native/NativeUiObservation.js +2 -2
  517. package/dist/native/SignatureTargetBinding.js +155 -0
  518. package/dist/native/parsers/lipo.js +71 -1
  519. package/dist/native/pwndbg/PwndbgCoreContext.js +25 -5
  520. package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
  521. package/dist/native/pwntools/RecordedCrashStructureBindings.js +2 -0
  522. package/dist/process/DarwinProcessRunTokenReader.js +23 -10
  523. package/dist/process/ExecFileOutput.js +108 -6
  524. package/dist/process/OwnedCommand.js +7 -2
  525. package/dist/process/PrivateRuntimeRoot.js +10 -5
  526. package/dist/process/ProcessOwnership.js +204 -57
  527. package/dist/process/ProcessOwnershipObservation.js +60 -9
  528. package/dist/process/ProviderProcess.js +39 -10
  529. package/dist/process/capture/FilesystemSnapshot.js +50 -13
  530. package/dist/process/capture/ProcessCaptureError.js +15 -2
  531. package/dist/process/capture/ProcessCaptureLifecycle.js +235 -81
  532. package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
  533. package/dist/process/capture/ProcessHarness.js +21 -25
  534. package/dist/process/capture/ProcessNormalization.js +20 -2
  535. package/dist/process/capture/ProcessSampling.js +25 -2
  536. package/dist/process/capture/TerminalRenderer.js +14 -0
  537. package/dist/process/snapshotEnvironment.js +14 -0
  538. package/dist/server/EvidenceMcpServer.js +157 -0
  539. package/dist/server/createServer.js +61 -41
  540. package/dist/server/mcpClientMetadata.js +12 -5
  541. package/dist/server/promptCompletion.js +3 -8
  542. package/dist/server/registerAnalysisViewTool.js +15 -0
  543. package/dist/server/registerAndroidTools.js +2 -5
  544. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
  545. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  546. package/dist/server/registerApplicationTools/compareVersions.js +4 -5
  547. package/dist/server/registerApplicationTools/coverage.js +1 -2
  548. package/dist/server/registerApplicationTools/helpers.js +1 -4
  549. package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
  550. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
  551. package/dist/server/registerApplicationTools/traceFeature.js +4 -5
  552. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  553. package/dist/server/registerArtifactComparisonTool.js +13 -10
  554. package/dist/server/registerBinaryDiagnosticsTools.js +2 -5
  555. package/dist/server/registerBrowserScenarioTool.js +3 -6
  556. package/dist/server/registerBrowserTools.js +13 -18
  557. package/dist/server/registerBundleComparisonTool.js +5 -7
  558. package/dist/server/registerCloseLifecycleTool.js +9 -20
  559. package/dist/server/registerElectronTools.js +10 -15
  560. package/dist/server/registerEnhancedTools.js +36 -77
  561. package/dist/server/registerEvidenceTools.js +3 -6
  562. package/dist/server/registerEvmTools.js +2 -5
  563. package/dist/server/registerFirmwareTools.js +2 -5
  564. package/dist/server/registerFunctionComparisonTool.js +15 -12
  565. package/dist/server/registerInvestigationTools.js +16 -17
  566. package/dist/server/registerJavaScriptRecoveryTool.js +2 -5
  567. package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -8
  568. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -8
  569. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -7
  570. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -9
  571. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -9
  572. package/dist/server/registerOfficialTools.js +4 -21
  573. package/dist/server/registerProcessComparisonTool.js +74 -48
  574. package/dist/server/registerRecordedCrashTools.js +2 -5
  575. package/dist/server/registerSessionRecordTools.js +19 -24
  576. package/dist/server/registerSessionStatusTool.js +19 -6
  577. package/dist/server/registerSessionTools.js +20 -18
  578. package/dist/server/registerWebModuleTool.js +2 -5
  579. package/dist/server/registerWebNetworkCaptureTool.js +2 -5
  580. package/dist/server/registerWebRuntimeTools.js +4 -9
  581. package/dist/server/registerWebScriptTool.js +2 -5
  582. package/dist/server/registerWebSourceLocationTool.js +2 -5
  583. package/dist/server/runDerivedOperation.js +15 -3
  584. package/dist/server/sessionAvailabilityPolicy.js +0 -1
  585. package/dist/server/toolRegistrationOptions.js +2 -2
  586. package/dist/server/toolResult.js +75 -51
  587. package/dist/server/toolResultEncoding.js +34 -0
  588. package/dist/windows/WindowsNativeLoader.js +1 -0
  589. package/dist/windows/WindowsOwnedProcess.js +60 -15
  590. package/dist/windows/WindowsPrivateRuntime.js +7 -8
  591. package/install.sh +1 -1
  592. package/native/windows/README.md +3 -1
  593. package/native/windows/build/manifest.json +2 -2
  594. package/native/windows/build/rea-windows-x64.node +0 -0
  595. package/package.json +44 -30
  596. package/scripts/electron-active-hook-boundaries.cjs +18 -20
  597. package/scripts/electron-active-hook.cjs +241 -37
  598. package/scripts/rea.mjs +3 -6
  599. package/skills/reverse-engineer-anything/SKILL.md +12 -3
  600. package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
  601. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
  602. package/skills/reverse-engineer-anything/references/javascript-applications.md +20 -3
  603. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
  604. package/dist/config.js +0 -1
  605. package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
  606. package/dist/contracts/process/processCaptureExample.js +0 -2
  607. package/dist/contracts/toolOutputSchemas.js +0 -2
  608. package/dist/ghidra/GhidraDefaults.js +0 -2
  609. package/dist/main/reload.js +0 -12
  610. package/dist/main/state.js +0 -3
  611. package/dist/server/sessionToolPolicies.js +0 -2
@@ -0,0 +1,237 @@
1
+ import { createHash } from "node:crypto";
2
+ import { constants } from "node:fs";
3
+ import { open } from "node:fs/promises";
4
+ import { z } from "zod";
5
+ import { AnalysisAccessDeniedError, AnalysisArtifactChangedError, AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisOutputError, } from "../domain/analysisErrorCore.js";
6
+ import { BinaryTargetError } from "../domain/configurationErrors.js";
7
+ import { readFatSliceDeclarations, validateFatSlice, } from "../domain/apple/machoContainer.js";
8
+ import { err, ok } from "../domain/result.js";
9
+ const OPERATION = "address_to_file_offset";
10
+ const MAX_FAT_ARCHITECTURES = 128;
11
+ const PREFIX_BYTES = 8 + MAX_FAT_ARCHITECTURES * 32;
12
+ const observationSchema = z.strictObject({
13
+ address: z.string().regex(/^0x[0-9a-f]+$/u),
14
+ provider_file_offset: z
15
+ .number()
16
+ .int()
17
+ .nonnegative()
18
+ .max(Number.MAX_SAFE_INTEGER),
19
+ provider_source_path: z.string().nullable(),
20
+ provider_image_header_hex: z
21
+ .string()
22
+ .regex(/^[a-f0-9]{24}$/u)
23
+ .nullable(),
24
+ });
25
+ /** Bind native image-relative offsets to coordinates in the admitted source bytes. */
26
+ export async function mapHopperFileOffset(target, value, signal) {
27
+ const parsed = observationSchema.safeParse(value);
28
+ if (!parsed.success)
29
+ return err(new AnalysisOutputError(OPERATION, "Hopper's native file mapping observation is malformed"));
30
+ const observation = parsed.data;
31
+ const partial = (reason) => ({
32
+ operation: OPERATION,
33
+ ...observation,
34
+ original_file_offset: { available: false, reason },
35
+ });
36
+ const unavailable = (reason) => err(new AnalysisCapabilityUnavailableError("hopper", OPERATION, reason, {
37
+ partialObservation: partial(reason),
38
+ }));
39
+ if (target.kind !== "executable")
40
+ return unavailable("The selected database digest does not identify its original executable bytes. Open that executable to verify original-file coordinates; read_bytes still exposes the database's native bytes.");
41
+ if (signal?.aborted)
42
+ return err(new AnalysisCancelledError(OPERATION, {
43
+ partialObservation: partial("Source verification was cancelled"),
44
+ }));
45
+ try {
46
+ const captured = await snapshotFromPath(target.path, signal);
47
+ if (!captured.ok)
48
+ return err(new AnalysisArtifactChangedError(OPERATION, target.path, captured.error, {
49
+ partialObservation: partial(captured.error),
50
+ }));
51
+ const snapshot = captured.value;
52
+ if (signal?.aborted)
53
+ return err(new AnalysisCancelledError(OPERATION, {
54
+ partialObservation: partial("Source verification was cancelled"),
55
+ }));
56
+ if (snapshot.sha256 !== target.sha256) {
57
+ const reason = `Source ${target.path} differs from the admitted artifact: expected SHA-256 ${target.sha256}, observed ${snapshot.sha256}. Reopen the changed source for a new analysis identity.`;
58
+ return err(new AnalysisArtifactChangedError(OPERATION, target.path, reason, {
59
+ partialObservation: partial(reason),
60
+ }));
61
+ }
62
+ const mapped = originalOffset(snapshot, observation);
63
+ if (!mapped.ok)
64
+ return unavailable(mapped.error);
65
+ return ok({
66
+ address: observation.address,
67
+ file_offset: mapped.value + observation.provider_file_offset,
68
+ provider_file_offset: observation.provider_file_offset,
69
+ image_base_file_offset: mapped.value,
70
+ source_path: target.path,
71
+ });
72
+ }
73
+ catch (cause) {
74
+ if (signal?.aborted)
75
+ return err(new AnalysisCancelledError(OPERATION, {
76
+ cause,
77
+ partialObservation: partial("Source verification was cancelled"),
78
+ }));
79
+ const reason = `Cannot verify original source bytes: ${cause instanceof Error ? cause.message : String(cause)}`;
80
+ const code = typeof cause === "object" && cause !== null && "code" in cause
81
+ ? cause.code
82
+ : undefined;
83
+ if (code === "EACCES" || code === "EPERM")
84
+ return err(new AnalysisAccessDeniedError(OPERATION, target.path, code, {
85
+ cause,
86
+ partialObservation: partial(reason),
87
+ }));
88
+ return err(new BinaryTargetError(target.path, reason, {
89
+ cause,
90
+ partialObservation: partial(reason),
91
+ }));
92
+ }
93
+ }
94
+ async function snapshotFromPath(path, signal) {
95
+ const file = await open(path, constants.O_RDONLY | constants.O_NONBLOCK);
96
+ try {
97
+ if (!(await file.stat()).isFile())
98
+ return err(`Source ${path} is no longer a regular file. Restore the admitted executable or reopen a regular source.`);
99
+ return ok(await readSourceSnapshot(file, signal));
100
+ }
101
+ finally {
102
+ await file.close();
103
+ }
104
+ }
105
+ function fatLayout(prefix) {
106
+ const magic = prefix.length < 4 ? 0 : prefix.readUInt32BE(0);
107
+ if (![0xcafebabe, 0xbebafeca, 0xcafebabf, 0xbfbafeca].includes(magic))
108
+ return ok(null);
109
+ if (prefix.length < 8)
110
+ return err("The original FAT header is truncated");
111
+ const littleEndian = magic === 0xbebafeca || magic === 0xbfbafeca;
112
+ const wide = magic === 0xcafebabf || magic === 0xbfbafeca;
113
+ const count = littleEndian ? prefix.readUInt32LE(4) : prefix.readUInt32BE(4);
114
+ if (count === 0 || count > MAX_FAT_ARCHITECTURES)
115
+ return err("FAT architecture count is outside the supported 1..128 range");
116
+ const tableEnd = 8 + count * (wide ? 32 : 20);
117
+ const table = prefix.subarray(8, tableEnd);
118
+ const parsed = readFatSliceDeclarations(table, { count, wide, littleEndian });
119
+ if (parsed.status !== "parsed")
120
+ return err(parsed.reason);
121
+ if (wide) {
122
+ for (const slice of parsed.slices)
123
+ if ((littleEndian
124
+ ? table.readUInt32LE(slice.index * 32 + 28)
125
+ : table.readUInt32BE(slice.index * 32 + 28)) !== 0)
126
+ return err(`FAT64 architecture ${slice.index} has a nonzero reserved field`);
127
+ }
128
+ return ok({ slices: parsed.slices, tableEnd });
129
+ }
130
+ async function readSourceSnapshot(file, signal) {
131
+ const prefix = Buffer.alloc(PREFIX_BYTES);
132
+ const hash = createHash("sha256");
133
+ let size = 0;
134
+ let layout;
135
+ const headers = new Map();
136
+ const capture = (bytes, position) => {
137
+ if (layout?.ok !== true || layout.value === null)
138
+ return;
139
+ for (const slice of layout.value.slices) {
140
+ const start = Math.max(position, slice.offset);
141
+ const end = Math.min(position + bytes.length, slice.offset + 12);
142
+ if (end <= start)
143
+ continue;
144
+ let header = headers.get(slice.index);
145
+ if (header === undefined) {
146
+ header = Buffer.alloc(12);
147
+ headers.set(slice.index, header);
148
+ }
149
+ bytes.copy(header, start - slice.offset, start - position, end - position);
150
+ }
151
+ };
152
+ for await (const chunk of file.createReadStream({
153
+ start: 0,
154
+ autoClose: false,
155
+ ...(signal === undefined ? {} : { signal }),
156
+ })) {
157
+ const bytes = Buffer.from(chunk);
158
+ hash.update(bytes);
159
+ if (size < prefix.length)
160
+ bytes.copy(prefix, size, 0, Math.min(bytes.length, prefix.length - size));
161
+ if (layout === undefined && size + bytes.length >= prefix.length) {
162
+ layout = fatLayout(prefix);
163
+ capture(prefix, 0);
164
+ }
165
+ capture(bytes, size);
166
+ size += bytes.length;
167
+ }
168
+ if (layout === undefined) {
169
+ layout = fatLayout(prefix.subarray(0, size));
170
+ capture(prefix.subarray(0, size), 0);
171
+ }
172
+ return { layout, headers, size, sha256: hash.digest("hex") };
173
+ }
174
+ function originalOffset(snapshot, observation) {
175
+ const { layout, size, headers } = snapshot;
176
+ if (!layout.ok)
177
+ return layout;
178
+ if (layout.value === null)
179
+ return observation.provider_file_offset < size
180
+ ? ok(0)
181
+ : err("Provider mapping lies outside the admitted executable bytes");
182
+ const header = observation.provider_image_header_hex === null
183
+ ? null
184
+ : Buffer.from(observation.provider_image_header_hex, "hex");
185
+ const loadedMagic = header?.readUInt32BE(0);
186
+ if (header === null ||
187
+ loadedMagic === undefined ||
188
+ ![0xfeedface, 0xfeedfacf, 0xcefaedfe, 0xcffaedfe].includes(loadedMagic))
189
+ return err("Hopper did not expose the loaded Mach-O header needed to identify its FAT slice");
190
+ const little = loadedMagic === 0xcefaedfe || loadedMagic === 0xcffaedfe;
191
+ const cpu = little ? header.readUInt32LE(4) : header.readUInt32BE(4);
192
+ const subtype = little ? header.readUInt32LE(8) : header.readUInt32BE(8);
193
+ const matches = [];
194
+ const ranges = [...layout.value.slices].sort((a, b) => a.offset - b.offset);
195
+ for (let index = 1; index < ranges.length; index++) {
196
+ const previous = ranges[index - 1];
197
+ const current = ranges[index];
198
+ if (previous !== undefined &&
199
+ current !== undefined &&
200
+ current.offset < previous.offset + previous.size)
201
+ return err("Original FAT slices overlap");
202
+ }
203
+ for (const slice of layout.value.slices) {
204
+ const reason = validateFatSlice(slice, size, layout.value.tableEnd);
205
+ if (reason !== null)
206
+ return err(reason);
207
+ const embedded = headers.get(slice.index);
208
+ if (slice.size < 12 || embedded === undefined)
209
+ return err(`FAT architecture ${slice.index} has a truncated Mach-O header`);
210
+ const embeddedMagic = embedded.readUInt32BE(0);
211
+ if (![0xfeedface, 0xfeedfacf, 0xcefaedfe, 0xcffaedfe].includes(embeddedMagic))
212
+ return err(`FAT architecture ${slice.index} does not contain a Mach-O image`);
213
+ const embeddedLittle = embeddedMagic === 0xcefaedfe || embeddedMagic === 0xcffaedfe;
214
+ const identityError = validateFatSlice(slice, size, layout.value.tableEnd, {
215
+ cpuType: embeddedLittle
216
+ ? embedded.readUInt32LE(4)
217
+ : embedded.readUInt32BE(4),
218
+ cpuSubtype: embeddedLittle
219
+ ? embedded.readUInt32LE(8)
220
+ : embedded.readUInt32BE(8),
221
+ });
222
+ if (identityError !== null)
223
+ return err(identityError);
224
+ if (slice.cpuType === cpu && slice.cpuSubtype === subtype)
225
+ matches.push(slice);
226
+ }
227
+ const selected = matches.length === 1 ? matches[0] : undefined;
228
+ if (selected === undefined)
229
+ return err(`Original FAT slice matching Hopper's loaded header is ${matches.length === 0 ? "missing" : "ambiguous"}`);
230
+ if (headers.get(selected.index)?.equals(header) !== true)
231
+ return err("Original FAT slice header disagrees with Hopper's loaded header");
232
+ if (observation.provider_file_offset >= selected.size)
233
+ return err("Provider mapping lies outside the loaded FAT slice");
234
+ if (!Number.isSafeInteger(selected.offset + observation.provider_file_offset))
235
+ return err("Original file offset exceeds the exact JSON integer range");
236
+ return ok(selected.offset);
237
+ }
@@ -0,0 +1,197 @@
1
+ import { createHash } from "node:crypto";
2
+ import { open } from "node:fs/promises";
3
+ import { z } from "zod";
4
+ import { BinaryTargetError } from "../domain/configurationErrors.js";
5
+ import { AnalysisCancelledError } from "../domain/analysisErrorCore.js";
6
+ import { readFatSliceDeclarations, validateFatSlice, } from "../domain/apple/machoContainer.js";
7
+ import { HopperCancelledError, HopperStartError, } from "../domain/hopperErrors.js";
8
+ import { err, ok } from "../domain/result.js";
9
+ /** Stable source coordinates committed before preparing an owned thin image. */
10
+ export const hopperMachOImageSchema = z.strictObject({
11
+ method: z.literal("fat64_thin_slice"),
12
+ architecture_count: z.number().int().min(1).max(128),
13
+ container_table_sha256: z.string().regex(/^[a-f0-9]{64}$/u),
14
+ source_offset: z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER),
15
+ byte_length: z.number().int().positive().max(Number.MAX_SAFE_INTEGER),
16
+ cpu_type: z.number().int().nonnegative(),
17
+ cpu_subtype: z.number().int().nonnegative(),
18
+ });
19
+ /** Validate the selected FAT64 slice without depending on Apple's lipo tool. */
20
+ export const resolveHopperMachOImage = async (target, signal) => {
21
+ const invalid = (reason, cause) => err(new BinaryTargetError(target.path, reason, cause === undefined ? undefined : { cause }));
22
+ if (signal?.aborted)
23
+ return err(new AnalysisCancelledError("open_binary"));
24
+ let file;
25
+ try {
26
+ file = await open(target.path, "r");
27
+ }
28
+ catch (cause) {
29
+ // Keep the OS error so a read-permission denial reports access_denied.
30
+ return invalid(`Cannot read FAT64 source for Hopper image preparation: ${cause instanceof Error ? cause.message : String(cause)}`, cause);
31
+ }
32
+ try {
33
+ const read = async (offset, length) => {
34
+ const bytes = Buffer.alloc(length);
35
+ const { bytesRead } = await file.read(bytes, 0, length, offset);
36
+ return bytes.subarray(0, bytesRead);
37
+ };
38
+ const header = await read(0, 8);
39
+ const magic = header.length === 8 ? header.readUInt32BE(0) : 0;
40
+ if (magic !== 0xcafebabf && magic !== 0xbfbafeca)
41
+ return invalid("FAT64 source header changed before Hopper image preparation");
42
+ const littleEndian = magic === 0xbfbafeca;
43
+ const count = littleEndian
44
+ ? header.readUInt32LE(4)
45
+ : header.readUInt32BE(4);
46
+ const size = (await file.stat()).size;
47
+ const tableEnd = 8 + count * 32;
48
+ if (count === 0 || count > 128 || tableEnd > size)
49
+ return invalid("FAT64 architecture table is truncated or exceeds the supported 128 entries");
50
+ const table = await read(8, count * 32);
51
+ const parsed = readFatSliceDeclarations(table, {
52
+ count,
53
+ wide: true,
54
+ littleEndian,
55
+ });
56
+ if (parsed.status === "malformed")
57
+ return invalid(parsed.reason);
58
+ const cpuTypes = { x86: 7, x86_64: 0x1000007, arm: 12, arm64: 0x100000c };
59
+ const matches = [];
60
+ const ranges = [];
61
+ for (const slice of parsed.slices) {
62
+ if (signal?.aborted)
63
+ return err(new AnalysisCancelledError("open_binary"));
64
+ const rangeError = validateFatSlice(slice, size, tableEnd);
65
+ if (rangeError !== null)
66
+ return invalid(rangeError);
67
+ const reserved = littleEndian
68
+ ? table.readUInt32LE(slice.index * 32 + 28)
69
+ : table.readUInt32BE(slice.index * 32 + 28);
70
+ if (reserved !== 0)
71
+ return invalid(`FAT64 architecture ${slice.index} has a nonzero reserved field`);
72
+ if (slice.size < 12)
73
+ return invalid(`FAT64 architecture ${slice.index} has a truncated Mach-O header`);
74
+ const embedded = await read(slice.offset, 12);
75
+ if (embedded.length !== 12)
76
+ return invalid(`FAT64 architecture ${slice.index} became truncated`);
77
+ const thinMagic = embedded.readUInt32BE(0);
78
+ if (![0xfeedface, 0xfeedfacf, 0xcefaedfe, 0xcffaedfe].includes(thinMagic))
79
+ return invalid(`FAT64 architecture ${slice.index} does not contain a Mach-O image`);
80
+ const little = thinMagic === 0xcefaedfe || thinMagic === 0xcffaedfe;
81
+ const identity = {
82
+ cpuType: little ? embedded.readUInt32LE(4) : embedded.readUInt32BE(4),
83
+ cpuSubtype: little
84
+ ? embedded.readUInt32LE(8)
85
+ : embedded.readUInt32BE(8),
86
+ };
87
+ const identityError = validateFatSlice(slice, size, tableEnd, identity);
88
+ if (identityError !== null)
89
+ return invalid(identityError);
90
+ ranges.push(slice);
91
+ if (slice.cpuType === cpuTypes[target.architecture])
92
+ matches.push(slice);
93
+ }
94
+ ranges.sort((a, b) => a.offset - b.offset);
95
+ for (let index = 1; index < ranges.length; index++) {
96
+ const previous = ranges[index - 1];
97
+ const current = ranges[index];
98
+ if (previous !== undefined &&
99
+ current !== undefined &&
100
+ current.offset < previous.offset + previous.size)
101
+ return invalid("FAT64 slices overlap");
102
+ }
103
+ const selected = matches.length === 1 ? matches[0] : undefined;
104
+ if (selected === undefined)
105
+ return invalid(`FAT64 selection for ${target.architecture} is ${matches.length === 0 ? "missing" : "ambiguous"}; extract the exact architecture into a thin image before opening it`);
106
+ return ok({
107
+ method: "fat64_thin_slice",
108
+ architecture_count: count,
109
+ container_table_sha256: createHash("sha256")
110
+ .update(header)
111
+ .update(table)
112
+ .digest("hex"),
113
+ source_offset: selected.offset,
114
+ byte_length: selected.size,
115
+ cpu_type: selected.cpuType,
116
+ cpu_subtype: selected.cpuSubtype,
117
+ });
118
+ }
119
+ catch (cause) {
120
+ return invalid(`Cannot validate FAT64 image: ${cause instanceof Error ? cause.message : String(cause)}`);
121
+ }
122
+ finally {
123
+ await file.close();
124
+ }
125
+ };
126
+ /** Copy a selected slice and verify the entire original source in the same pass. */
127
+ export const prepareHopperMachOImage = async (sourcePath, sourceSha256, image, destination, signal) => {
128
+ if (signal?.aborted)
129
+ return err(new HopperCancelledError());
130
+ try {
131
+ const source = await open(sourcePath, "r");
132
+ try {
133
+ const output = await open(destination, "wx", 0o600);
134
+ try {
135
+ const hash = createHash("sha256");
136
+ const tableHash = createHash("sha256");
137
+ const tableEnd = 8 + image.architecture_count * 32;
138
+ const thinHeader = [];
139
+ let position = 0;
140
+ let copied = 0;
141
+ for await (const chunk of source.createReadStream({
142
+ autoClose: false,
143
+ })) {
144
+ if (signal?.aborted)
145
+ return err(new HopperCancelledError());
146
+ const bytes = Buffer.from(chunk);
147
+ hash.update(bytes);
148
+ if (position < tableEnd)
149
+ tableHash.update(bytes.subarray(0, Math.min(bytes.length, tableEnd - position)));
150
+ const start = Math.max(0, image.source_offset - position);
151
+ const end = Math.min(bytes.length, image.source_offset + image.byte_length - position);
152
+ if (end > start) {
153
+ if (copied < 12)
154
+ thinHeader.push(bytes.subarray(start, Math.min(end, start + 12 - copied)));
155
+ await output.writeFile(bytes.subarray(start, end));
156
+ copied += end - start;
157
+ }
158
+ position += bytes.length;
159
+ }
160
+ const observed = hash.digest("hex");
161
+ const header = Buffer.concat(thinHeader);
162
+ const magic = header.length === 12 ? header.readUInt32BE(0) : 0;
163
+ const little = magic === 0xcefaedfe || magic === 0xcffaedfe;
164
+ const headerMatches = header.length === 12 &&
165
+ [0xfeedface, 0xfeedfacf, 0xcefaedfe, 0xcffaedfe].includes(magic) &&
166
+ (little ? header.readUInt32LE(4) : header.readUInt32BE(4)) ===
167
+ image.cpu_type &&
168
+ (little ? header.readUInt32LE(8) : header.readUInt32BE(8)) ===
169
+ image.cpu_subtype;
170
+ if (tableHash.digest("hex") !== image.container_table_sha256 ||
171
+ !headerMatches)
172
+ return err(new HopperStartError({
173
+ userMessage: `FAT64 source ${sourcePath} no longer agrees with its committed architecture table or selected Mach-O header. Open the stable source again.`,
174
+ }));
175
+ if (observed !== sourceSha256 || copied !== image.byte_length)
176
+ return err(new HopperStartError({
177
+ userMessage: `FAT64 source ${sourcePath} changed before launch: expected SHA-256 ${sourceSha256}, observed ${observed}; copied ${copied} of ${image.byte_length} selected bytes. Open the stable source again.`,
178
+ }));
179
+ return ok(destination);
180
+ }
181
+ finally {
182
+ await output.close();
183
+ }
184
+ }
185
+ finally {
186
+ await source.close();
187
+ }
188
+ }
189
+ catch (cause) {
190
+ return signal?.aborted
191
+ ? err(new HopperCancelledError())
192
+ : err(new HopperStartError({
193
+ cause,
194
+ userMessage: `Cannot prepare the selected FAT64 image from ${sourcePath}: ${cause instanceof Error ? cause.message : String(cause)}`,
195
+ }));
196
+ }
197
+ };
@@ -0,0 +1,6 @@
1
+ /** Classify Hopper wire operations at their provider boundary. */
2
+ export const hopperOperationStage = (operation) => {
3
+ if (operation === "health")
4
+ return "connection";
5
+ return operation === "procedure_pseudo_code" ? "decompilation" : "analysis";
6
+ };
@@ -1,32 +1,36 @@
1
+ import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
1
2
  import { fileURLToPath } from "node:url";
2
3
  import { accessSync, constants } from "node:fs";
3
4
  import { createAnalysisExecution } from "../application/AnalysisProvider.js";
4
5
  import { AnalysisCapabilityUnavailableError } from "../domain/analysisErrorCore.js";
5
- import { err } from "../domain/result.js";
6
+ import { err, ok } from "../domain/result.js";
6
7
  import { HopperApplicationLauncher } from "./BridgeLauncher.js";
7
8
  import { hopperLoaderArgsForTarget, resolveHopperAnalysisProfile, } from "./HopperAnalysisProfile.js";
9
+ import { mapHopperFileOffset } from "./HopperFileOffset.js";
10
+ import { HopperRegexSearch } from "./HopperRegexSearch.js";
8
11
  import { HopperClient } from "./HopperClient.js";
12
+ import { hopperMachOImageSchema } from "./HopperMachOImage.js";
9
13
  import { CAPABILITIES, HOPPER_PROVIDER_IDENTITY, } from "./HopperProviderCapabilities.js";
10
- export { HOPPER_PROVIDER_IDENTITY, HOPPER_OPERATIONS, } from "./HopperProviderCapabilities.js";
11
- const IDENTITY = HOPPER_PROVIDER_IDENTITY;
12
14
  /** Concrete analysis provider backed by REA's private Hopper bridge. */
13
15
  export class HopperProvider {
14
16
  config;
15
17
  logger;
16
18
  platform;
19
+ environment;
17
20
  /**
18
21
  * Host platform, injected so availability and launch-mode decisions can be
19
22
  * exercised for any host rather than only the machine running the suite.
20
23
  * Mirrors `GhidraProvider`, which already threads its installation host's
21
24
  * platform the same way.
22
25
  */
23
- constructor(config, logger, platform = process.platform) {
26
+ constructor(config, logger, environment, platform = process.platform) {
24
27
  this.config = config;
25
28
  this.logger = logger;
26
29
  this.platform = platform;
30
+ this.environment = snapshotEnvironment(environment, platform);
27
31
  }
28
32
  identity() {
29
- return IDENTITY;
33
+ return HOPPER_PROVIDER_IDENTITY;
30
34
  }
31
35
  capabilities() {
32
36
  return CAPABILITIES;
@@ -101,28 +105,52 @@ export class HopperProvider {
101
105
  return resolveHopperAnalysisProfile(target, {
102
106
  launcherPath: this.config.hopperLauncherPath,
103
107
  loaderArgsOverride: this.config.hopperLoaderArgs,
104
- provider: IDENTITY,
108
+ provider: HOPPER_PROVIDER_IDENTITY,
105
109
  ...(options?.signal === undefined ? {} : { signal: options.signal }),
106
110
  });
107
111
  }
108
112
  createClient(target, profile, context) {
109
113
  if (target.kind !== "executable" && target.kind !== "database")
110
114
  return {
111
- execute: (operation) => Promise.resolve(err(new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, `Hopper cannot open ${target.kind} targets directly. Inventory or extract the artifact first.`))),
112
- close: () => Promise.resolve(),
115
+ execute: (operation) => Promise.resolve(err(new AnalysisCapabilityUnavailableError(HOPPER_PROVIDER_IDENTITY.id, operation, `Hopper cannot open ${target.kind} targets directly. Inventory or extract the artifact first.`))),
116
+ close: () => Promise.resolve(ok(null)),
113
117
  };
114
- const derivedLoaderArgs = hopperLoaderArgsForTarget(target);
118
+ const preparation = profile?.parameters.prepared_image;
119
+ const parsedImage = preparation === undefined
120
+ ? undefined
121
+ : hopperMachOImageSchema.safeParse(preparation);
122
+ if (parsedImage?.success === false)
123
+ return {
124
+ execute: (operation) => Promise.resolve(err(new AnalysisCapabilityUnavailableError(HOPPER_PROVIDER_IDENTITY.id, operation, "Hopper prepared-image profile is malformed; resolve the analysis profile again."))),
125
+ close: () => Promise.resolve(ok(null)),
126
+ };
127
+ const preparedImage = parsedImage?.data;
128
+ const container = preparedImage === undefined
129
+ ? profile?.parameters.macho_container
130
+ : "thin";
131
+ const derivedLoaderArgs = hopperLoaderArgsForTarget(target, container === "thin" || container === "fat32" || container === "fat64"
132
+ ? container
133
+ : undefined);
115
134
  if (!derivedLoaderArgs.ok)
116
135
  return {
117
136
  execute: () => Promise.resolve(err(derivedLoaderArgs.error)),
118
- close: () => Promise.resolve(),
137
+ close: () => Promise.resolve(ok(null)),
119
138
  };
120
- const executionProvider = profile?.provider ?? IDENTITY;
139
+ const executionProvider = profile?.provider ?? HOPPER_PROVIDER_IDENTITY;
121
140
  const client = new HopperClient({
122
141
  launcher: new HopperApplicationLauncher({
142
+ environment: this.environment,
123
143
  launcherPath: this.config.hopperLauncherPath,
124
144
  targetPath: target.path,
125
145
  targetKind: target.kind,
146
+ ...(preparedImage === undefined
147
+ ? {}
148
+ : {
149
+ preparedImage: {
150
+ image: preparedImage,
151
+ sourceSha256: target.sha256,
152
+ },
153
+ }),
126
154
  loaderArgs: this.config.hopperLoaderArgs.length > 0
127
155
  ? this.config.hopperLoaderArgs
128
156
  : derivedLoaderArgs.value,
@@ -138,25 +166,46 @@ export class HopperProvider {
138
166
  logger: this.logger.child({ layer: "bridge" }),
139
167
  onDiagnostic: (diagnostic) => this.logger.info(diagnostic, "Hopper bridge reported a diagnostic"),
140
168
  });
169
+ const regexSearch = new HopperRegexSearch(client);
141
170
  return {
142
171
  execute: async (operation, parameters, options) => {
143
- const result = await client.callTool(operation, parameters, options);
144
- return result.ok
172
+ const result = (operation === "search_strings" ||
173
+ operation === "search_procedures") &&
174
+ parameters.mode === "regex"
175
+ ? await regexSearch.execute(operation, parameters, options)
176
+ : await client.callTool(operation, parameters, options);
177
+ if (!result.ok)
178
+ return result;
179
+ const mapped = operation === "address_to_file_offset"
180
+ ? await mapHopperFileOffset(target, result.value, options?.signal)
181
+ : result;
182
+ return mapped.ok
145
183
  ? {
146
184
  ok: true,
147
- value: createAnalysisExecution(result.value, executionProvider, {
185
+ value: createAnalysisExecution(mapped.value, executionProvider, {
186
+ rawResult: result.value,
148
187
  ...(profile === undefined ? {} : { analysisProfile: profile }),
149
188
  limitations: [
150
- "Results depend on Hopper's completed static analysis.",
189
+ ...(preparedImage === undefined
190
+ ? []
191
+ : [
192
+ "REA loaded a verified thin Mach-O slice from the original FAT64 source. Identity and file offsets refer to the original file. The owned temporary image and its Hopper document close together, including on MCP shutdown.",
193
+ ]),
194
+ ...(CAPABILITIES.find((descriptor) => descriptor.operation === operation)?.limitations ?? []),
195
+ ...(operation === "read_bytes"
196
+ ? [
197
+ "Hopper byte reads stop at the containing segment's exclusive end; a readable prefix is returned with complete=false when the requested range crosses it.",
198
+ ]
199
+ : []),
151
200
  ...(operation === "procedure_references"
152
201
  ? [
153
- "Hopper's public Python API does not expose flow classification for calls without resolved targets; unresolved_calls is empty and its coverage is unknown.",
202
+ "Native CallReference classifications and unresolved targets are preserved. Detailed reference flags and coverage beyond reported CallReference objects remain unknown.",
154
203
  ]
155
204
  : []),
156
205
  ],
157
206
  }),
158
207
  }
159
- : result;
208
+ : mapped;
160
209
  },
161
210
  runtimeLineageSnapshots: () => {
162
211
  const observation = client.runtimeLineage();
@@ -181,8 +230,11 @@ export class HopperProvider {
181
230
  },
182
231
  ];
183
232
  },
184
- closeWithOutcome: (options) => client.closeWithOutcome(options),
185
- close: () => client.close(),
233
+ operationHealthSnapshot: () => client.operationHealth(),
234
+ close: async (options) => {
235
+ await regexSearch.close();
236
+ return client.close(options);
237
+ },
186
238
  };
187
239
  }
188
240
  }
@@ -38,7 +38,6 @@ export const HOPPER_OPERATIONS = Object.freeze([
38
38
  "set_addresses_names",
39
39
  "set_bookmark",
40
40
  "set_comment",
41
- "set_current_document",
42
41
  "set_inline_comment",
43
42
  "unset_bookmark",
44
43
  "xrefs",
@@ -69,5 +68,24 @@ export const CAPABILITIES = Object.freeze(HOPPER_OPERATIONS.map((operation) => O
69
68
  }),
70
69
  limitations: Object.freeze([
71
70
  "Results depend on Hopper's completed static analysis.",
71
+ ...(operation === "address_to_file_offset"
72
+ ? [
73
+ "Original-file coordinates require source bytes matching the selected executable digest. A changed, unavailable, or database-only source retains native mapping facts in partial error evidence.",
74
+ ]
75
+ : []),
76
+ ...(operation === "search_strings" || operation === "search_procedures"
77
+ ? [
78
+ "Regex mode uses ECMAScript Unicode semantics in a supervised worker with a five-second matching deadline. Cancellation or deadline failure stops matching without blocking Hopper; literal mode retains native casefold semantics.",
79
+ ]
80
+ : []),
81
+ ...(operation === "list_strings" ||
82
+ operation === "search_strings" ||
83
+ operation === "analyze_function"
84
+ ? [
85
+ "String values cover native typed objects. Hopper may split long literals into adjacent unterminated fragments; string searches match each object independently.",
86
+ "Undecodable typed objects retain native display text with an explicit decoding unknown; these values do not establish decoded source literals.",
87
+ "Reported string encodings are inferred from typed bytes and native display; the original source's intended encoding is unknown.",
88
+ ]
89
+ : []),
72
90
  ]),
73
91
  })));