rea-agents 6.3.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (487) hide show
  1. package/README.md +7 -4
  2. package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
  3. package/bridge/ghidra/ReaGhidraBridge.java +597 -209
  4. package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
  5. package/dist/adb/AdbConfiguration.js +88 -0
  6. package/dist/adb/AdbDeviceOutput.js +186 -0
  7. package/dist/adb/AdbProvider.js +1190 -0
  8. package/dist/adb/AdbShellOutput.js +309 -0
  9. package/dist/android/AndroidTargetSnapshot.js +104 -22
  10. package/dist/android/JadxConfiguration.js +44 -24
  11. package/dist/android/JadxProvider.js +51 -19
  12. package/dist/apktool/ApktoolConfiguration.js +84 -0
  13. package/dist/apktool/ApktoolDecodeOutput.js +59 -0
  14. package/dist/apktool/ApktoolProvider.js +506 -0
  15. package/dist/application/AnalysisProvider.js +8 -2
  16. package/dist/application/AppBundleExecutable.js +27 -22
  17. package/dist/application/BinaryTargetResolver.js +22 -2
  18. package/dist/application/CapabilityInventory.js +11 -1
  19. package/dist/application/ClientConfigurationDocument.js +70 -0
  20. package/dist/application/ClientConfigurationFiles.js +91 -0
  21. package/dist/application/ClientRegistrationEnvironment.js +35 -0
  22. package/dist/application/ClientRegistrationStatus.js +66 -31
  23. package/dist/application/DirectAnalysis.js +2 -2
  24. package/dist/application/DirectAnalysisCleanup.js +1 -1
  25. package/dist/application/DirectAnalysisStatus.js +1 -1
  26. package/dist/application/Doctor.js +5 -3
  27. package/dist/application/DoctorDiagnostics.js +1 -1
  28. package/dist/application/EvidenceBundleCommands.js +6 -12
  29. package/dist/application/GeminiClientSettings.js +139 -0
  30. package/dist/application/HermesClientHome.js +115 -0
  31. package/dist/application/HopperDownload.js +39 -0
  32. package/dist/application/InvestigationProviders.js +6 -0
  33. package/dist/application/JsonFiles.js +6 -5
  34. package/dist/{cliJsonFile.js → application/JsonInputFile.js} +108 -35
  35. package/dist/application/LinuxHopper.js +4 -12
  36. package/dist/application/MacHopper.js +172 -149
  37. package/dist/application/MipsElfAbiFlags.js +140 -0
  38. package/dist/application/ProviderOperationExecution.js +31 -0
  39. package/dist/application/ReconstructionObligationCandidates.js +9 -3
  40. package/dist/application/ReferenceSourceImport.js +76 -29
  41. package/dist/application/ReferenceSourceImportEntries.js +18 -9
  42. package/dist/application/ReferenceSourceImportPolicy.js +99 -23
  43. package/dist/application/ReferenceSourceImportTypes.js +30 -22
  44. package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
  45. package/dist/application/RegularFileRead.js +93 -7
  46. package/dist/application/Setup.js +54 -6
  47. package/dist/application/SetupClientConfiguration.js +116 -16
  48. package/dist/application/SetupHost.js +102 -24
  49. package/dist/application/SetupPlan.js +5 -8
  50. package/dist/application/SetupSkill.js +58 -39
  51. package/dist/application/SupportedClients.js +290 -65
  52. package/dist/application/Uninstall.js +158 -10
  53. package/dist/application/UpdateMaintenance.js +17 -21
  54. package/dist/application/Utf8JsonInput.js +7 -0
  55. package/dist/application/WebScriptExportService.js +131 -65
  56. package/dist/application/WebSourceLocationService.js +3 -0
  57. package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
  58. package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
  59. package/dist/application/analysisView/AnalysisViewService.js +40 -2
  60. package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
  61. package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
  62. package/dist/application/binary/AnalysisClientCleanup.js +0 -24
  63. package/dist/application/binary/BinarySession.js +2 -1
  64. package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
  65. package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
  66. package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
  67. package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
  68. package/dist/application/evm/EvmInterfaceService.js +3 -0
  69. package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
  70. package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
  71. package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
  72. package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
  73. package/dist/application/javascript/ElectronBoundaryGraphNative.js +19 -6
  74. package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
  75. package/dist/application/javascript/JavaScriptApplicationService.js +22 -11
  76. package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
  77. package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -30
  78. package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
  79. package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +67 -19
  80. package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
  81. package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
  82. package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +19 -16
  83. package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
  84. package/dist/application/javascript/JavaScriptArtifactPathResolution.js +258 -235
  85. package/dist/application/javascript/JavaScriptArtifactReconstruction.js +115 -26
  86. package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -1
  87. package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -4
  88. package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
  89. package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +9 -3
  90. package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +199 -61
  91. package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +12 -19
  92. package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +4 -1
  93. package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -3
  94. package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +5 -3
  95. package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +19 -8
  96. package/dist/application/jeb/JebAnalysisPort.js +1 -0
  97. package/dist/application/jeb/JebAnalysisService.js +13 -0
  98. package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
  99. package/dist/application/native/NativeUiActionTrace.js +16 -8
  100. package/dist/application/native/NativeValueTrace.js +23 -6
  101. package/dist/application/process/ProcessCli.js +25 -20
  102. package/dist/artifacts/ArtifactPaths.js +129 -8
  103. package/dist/artifacts/ArtifactProvider.js +20 -15
  104. package/dist/artifacts/ArtifactReader.js +23 -0
  105. package/dist/artifacts/ArtifactResourceScope.js +100 -0
  106. package/dist/artifacts/AsarArtifactReader.js +176 -102
  107. package/dist/artifacts/AsarHeader.js +24 -0
  108. package/dist/artifacts/DirectoryArtifactReader.js +168 -65
  109. package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
  110. package/dist/artifacts/NativeDmgArtifactReader.js +29 -22
  111. package/dist/artifacts/SafeOutputTree.js +245 -70
  112. package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
  113. package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
  114. package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
  115. package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
  116. package/dist/artifacts/ZipArtifactReader.js +77 -27
  117. package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
  118. package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
  119. package/dist/artifacts/apple/KeyedArchiveReader.js +32 -13
  120. package/dist/artifacts/extraction/ArtifactExtraction.js +110 -86
  121. package/dist/artifacts/inventory/ArtifactGraphConstruction.js +110 -43
  122. package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
  123. package/dist/artifacts/inventory/classify.js +75 -32
  124. package/dist/artifacts/inventory/hashStableRootArtifact.js +48 -15
  125. package/dist/artifacts/inventory/reader.js +13 -5
  126. package/dist/artifacts/inventory/scanCanonical.js +62 -25
  127. package/dist/artifacts/inventory/scanReader.js +38 -11
  128. package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +15 -9
  129. package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
  130. package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
  131. package/dist/browser/BrowserScenarioSecrets.js +52 -37
  132. package/dist/browser/CdpBrowserProvider.js +5 -0
  133. package/dist/browser/CdpCaptureDocuments.js +40 -6
  134. package/dist/browser/CdpCaptureDomSvg.js +210 -0
  135. package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
  136. package/dist/browser/CdpCaptureEventHandlers.js +26 -9
  137. package/dist/browser/CdpCaptureEvents.js +4 -9
  138. package/dist/browser/CdpConnection.js +22 -5
  139. package/dist/browser/CdpPageCapture.js +1 -1
  140. package/dist/browser/CdpTargetSession.js +30 -34
  141. package/dist/browser/CdpWebMcpDiscovery.js +32 -10
  142. package/dist/browser/ElectronFileScope.js +99 -9
  143. package/dist/browser/PlaywrightBrowserScenarioProvider.js +60 -4
  144. package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
  145. package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
  146. package/dist/browser/PlaywrightScenarioBrowser.js +69 -7
  147. package/dist/browser/PlaywrightScenarioSession.js +127 -54
  148. package/dist/browser/PlaywrightScenarioStorage.js +507 -0
  149. package/dist/browser/PngVisualDiff.js +198 -29
  150. package/dist/browser/WebSourceMapFetcher.js +3 -3
  151. package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
  152. package/dist/browser/assets/PublishWebScripts.js +75 -20
  153. package/dist/browser/assets/WebArtifactReads.js +23 -1
  154. package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
  155. package/dist/browser/execution/CdpExecutionCapture.js +3 -3
  156. package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
  157. package/dist/browser/history/HarCapture.js +14 -0
  158. package/dist/browser/history/HarCaptureProcess.js +2 -10
  159. package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
  160. package/dist/browser/modules/WebModuleArtifacts.js +1 -0
  161. package/dist/cli/adbCommands.js +337 -0
  162. package/dist/cli/analysisViewCommands.js +39 -1
  163. package/dist/cli/apktoolCommands.js +53 -0
  164. package/dist/cli/artifactCommands.js +8 -11
  165. package/dist/cli/binaryDiagnosticsCommands.js +19 -1
  166. package/dist/cli/browserAdvancedCommands.js +65 -36
  167. package/dist/cli/coreBinaryCommands.js +0 -5
  168. package/dist/cli/coreNativeCommands.js +1 -14
  169. package/dist/cli/electronCommands.js +6 -1
  170. package/dist/cli/evmCommands.js +13 -4
  171. package/dist/cli/firmwareCommands.js +7 -2
  172. package/dist/cli/javascriptApplicationAnalysis.js +17 -1
  173. package/dist/cli/javascriptRecoveryCommands.js +22 -15
  174. package/dist/cli/jebCommands.js +99 -0
  175. package/dist/cli/jsonOutput.js +11 -4
  176. package/dist/cli/referenceSourceImportStatus.js +7 -0
  177. package/dist/cli/setupCommands.js +15 -3
  178. package/dist/cli/utilityCommands.js +66 -18
  179. package/dist/cli/webScriptCommands.js +20 -1
  180. package/dist/cli/webSourceLocationCommands.js +21 -9
  181. package/dist/cli.js +6 -0
  182. package/dist/cliBrowserScenarioCommands.js +2 -1
  183. package/dist/cliCommandNames.js +32 -0
  184. package/dist/cliJsonInput.js +2 -2
  185. package/dist/cliObservationOptions.js +3 -0
  186. package/dist/composition/adb.js +3 -0
  187. package/dist/composition/apktool.js +3 -0
  188. package/dist/composition/binaryDiagnostics.js +4 -0
  189. package/dist/composition/directAnalysis.js +12 -4
  190. package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
  191. package/dist/composition/jeb.js +6 -0
  192. package/dist/config/environment.js +10 -0
  193. package/dist/config/ghidraLanguageOverride.js +9 -0
  194. package/dist/config/mcpInputSchemaProfile.js +27 -0
  195. package/dist/config/parseConfig.js +28 -1
  196. package/dist/contracts/adb/adbToolContracts.js +353 -0
  197. package/dist/contracts/advertisedInputExamples.js +48 -0
  198. package/dist/contracts/analysisDetail.js +10 -0
  199. package/dist/contracts/analysisViewToolContracts.js +17 -2
  200. package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
  201. package/dist/contracts/artifactToolContracts.js +8 -5
  202. package/dist/contracts/browserToolContracts.js +1 -1
  203. package/dist/contracts/compactInputSchema.js +256 -0
  204. package/dist/contracts/functionWorkflowToolContracts.js +1 -1
  205. package/dist/contracts/inputSchemaPresentation.js +10 -10
  206. package/dist/contracts/javascript/electronToolContracts.js +15 -3
  207. package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
  208. package/dist/contracts/jeb/jebToolContracts.js +64 -0
  209. package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
  210. package/dist/contracts/officialToolContracts.js +5 -5
  211. package/dist/contracts/sessionToolContracts.js +2 -2
  212. package/dist/contracts/sessionToolSchemas.js +6 -2
  213. package/dist/contracts/toolContractExamples.js +6 -0
  214. package/dist/contracts/toolContractTypes.js +3 -0
  215. package/dist/contracts/toolContracts.js +6 -0
  216. package/dist/contracts/toolEffects.js +167 -0
  217. package/dist/contracts/toolOutputSchemaGroups.js +5 -3
  218. package/dist/contracts/toolSchemaMetadata.js +82 -7
  219. package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
  220. package/dist/domain/analysisErrorCleanup.js +29 -0
  221. package/dist/domain/analysisErrorPresentation.js +18 -6
  222. package/dist/domain/analysisErrorProjection.js +4 -1
  223. package/dist/domain/analysisSnapshot.js +2 -1
  224. package/dist/domain/analysisView/analysisView.js +52 -2
  225. package/dist/domain/analysisView/binaryLayoutView.js +2 -0
  226. package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
  227. package/dist/domain/analysisView/nativeFunctionView.js +155 -0
  228. package/dist/domain/android/androidApplication.js +25 -20
  229. package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
  230. package/dist/domain/apple/appleApplication.js +40 -23
  231. package/dist/domain/apple/appleBundleAnatomy.js +95 -28
  232. package/dist/domain/apple/dyldPaths.js +9 -1
  233. package/dist/domain/apple/dylibResolution.js +2 -2
  234. package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
  235. package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
  236. package/dist/domain/artifactComparison.js +35 -7
  237. package/dist/domain/artifactGraph.js +5 -3
  238. package/dist/domain/artifactIdentity.js +30 -2
  239. package/dist/domain/artifactInspection.js +3 -43
  240. package/dist/domain/artifactIntegrityPolicy.js +10 -0
  241. package/dist/domain/artifactInventoryEvidence.js +11 -12
  242. package/dist/domain/artifactPathSyntax.js +1 -1
  243. package/dist/domain/binaryTarget.js +16 -0
  244. package/dist/domain/binaryTargetTypes.js +8 -1
  245. package/dist/domain/browserObservationSchemas.js +8 -4
  246. package/dist/domain/canonicalJsonDigestSteps.js +34 -12
  247. package/dist/domain/compactStringIdentity.js +9 -0
  248. package/dist/domain/evidence.js +2 -1
  249. package/dist/domain/evidenceRecordSummary.js +144 -0
  250. package/dist/domain/inputIssueProjection.js +16 -1
  251. package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -13
  252. package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -20
  253. package/dist/domain/javascript/electronStaticAnalysisNative.js +70 -40
  254. package/dist/domain/javascript/electronStaticAnalysisValues.js +16 -0
  255. package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
  256. package/dist/domain/javascript/javascriptApplicationAnalysis.js +4 -1
  257. package/dist/domain/javascript/javascriptApplicationChangeGraph.js +6 -6
  258. package/dist/domain/javascript/javascriptApplicationGraph.js +79 -18
  259. package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
  260. package/dist/domain/javascript/javascriptApplicationVersionItems.js +28 -12
  261. package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -1
  262. package/dist/domain/javascript/javascriptAstFingerprint.js +58 -31
  263. package/dist/domain/javascript/javascriptAstValues.js +32 -0
  264. package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
  265. package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
  266. package/dist/domain/javascript/javascriptNativeHandoff.js +6 -1
  267. package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
  268. package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
  269. package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +7 -2
  270. package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +8 -11
  271. package/dist/domain/javascript/javascriptSemanticAnalysis.js +190 -33
  272. package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
  273. package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
  274. package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
  275. package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
  276. package/dist/domain/javascript/javascriptSemanticFingerprints.js +42 -41
  277. package/dist/domain/javascript/javascriptSemanticGraph.js +69 -23
  278. package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +2 -10
  279. package/dist/domain/javascript/javascriptSemanticIterationSources.js +40 -7
  280. package/dist/domain/javascript/javascriptSemanticMemberMutations.js +341 -87
  281. package/dist/domain/javascript/javascriptSemanticMutationValues.js +78 -35
  282. package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
  283. package/dist/domain/javascript/javascriptSemanticObjects.js +7 -1
  284. package/dist/domain/javascript/javascriptSemanticProjection.js +52 -14
  285. package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +77 -0
  286. package/dist/domain/javascript/javascriptSemanticQuery.js +27 -29
  287. package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +1 -3
  288. package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
  289. package/dist/domain/javascript/javascriptSemanticReturns.js +13 -23
  290. package/dist/domain/javascript/javascriptSemanticState.js +22 -2
  291. package/dist/domain/javascript/javascriptSemanticTraversal.js +19 -1
  292. package/dist/domain/javascript/javascriptSemanticValues.js +47 -19
  293. package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
  294. package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
  295. package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +8 -6
  296. package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
  297. package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
  298. package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
  299. package/dist/domain/jeb/jebAnalysis.js +114 -0
  300. package/dist/domain/jsonShape.js +63 -52
  301. package/dist/domain/jsonValue.js +3 -0
  302. package/dist/domain/managed/managedApplicationGraph.js +37 -0
  303. package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
  304. package/dist/domain/managed/managedApplicationGraphNodes.js +32 -22
  305. package/dist/domain/managed/managedArtifact.js +1 -0
  306. package/dist/domain/managed/managedInspectionEvidence.js +13 -0
  307. package/dist/domain/native/nativeAotPe.js +1408 -0
  308. package/dist/domain/native/nativeInstruction.js +21 -0
  309. package/dist/domain/native/nativeMetadataRecovery.js +79 -6
  310. package/dist/domain/native/peResources.js +94 -0
  311. package/dist/domain/nativeConvention.js +33 -0
  312. package/dist/domain/process/processCapture.js +91 -1
  313. package/dist/domain/process/processCaptureExample.js +24 -0
  314. package/dist/domain/process/processCaptureValidation.js +79 -0
  315. package/dist/domain/process/processScenario.js +59 -7
  316. package/dist/domain/propertyListKeys.js +3 -1
  317. package/dist/domain/referenceSourceGraph.js +25 -16
  318. package/dist/domain/referenceSourceImportParsing.js +6 -3
  319. package/dist/domain/referenceSourcePathIdentity.js +22 -0
  320. package/dist/domain/referenceSourceRequireBindings.js +137 -0
  321. package/dist/domain/webBundleAnalyzerInspection.js +14 -2
  322. package/dist/domain/webCaptureDiff.js +102 -4
  323. package/dist/domain/webScriptExportError.js +10 -4
  324. package/dist/domain/webScriptExportPlan.js +7 -13
  325. package/dist/domain/zipPackageFormat.js +4 -1
  326. package/dist/domain/zodCollectionSteps.js +24 -0
  327. package/dist/dotnet/ManagedArtifactInspector.js +55 -43
  328. package/dist/dotnet/ManagedDecodeBudget.js +80 -0
  329. package/dist/dotnet/ManagedMemberInspector.js +13 -6
  330. package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
  331. package/dist/dotnet/ManagedMemberInstructionDecoder.js +4 -2
  332. package/dist/dotnet/ManagedMemberRows.js +9 -4
  333. package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
  334. package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
  335. package/dist/dotnet/ManagedMetadataLayout.js +10 -4
  336. package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
  337. package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
  338. package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
  339. package/dist/dotnet/ManagedPeReader.js +41 -25
  340. package/dist/dotnet/ManagedReaderFailure.js +2 -1
  341. package/dist/dotnet/ManagedStaticProvider.js +55 -24
  342. package/dist/evaluation/AgentEvaluationReport.js +9 -5
  343. package/dist/evaluation/CodexAgentEval.js +43 -13
  344. package/dist/evm/EvmoleFailures.js +0 -2
  345. package/dist/evm/EvmoleInterfaceProvider.js +67 -2
  346. package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
  347. package/dist/filesystem/OwnedFileHandle.js +36 -0
  348. package/dist/filesystem/RegularFile.js +33 -1
  349. package/dist/filesystem/StableFileHash.js +46 -0
  350. package/dist/filesystem/readFileHandleChunks.js +26 -0
  351. package/dist/firmware/FirmwareCommand.js +25 -3
  352. package/dist/firmware/FirmwareFiles.js +23 -8
  353. package/dist/firmware/FirmwareProvider.js +156 -32
  354. package/dist/firmware/FirmwarePublication.js +24 -3
  355. package/dist/firmware/FirmwareRelease.js +1 -0
  356. package/dist/generatedPackageMetadata.js +2 -2
  357. package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
  358. package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
  359. package/dist/ghidra/GhidraClient.js +76 -4
  360. package/dist/ghidra/GhidraDiagnostics.js +11 -8
  361. package/dist/ghidra/GhidraFunctionValues.js +26 -2
  362. package/dist/ghidra/GhidraInstallation.js +1 -1
  363. package/dist/ghidra/GhidraInventoryValues.js +23 -1
  364. package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
  365. package/dist/ghidra/GhidraLauncher.js +80 -39
  366. package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
  367. package/dist/ghidra/GhidraMipsProfile.js +79 -0
  368. package/dist/ghidra/GhidraProvider.js +57 -9
  369. package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
  370. package/dist/ghidra/GhidraProviderClient.js +282 -21
  371. package/dist/ghidra/GhidraSessionValues.js +9 -2
  372. package/dist/hopper/HopperAnalysisProfile.js +2 -0
  373. package/dist/hopper/HopperClient.js +15 -6
  374. package/dist/hopper/HopperMachOImage.js +2 -0
  375. package/dist/hopper/HopperProvider.js +13 -2
  376. package/dist/ida/IdaOperationRunner.js +8 -2
  377. package/dist/ida/IdaProvider.js +7 -0
  378. package/dist/ida/IdaSessionClient.js +3 -1
  379. package/dist/ida/IdaWorkspace.js +4 -2
  380. package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
  381. package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
  382. package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
  383. package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
  384. package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
  385. package/dist/javascript/recovery/RecoveryFiles.js +18 -7
  386. package/dist/javascript/recovery/WakaruCommand.js +22 -9
  387. package/dist/javascript/recovery/WakaruExecution.js +11 -7
  388. package/dist/javascript/recovery/WakaruProvider.js +139 -16
  389. package/dist/javascript/recovery/WakaruPublication.js +14 -4
  390. package/dist/javascript/recovery/WakaruRelease.js +10 -3
  391. package/dist/javascript/recovery/WakaruReport.js +12 -7
  392. package/dist/javascript/recovery/WakaruVersion.js +24 -0
  393. package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
  394. package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
  395. package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
  396. package/dist/jeb/JebMcpConnection.js +179 -0
  397. package/dist/jeb/JebMcpEndpoint.js +40 -0
  398. package/dist/jeb/JebProvider.js +299 -0
  399. package/dist/mcpDoctor.js +15 -6
  400. package/dist/native/AppleDispatchCoverage.js +25 -12
  401. package/dist/native/AppleDispatchMetadata.js +14 -7
  402. package/dist/native/AppleMachoFixups.js +71 -15
  403. package/dist/native/AppleMachoSelection.js +23 -3
  404. package/dist/native/NativeMacOSProvider.js +91 -16
  405. package/dist/native/NativeMachoInspection.js +11 -7
  406. package/dist/native/NativeUiHelperRuntime.js +6 -1
  407. package/dist/native/NativeUiObservation.js +4 -3
  408. package/dist/native/pe/PeResourceLayout.js +120 -0
  409. package/dist/native/pe/PeResourceParser.js +286 -0
  410. package/dist/native/pe/PeResourcesProvider.js +63 -0
  411. package/dist/process/BoundedFileBytes.js +30 -7
  412. package/dist/process/DarwinProcessRunTokenReader.js +8 -3
  413. package/dist/process/OwnedCommand.js +4 -3
  414. package/dist/process/ProcessOwnership.js +104 -112
  415. package/dist/process/ProcessOwnershipObservation.js +96 -39
  416. package/dist/process/ProcessOwnershipProcessTree.js +4 -4
  417. package/dist/process/ProcessRunTokenObservations.js +48 -0
  418. package/dist/process/ProviderDiagnosticRedaction.js +17 -0
  419. package/dist/process/ProviderProcess.js +4 -3
  420. package/dist/process/capture/FilesystemSnapshot.js +28 -4
  421. package/dist/process/capture/ProcessCaptureLifecycle.js +350 -59
  422. package/dist/process/capture/ProcessCaptureProgress.js +62 -0
  423. package/dist/process/capture/ProcessHarness.js +194 -26
  424. package/dist/process/capture/ProcessNormalization.js +3 -1
  425. package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
  426. package/dist/process/capture/TerminalRenderer.js +24 -7
  427. package/dist/reference/ReferenceSourceReader.js +22 -5
  428. package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
  429. package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
  430. package/dist/reference/ReferenceSourceReaderFile.js +50 -10
  431. package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
  432. package/dist/server/EvidenceMcpServer.js +36 -1
  433. package/dist/server/admittedToolOperation.js +9 -0
  434. package/dist/server/contractToolHandler.js +21 -0
  435. package/dist/server/createServer.js +97 -25
  436. package/dist/server/registerAdbTools.js +36 -0
  437. package/dist/server/registerAnalysisViewTool.js +4 -9
  438. package/dist/server/registerAndroidTools.js +3 -12
  439. package/dist/server/registerApktoolTools.js +14 -0
  440. package/dist/server/registerApplicationTools/compareExportShapes.js +4 -6
  441. package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
  442. package/dist/server/registerApplicationTools/compareVersions.js +3 -2
  443. package/dist/server/registerApplicationTools/coverage.js +3 -2
  444. package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
  445. package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
  446. package/dist/server/registerApplicationTools/traceFeature.js +3 -2
  447. package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
  448. package/dist/server/registerArtifactComparisonTool.js +5 -2
  449. package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
  450. package/dist/server/registerBrowserScenarioTool.js +10 -7
  451. package/dist/server/registerBrowserTools.js +12 -9
  452. package/dist/server/registerBundleComparisonTool.js +16 -2
  453. package/dist/server/registerCloseLifecycleTool.js +32 -3
  454. package/dist/server/registerElectronTools.js +28 -10
  455. package/dist/server/registerEvmTools.js +4 -9
  456. package/dist/server/registerFirmwareTools.js +3 -11
  457. package/dist/server/registerFunctionComparisonTool.js +5 -2
  458. package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
  459. package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
  460. package/dist/server/registerJebTools.js +16 -0
  461. package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
  462. package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
  463. package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
  464. package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
  465. package/dist/server/registerPeResourcesTool.js +9 -0
  466. package/dist/server/registerProcessComparisonTool.js +5 -2
  467. package/dist/server/registerRecordedCrashTools.js +4 -9
  468. package/dist/server/registerSessionRecordTools.js +2 -1
  469. package/dist/server/registerSessionTools.js +49 -18
  470. package/dist/server/registerWebModuleTool.js +4 -9
  471. package/dist/server/registerWebNetworkCaptureTool.js +4 -9
  472. package/dist/server/registerWebRuntimeTools.js +6 -5
  473. package/dist/server/registerWebScriptTool.js +6 -3
  474. package/dist/server/registerWebSourceLocationTool.js +4 -9
  475. package/dist/server/toolResult.js +21 -2
  476. package/dist/windows/WindowsPrivateRuntime.js +12 -5
  477. package/install.sh +7 -4
  478. package/licenses/nativeaot-parser-MIT.txt +28 -0
  479. package/native/windows/build/manifest.json +2 -2
  480. package/native/windows/build/rea-windows-x64.node +0 -0
  481. package/package.json +33 -5
  482. package/scripts/rea.mjs +16 -1
  483. package/skills/reverse-engineer-anything/SKILL.md +52 -51
  484. package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
  485. package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
  486. package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
  487. package/skills/reverse-engineer-anything/references/native-and-artifacts.md +22 -1
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Parsers for fixed observation commands REA runs through `adb shell`.
3
+ *
4
+ * Formats follow toybox output on Android 8+ (verified against an Android 14
5
+ * emulator). Unparseable lines are retained rather than dropped so callers
6
+ * can see the format drift instead of silently losing rows.
7
+ */
8
+ const PROCESS_LINE = /^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S+)\s+(\S+)\s+(\S+)\s+(.+)$/u;
9
+ /** Parse `ps -A` output; the header line is preserved verbatim as `columns`. */
10
+ export const parseProcessListOutput = (stdout) => {
11
+ const processes = [];
12
+ const unparsedLines = [];
13
+ let columns = null;
14
+ for (const rawLine of stdout.split(/\r?\n/u)) {
15
+ const line = rawLine.trimEnd();
16
+ if (line === "")
17
+ continue;
18
+ if (/^USER\s+PID\s+PPID\b/u.test(line)) {
19
+ columns = line.trim();
20
+ continue;
21
+ }
22
+ const match = PROCESS_LINE.exec(line);
23
+ if (match === null) {
24
+ unparsedLines.push(line);
25
+ continue;
26
+ }
27
+ processes.push({
28
+ user: match[1],
29
+ pid: Number(match[2]),
30
+ ppid: Number.isSafeInteger(Number(match[3])) ? Number(match[3]) : null,
31
+ rss: Number.isSafeInteger(Number(match[5])) ? Number(match[5]) : null,
32
+ state: match[8],
33
+ name: match[9].trim(),
34
+ });
35
+ }
36
+ return { columns, processes, unparsedLines };
37
+ };
38
+ const LS_LINE = /^([bcdlps-][rwxstST-]{9})\s+(?:(\d+)\s+)?(\S+)\s+(\S+)\s+(?:(\d+)\s+)?([\d-]{10})\s+([\d:]{4,8})\s+(.+)$/u;
39
+ /** Parse `ls -la` output, including `total` headers and symlink targets. */
40
+ export const parseLsOutput = (stdout) => {
41
+ const entries = [];
42
+ const unparsedLines = [];
43
+ for (const rawLine of stdout.split(/\r?\n/u)) {
44
+ const line = rawLine.trimEnd();
45
+ if (line === "" || line.startsWith("total "))
46
+ continue;
47
+ const match = LS_LINE.exec(line);
48
+ if (match === null) {
49
+ if (line.trim() !== "")
50
+ unparsedLines.push(line);
51
+ continue;
52
+ }
53
+ const permissions = match[1];
54
+ let name = match[8].trim();
55
+ let linkTarget = null;
56
+ const linkArrow = name.indexOf(" -> ");
57
+ if (linkArrow !== -1 && permissions.startsWith("l")) {
58
+ linkTarget = name.slice(linkArrow + 4);
59
+ name = name.slice(0, linkArrow);
60
+ }
61
+ entries.push({
62
+ name,
63
+ kind: permissions.startsWith("d")
64
+ ? "directory"
65
+ : permissions.startsWith("l")
66
+ ? "symlink"
67
+ : permissions.startsWith("-")
68
+ ? "file"
69
+ : "other",
70
+ permissions,
71
+ owner: match[3] ?? null,
72
+ group: match[4] ?? null,
73
+ bytes: match[5] === undefined ? null : Number(match[5]),
74
+ date: `${match[6] ?? ""} ${match[7] ?? ""}`.trim() || null,
75
+ link_target: linkTarget,
76
+ });
77
+ }
78
+ return { entries, unparsedLines };
79
+ };
80
+ const FEATURE_LINE = /^feature:([^=\s]+)(?:=(0x[0-9a-fA-F]+|\d+))?$/u;
81
+ const parseFeatureVersion = (text) => text.startsWith("0x") ? Number.parseInt(text.slice(2), 16) : Number(text);
82
+ /** Parse `pm list features` output, including hex GL versions. */
83
+ export const parseFeatureListOutput = (stdout) => {
84
+ const features = [];
85
+ const unparsedLines = [];
86
+ for (const rawLine of stdout.split(/\r?\n/u)) {
87
+ const line = rawLine.trim();
88
+ if (line === "")
89
+ continue;
90
+ const match = FEATURE_LINE.exec(line);
91
+ if (match === null) {
92
+ unparsedLines.push(line);
93
+ continue;
94
+ }
95
+ features.push({
96
+ name: match[1],
97
+ version: match[2] === undefined ? null : parseFeatureVersion(match[2]),
98
+ });
99
+ }
100
+ return { features, unparsedLines };
101
+ };
102
+ const SERVICE_LINE = /^\s*(?:\d+\s+)?([A-Za-z0-9._$/-]+):\s*\[([^\]]*)\]\s*$/u;
103
+ /** Parse `service list` output, tolerating numbered and plain formats. */
104
+ export const parseServiceListOutput = (stdout) => {
105
+ const services = [];
106
+ const unparsedLines = [];
107
+ for (const rawLine of stdout.split(/\r?\n/u)) {
108
+ const line = rawLine.trimEnd();
109
+ if (line.trim() === "" || /^Found \d+ services:/u.test(line.trim()))
110
+ continue;
111
+ const match = SERVICE_LINE.exec(line);
112
+ if (match === null) {
113
+ if (line.trim() !== "")
114
+ unparsedLines.push(line.trim());
115
+ continue;
116
+ }
117
+ services.push({
118
+ name: match[1],
119
+ interface: match[2] === "" ? null : match[2],
120
+ });
121
+ }
122
+ return { services, unparsedLines };
123
+ };
124
+ const SIZE_PAIR = /^Physical size:\s+(\d+)x(\d+)$/u;
125
+ const SIZE_OVERRIDE = /^Override size:\s+(\d+)x(\d+)$/u;
126
+ const DENSITY_PHYSICAL = /^Physical density:\s+(\d+)$/u;
127
+ const DENSITY_OVERRIDE = /^Override density:\s+(\d+)$/u;
128
+ /** Parse `wm size` output into physical and optional override sizes. */
129
+ export const parseWmSizeOutput = (stdout) => {
130
+ let physical = null;
131
+ let override = null;
132
+ for (const line of stdout.split(/\r?\n/u)) {
133
+ const trimmed = line.trim();
134
+ const physicalMatch = SIZE_PAIR.exec(trimmed);
135
+ if (physicalMatch !== null)
136
+ physical = {
137
+ width: Number(physicalMatch[1]),
138
+ height: Number(physicalMatch[2]),
139
+ };
140
+ const overrideMatch = SIZE_OVERRIDE.exec(trimmed);
141
+ if (overrideMatch !== null)
142
+ override = {
143
+ width: Number(overrideMatch[1]),
144
+ height: Number(overrideMatch[2]),
145
+ };
146
+ }
147
+ return { physical, override };
148
+ };
149
+ /** Parse `wm density` output. Older builds print a bare number. */
150
+ export const parseWmDensityOutput = (stdout) => {
151
+ let physical = null;
152
+ let override = null;
153
+ for (const line of stdout.split(/\r?\n/u)) {
154
+ const trimmed = line.trim();
155
+ const physicalMatch = DENSITY_PHYSICAL.exec(trimmed);
156
+ if (physicalMatch !== null)
157
+ physical = Number(physicalMatch[1]);
158
+ const overrideMatch = DENSITY_OVERRIDE.exec(trimmed);
159
+ if (overrideMatch !== null)
160
+ override = Number(overrideMatch[1]);
161
+ }
162
+ return { physical, override };
163
+ };
164
+ /** Parse the focus declarations from `dumpsys window windows`. */
165
+ export const parseWindowFocusOutput = (stdout) => {
166
+ let focusedWindow = null;
167
+ let focusedApp = null;
168
+ for (const line of stdout.split(/\r?\n/u)) {
169
+ const trimmed = line.trim();
170
+ if (focusedWindow === null && trimmed.startsWith("mCurrentFocus="))
171
+ focusedWindow = trimmed.slice("mCurrentFocus=".length).trim();
172
+ if (focusedApp === null && trimmed.startsWith("mFocusedApp="))
173
+ focusedApp = trimmed.slice("mFocusedApp=".length).trim();
174
+ }
175
+ return { focusedWindow, focusedApp };
176
+ };
177
+ const DETAIL_LINE = /^\s+([A-Za-z][A-Za-z0-9_]*)=(.*)$/u;
178
+ /**
179
+ * Project `dumpsys package PACKAGE` output. Only the listed fields are
180
+ * extracted; the input is version-dependent and everything else is ignored
181
+ * by design rather than guessed.
182
+ */
183
+ export const parseDumpsysPackageOutput = (stdout) => {
184
+ const details = {
185
+ versionName: null,
186
+ versionCode: null,
187
+ firstInstallTime: null,
188
+ lastUpdateTime: null,
189
+ installerPackageName: null,
190
+ userId: null,
191
+ pkgFlags: null,
192
+ };
193
+ let inPermissions = false;
194
+ let permissions = 0;
195
+ for (const line of stdout.split(/\r?\n/u)) {
196
+ if (line.trim().startsWith("requested permissions:")) {
197
+ inPermissions = true;
198
+ continue;
199
+ }
200
+ if (inPermissions && /^\s{2,}[A-Za-z0-9._]+$/.test(line)) {
201
+ permissions += 1;
202
+ continue;
203
+ }
204
+ inPermissions = false;
205
+ const match = DETAIL_LINE.exec(line);
206
+ if (match === null)
207
+ continue;
208
+ const key = match[1];
209
+ const value = match[2].trim();
210
+ if (key === "versionName" && details.versionName === null)
211
+ details.versionName = value === "" ? null : value;
212
+ else if (key === "versionCode" && details.versionCode === null) {
213
+ const parsed = /^(\d+)/u.exec(value);
214
+ if (parsed !== null)
215
+ details.versionCode = Number(parsed[1]);
216
+ }
217
+ else if (key === "firstInstallTime" && details.firstInstallTime === null)
218
+ details.firstInstallTime = value === "" ? null : value;
219
+ else if (key === "lastUpdateTime" && details.lastUpdateTime === null)
220
+ details.lastUpdateTime = value === "" ? null : value;
221
+ else if (key === "installerPackageName" &&
222
+ details.installerPackageName === null)
223
+ details.installerPackageName = value === "" ? null : value;
224
+ else if (key === "userId" && details.userId === null) {
225
+ const parsed = /^(\d+)/u.exec(value);
226
+ if (parsed !== null)
227
+ details.userId = Number(parsed[1]);
228
+ }
229
+ else if (key === "pkgFlags" && details.pkgFlags === null)
230
+ details.pkgFlags = value === "" ? null : value;
231
+ }
232
+ return { ...details, requestedPermissions: permissions };
233
+ };
234
+ /**
235
+ * Parse `settings get` output. Android prints the literal string `null` for
236
+ * absent keys; that is reported as a device-side null observation.
237
+ */
238
+ export const parseSettingsGetOutput = (stdout) => {
239
+ const trimmed = stdout.replace(/\r?\n$/u, "");
240
+ if (trimmed === "null")
241
+ return { value: null, deviceReportedNull: true };
242
+ return { value: trimmed, deviceReportedNull: false };
243
+ };
244
+ /** Parse the host-side completion line from `adb bugreport`. */
245
+ export const parseBugreportCopiedPath = (stdout) => {
246
+ const match = /^Bug report copied to (.+)\r?$/mu.exec(stdout.trim());
247
+ return match === null ? null : match[1];
248
+ };
249
+ /**
250
+ * Parse `adb install`/`adb uninstall` output. adb can print `Failure [...]`
251
+ * with a zero exit code, so the text decides, not the exit status.
252
+ */
253
+ export const parsePackageChangeOutput = (stdout) => {
254
+ const text = stdout.trim();
255
+ if (/^Success$/mu.test(text))
256
+ return { status: "success", reason: null };
257
+ const failure = /Failure \[([^\]]+)\]/u.exec(text);
258
+ return {
259
+ status: "failure",
260
+ reason: failure?.[1] ?? (text === "" ? null : text.slice(0, 512)),
261
+ };
262
+ };
263
+ /**
264
+ * Parse `cmd package resolve-activity --brief` output: the component is the
265
+ * last non-empty line.
266
+ */
267
+ export const parseResolveActivityOutput = (stdout) => {
268
+ const lines = stdout
269
+ .split(/\r?\n/u)
270
+ .map((line) => line.trim())
271
+ .filter((line) => line !== "" && !/^No activity found$/iu.test(line));
272
+ return lines.length === 0 ? null : lines[lines.length - 1];
273
+ };
274
+ /**
275
+ * Parse `am start` output. Success prints `Starting: Intent { ... }`;
276
+ * refusals print lines starting with `Error:` or `Warning:` and activity
277
+ * classes that do not exist name the component.
278
+ */
279
+ export const parseAmStartOutput = (stdout) => {
280
+ const text = stdout.trim();
281
+ const starting = /^Starting:\s+Intent\s*\{(.*)\}\s*$/mu.exec(text);
282
+ if (starting !== null)
283
+ return {
284
+ status: "started",
285
+ startedActivity: starting[1].trim(),
286
+ reason: null,
287
+ };
288
+ const error = /^(?:Error|Warning|Exception)(?::|\b)(.*)$/mu.exec(text);
289
+ return {
290
+ status: "refused",
291
+ startedActivity: null,
292
+ reason: error?.[1]?.trim() ??
293
+ (text === "" ? "am start returned no activity" : text.slice(0, 512)),
294
+ };
295
+ };
296
+ const PNG_SIGNATURE = Buffer.from([
297
+ 0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a,
298
+ ]);
299
+ /** Read image dimensions from a PNG header, or null for other payloads. */
300
+ export const parsePngDimensions = (bytes) => {
301
+ if (bytes.length < 24 ||
302
+ !Buffer.from(bytes.subarray(0, 8)).equals(PNG_SIGNATURE))
303
+ return { width: null, height: null };
304
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
305
+ return {
306
+ width: view.getUint32(16),
307
+ height: view.getUint32(20),
308
+ };
309
+ };
@@ -1,36 +1,118 @@
1
- import { constants, createReadStream } from "node:fs";
2
- import { chmod, copyFile } from "node:fs/promises";
3
1
  import { createHash } from "node:crypto";
