rea-agents 6.1.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.
- package/README.md +7 -5
- package/bridge/ghidra/ReaGhidraBridge.java +32 -4
- package/bridge/hopper_bridge.py +6 -1
- package/dist/android/JadxConfiguration.js +87 -7
- package/dist/android/JadxMcpTransport.js +14 -2
- package/dist/android/JadxProvider.js +57 -35
- package/dist/application/BinaryTargetResolver.js +5 -3
- package/dist/application/BrowserEvidence.js +3 -8
- package/dist/application/BrowserScenarioEvidence.js +2 -18
- package/dist/application/CapabilityInventory.js +43 -9
- package/dist/application/ClientConfigurationDocument.js +69 -25
- package/dist/application/DirectAnalysis.js +29 -14
- package/dist/application/DirectAnalysisCleanup.js +72 -0
- package/dist/application/DirectAnalysisStatus.js +4 -5
- package/dist/application/Doctor.js +15 -19
- package/dist/application/DoctorDiagnostics.js +1 -2
- package/dist/application/EnhancedTools.js +51 -6
- package/dist/application/EvidenceBundleFiles.js +8 -3
- package/dist/application/InvestigationProviders.js +9 -1
- package/dist/application/JsonFiles.js +42 -9
- package/dist/application/LinuxHopper.js +9 -6
- package/dist/application/MacHopper.js +15 -18
- package/dist/application/RealHopperAssertions.js +0 -11
- package/dist/application/ReconstructionObligationCandidates.js +1 -1
- package/dist/application/ReferenceSourceImportEntries.js +1 -1
- package/dist/application/Setup.js +8 -16
- package/dist/application/SetupHost.js +16 -27
- package/dist/application/SetupPlan.js +6 -6
- package/dist/application/Uninstall.js +81 -29
- package/dist/application/UpdateMaintenance.js +7 -5
- package/dist/application/UpdateRuntime.js +12 -12
- package/dist/application/WebScriptExportService.js +30 -4
- package/dist/application/WorkflowEvidence.js +25 -2
- package/dist/application/XrefsAddressResolution.js +45 -0
- package/dist/application/analysisView/AnalysisViewService.js +76 -0
- package/dist/application/binary/AnalysisClientCleanup.js +30 -5
- package/dist/application/binary/AnalysisProviderEvaluation.js +1 -2
- package/dist/application/binary/AnalysisProviderRegistry.js +2 -6
- package/dist/application/binary/AnalysisSnapshotCache.js +10 -8
- package/dist/application/binary/BinarySession.js +70 -29
- package/dist/application/binary/BinarySessionComposition.js +1 -3
- package/dist/application/binary/BinarySessionExecution.js +3 -5
- package/dist/application/binary/BinarySessionOpen.js +1 -1
- package/dist/application/binary/BinarySessionRecords.js +1 -1
- package/dist/application/binary/BinarySessionStatus.js +1 -6
- package/dist/application/binary/CompositeProvider.js +4 -18
- package/dist/application/binary/LazyAnalysisProvider.js +5 -5
- package/dist/application/binary/SessionProviderRouter.js +27 -135
- package/dist/application/homebrew.js +48 -0
- package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +2 -6
- package/dist/application/javascript/JavaScriptApplicationService.js +6 -1
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -3
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +11 -9
- package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
- package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
- package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +43 -16
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +46 -6
- package/dist/application/javascript/JavaScriptModuleRelationships.js +1 -1
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +42 -19
- package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
- package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
- package/dist/application/process/ProcessCli.js +11 -11
- package/dist/application/process/ProcessEvidence.js +0 -1
- package/dist/artifacts/ArtifactProvider.js +39 -14
- package/dist/artifacts/ArtifactReader.js +31 -0
- package/dist/artifacts/DirectoryArtifactReader.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
- package/dist/artifacts/NativeDmgArtifactReader.js +65 -20
- package/dist/artifacts/SafeOutputTree.js +16 -2
- package/dist/artifacts/ZipArtifactReader.js +11 -4
- package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +4 -2
- package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
- package/dist/artifacts/apple/KeyedArchiveReader.js +21 -3
- package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +67 -61
- package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
- package/dist/artifacts/inventory/reader.js +3 -3
- package/dist/artifacts/inventory/scanCanonical.js +48 -24
- package/dist/artifacts/inventory/scanReader.js +5 -9
- package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
- package/dist/browser/CdpBrowserProvider.js +2 -3
- package/dist/browser/CdpCaptureEventHandlers.js +2 -4
- package/dist/browser/CdpCaptureEvents.js +0 -1
- package/dist/browser/CdpCaptureValues.js +20 -0
- package/dist/browser/CdpElectronProvider.js +0 -2
- package/dist/browser/CdpElectronScriptEvents.js +2 -8
- package/dist/browser/CdpElectronScripts.js +2 -3
- package/dist/browser/CdpPageCaptureScripts.js +2 -3
- package/dist/browser/CdpSafeMetadata.js +10 -10
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
- package/dist/browser/PlaywrightElectronActiveActions.js +2 -56
- package/dist/browser/PlaywrightElectronActiveProvider.js +10 -6
- package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
- package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
- package/dist/browser/PlaywrightScenarioEvents.js +1 -1
- package/dist/browser/PlaywrightScenarioSession.js +39 -22
- package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
- package/dist/browser/history/CaptureFailures.js +6 -2
- package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
- package/dist/catalogIdentity.js +0 -1
- package/dist/cli/analysisViewCommands.js +36 -0
- package/dist/cli/artifactCommands.js +11 -12
- package/dist/cli/coreAnalysisCommands.js +3 -3
- package/dist/cli/coreBinaryCommands.js +32 -27
- package/dist/cli/coreNativeCommands.js +9 -10
- package/dist/cli/electronCommands.js +4 -4
- package/dist/cli/interactiveSetup.js +6 -6
- package/dist/cli/managedCommands.js +7 -8
- package/dist/cli/nativeCallCommands.js +1 -2
- package/dist/cli/omittableDefaults.js +50 -0
- package/dist/cli/processCommands.js +3 -2
- package/dist/cli/setupCommands.js +16 -15
- package/dist/cli/utilityCommands.js +9 -9
- package/dist/cli.js +16 -8
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +1 -0
- package/dist/cliJsonInput.js +15 -1
- package/dist/cliOutput.js +0 -38
- package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
- package/dist/composition/binary.js +9 -9
- package/dist/composition/browserScenario.js +2 -1
- package/dist/composition/directAnalysis.js +20 -13
- package/dist/composition/electronScenario.js +1 -1
- package/dist/composition/optionalObservationProviders.js +12 -7
- package/dist/config/environment.js +6 -0
- package/dist/config/ghidraStartupTimeout.js +4 -9
- package/dist/config/homeDirectory.js +12 -0
- package/dist/config/mcpResponseBudget.js +9 -1
- package/dist/config/parseConfig.js +7 -3
- package/dist/config/parsers.js +19 -22
- package/dist/contracts/analysisViewToolContracts.js +56 -0
- package/dist/contracts/applicationToolContracts.js +5 -4
- package/dist/contracts/artifactComparisonExample.js +2 -2
- package/dist/contracts/artifactToolContracts.js +1 -1
- package/dist/contracts/browserScenarioToolContracts.js +1 -1
- package/dist/contracts/browserToolContracts.js +19 -15
- package/dist/contracts/enhancedInputs.js +2 -2
- package/dist/contracts/enhancedToolContracts.js +4 -3
- package/dist/contracts/evm/evmToolContracts.js +1 -1
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/inputSchemaPresentation.js +90 -0
- package/dist/contracts/investigationExamples.js +4 -3
- package/dist/contracts/javascript/electronToolContracts.js +1 -1
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
- package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
- package/dist/contracts/managed/managedToolContracts.js +5 -10
- package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
- package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
- package/dist/contracts/native/nativeToolContracts.js +2 -2
- package/dist/contracts/officialToolContracts.js +2 -1
- package/dist/contracts/promptContracts.js +2 -2
- package/dist/contracts/providerSelection.js +1 -1
- package/dist/contracts/sessionToolContracts.js +14 -2
- package/dist/contracts/sessionToolSchemas.js +1 -14
- package/dist/contracts/toolContracts.js +2 -0
- package/dist/contracts/toolEffects.js +1 -0
- package/dist/contracts/toolOutputSchemaGroups.js +136 -92
- package/dist/contracts/toolOutputSchemaPrimitives.js +11 -21
- package/dist/contracts/toolSchemaMetadata.js +18 -69
- package/dist/contracts/webNetworkCaptureToolContracts.js +1 -1
- package/dist/contracts/webRuntimeToolContracts.js +1 -1
- package/dist/contracts/webScriptToolContracts.js +1 -1
- package/dist/doctorRuntime.js +7 -5
- package/dist/domain/analysisErrorCore.js +3 -0
- package/dist/domain/analysisErrorPresentation.js +18 -3
- package/dist/domain/analysisErrorProjection.js +24 -5
- package/dist/domain/analysisSnapshot.js +29 -31
- package/dist/domain/analysisView/analysisView.js +243 -0
- package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
- package/dist/domain/analysisView/binaryLayoutView.js +159 -0
- package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
- package/dist/domain/android/androidApplication.js +1 -1
- package/dist/domain/apple/appleApplication.js +1 -1
- package/dist/domain/apple/dylibResolution.js +10 -3
- package/dist/domain/apple/interfaceBuilderGraph.js +0 -1
- package/dist/domain/apple/keyedArchive.js +26 -2
- package/dist/domain/artifactComparison.js +15 -6
- package/dist/domain/artifactGraph.js +16 -3
- package/dist/domain/artifactInventoryEvidence.js +9 -16
- package/dist/domain/artifactOperationError.js +3 -3
- package/dist/domain/artifactPartialObservation.js +1 -0
- package/dist/domain/artifactPathSyntax.js +49 -0
- package/dist/domain/binaryTarget.js +39 -13
- package/dist/domain/browserCaptureComparison.js +13 -49
- package/dist/domain/browserNetworkEvidence.js +10 -4
- package/dist/domain/browserObservation.js +0 -1
- package/dist/domain/browserObservationSchemas.js +14 -3
- package/dist/domain/browserScenario.js +0 -1
- package/dist/domain/browserScenarioCapture.js +1 -2
- package/dist/domain/browserScenarioDiff.js +0 -2
- package/dist/domain/browserScenarioDiffEvidence.js +0 -12
- package/dist/domain/browserScenarioDiffValues.js +2 -2
- package/dist/domain/browserScenarioValues.js +3 -4
- package/dist/domain/callPath.js +8 -9
- package/dist/domain/callPathSchemas.js +2 -2
- package/dist/domain/changedBehavior.js +3 -3
- package/dist/domain/completionLedgerGeneration.js +2 -1
- package/dist/domain/configurationErrors.js +12 -0
- package/dist/domain/conformancePackage.js +4 -3
- package/dist/domain/evidence.js +10 -36
- package/dist/domain/evidenceBundle.js +7 -9
- package/dist/domain/evidenceCompletionLedger.js +2 -1
- package/dist/domain/functionComparison.js +4 -5
- package/dist/domain/functionComparisonDimensions.js +120 -87
- package/dist/domain/functionComparisonNormalization.js +23 -34
- package/dist/domain/functionComparisonResults.js +1 -4
- package/dist/domain/functionComparisonSchemas.js +2 -8
- package/dist/domain/functionDossierEvidence.js +2 -37
- package/dist/domain/javascript/electronActiveObservation.js +26 -69
- package/dist/domain/javascript/electronObservation.js +14 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
- package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +26 -3
- package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
- package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
- package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
- package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
- package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
- package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
- package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
- package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
- package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +9 -3
- package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +1 -1
- package/dist/domain/javascript/javascriptSemanticGraph.js +88 -46
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
- package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +1 -12
- package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
- package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
- package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
- package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
- package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
- package/dist/domain/javascript/javascriptSemanticValues.js +47 -54
- package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +0 -1
- package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
- package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
- package/dist/domain/localPath.js +1 -1
- package/dist/domain/managed/managedArtifact.js +6 -4
- package/dist/domain/managed/managedMemberComparison.js +2 -9
- package/dist/domain/managed/managedNativeVerification.js +0 -2
- package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
- package/dist/domain/native/binaryLayout.js +2 -3
- package/dist/domain/native/nativeApiBoundary.js +1 -1
- package/dist/domain/native/nativeCallObservation.js +5 -3
- package/dist/domain/native/nativeInstruction.js +7 -0
- package/dist/domain/native/recordedCrash.js +2 -3
- package/dist/domain/offsetDateTime.js +17 -0
- package/dist/domain/process/processCapture.js +13 -12
- package/dist/domain/process/processCaptureCoverage.js +67 -0
- package/dist/domain/process/processCaptureExample.js +2 -1
- package/dist/domain/process/processCaptureParsing.js +1 -34
- package/dist/domain/process/processCaptureValidation.js +81 -13
- package/dist/domain/process/processComparison.js +41 -22
- package/dist/domain/process/processObservation.js +10 -2
- package/dist/domain/process/processScenario.js +24 -2
- package/dist/domain/process/processTraceComparison.js +0 -2
- package/dist/domain/process/processTraceDimensionProjection.js +1 -1
- package/dist/domain/process/processTraceEvaluation.js +15 -11
- package/dist/domain/process/processTraceSpecification.js +3 -4
- package/dist/domain/providerAdapterError.js +2 -0
- package/dist/domain/reconstructionCoverage.js +5 -2
- package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
- package/dist/domain/reconstructionReadinessSchemas.js +2 -1
- package/dist/domain/reconstructionVerification.js +3 -3
- package/dist/domain/reconstructionVerificationSchemas.js +2 -1
- package/dist/domain/referenceSourceGraph.js +20 -21
- package/dist/domain/staticRuntimeCorrelation.js +2 -2
- package/dist/domain/stringPatterns.js +6 -0
- package/dist/domain/swiftSymbolClassification.js +61 -0
- package/dist/domain/symbolAnalysis.js +66 -18
- package/dist/domain/webCaptureDiff.js +0 -1
- package/dist/domain/webCaptureDiffSchemas.js +6 -3
- package/dist/domain/webEventListeners.js +3 -2
- package/dist/domain/webExecution.js +3 -2
- package/dist/domain/webRuntime.js +0 -2
- package/dist/domain/webScriptExport.js +1 -1
- package/dist/dotnet/ManagedArtifactInspector.js +2 -19
- package/dist/dotnet/ManagedMemberInspector.js +12 -18
- package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
- package/dist/dotnet/ManagedMemberRows.js +75 -62
- package/dist/dotnet/ManagedMetadataInventory.js +16 -22
- package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
- package/dist/dotnet/ManagedReaderFailure.js +16 -0
- package/dist/dotnet/ManagedStaticProvider.js +3 -5
- package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
- package/dist/evaluation/AgentEvaluationReport.js +28 -0
- package/dist/evaluation/CodexAgentEval.js +12 -8
- package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
- package/dist/evm/EvmoleInterfaceProvider.js +2 -1
- package/dist/firmware/FirmwareCommand.js +9 -5
- package/dist/firmware/FirmwareProvider.js +4 -4
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +3 -6
- package/dist/ghidra/GhidraClient.js +91 -32
- package/dist/ghidra/GhidraClientStartup.js +0 -2
- package/dist/ghidra/GhidraDoctor.js +6 -5
- package/dist/ghidra/GhidraFunctionValues.js +3 -5
- package/dist/ghidra/GhidraInstallation.js +40 -12
- package/dist/ghidra/GhidraJavaLaunch.js +6 -2
- package/dist/ghidra/GhidraLauncher.js +15 -7
- package/dist/ghidra/GhidraProvider.js +6 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +6 -0
- package/dist/ghidra/GhidraProviderClient.js +13 -3
- package/dist/ghidra/GhidraSessionError.js +2 -0
- package/dist/ghidra/GhidraSessionRoot.js +39 -0
- package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
- package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
- package/dist/hopper/BridgeLauncher.js +34 -45
- package/dist/hopper/HopperAnalysisProfile.js +3 -8
- package/dist/hopper/HopperCleanup.js +56 -27
- package/dist/hopper/HopperClient.js +86 -65
- package/dist/hopper/HopperMachOImage.js +3 -2
- package/dist/hopper/HopperProvider.js +16 -18
- package/dist/hopper/HopperRegexSearch.js +3 -6
- package/dist/hopper/HopperTargetLease.js +132 -49
- package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
- package/dist/ida/IdaConfiguration.js +8 -3
- package/dist/ida/IdaInput.js +1 -7
- package/dist/ida/IdaMcpConnection.js +8 -4
- package/dist/ida/IdaOperationRunner.js +3 -3
- package/dist/ida/IdaProvider.js +8 -12
- package/dist/ida/IdaSessionClient.js +20 -18
- package/dist/ida/IdaWorkspace.js +12 -13
- package/dist/inspector/V8InspectorCaptureProjection.js +1 -1
- package/dist/inspector/V8InspectorProvider.js +38 -28
- package/dist/javascript/recovery/WakaruCommand.js +7 -2
- package/dist/javascript/recovery/WakaruExecution.js +5 -2
- package/dist/main/shutdown.js +11 -3
- package/dist/main/startup.js +9 -2
- package/dist/main/transport.js +22 -2
- package/dist/main.js +11 -18
- package/dist/native/AppleMachoSelection.js +16 -6
- package/dist/native/CommandRunner.js +9 -7
- package/dist/native/LldbCallTracer.js +8 -2
- package/dist/native/NativeMacOSProvider.js +25 -15
- package/dist/native/NativeUiHelperRuntime.js +11 -2
- package/dist/native/NativeUiObservation.js +2 -2
- package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
- package/dist/process/DarwinProcessRunTokenReader.js +16 -2
- package/dist/process/ExecFileOutput.js +88 -6
- package/dist/process/PrivateRuntimeRoot.js +10 -5
- package/dist/process/ProcessOwnership.js +1 -4
- package/dist/process/ProcessOwnershipObservation.js +11 -5
- package/dist/process/ProviderProcess.js +1 -3
- package/dist/process/capture/FilesystemSnapshot.js +50 -13
- package/dist/process/capture/ProcessCaptureError.js +13 -0
- package/dist/process/capture/ProcessCaptureLifecycle.js +158 -70
- package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
- package/dist/process/capture/ProcessHarness.js +21 -25
- package/dist/process/capture/ProcessNormalization.js +20 -2
- package/dist/process/capture/ProcessSampling.js +25 -2
- package/dist/process/capture/TerminalRenderer.js +14 -0
- package/dist/process/snapshotEnvironment.js +14 -0
- package/dist/server/EvidenceMcpServer.js +25 -14
- package/dist/server/createServer.js +49 -36
- package/dist/server/mcpClientMetadata.js +12 -5
- package/dist/server/promptCompletion.js +3 -8
- package/dist/server/registerAnalysisViewTool.js +15 -0
- package/dist/server/registerAndroidTools.js +2 -3
- package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
- package/dist/server/registerApplicationTools/compareVersions.js +4 -5
- package/dist/server/registerApplicationTools/coverage.js +1 -2
- package/dist/server/registerApplicationTools/helpers.js +1 -2
- package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
- package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
- package/dist/server/registerApplicationTools/traceFeature.js +4 -5
- package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
- package/dist/server/registerArtifactComparisonTool.js +4 -5
- package/dist/server/registerBinaryDiagnosticsTools.js +2 -3
- package/dist/server/registerBrowserScenarioTool.js +3 -4
- package/dist/server/registerBrowserTools.js +13 -16
- package/dist/server/registerBundleComparisonTool.js +5 -6
- package/dist/server/registerCloseLifecycleTool.js +2 -3
- package/dist/server/registerElectronTools.js +10 -13
- package/dist/server/registerEnhancedTools.js +23 -23
- package/dist/server/registerEvidenceTools.js +3 -4
- package/dist/server/registerEvmTools.js +2 -3
- package/dist/server/registerFirmwareTools.js +2 -3
- package/dist/server/registerFunctionComparisonTool.js +7 -8
- package/dist/server/registerInvestigationTools.js +14 -15
- package/dist/server/registerJavaScriptRecoveryTool.js +2 -3
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -6
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -6
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -5
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -7
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -7
- package/dist/server/registerOfficialTools.js +4 -19
- package/dist/server/registerProcessComparisonTool.js +8 -8
- package/dist/server/registerRecordedCrashTools.js +2 -3
- package/dist/server/registerSessionRecordTools.js +15 -19
- package/dist/server/registerSessionStatusTool.js +3 -4
- package/dist/server/registerSessionTools.js +12 -18
- package/dist/server/registerWebModuleTool.js +2 -3
- package/dist/server/registerWebNetworkCaptureTool.js +2 -3
- package/dist/server/registerWebRuntimeTools.js +4 -5
- package/dist/server/registerWebScriptTool.js +2 -3
- package/dist/server/registerWebSourceLocationTool.js +2 -3
- package/dist/server/toolResult.js +66 -94
- package/dist/server/toolResultEncoding.js +11 -10
- package/dist/windows/WindowsNativeLoader.js +1 -0
- package/dist/windows/WindowsOwnedProcess.js +60 -15
- package/dist/windows/WindowsPrivateRuntime.js +7 -8
- package/native/windows/README.md +3 -1
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +39 -30
- package/scripts/rea.mjs +3 -6
- package/skills/reverse-engineer-anything/SKILL.md +9 -8
- package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
- package/skills/reverse-engineer-anything/references/javascript-applications.md +16 -6
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
- package/dist/config.js +0 -1
- package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
- package/dist/contracts/process/processCaptureExample.js +0 -2
- package/dist/contracts/toolOutputSchemas.js +0 -2
- package/dist/main/reload.js +0 -12
- package/dist/main/state.js +0 -3
- package/dist/server/sessionToolPolicies.js +0 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
**English** · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
|
|
3
|
+
**English** · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
|
|
4
4
|
|
|
5
5
|
# REA: Reverse Engineer Anything
|
|
6
6
|
|
|
@@ -157,7 +157,7 @@ Additional tools and host support depend on the target:
|
|
|
157
157
|
| Websites | Page structure, scripts, network observations and requested screenshots | A Chrome-family browser; [browser analysis](https://rea.tools/guides/browser/) |
|
|
158
158
|
| Saved network captures | Requests, responses, exposed payloads and source locations | HAR; mitmdump on Linux for native mitmproxy captures; [capture guide](docs/web-network-captures.md) |
|
|
159
159
|
| .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | Static inspection; [managed-code guide](docs/managed-code-analysis.md) |
|
|
160
|
-
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS; [Android guide](docs/android-analysis.md)
|
|
160
|
+
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS/Windows x64; [Android guide](docs/android-analysis.md) |
|
|
161
161
|
| Firmware | Regions, extraction results and native-analysis handoffs | Binwalk / Unblob on Linux; [firmware guide](docs/firmware-analysis.md) |
|
|
162
162
|
| Packages and resources | File inventories, digests, plists, Apple bundle anatomy and extracted resources | [Artifact and JavaScript guide](docs/javascript-artifact-reconstruction.md), [Apple applications](docs/apple-application-analysis.md) |
|
|
163
163
|
| Process behavior | Terminal output, interactions, exit and filesystem observations, and run comparisons | Linux/macOS with a native PTY; [process capture](docs/process-capture.md) |
|
|
@@ -298,7 +298,7 @@ For exact options, prerequisites and result contracts:
|
|
|
298
298
|
- [Readiness and troubleshooting](docs/installation.md#check-readiness-for-your-task): diagnose one agent or analysis engine.
|
|
299
299
|
- [CLI and Evidence](docs/cli.md): commands, provider selection, snapshots, import/export and exit statuses.
|
|
300
300
|
- [MCP contracts](docs/mcp-contracts.md) and [agent prompts](docs/mcp-prompts.md): tool results, sessions and guided investigations.
|
|
301
|
-
- [Tool catalog](docs/mcp-contracts.md#generated-catalog):
|
|
301
|
+
- [Tool catalog](docs/mcp-contracts.md#generated-catalog): generated inventory of tools, providers and CLI commands.
|
|
302
302
|
- [Roadmap](docs/roadmap.md): planned work and capability trackers.
|
|
303
303
|
|
|
304
304
|
Report vulnerabilities through [SECURITY.md](SECURITY.md).
|
|
@@ -319,9 +319,9 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and checks,
|
|
|
319
319
|
|
|
320
320
|
## Star history
|
|
321
321
|
|
|
322
|
-
🎉 **
|
|
322
|
+
🎉 **30,000 GitHub stars — thank you!**
|
|
323
323
|
|
|
324
|
-
Thanks to everyone using REA, reporting bugs, testing builds, and contributing fixes.
|
|
324
|
+
Thanks to everyone using REA, reporting bugs, requesting features, testing builds, and contributing fixes.
|
|
325
325
|
|
|
326
326
|
<a href="https://www.star-history.com/?repos=morluto%2Frea&type=date">
|
|
327
327
|
<picture>
|
|
@@ -335,6 +335,8 @@ Thanks to everyone using REA, reporting bugs, testing builds, and contributing f
|
|
|
335
335
|
|
|
336
336
|
REA provides tools for lawful reverse-engineering research, analysis, and reconstruction. You are responsible for obtaining any required authorization and complying with applicable laws. The project does not endorse illegal or unauthorized use.
|
|
337
337
|
|
|
338
|
+
REA is an open-source software project. We have not issued or endorsed any cryptocurrency or token. Tokens using the REA name are not affiliated with the project.
|
|
339
|
+
|
|
338
340
|
## License
|
|
339
341
|
|
|
340
342
|
[MIT](LICENSE)
|
|
@@ -866,6 +866,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
866
866
|
JsonArray operands = new JsonArray();
|
|
867
867
|
JsonArray references = new JsonArray();
|
|
868
868
|
JsonArray destinations = new JsonArray();
|
|
869
|
+
JsonArray flowEvidence = new JsonArray();
|
|
869
870
|
JsonObject flow = new JsonObject();
|
|
870
871
|
flow.addProperty("kind", "unavailable");
|
|
871
872
|
flow.addProperty("conditional", false);
|
|
@@ -881,7 +882,20 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
881
882
|
result.addProperty("mnemonic", instruction.getMnemonicString());
|
|
882
883
|
result.addProperty("raw_disassembly", instruction.toString());
|
|
883
884
|
RefType type = instruction.getFlowType();
|
|
884
|
-
|
|
885
|
+
JsonObject listingFlow = new JsonObject();
|
|
886
|
+
listingFlow.addProperty("source", "ghidra-listing-flow-type");
|
|
887
|
+
listingFlow.addProperty("value", type.getName());
|
|
888
|
+
flowEvidence.add(listingFlow);
|
|
889
|
+
boolean decodedReturn = false;
|
|
890
|
+
for (PcodeOp operation : instruction.getPcode()) {
|
|
891
|
+
if (operation.getOpcode() != PcodeOp.RETURN) continue;
|
|
892
|
+
decodedReturn = true;
|
|
893
|
+
JsonObject returnEvidence = new JsonObject();
|
|
894
|
+
returnEvidence.addProperty("source", "ghidra-instruction-pcode");
|
|
895
|
+
returnEvidence.addProperty("value", operation.getMnemonic());
|
|
896
|
+
flowEvidence.add(returnEvidence);
|
|
897
|
+
}
|
|
898
|
+
flow.addProperty("kind", type.isCall() ? "call" : type.isJump() ? "jump" : decodedReturn ? "return" : type.isTerminal() ? "terminal" : "fallthrough");
|
|
885
899
|
flow.addProperty("conditional", type.isConditional());
|
|
886
900
|
flow.addProperty("computed", type.isComputed());
|
|
887
901
|
if (!type.isComputed()) for (Address target : instruction.getFlows()) destinations.add(canonicalAddress(target));
|
|
@@ -917,10 +931,13 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
917
931
|
}
|
|
918
932
|
}
|
|
919
933
|
flow.add("direct_destinations", destinations);
|
|
934
|
+
flow.add("classification_evidence", flowEvidence);
|
|
920
935
|
result.add("operands", operands);
|
|
921
936
|
result.add("flow", flow);
|
|
922
937
|
result.add("references", references);
|
|
923
|
-
|
|
938
|
+
List<String> limitations = new ArrayList<>(List.of("Operand components are Ghidra Listing decoder tokens; effective memory base/index/displacement roles and per-instruction context mode are unavailable. The mode field is the program language variant."));
|
|
939
|
+
if (flow.get("kind").getAsString().equals("terminal")) limitations.add("No RETURN operation was observed in the provider's instruction p-code; terminal classification remains generic.");
|
|
940
|
+
result.add("limitations", GSON.toJsonTree(limitations));
|
|
924
941
|
return result;
|
|
925
942
|
}
|
|
926
943
|
|
|
@@ -1629,9 +1646,20 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1629
1646
|
Function function = entry.function;
|
|
1630
1647
|
Symbol symbol = function.getSymbol();
|
|
1631
1648
|
String qualified = symbol == null ? function.getName() : symbol.getName(true);
|
|
1632
|
-
|
|
1633
|
-
|
|
1649
|
+
boolean matchesName = function.getName().equals(value) || qualified.equals(value);
|
|
1650
|
+
if (!matchesName) {
|
|
1651
|
+
// Imported labels (for example Mach-O _main) can share a
|
|
1652
|
+
// function entry without becoming its primary symbol. Only
|
|
1653
|
+
// exact entries qualify; an interior label is not a selector.
|
|
1654
|
+
for (Symbol entrySymbol : currentProgram.getSymbolTable().getSymbols(function.getEntryPoint())) {
|
|
1655
|
+
monitor.checkCancelled();
|
|
1656
|
+
if (entrySymbol.getName().equals(value) || entrySymbol.getName(true).equals(value)) {
|
|
1657
|
+
matchesName = true;
|
|
1658
|
+
break;
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1634
1661
|
}
|
|
1662
|
+
if (matchesName) matches.add(function);
|
|
1635
1663
|
}
|
|
1636
1664
|
if (matches.size() > 1)
|
|
1637
1665
|
throw new RequestFailure("ambiguous", "Ghidra procedure name is ambiguous: " + value +
|
package/bridge/hopper_bridge.py
CHANGED
|
@@ -553,7 +553,12 @@ def _search_results(document, kind, params):
|
|
|
553
553
|
if not matches(item[1]):
|
|
554
554
|
continue
|
|
555
555
|
selected.append(item)
|
|
556
|
-
|
|
556
|
+
if not selected:
|
|
557
|
+
return []
|
|
558
|
+
if kind == "string":
|
|
559
|
+
records = _string_inventory(document)
|
|
560
|
+
return [{"address": address, **records[address]} for address, _ in selected]
|
|
561
|
+
return [
|
|
557
562
|
{
|
|
558
563
|
"address": address,
|
|
559
564
|
"value": value,
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import { constants } from "node:fs";
|
|
2
2
|
import { access, realpath, stat } from "node:fs/promises";
|
|
3
|
-
import { isAbsolute, join } from "node:path";
|
|
3
|
+
import { delimiter, isAbsolute, join, resolve } from "node:path";
|
|
4
|
+
import { systemWindowsNativeAuthority } from "../windows/WindowsNativeLoader.js";
|
|
4
5
|
import { AnalysisCapabilityUnavailableError } from "../domain/analysisErrorCore.js";
|
|
6
|
+
import { ZipArtifactReader } from "../artifacts/ZipArtifactReader.js";
|
|
5
7
|
import { execFileOutput, execFileOutputFailure, } from "../process/ExecFileOutput.js";
|
|
6
8
|
import { JADX_JAR_CONFIGURATION_REMEDIATION } from "./JadxRelease.js";
|
|
7
9
|
const JAVA_MODULE_LISTING_TIMEOUT_MS = 10_000;
|
|
8
10
|
const JAVA_MODULE_LISTING_MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
11
|
+
// Bound ZIP metadata allocation during discovery. The audited 0.7.1 JAR's
|
|
12
|
+
// central directory occupies 2,294,350 bytes; class bodies are not read here.
|
|
13
|
+
const JAR_METADATA_READ_MAX_BYTES = 8 * 1024 * 1024;
|
|
9
14
|
class JadxConfigurationFailure extends Error {
|
|
10
15
|
code;
|
|
11
16
|
diagnostics;
|
|
@@ -74,16 +79,65 @@ export const resolveJadxConfiguration = async (environment, operation, signal) =
|
|
|
74
79
|
const readJadxConfiguration = async (environment, signal) => {
|
|
75
80
|
requireSupportedHost();
|
|
76
81
|
const jar = await resolveJar(environment);
|
|
77
|
-
const java = resolveJava(environment);
|
|
82
|
+
const java = await resolveJava(environment, signal);
|
|
78
83
|
await requireJavaHomeExecutable(environment.JAVA_HOME, java);
|
|
79
84
|
const jvmArguments = resolveJvmArguments(environment);
|
|
80
85
|
await inspectJavaRuntime(java, environment, signal);
|
|
86
|
+
await requireEngineArchive(jar, signal);
|
|
81
87
|
return { jar, java, jvmArguments };
|
|
82
88
|
};
|
|
89
|
+
const requireEngineArchive = async (jar, signal) => {
|
|
90
|
+
// These classes are consumed directly by ReaJadxBridge.java. This checks the
|
|
91
|
+
// classpath inventory without loading engine code or starting a JADX session.
|
|
92
|
+
const missing = new Set([
|
|
93
|
+
"com/atxx/jhmcp/JadxSession.class",
|
|
94
|
+
"com/atxx/jhmcp/SessionHolder.class",
|
|
95
|
+
"jadx/api/JadxDecompiler.class",
|
|
96
|
+
"com/google/gson/Gson.class",
|
|
97
|
+
"io/modelcontextprotocol/kotlin/sdk/server/Server.class",
|
|
98
|
+
]);
|
|
99
|
+
const reader = new ZipArtifactReader(jar, "zip", JAR_METADATA_READ_MAX_BYTES);
|
|
100
|
+
try {
|
|
101
|
+
for await (const entry of reader.entries(signal)) {
|
|
102
|
+
if (entry.kind === "file" && !entry.encrypted)
|
|
103
|
+
missing.delete(entry.path);
|
|
104
|
+
if (missing.size === 0)
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
catch (cause) {
|
|
109
|
+
if (signal?.aborted === true)
|
|
110
|
+
throw cause;
|
|
111
|
+
const reason = cause instanceof Error ? cause.message : String(cause);
|
|
112
|
+
throw configurationFailure("version_unresolved", `Cannot inspect REA_JADX_MCP_JAR ${jar} as a Java archive: ${reason}. ${JADX_JAR_CONFIGURATION_REMEDIATION}`, {
|
|
113
|
+
jar_path: jar,
|
|
114
|
+
phase: "jar-inspection",
|
|
115
|
+
archive_error: reason,
|
|
116
|
+
maximum_metadata_read_bytes: JAR_METADATA_READ_MAX_BYTES,
|
|
117
|
+
}, cause);
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
await reader.close();
|
|
121
|
+
}
|
|
122
|
+
throw configurationFailure("unsupported_version", `REA_JADX_MCP_JAR ${jar} does not contain the required metadata bridge classes: ${[...missing].join(", ")}. ${JADX_JAR_CONFIGURATION_REMEDIATION}`, { jar_path: jar, phase: "jar-inspection", missing_classes: [...missing] });
|
|
123
|
+
};
|
|
83
124
|
const requireSupportedHost = () => {
|
|
84
125
|
if (process.platform === "linux" || process.platform === "darwin")
|
|
85
126
|
return;
|
|
86
|
-
|
|
127
|
+
if (process.platform === "win32" && process.arch === "x64") {
|
|
128
|
+
const loaded = systemWindowsNativeAuthority();
|
|
129
|
+
if (loaded.available && loaded.authority.inspection.protocolStdin === true)
|
|
130
|
+
return;
|
|
131
|
+
throw configurationFailure("runtime_missing", loaded.available
|
|
132
|
+
? "The bundled Windows native artifact lacks owned protocol stdin; use a matching current Windows x64 REA package."
|
|
133
|
+
: loaded.reason, {
|
|
134
|
+
platform: process.platform,
|
|
135
|
+
architecture: process.arch,
|
|
136
|
+
phase: "process-ownership",
|
|
137
|
+
owned_protocol_stdin: false,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
throw configurationFailure("unsupported_host", `Android JADX subprocess ownership is unsupported on ${process.platform}/${process.arch}; use Linux, macOS, or Windows x64 with its bundled native controls.`, { platform: process.platform });
|
|
87
141
|
};
|
|
88
142
|
const resolveJar = async (environment) => {
|
|
89
143
|
const jar = environment.REA_JADX_MCP_JAR;
|
|
@@ -101,11 +155,37 @@ const resolveJar = async (environment) => {
|
|
|
101
155
|
throw configurationFailure("executable_missing", `Cannot read REA_JADX_MCP_JAR ${jar}: ${cause instanceof Error ? cause.message : String(cause)}`, { jar_path: jar }, cause);
|
|
102
156
|
}
|
|
103
157
|
};
|
|
104
|
-
const resolveJava = (environment) => {
|
|
105
|
-
|
|
106
|
-
|
|
158
|
+
const resolveJava = async (environment, signal) => {
|
|
159
|
+
const executable = process.platform === "win32" ? "java.exe" : "java";
|
|
160
|
+
if (environment.JAVA_HOME === undefined) {
|
|
161
|
+
if (process.platform !== "win32")
|
|
162
|
+
return executable;
|
|
163
|
+
const path = Object.entries(environment).find(([key]) => key.toLowerCase() === "path")?.[1] ?? "";
|
|
164
|
+
for (const directory of [process.cwd(), ...path.split(delimiter)]) {
|
|
165
|
+
signal?.throwIfAborted();
|
|
166
|
+
// Windows PATH commonly quotes individual entries containing spaces.
|
|
167
|
+
const selected = directory.startsWith('"') && directory.endsWith('"')
|
|
168
|
+
? directory.slice(1, -1)
|
|
169
|
+
: directory;
|
|
170
|
+
const candidate = resolve(selected, executable);
|
|
171
|
+
try {
|
|
172
|
+
await access(candidate, constants.R_OK | constants.X_OK);
|
|
173
|
+
if ((await stat(candidate)).isFile())
|
|
174
|
+
return await realpath(candidate);
|
|
175
|
+
}
|
|
176
|
+
catch (cause) {
|
|
177
|
+
if (typeof cause === "object" &&
|
|
178
|
+
cause !== null &&
|
|
179
|
+
"code" in cause &&
|
|
180
|
+
(cause.code === "ENOENT" || cause.code === "ENOTDIR"))
|
|
181
|
+
continue;
|
|
182
|
+
throw configurationFailure("runtime_missing", `Cannot inspect selected Java executable ${candidate}: ${errorText(cause)}`, { java_executable: candidate }, cause);
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
throw configurationFailure("runtime_missing", "Cannot find java.exe on the selected Windows PATH. Select a full JDK with JAVA_HOME or PATH, then verify it with java --list-modules. REA does not install Java.", { java_executable: executable });
|
|
186
|
+
}
|
|
107
187
|
if (isAbsolute(environment.JAVA_HOME))
|
|
108
|
-
return join(environment.JAVA_HOME, "bin",
|
|
188
|
+
return join(environment.JAVA_HOME, "bin", executable);
|
|
109
189
|
throw configurationFailure("open_options_invalid", "JAVA_HOME must select an existing JDK by absolute path; omit it to use java on PATH.", { java_home: environment.JAVA_HOME });
|
|
110
190
|
};
|
|
111
191
|
const requireJavaHomeExecutable = async (javaHome, java) => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { deserializeMessage, serializeMessage, } from "@modelcontextprotocol/client";
|
|
2
2
|
import { randomUUID } from "node:crypto";
|
|
3
|
+
import { finished } from "node:stream/promises";
|
|
3
4
|
import { ProviderProcessSupervisor, spawnOwnedProviderProcess, } from "../process/ProviderProcess.js";
|
|
4
5
|
import { cleanupOwnedProcessGroup } from "../process/ProcessOwnership.js";
|
|
5
6
|
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
|
|
@@ -71,7 +72,10 @@ export class JadxMcpTransport {
|
|
|
71
72
|
}
|
|
72
73
|
/** Verifies owned process exit before declaring the transport closed. */
|
|
73
74
|
close() {
|
|
74
|
-
this.#closePromise ??= this.#stop()
|
|
75
|
+
this.#closePromise ??= this.#stop().catch((cause) => {
|
|
76
|
+
this.#closePromise = undefined;
|
|
77
|
+
throw cause;
|
|
78
|
+
});
|
|
75
79
|
return this.#closePromise;
|
|
76
80
|
}
|
|
77
81
|
/** Captured provider stderr without persisting inherited environment values. */
|
|
@@ -102,8 +106,16 @@ export class JadxMcpTransport {
|
|
|
102
106
|
process?.stderr?.off("data", this.#countStderr);
|
|
103
107
|
process?.off("error", this.#error);
|
|
104
108
|
process?.off("exit", this.#exit);
|
|
105
|
-
process?.stdin
|
|
109
|
+
const input = process?.stdin;
|
|
110
|
+
// A job termination can complete an in-flight pipe write asynchronously.
|
|
111
|
+
// Observe its errors until the owned Writable has finished closing.
|
|
112
|
+
const inputClosed = input === undefined || input === null
|
|
113
|
+
? undefined
|
|
114
|
+
: finished(input, { readable: false, cleanup: true }).catch(() => undefined);
|
|
106
115
|
const stopped = await this.#supervisor?.stop();
|
|
116
|
+
input?.destroy();
|
|
117
|
+
await inputClosed;
|
|
118
|
+
input?.off("error", this.#error);
|
|
107
119
|
this.onclose?.();
|
|
108
120
|
if (stopped?.status === "incomplete")
|
|
109
121
|
throw new ProviderCleanupError("jadx", [this.runId], {
|
|
@@ -6,6 +6,7 @@ import { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
|
6
6
|
import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisOutputError, AnalysisInputError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
|
|
7
7
|
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
8
8
|
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
|
|
9
|
+
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
|
9
10
|
import { err, ok } from "../domain/result.js";
|
|
10
11
|
import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
|
|
11
12
|
import { snapshotAndroidEngine, hashAndroidFile, snapshotAndroidTarget, } from "./AndroidTargetSnapshot.js";
|
|
@@ -59,14 +60,14 @@ const executionError = (context) => {
|
|
|
59
60
|
},
|
|
60
61
|
});
|
|
61
62
|
};
|
|
62
|
-
const cleanup = async (
|
|
63
|
+
const cleanup = async (resources) => {
|
|
64
|
+
const { session, root, previousError } = resources;
|
|
63
65
|
const diagnostics = {
|
|
64
|
-
previous_error:
|
|
65
|
-
? null
|
|
66
|
-
: { tag: previous.error._tag, message: previous.error.message },
|
|
66
|
+
previous_error: previousError === undefined ? null : projectAnalysisError(previousError),
|
|
67
67
|
};
|
|
68
68
|
try {
|
|
69
69
|
await session?.close();
|
|
70
|
+
resources.session = undefined;
|
|
70
71
|
}
|
|
71
72
|
catch (cause) {
|
|
72
73
|
// Retain an uncertain workspace until the caller can resolve process ownership.
|
|
@@ -79,30 +80,31 @@ const cleanup = async (session, root, previous) => {
|
|
|
79
80
|
provider_cleanup: cause instanceof ProviderCleanupError
|
|
80
81
|
? (cause.diagnostics ?? null)
|
|
81
82
|
: null,
|
|
82
|
-
}, { cause }));
|
|
83
|
+
}, { cause: previousError ?? cause }));
|
|
83
84
|
}
|
|
84
85
|
try {
|
|
85
86
|
await root?.close();
|
|
87
|
+
resources.root = undefined;
|
|
86
88
|
}
|
|
87
89
|
catch (cause) {
|
|
88
90
|
return err(new ProviderCleanupError("jadx", [root?.path ?? "unknown"], {
|
|
89
91
|
...diagnostics,
|
|
90
92
|
reason: cause instanceof Error ? cause.message : String(cause),
|
|
91
|
-
}, { cause }));
|
|
93
|
+
}, { cause: previousError ?? cause }));
|
|
92
94
|
}
|
|
93
|
-
return
|
|
95
|
+
return ok(undefined);
|
|
94
96
|
};
|
|
95
97
|
/** One serialized, immutable APK session per REA instance, retired on idle or shutdown. */
|
|
96
98
|
export class JadxProvider {
|
|
97
99
|
environment;
|
|
98
100
|
launcher;
|
|
99
101
|
#tail = Promise.resolve();
|
|
100
|
-
#
|
|
102
|
+
#pendingCleanup;
|
|
101
103
|
#retained;
|
|
102
104
|
#idle;
|
|
103
105
|
#shutdown = new AbortController();
|
|
104
106
|
#closePromise;
|
|
105
|
-
constructor(environment
|
|
107
|
+
constructor(environment, launcher) {
|
|
106
108
|
this.environment = environment;
|
|
107
109
|
this.launcher = launcher;
|
|
108
110
|
}
|
|
@@ -132,12 +134,13 @@ export class JadxProvider {
|
|
|
132
134
|
try {
|
|
133
135
|
if (signal.aborted)
|
|
134
136
|
return err(new AnalysisCancelledError(request.operation));
|
|
135
|
-
if (this.#cleanupFailure !== undefined)
|
|
136
|
-
return err(this.#cleanupFailure);
|
|
137
137
|
clearTimeout(this.#idle);
|
|
138
|
+
if (this.#pendingCleanup !== undefined) {
|
|
139
|
+
const retired = await this.#retire();
|
|
140
|
+
if (!retired.ok)
|
|
141
|
+
return retired;
|
|
142
|
+
}
|
|
138
143
|
const outcome = await this.#execute(target, request, { signal });
|
|
139
|
-
if (!outcome.ok && outcome.error.cleanupIncomplete)
|
|
140
|
-
this.#cleanupFailure = outcome.error;
|
|
141
144
|
if (outcome.ok)
|
|
142
145
|
this.#scheduleIdle();
|
|
143
146
|
return outcome;
|
|
@@ -150,24 +153,39 @@ export class JadxProvider {
|
|
|
150
153
|
close() {
|
|
151
154
|
this.#shutdown.abort();
|
|
152
155
|
clearTimeout(this.#idle);
|
|
153
|
-
this.#closePromise ??= this.#tail
|
|
156
|
+
this.#closePromise ??= this.#tail
|
|
157
|
+
.then(async () => {
|
|
158
|
+
const retired = await this.#retire();
|
|
159
|
+
if (!retired.ok)
|
|
160
|
+
throw retired.error;
|
|
161
|
+
})
|
|
162
|
+
.catch((cause) => {
|
|
163
|
+
this.#closePromise = undefined;
|
|
164
|
+
throw cause;
|
|
165
|
+
});
|
|
154
166
|
return this.#closePromise;
|
|
155
167
|
}
|
|
156
168
|
async #retire() {
|
|
157
|
-
if (this.#
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
this.#
|
|
164
|
-
throw result.error;
|
|
169
|
+
if (this.#pendingCleanup === undefined && this.#retained !== undefined) {
|
|
170
|
+
this.#pendingCleanup = {
|
|
171
|
+
session: this.#retained.session,
|
|
172
|
+
root: this.#retained.root,
|
|
173
|
+
previousError: undefined,
|
|
174
|
+
};
|
|
175
|
+
this.#retained = undefined;
|
|
165
176
|
}
|
|
177
|
+
if (this.#pendingCleanup === undefined)
|
|
178
|
+
return ok(undefined);
|
|
179
|
+
const result = await cleanup(this.#pendingCleanup);
|
|
180
|
+
if (result.ok)
|
|
181
|
+
this.#pendingCleanup = undefined;
|
|
182
|
+
return result;
|
|
166
183
|
}
|
|
167
184
|
#scheduleIdle() {
|
|
168
185
|
this.#idle = setTimeout(() => {
|
|
169
|
-
|
|
170
|
-
|
|
186
|
+
this.#tail = this.#tail.then(async () => {
|
|
187
|
+
await this.#retire();
|
|
188
|
+
});
|
|
171
189
|
}, 60_000);
|
|
172
190
|
this.#idle.unref();
|
|
173
191
|
}
|
|
@@ -178,7 +196,6 @@ export class JadxProvider {
|
|
|
178
196
|
: AbortSignal.any([options.signal, timeout]);
|
|
179
197
|
let root;
|
|
180
198
|
let session;
|
|
181
|
-
let outcome;
|
|
182
199
|
try {
|
|
183
200
|
if (target.format !== "apk")
|
|
184
201
|
throw new AnalysisCapabilityUnavailableError("jadx", request.operation, `Target ${target.path} is ${target.format}; provide one standalone APK.`);
|
|
@@ -210,8 +227,11 @@ export class JadxProvider {
|
|
|
210
227
|
this.environment.JAVA_HOME,
|
|
211
228
|
],
|
|
212
229
|
});
|
|
213
|
-
if (this.#retained !== undefined && this.#retained.key !== key)
|
|
214
|
-
await this.#retire();
|
|
230
|
+
if (this.#retained !== undefined && this.#retained.key !== key) {
|
|
231
|
+
const retired = await this.#retire();
|
|
232
|
+
if (!retired.ok)
|
|
233
|
+
return retired;
|
|
234
|
+
}
|
|
215
235
|
let retained = this.#retained;
|
|
216
236
|
if (retained === undefined) {
|
|
217
237
|
root = await PrivateRuntimeRoot.create({ prefix: "rea-android-" });
|
|
@@ -247,7 +267,7 @@ export class JadxProvider {
|
|
|
247
267
|
root = retained.root;
|
|
248
268
|
session = retained.session;
|
|
249
269
|
const { snapshot } = retained;
|
|
250
|
-
outcome = ok(await session.execute({
|
|
270
|
+
const outcome = ok(await session.execute({
|
|
251
271
|
request,
|
|
252
272
|
target,
|
|
253
273
|
snapshot,
|
|
@@ -260,18 +280,20 @@ export class JadxProvider {
|
|
|
260
280
|
return outcome;
|
|
261
281
|
}
|
|
262
282
|
catch (cause) {
|
|
263
|
-
|
|
283
|
+
const previousError = executionError({
|
|
264
284
|
cause,
|
|
265
285
|
request,
|
|
266
286
|
timeout,
|
|
267
287
|
signal: options?.signal,
|
|
268
288
|
session,
|
|
269
|
-
})
|
|
289
|
+
});
|
|
290
|
+
// Admission can fail before selecting an existing session for execution.
|
|
291
|
+
root ??= this.#retained?.root;
|
|
292
|
+
session ??= this.#retained?.session;
|
|
293
|
+
this.#retained = undefined;
|
|
294
|
+
this.#pendingCleanup = { session, root, previousError };
|
|
295
|
+
const retired = await this.#retire();
|
|
296
|
+
return retired.ok ? err(previousError) : retired;
|
|
270
297
|
}
|
|
271
|
-
// An existing session also needs retirement when admission fails before selection.
|
|
272
|
-
root ??= this.#retained?.root;
|
|
273
|
-
session ??= this.#retained?.session;
|
|
274
|
-
this.#retained = undefined;
|
|
275
|
-
return cleanup(session, root, outcome);
|
|
276
298
|
}
|
|
277
299
|
}
|
|
@@ -169,6 +169,9 @@ const readExecutableMetadata = async (handle, hostArchitecture) => {
|
|
|
169
169
|
const prefix = Buffer.alloc(4096);
|
|
170
170
|
const prefixRead = await handle.read(prefix, 0, prefix.length, 0);
|
|
171
171
|
const bytes = prefix.subarray(0, prefixRead.bytesRead);
|
|
172
|
+
// Header commitments such as Mach-O load commands and FAT slices are
|
|
173
|
+
// checked against the whole file, not the probed prefix.
|
|
174
|
+
const fileSize = (await handle.stat()).size;
|
|
172
175
|
if (bytes.length >= 2 && bytes[0] === 0x4d && bytes[1] === 0x5a) {
|
|
173
176
|
const offset = mzWindowsHeaderOffset(bytes);
|
|
174
177
|
if (offset !== null) {
|
|
@@ -182,7 +185,6 @@ const readExecutableMetadata = async (handle, hostArchitecture) => {
|
|
|
182
185
|
? bytes.readUInt16LE(24) + bytes.readUInt16LE(6) * 4
|
|
183
186
|
: 0;
|
|
184
187
|
const headerBytes = bytes.length >= 28 ? bytes.readUInt16LE(8) * 16 : 0;
|
|
185
|
-
const fileSize = (await handle.stat()).size;
|
|
186
188
|
if (tableEnd > bytes.length &&
|
|
187
189
|
tableEnd <= headerBytes &&
|
|
188
190
|
tableEnd <= fileSize) {
|
|
@@ -201,11 +203,11 @@ const readExecutableMetadata = async (handle, hostArchitecture) => {
|
|
|
201
203
|
if (count <= 128 && required > bytes.length) {
|
|
202
204
|
const header = Buffer.alloc(required);
|
|
203
205
|
const headerRead = await handle.read(header, 0, header.length, 0);
|
|
204
|
-
return parseExecutableHeader(header.subarray(0, headerRead.bytesRead), hostArchitecture);
|
|
206
|
+
return parseExecutableHeader(header.subarray(0, headerRead.bytesRead), hostArchitecture, fileSize);
|
|
205
207
|
}
|
|
206
208
|
}
|
|
207
209
|
}
|
|
208
|
-
return parseExecutableHeader(bytes, hostArchitecture);
|
|
210
|
+
return parseExecutableHeader(bytes, hostArchitecture, fileSize);
|
|
209
211
|
};
|
|
210
212
|
const readPeMetadata = async (handle, offset) => {
|
|
211
213
|
const fileHeader = Buffer.alloc(24);
|
|
@@ -27,21 +27,16 @@ export const createBrowserEvidence = (operation, input, result, provider) => cre
|
|
|
27
27
|
});
|
|
28
28
|
const browserParameters = (input, result) => {
|
|
29
29
|
if (!("cdp_endpoint" in input)) {
|
|
30
|
-
if ("before_scenario" in input
|
|
31
|
-
input.before_scenario !== undefined &&
|
|
32
|
-
input.after_scenario !== undefined)
|
|
30
|
+
if ("before_scenario" in input)
|
|
33
31
|
return {
|
|
34
32
|
comparison_kind: "browser_scenario",
|
|
35
33
|
before_browser: input.before_scenario.browser,
|
|
36
34
|
after_browser: input.after_scenario.browser,
|
|
37
35
|
before_start_origin: input.before_scenario.scenario.start_origin,
|
|
38
36
|
after_start_origin: input.after_scenario.scenario.start_origin,
|
|
39
|
-
normalization_sha256: commitBrowserScenarioNormalization(input.normalization
|
|
37
|
+
normalization_sha256: commitBrowserScenarioNormalization(input.normalization).sha256,
|
|
40
38
|
};
|
|
41
|
-
if (input.before
|
|
42
|
-
input.after !== undefined &&
|
|
43
|
-
"inspection" in input.before &&
|
|
44
|
-
"inspection" in input.after)
|
|
39
|
+
if ("inspection" in input.before && "inspection" in input.after)
|
|
45
40
|
return {
|
|
46
41
|
before_target_id: input.before.inspection.target.target_id,
|
|
47
42
|
before_capture_ended_at: input.before.inspection.capture_window.ended_at,
|
|
@@ -1,25 +1,9 @@
|
|
|
1
1
|
import { canonicalDigest } from "../domain/comparisonSemantics.js";
|
|
2
|
-
import { sanitizeBrowserUrl } from "../domain/browserObservation.js";
|
|
3
2
|
import { createEvidence, } from "../domain/evidence.js";
|
|
4
|
-
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
3
|
+
import { jsonObjectSchema, jsonValueSchema } from "../domain/jsonValue.js";
|
|
5
4
|
const browserScenarioParameters = (scenario) => ({
|
|
5
|
+
...jsonObjectSchema.parse(scenario),
|
|
6
6
|
scenario_sha256: canonicalDigest(scenario, "Browser scenario"),
|
|
7
|
-
browser_mode: scenario.browser.mode,
|
|
8
|
-
...(scenario.browser.mode === "launch"
|
|
9
|
-
? { browser_headless: scenario.browser.headless }
|
|
10
|
-
: {}),
|
|
11
|
-
start_url: sanitizeBrowserUrl(scenario.start_url.url),
|
|
12
|
-
environment: scenario.environment,
|
|
13
|
-
actions: scenario.actions.map(({ step_id, action }) => ({
|
|
14
|
-
step_id,
|
|
15
|
-
action,
|
|
16
|
-
})),
|
|
17
|
-
action_timeouts_ms: scenario.actions.map((item) => "timeout_ms" in item ? (item.timeout_ms ?? null) : null),
|
|
18
|
-
secret_declarations: scenario.secrets.map(({ secret_id, environment_variable }) => ({
|
|
19
|
-
secret_id,
|
|
20
|
-
environment_variable,
|
|
21
|
-
})),
|
|
22
|
-
capture: scenario.capture,
|
|
23
7
|
});
|
|
24
8
|
/** Create Evidence without retaining resolved scenario secret values. */
|
|
25
9
|
export const createBrowserScenarioEvidence = (scenario, capture, provider) => createEvidence(undefined, provider, {
|