2
+ import { chmod, open, rm, stat } from "node:fs/promises";
4
3
  import { join } from "node:path";
4
+ import { Transform } from "node:stream";
5
+ import { pipeline } from "node:stream/promises";
5
6
  import { AnalysisInputError, AnalysisCapabilityUnavailableError, } from "../domain/analysisErrorCore.js";
6
- /** Stream a local file digest without retaining the APK or JAR in memory. */
7
- export const hashAndroidFile = async (path) => {
8
- const hash = createHash("sha256");
9
- for await (const chunk of createReadStream(path))
10
- hash.update(chunk);
11
- return hash.digest("hex");
12
- };
7
+ import { openRegularFile, sameRegularFileState, } from "../filesystem/RegularFile.js";
13
8
  /** Bind decompiler input to the admitted artifact, even if the original changes. */
14
- export const snapshotAndroidTarget = async (path, sha256, root, operation) => {
9
+ export const snapshotAndroidTarget = async (path, sha256, root, operation, signal) => {
15
10
  const snapshot = join(root, "target.apk");
16
- await copyFile(path, snapshot, constants.COPYFILE_EXCL);
17
- await chmod(snapshot, 0o400);
18
- if ((await hashAndroidFile(snapshot)) !== sha256)
19
- throw new AnalysisInputError(operation, undefined, [
11
+ try {
12
+ await copyAndroidSnapshot(path, snapshot, sha256, signal);
13
+ signal?.throwIfAborted();
14
+ await chmod(snapshot, 0o400);
15
+ return snapshot;
16
+ }
17
+ catch (cause) {
18
+ if (!(cause instanceof AndroidSnapshotChangedError))
19
+ throw cause;
20
+ throw new AnalysisInputError(operation, { cause }, [
20
21
  {
21
22
  path: ["path"],
22
23
  reason: "invalid_value",
23
- message: "APK bytes changed after admission; retry against a stable file.",
24
+ message: `APK bytes changed after admission at ${path}; retry against a stable file.`,
24
25
  },
25
26
  ]);
26
- return snapshot;
27
+ }
27
28
  };
28
29
  /** Fingerprint the actual immutable engine bytes executed for this observation. */
29
- export const snapshotAndroidEngine = async (source, sha256, root, operation) => {
30
+ export const snapshotAndroidEngine = async (source, sha256, root, operation, signal) => {
30
31
  const path = join(root, "engine.jar");
31
- await copyFile(source, path, constants.COPYFILE_EXCL);
32
- await chmod(path, 0o400);
33
- if ((await hashAndroidFile(path)) !== sha256)
34
- throw new AnalysisCapabilityUnavailableError("jadx", operation, "REA_JADX_MCP_JAR bytes changed during admission; retry with a stable engine file.");
35
- return { path, sha256 };
32
+ try {
33
+ const observed = await copyAndroidSnapshot(source, path, sha256, signal);
34
+ signal?.throwIfAborted();
35
+ await chmod(path, 0o400);
36
+ return { path, sha256: observed };
37
+ }
38
+ catch (cause) {
39
+ if (!(cause instanceof AndroidSnapshotChangedError))
40
+ throw cause;
41
+ throw new AnalysisCapabilityUnavailableError("jadx", operation, `REA_JADX_MCP_JAR bytes changed during admission at ${source}; retry with a stable engine file.`, { cause });
42
+ }
43
+ };
44
+ const copyAndroidSnapshot = async (sourcePath, snapshotPath, expectedSha256, signal) => {
45
+ signal?.throwIfAborted();
46
+ const source = await openRegularFile(sourcePath, {
47
+ symlinks: "follow",
48
+ signal,
49
+ });
50
+ let destination;
51
+ let inputStream;
52
+ let outputStream;
53
+ let removeSnapshot = false;
54
+ let copiedBytes = 0;
55
+ const hash = createHash("sha256");
56
+ try {
57
+ const initial = await source.stat();
58
+ signal?.throwIfAborted();
59
+ const digest = new Transform({
60
+ transform(chunk, _encoding, callback) {
61
+ copiedBytes += chunk.length;
62
+ if (copiedBytes > initial.size) {
63
+ callback(new AndroidSnapshotChangedError(`Android input grew while being copied: ${sourcePath}`));
64
+ return;
65
+ }
66
+ hash.update(chunk);
67
+ callback(null, chunk);
68
+ },
69
+ });
70
+ try {
71
+ destination = await open(snapshotPath, "wx", 0o600);
72
+ signal?.throwIfAborted();
73
+ inputStream = source.createReadStream({
74
+ start: 0,
75
+ end: initial.size,
76
+ autoClose: false,
77
+ });
78
+ outputStream = destination.createWriteStream({ autoClose: false });
79
+ await pipeline(inputStream, digest, outputStream, { signal });
80
+ signal?.throwIfAborted();
81
+ await verifySourceState(source, sourcePath, initial, copiedBytes);
82
+ const observedSha256 = hash.digest("hex");
83
+ if (observedSha256 !== expectedSha256)
84
+ throw new AndroidSnapshotChangedError(`Android snapshot digest mismatch for ${sourcePath}`);
85
+ return observedSha256;
86
+ }
87
+ catch (cause) {
88
+ removeSnapshot = destination !== undefined;
89
+ throw cause;
90
+ }
91
+ }
92
+ finally {
93
+ // Non-auto-closing streams retain a reference to their FileHandle even
94
+ // after pipeline completion. Release those references before awaiting
95
+ // descriptor closure, after the admitted source state has been verified.
96
+ inputStream?.destroy();
97
+ outputStream?.destroy();
98
+ try {
99
+ await Promise.all([source.close(), destination?.close()]);
100
+ }
101
+ finally {
102
+ if (removeSnapshot)
103
+ await rm(snapshotPath, { force: true }).catch(() => undefined);
104
+ }
105
+ }
106
+ };
107
+ const verifySourceState = async (handle, path, initial, observedBytes) => {
108
+ const [opened, currentPath] = await Promise.all([handle.stat(), stat(path)]);
109
+ if (observedBytes !== initial.size ||
110
+ !sameRegularFileState(initial, opened) ||
111
+ !sameRegularFileState(initial, currentPath))
112
+ throw new AndroidSnapshotChangedError(`Android input changed while being read: ${path}`);
36
113
  };
114
+ class AndroidSnapshotChangedError extends Error {
115
+ constructor(message, options) {
116
+ super(message, options);
117
+ }
118
+ }
@@ -23,7 +23,8 @@ class JadxConfigurationFailure extends Error {
23
23
  /** Inspect the same JAR and Java prerequisites that gate actual execution. */
24
24
  export const inspectJadxAvailability = async (environment, signal) => {
25
25
  try {
26
- const configuration = await readJadxConfiguration(environment, signal);
26
+ const configuration = await readJadxConfigurationInputs(environment, signal);
27
+ await validateJadxConfigurationContents(configuration, environment, signal);
27
28
  return {
28
29
  status: "available",
29
30
  code: null,
@@ -49,42 +50,61 @@ export const inspectJadxAvailability = async (environment, signal) => {
49
50
  throw cause;
50
51
  }
51
52
  };
52
- /** Resolve caller-selected tools and preserve the same prerequisite diagnostics. */
53
- export const resolveJadxConfiguration = async (environment, operation, signal) => {
53
+ /** Resolve caller-selected paths and JVM options without probing their contents. */
54
+ export const resolveJadxConfigurationInputs = async (environment, operation, signal) => {
54
55
  try {
55
- return await readJadxConfiguration(environment, signal);
56
+ return await readJadxConfigurationInputs(environment, signal);
56
57
  }
57
58
  catch (cause) {
58
59
  if (signal?.aborted === true)
59
60
  throw cause;
60
61
  if (!(cause instanceof JadxConfigurationFailure))
61
62
  throw cause;
62
- const output = cause.diagnostics;
63
- throw new AnalysisCapabilityUnavailableError("jadx", operation, cause.message, {
64
- cause,
65
- userMessage: cause.message,
66
- ...(typeof output.stdout === "string" &&
67
- typeof output.stderr === "string"
68
- ? {
69
- capturedOutput: {
70
- stdout: output.stdout,
71
- stderr: output.stderr,
72
- truncated: output.output_truncated === true,
73
- },
74
- }
75
- : {}),
76
- });
63
+ throw projectConfigurationFailure(operation, cause);
77
64
  }
78
65
  };
79
- const readJadxConfiguration = async (environment, signal) => {
66
+ /** Probe Java and archive prerequisites before starting a new engine session. */
67
+ export const validateJadxConfiguration = async (configuration, environment, operation, signal) => {
68
+ try {
69
+ await validateJadxConfigurationContents(configuration, environment, signal);
70
+ }
71
+ catch (cause) {
72
+ if (signal?.aborted === true)
73
+ throw cause;
74
+ if (!(cause instanceof JadxConfigurationFailure))
75
+ throw cause;
76
+ throw projectConfigurationFailure(operation, cause);
77
+ }
78
+ };
79
+ const readJadxConfigurationInputs = async (environment, signal) => {
80
+ signal?.throwIfAborted();
80
81
  requireSupportedHost();
81
82
  const jar = await resolveJar(environment);
82
83
  const java = await resolveJava(environment, signal);
83
84
  await requireJavaHomeExecutable(environment.JAVA_HOME, java);
84
- const jvmArguments = resolveJvmArguments(environment);
85
- await inspectJavaRuntime(java, environment, signal);
86
- await requireEngineArchive(jar, signal);
87
- return { jar, java, jvmArguments };
85
+ signal?.throwIfAborted();
86
+ return { jar, java, jvmArguments: resolveJvmArguments(environment) };
87
+ };
88
+ const validateJadxConfigurationContents = async (configuration, environment, signal) => {
89
+ signal?.throwIfAborted();
90
+ await inspectJavaRuntime(configuration.java, environment, signal);
91
+ await requireEngineArchive(configuration.jar, signal);
92
+ };
93
+ const projectConfigurationFailure = (operation, cause) => {
94
+ const output = cause.diagnostics;
95
+ return new AnalysisCapabilityUnavailableError("jadx", operation, cause.message, {
96
+ cause,
97
+ userMessage: cause.message,
98
+ ...(typeof output.stdout === "string" && typeof output.stderr === "string"
99
+ ? {
100
+ capturedOutput: {
101
+ stdout: output.stdout,
102
+ stderr: output.stderr,
103
+ truncated: output.output_truncated === true,
104
+ },
105
+ }
106
+ : {}),
107
+ });
88
108
  };
89
109
  const requireEngineArchive = async (jar, signal) => {
90
110
  // These classes are consumed directly by ReaJadxBridge.java. This checks the
@@ -9,8 +9,10 @@ import { ProviderCleanupError } from "../domain/providerCleanupError.js";
9
9
  import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
10
10
  import { err, ok } from "../domain/result.js";
11
11
  import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
12
- import { snapshotAndroidEngine, hashAndroidFile, snapshotAndroidTarget, } from "./AndroidTargetSnapshot.js";
13
- import { inspectJadxAvailability, resolveJadxConfiguration, } from "./JadxConfiguration.js";
12
+ import { snapshotAndroidEngine, snapshotAndroidTarget, } from "./AndroidTargetSnapshot.js";
13
+ import { hashStableFile } from "../filesystem/StableFileHash.js";
14
+ import { RegularFileChangedError } from "../filesystem/RegularFile.js";
15
+ import { inspectJadxAvailability, resolveJadxConfigurationInputs, validateJadxConfiguration, } from "./JadxConfiguration.js";
14
16
  import { JadxSession } from "./JadxSession.js";
15
17
  const OPERATION_TIMEOUT_MS = 120_000;
16
18
  const BRIDGE_SOURCE = fileURLToPath(new URL("../../bridge/android/ReaJadxBridge.java", import.meta.url));
@@ -60,6 +62,26 @@ const executionError = (context) => {
60
62
  },
61
63
  });
62
64
  };
65
+ const androidTargetChanged = (operation, path, cause) => new AnalysisInputError(operation, cause === undefined ? undefined : { cause }, [
66
+ {
67
+ path: ["path"],
68
+ reason: "invalid_value",
69
+ message: `APK bytes changed after admission at ${path}; retry against a stable file.`,
70
+ },
71
+ ]);
72
+ const androidSourceChanged = (operation, source, cause) => new AnalysisCapabilityUnavailableError("jadx", operation, `Selected JADX input bytes changed during admission at ${source}; retry with a stable installation.`, cause === undefined ? undefined : { cause });
73
+ const hashAndroidSource = async (path, operation, signal) => {
74
+ try {
75
+ return (await hashStableFile(path, signal)).sha256;
76
+ }
77
+ catch (cause) {
78
+ if (signal.aborted)
79
+ throw cause;
80
+ if (cause instanceof RegularFileChangedError)
81
+ throw androidSourceChanged(operation, path, cause);
82
+ throw cause;
83
+ }
84
+ };
63
85
  const cleanup = async (resources) => {
64
86
  const { session, root, previousError } = resources;
65
87
  const diagnostics = {
@@ -90,10 +112,13 @@ const cleanup = async (resources) => {
90
112
  resources.root = undefined;
91
113
  }
92
114
  catch (cause) {
93
- return err(new ProviderCleanupError("jadx", [root?.path ?? "unknown"], {
115
+ const error = new ProviderCleanupError("jadx", [root?.path ?? "unknown"], {
94
116
  ...diagnostics,
95
117
  reason: cause instanceof Error ? cause.message : String(cause),
96
- }, { cause: previousError ?? cause }));
118
+ }, { cause: previousError ?? cause });
119
+ if (previousError?.partialObservation !== undefined)
120
+ error.retainPartialObservation(previousError.partialObservation);
121
+ return err(error);
97
122
  }
98
123
  return ok(undefined);
99
124
  };
@@ -202,18 +227,23 @@ export class JadxProvider {
202
227
  try {
203
228
  if (target.format !== "apk")
204
229
  throw new AnalysisCapabilityUnavailableError("jadx", request.operation, `Target ${target.path} is ${target.format}; provide one standalone APK.`);
205
- const configuration = await resolveJadxConfiguration(this.environment, request.operation, signal);
230
+ const configuration = await resolveJadxConfigurationInputs(this.environment, request.operation, signal);
206
231
  signal.throwIfAborted();
207
- const jarHash = await hashAndroidFile(configuration.jar);
208
- const bridgeHash = await hashAndroidFile(BRIDGE_SOURCE);
209
- if ((await hashAndroidFile(target.path)) !== target.sha256)
210
- throw new AnalysisInputError(request.operation, undefined, [
211
- {
212
- path: ["path"],
213
- reason: "invalid_value",
214
- message: "APK bytes changed after admission; retry against a stable file.",
215
- },
216
- ]);
232
+ const jarHash = await hashAndroidSource(configuration.jar, request.operation, signal);
233
+ const bridgeHash = await hashAndroidSource(BRIDGE_SOURCE, request.operation, signal);
234
+ let targetHash;
235
+ try {
236
+ targetHash = (await hashStableFile(target.path, signal)).sha256;
237
+ }
238
+ catch (cause) {
239
+ if (signal.aborted)
240
+ throw cause;
241
+ if (cause instanceof RegularFileChangedError)
242
+ throw androidTargetChanged(request.operation, target.path, cause);
243
+ throw cause;
244
+ }
245
+ if (targetHash !== target.sha256)
246
+ throw androidTargetChanged(request.operation, target.path);
217
247
  const key = JSON.stringify({
218
248
  path: target.path,
219
249
  sha256: target.sha256,
@@ -237,14 +267,16 @@ export class JadxProvider {
237
267
  }
238
268
  let retained = this.#retained;
239
269
  if (retained === undefined) {
270
+ await validateJadxConfiguration(configuration, this.environment, request.operation, signal);
240
271
  root = await PrivateRuntimeRoot.create({ prefix: "rea-android-" });
241
- const engine = await snapshotAndroidEngine(configuration.jar, jarHash, root.path, request.operation);
242
- const snapshot = await snapshotAndroidTarget(target.path, target.sha256, root.path, request.operation);
272
+ const engine = await snapshotAndroidEngine(configuration.jar, jarHash, root.path, request.operation, signal);
273
+ const snapshot = await snapshotAndroidTarget(target.path, target.sha256, root.path, request.operation, signal);
243
274
  const bridge = join(root.path, "ReaJadxBridge.java");
244
275
  await copyFile(BRIDGE_SOURCE, bridge);
245
276
  await chmod(bridge, 0o400);
246
- if ((await hashAndroidFile(bridge)) !== bridgeHash)
247
- throw new AnalysisCapabilityUnavailableError("jadx", request.operation, "REA Android bridge bytes changed during admission; retry with a stable installation.");
277
+ const copiedBridgeHash = await hashAndroidSource(bridge, request.operation, signal);
278
+ if (copiedBridgeHash !== bridgeHash)
279
+ throw androidSourceChanged(request.operation, BRIDGE_SOURCE, undefined);
248
280
  signal.throwIfAborted();
249
281
  session = new JadxSession({
250
282
  command: configuration.java,