rea-agents 6.1.0 → 6.3.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 +24 -24
- package/bridge/ghidra/ReaGhidraBridge.java +32 -4
- package/bridge/hopper_bridge.py +8 -1
- package/dist/android/JadxConfiguration.js +87 -7
- package/dist/android/JadxMcpTransport.js +14 -2
- package/dist/android/JadxProvider.js +64 -36
- package/dist/android/JadxSession.js +51 -9
- package/dist/application/BinaryTargetResolver.js +68 -20
- package/dist/application/BrowserEvidence.js +3 -8
- package/dist/application/BrowserScenarioEvidence.js +4 -20
- package/dist/application/CapabilityInventory.js +43 -9
- package/dist/application/ClientConfigurationDocument.js +97 -25
- package/dist/application/ClientRegistrationStatus.js +19 -6
- package/dist/application/DirectAnalysis.js +41 -20
- package/dist/application/DirectAnalysisCleanup.js +71 -0
- package/dist/application/DirectAnalysisStatus.js +3 -7
- package/dist/application/Doctor.js +40 -53
- package/dist/application/DoctorDiagnostics.js +2 -3
- package/dist/application/EnhancedTools.js +51 -6
- package/dist/application/EvidenceBundleFiles.js +8 -3
- package/dist/application/InvestigationProviders.js +13 -5
- package/dist/application/JsonFiles.js +56 -23
- package/dist/application/LinuxHopper.js +11 -7
- package/dist/application/MacHopper.js +15 -18
- package/dist/application/RealHopperAssertions.js +0 -11
- package/dist/application/ReconstructionObligationCandidates.js +10 -3
- package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
- package/dist/application/ReferenceSourceImportEntries.js +1 -1
- package/dist/application/RegularFileRead.js +17 -0
- package/dist/application/Setup.js +26 -23
- package/dist/application/SetupClientConfiguration.js +18 -7
- package/dist/application/SetupHost.js +20 -29
- package/dist/application/SetupPlan.js +24 -20
- package/dist/application/SetupSkill.js +57 -8
- package/dist/application/SupportedClients.js +43 -0
- package/dist/application/Uninstall.js +98 -30
- package/dist/application/UpdateMaintenance.js +13 -7
- package/dist/application/UpdateRuntime.js +12 -12
- package/dist/application/Utf8JsonInput.js +64 -0
- package/dist/application/WebScriptExportService.js +38 -5
- 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/android/AndroidAnalysisService.js +1 -1
- 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 +13 -10
- package/dist/application/binary/BinarySession.js +86 -29
- package/dist/application/binary/BinarySessionComposition.js +1 -3
- package/dist/application/binary/BinarySessionExecution.js +3 -5
- package/dist/application/binary/BinarySessionOpen.js +10 -2
- 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 +10 -14
- package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
- package/dist/application/javascript/ElectronBoundaryGraphNative.js +5 -1
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +3 -6
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
- package/dist/application/javascript/JavaScriptApplicationService.js +7 -1
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +5 -9
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +19 -27
- 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 +46 -29
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +86 -27
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +52 -9
- package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +1 -0
- package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
- package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -18
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -3
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +4 -5
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +8 -6
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +7 -5
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +3 -4
- package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +3 -7
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +76 -47
- package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -4
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +51 -25
- package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
- package/dist/application/managed/ManagedMemberComparisonService.js +2 -1
- package/dist/application/managed/ManagedNativeVerificationService.js +2 -1
- package/dist/application/native/NativeCallRoutes.js +2 -4
- package/dist/application/process/ProcessCli.js +11 -11
- package/dist/application/process/ProcessEvidence.js +0 -1
- package/dist/artifacts/ArtifactProvider.js +53 -30
- package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
- package/dist/artifacts/ArtifactReader.js +31 -0
- package/dist/artifacts/AsarArtifactReader.js +81 -17
- package/dist/artifacts/DirectoryArtifactReader.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +9 -2
- package/dist/artifacts/NativeDmgArtifactReader.js +207 -77
- package/dist/artifacts/NativeDmgOwnership.js +109 -0
- 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 +68 -42
- package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
- package/dist/artifacts/extraction/ArtifactExtraction.js +104 -29
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +71 -66
- package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
- package/dist/artifacts/inventory/classify.js +33 -14
- package/dist/artifacts/inventory/hashStableRootArtifact.js +37 -0
- package/dist/artifacts/inventory/reader.js +3 -3
- package/dist/artifacts/inventory/scanCanonical.js +64 -34
- package/dist/artifacts/inventory/scanReader.js +12 -20
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +65 -27
- package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
- package/dist/browser/CdpBrowserProvider.js +6 -6
- package/dist/browser/CdpCaptureEventHandlers.js +2 -4
- package/dist/browser/CdpCaptureEvents.js +0 -1
- package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
- package/dist/browser/CdpCaptureValues.js +20 -0
- package/dist/browser/CdpElectronInspection.js +2 -2
- package/dist/browser/CdpElectronProvider.js +4 -5
- package/dist/browser/CdpElectronScriptEvents.js +2 -8
- package/dist/browser/CdpElectronScripts.js +4 -5
- package/dist/browser/CdpPageCaptureScripts.js +2 -3
- package/dist/browser/CdpSafeMetadata.js +10 -10
- package/dist/browser/CdpWebMcpDiscovery.js +16 -13
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +64 -49
- 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 +269 -66
- package/dist/browser/PlaywrightScenarioEvents.js +1 -1
- package/dist/browser/PlaywrightScenarioSession.js +41 -32
- package/dist/browser/WebSourceMapFetcher.js +32 -6
- package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
- 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 +37 -28
- package/dist/cli/coreNativeCommands.js +9 -10
- package/dist/cli/electronCommands.js +12 -13
- package/dist/cli/interactiveSetup.js +6 -6
- package/dist/cli/javascriptApplicationAnalysis.js +2 -12
- package/dist/cli/jsonOutput.js +3 -2
- 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/streamedJsonOutput.js +83 -4
- package/dist/cli/utilityCommands.js +10 -12
- package/dist/cli.js +19 -8
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +1 -0
- package/dist/cliJsonFile.js +179 -0
- package/dist/cliJsonInput.js +60 -33
- package/dist/cliObservationOptions.js +4 -0
- package/dist/cliOutput.js +0 -38
- package/dist/composition/auxiliaryAnalysisProviders.js +30 -25
- package/dist/composition/binary.js +9 -9
- package/dist/composition/browserScenario.js +2 -1
- package/dist/composition/directAnalysis.js +20 -14
- 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 +7 -7
- 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/errorSchemas.js +3 -1
- package/dist/contracts/evm/evmToolContracts.js +1 -1
- package/dist/contracts/functionComparisonExample.js +8 -0
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/inputSchemaPresentation.js +181 -0
- package/dist/contracts/investigationExamples.js +4 -3
- package/dist/contracts/javascript/electronToolContracts.js +3 -2
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -22
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +248 -0
- package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
- package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
- package/dist/contracts/managed/managedToolContracts.js +8 -12
- package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
- package/dist/contracts/mobileApplicationGraphExamples.js +8 -8
- 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/sessionLifecycleInputs.js +4 -3
- package/dist/contracts/sessionStatusContract.js +3 -2
- package/dist/contracts/sessionToolContracts.js +17 -4
- package/dist/contracts/sessionToolSchemas.js +4 -16
- package/dist/contracts/toolContracts.js +2 -0
- package/dist/contracts/toolEffects.js +1 -0
- package/dist/contracts/toolOutputSchemaGroups.js +138 -94
- package/dist/contracts/toolOutputSchemaPrimitives.js +13 -26
- 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/analysisErrorBase.js +5 -0
- package/dist/domain/analysisErrorCore.js +3 -0
- package/dist/domain/analysisErrorPresentation.js +22 -5
- package/dist/domain/analysisErrorProjection.js +24 -5
- package/dist/domain/analysisSnapshot.js +31 -31
- package/dist/domain/analysisView/analysisView.js +241 -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/android/androidPartialObservation.js +36 -0
- 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 +17 -4
- package/dist/domain/artifactIdentity.js +8 -8
- package/dist/domain/artifactInspection.js +8 -8
- 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/browserCompleteness.js +3 -2
- 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/browserScenarioCaptureValues.js +2 -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/browserScenarioNormalization.js +3 -3
- package/dist/domain/browserScenarioValues.js +6 -6
- package/dist/domain/callPath.js +15 -18
- package/dist/domain/callPathSchemas.js +2 -2
- package/dist/domain/canonicalDigest.js +7 -1
- package/dist/domain/canonicalOrdering.js +1 -13
- package/dist/domain/changedBehavior.js +5 -6
- package/dist/domain/comparisonSemantics.js +0 -5
- package/dist/domain/completionLedgerGeneration.js +2 -1
- package/dist/domain/configurationErrors.js +12 -0
- package/dist/domain/conformancePackage.js +4 -3
- package/dist/domain/digests.js +0 -3
- package/dist/domain/evidence.js +19 -40
- package/dist/domain/evidenceBundle.js +58 -42
- package/dist/domain/evidenceCompletionLedger.js +2 -1
- package/dist/domain/firmware/firmwareAnalysis.js +4 -3
- package/dist/domain/functionComparison.js +6 -6
- package/dist/domain/functionComparisonDimensions.js +120 -87
- package/dist/domain/functionComparisonNormalization.js +26 -36
- package/dist/domain/functionComparisonResults.js +3 -6
- package/dist/domain/functionComparisonSchemas.js +2 -8
- package/dist/domain/functionDossierEvidence.js +4 -38
- package/dist/domain/hopperValues.js +11 -15
- package/dist/domain/javascript/electronActiveObservation.js +29 -71
- package/dist/domain/javascript/electronObservation.js +14 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -11
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -2
- package/dist/domain/javascript/electronStaticAnalysisNative.js +7 -4
- package/dist/domain/javascript/electronStaticAnalysisValues.js +8 -4
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +3 -1
- package/dist/domain/javascript/javascriptApplicationChangeGraph.js +12 -8
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +6 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +41 -16
- package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
- package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
- package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +50 -36
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -8
- package/dist/domain/javascript/javascriptAstFingerprint.js +2 -2
- package/dist/domain/javascript/javascriptAstValues.js +22 -0
- package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
- package/dist/domain/javascript/javascriptExportShapeComparison.js +10 -3
- package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +58 -22
- package/dist/domain/javascript/javascriptExportShapeSelection.js +7 -7
- package/dist/domain/javascript/javascriptExportShapeVariants.js +70 -16
- package/dist/domain/javascript/javascriptFeatureSeed.js +25 -3
- package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
- package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
- package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -5
- package/dist/domain/javascript/javascriptNativeHandoff.js +7 -7
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
- package/dist/domain/javascript/javascriptRuntimeObservation.js +18 -7
- package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
- package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
- package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +5 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +6 -6
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -222
- package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +7 -7
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +209 -11
- package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
- package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +4 -3
- package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
- package/dist/domain/javascript/javascriptSemanticFingerprints.js +2 -2
- package/dist/domain/javascript/javascriptSemanticGraph.js +220 -71
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +19 -1
- package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
- package/dist/domain/javascript/javascriptSemanticIterationSources.js +106 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +515 -74
- package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +44 -36
- package/dist/domain/javascript/javascriptSemanticObjects.js +79 -42
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +8 -14
- package/dist/domain/javascript/javascriptSemanticProjection.js +21 -16
- package/dist/domain/javascript/javascriptSemanticPromises.js +16 -21
- package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +23 -0
- package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
- package/dist/domain/javascript/javascriptSemanticQuery.js +8 -2
- package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +3 -2
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
- package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +1 -1
- package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
- package/dist/domain/javascript/javascriptSemanticReturns.js +55 -44
- package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
- package/dist/domain/javascript/javascriptSemanticTraversal.js +6 -1
- package/dist/domain/javascript/javascriptSemanticValues.js +180 -76
- package/dist/domain/javascript/javascriptSourceMapPaths.js +114 -0
- package/dist/domain/javascript/javascriptSourceParser.js +34 -9
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -6
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +2 -1
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -16
- package/dist/domain/javascript/sourceToBundleComparison.js +19 -8
- package/dist/domain/javascript/sourceToBundleSignals.js +53 -25
- package/dist/domain/jsonSerialization.js +109 -55
- package/dist/domain/jsonShape.js +46 -19
- package/dist/domain/localPath.js +10 -4
- package/dist/domain/managed/managedApplicationGraph.js +10 -6
- package/dist/domain/managed/managedApplicationGraphNodes.js +82 -57
- package/dist/domain/managed/managedArtifact.js +6 -4
- package/dist/domain/managed/managedMemberComparison.js +2 -9
- package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
- 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 +3 -3
- package/dist/domain/native/nativeInstruction.js +7 -0
- package/dist/domain/native/nativeValueFlow.js +5 -11
- package/dist/domain/native/objcSwiftMetadata.js +15 -17
- package/dist/domain/native/recordedCrash.js +2 -3
- package/dist/domain/offsetDateTime.js +17 -0
- package/dist/domain/process/processCapture.js +22 -20
- package/dist/domain/process/processCaptureCoverage.js +70 -0
- package/dist/domain/process/processCaptureExample.js +45 -1
- package/dist/domain/process/processCaptureParsing.js +1 -34
- package/dist/domain/process/processCaptureValidation.js +82 -13
- package/dist/domain/process/processComparison.js +39 -43
- 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 +19 -15
- package/dist/domain/process/processTraceSpecification.js +4 -7
- package/dist/domain/providerAdapterError.js +2 -0
- package/dist/domain/providerCleanupError.js +6 -2
- package/dist/domain/reconstructionCoverage.js +7 -3
- package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
- package/dist/domain/reconstructionReadinessSchemas.js +2 -1
- package/dist/domain/reconstructionUnknowns.js +4 -3
- package/dist/domain/reconstructionVerification.js +6 -5
- package/dist/domain/reconstructionVerificationSchemas.js +2 -1
- package/dist/domain/referenceSourceGraph.js +27 -28
- package/dist/domain/referenceSourceImportParsing.js +34 -45
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/staticRuntimeCorrelation.js +4 -3
- package/dist/domain/stringPatterns.js +6 -0
- package/dist/domain/swiftSymbolClassification.js +66 -0
- package/dist/domain/symbolAnalysis.js +83 -20
- package/dist/domain/unicodeCodePointOrder.js +6 -0
- package/dist/domain/webBundleAnalyzerInspection.js +9 -1
- package/dist/domain/webCaptureDiff.js +71 -30
- package/dist/domain/webCaptureDiffSchemas.js +8 -11
- package/dist/domain/webEventListeners.js +3 -2
- package/dist/domain/webExecution.js +3 -2
- package/dist/domain/webInventory.js +3 -2
- package/dist/domain/webMcpDiscovery.js +4 -3
- package/dist/domain/webRuntime.js +0 -2
- package/dist/domain/webScriptExport.js +2 -2
- package/dist/dotnet/ManagedArtifactInspector.js +2 -19
- package/dist/dotnet/ManagedMemberInspector.js +12 -18
- package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +1 -2
- 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 +13 -12
- package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
- 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/filesystem/RegularFile.js +41 -0
- 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 +105 -36
- 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 +151 -22
- package/dist/ghidra/GhidraJavaLaunch.js +6 -2
- package/dist/ghidra/GhidraLauncher.js +58 -26
- 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 +5 -3
- package/dist/ida/IdaProvider.js +8 -12
- package/dist/ida/IdaSessionClient.js +24 -20
- package/dist/ida/IdaWorkspace.js +12 -13
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
- package/dist/inspector/V8InspectorCaptureProjection.js +47 -14
- package/dist/inspector/V8InspectorProvider.js +97 -35
- package/dist/javascript/recovery/WakaruCommand.js +7 -2
- package/dist/javascript/recovery/WakaruExecution.js +5 -2
- package/dist/main/shutdown.js +81 -29
- package/dist/main/startup.js +9 -2
- package/dist/main/transport.js +23 -3
- package/dist/main.js +11 -18
- package/dist/native/AppleMachoSelection.js +16 -6
- package/dist/native/AppleObjcDispatchFacets.js +3 -3
- package/dist/native/AppleObjcProperties.js +17 -7
- package/dist/native/CommandRunner.js +9 -7
- package/dist/native/LldbCallTracer.js +249 -77
- package/dist/native/NativeMacOSProvider.js +32 -17
- package/dist/native/NativeMacOSProviderMetadata.js +1 -2
- 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 +18 -16
- package/dist/process/ProviderProcess.js +1 -3
- package/dist/process/capture/FilesystemSnapshot.js +131 -24
- package/dist/process/capture/ProcessCaptureError.js +13 -0
- package/dist/process/capture/ProcessCaptureLifecycle.js +148 -74
- package/dist/process/capture/ProcessFilesystemEffects.js +51 -6
- package/dist/process/capture/ProcessHarness.js +16 -33
- 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/analysisAdmission.js +8 -0
- package/dist/server/createServer.js +71 -59
- 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 +6 -6
- 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 +4 -4
- 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/registerArtifactTools.js +2 -2
- 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 +8 -7
- package/dist/server/registerElectronTools.js +10 -13
- package/dist/server/registerEnhancedTools.js +82 -77
- package/dist/server/registerEvidenceTools.js +54 -47
- 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/registerManagedTools.js +7 -4
- 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 +32 -41
- 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 +19 -19
- 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 +42 -30
- package/scripts/rea.mjs +3 -6
- package/skills/reverse-engineer-anything/SKILL.md +14 -13
- 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 +18 -0
- package/dist/artifacts/inventory/policy.js +0 -2
- 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/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
- package/dist/main/reload.js +0 -12
- package/dist/main/state.js +0 -3
- package/dist/server/registerNativeTools.js +0 -6
- package/dist/server/sessionToolPolicies.js +0 -2
|
@@ -9,6 +9,10 @@ import { spawnOwnedProviderProcess, ProviderProcessSupervisor, } from "../proces
|
|
|
9
9
|
import { cleanupOwnedProcessGroup } from "../process/ProcessOwnership.js";
|
|
10
10
|
import { FIRMWARE_LIMITS } from "./FirmwareRelease.js";
|
|
11
11
|
import { hashFirmwareFile, inventoryFirmwareOutput, readFirmwareReport, } from "./FirmwareFiles.js";
|
|
12
|
+
/** Refuse an unmet host or tool requirement, which another target cannot satisfy. */
|
|
13
|
+
export const firmwareToolUnavailable = (engine, operation, reason) => new AnalysisCapabilityUnavailableError(engine, operation, reason, {
|
|
14
|
+
userMessage: reason,
|
|
15
|
+
});
|
|
12
16
|
/** Resolve explicitly supplied executable paths; never install or search for engines. */
|
|
13
17
|
export const resolveFirmwareCommand = async (environment, engine, operation) => {
|
|
14
18
|
const variable = engine === "binwalk" ? "REA_BINWALK_COMMAND" : "REA_UNBLOB_COMMAND";
|
|
@@ -16,9 +20,9 @@ export const resolveFirmwareCommand = async (environment, engine, operation) =>
|
|
|
16
20
|
if (process.platform !== "linux" ||
|
|
17
21
|
configured === undefined ||
|
|
18
22
|
!isAbsolute(configured))
|
|
19
|
-
throw
|
|
23
|
+
throw firmwareToolUnavailable(engine, operation, `This integration requires Linux and an absolute ${variable} path to the caller-supplied tool`);
|
|
20
24
|
const command = await realpath(configured).catch((cause) => {
|
|
21
|
-
throw
|
|
25
|
+
throw firmwareToolUnavailable(engine, operation, `${variable} is unavailable: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
22
26
|
});
|
|
23
27
|
let sha256;
|
|
24
28
|
try {
|
|
@@ -28,18 +32,18 @@ export const resolveFirmwareCommand = async (environment, engine, operation) =>
|
|
|
28
32
|
sha256 = await hashFirmwareFile(command);
|
|
29
33
|
}
|
|
30
34
|
catch (cause) {
|
|
31
|
-
throw
|
|
35
|
+
throw firmwareToolUnavailable(engine, operation, `${variable} is not a readable executable regular file: ${command}: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
32
36
|
}
|
|
33
37
|
const limiter = environment.REA_FIRMWARE_PRLIMIT_COMMAND ?? "/usr/bin/prlimit";
|
|
34
38
|
if (!isAbsolute(limiter))
|
|
35
|
-
throw
|
|
39
|
+
throw firmwareToolUnavailable(engine, operation, "REA_FIRMWARE_PRLIMIT_COMMAND must be absolute");
|
|
36
40
|
try {
|
|
37
41
|
await access(limiter, constants.X_OK);
|
|
38
42
|
if (!(await stat(limiter)).isFile())
|
|
39
43
|
throw new TypeError("Configured path is not a regular file");
|
|
40
44
|
}
|
|
41
45
|
catch (cause) {
|
|
42
|
-
throw
|
|
46
|
+
throw firmwareToolUnavailable(engine, operation, `Resource limiter is not an executable regular file: ${limiter}: ${cause instanceof Error ? cause.message : String(cause)}; provide util-linux prlimit`);
|
|
43
47
|
}
|
|
44
48
|
return { command, limiter, sha256 };
|
|
45
49
|
};
|
|
@@ -3,7 +3,7 @@ import { z } from "zod";
|
|
|
3
3
|
import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
|
|
4
4
|
import { firmwareResultSchemas, } from "../domain/firmware/firmwareAnalysis.js";
|
|
5
5
|
import { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
6
|
-
import { AnalysisCancelledError,
|
|
6
|
+
import { AnalysisCancelledError, AnalysisInputError, AnalysisOutputError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
|
|
7
7
|
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
8
8
|
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
|
|
9
9
|
import { err, ok } from "../domain/result.js";
|
|
@@ -11,7 +11,7 @@ import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
|
|
|
11
11
|
import { publishFirmwareExtraction } from "./FirmwarePublication.js";
|
|
12
12
|
import { FIRMWARE_LIMITS, BINWALK_PROVIDER_IDENTITY, UNBLOB_PROVIDER_IDENTITY, } from "./FirmwareRelease.js";
|
|
13
13
|
import { admitFirmwareVersion } from "./FirmwareVersion.js";
|
|
14
|
-
import { resolveFirmwareCommand, runFirmwareCommand, readFirmwareCommandReport, } from "./FirmwareCommand.js";
|
|
14
|
+
import { firmwareToolUnavailable, resolveFirmwareCommand, runFirmwareCommand, readFirmwareCommandReport, } from "./FirmwareCommand.js";
|
|
15
15
|
import { inventoryFirmwareOutput, snapshotFirmware } from "./FirmwareFiles.js";
|
|
16
16
|
import { normalizeBinwalkReport, normalizeUnblobReport, } from "./FirmwareReports.js";
|
|
17
17
|
const waitForPredecessor = (predecessor, operation, signal) => new Promise((resolve, reject) => {
|
|
@@ -96,10 +96,10 @@ export class FirmwareProvider {
|
|
|
96
96
|
const versionRun = await run(["--version"]);
|
|
97
97
|
const version = versionRun.stdout.text.trim();
|
|
98
98
|
if (versionRun.stdout.bytes > 1024)
|
|
99
|
-
throw
|
|
99
|
+
throw firmwareToolUnavailable(engineName, request.operation, `Tool version banner is ${String(versionRun.stdout.bytes)} bytes; expected a short ${engineName} version line.`);
|
|
100
100
|
const admitted = admitFirmwareVersion(engineName, version);
|
|
101
101
|
if (admitted.status === "unsupported" || admitted.status === "unresolved")
|
|
102
|
-
throw
|
|
102
|
+
throw firmwareToolUnavailable(engineName, request.operation, admitted.message);
|
|
103
103
|
const engine = {
|
|
104
104
|
name: engineName,
|
|
105
105
|
version: admitted.version,
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/** Generated from package.json and package-lock.json; do not edit. */
|
|
2
2
|
export const PACKAGE_METADATA = {
|
|
3
3
|
name: "rea-agents",
|
|
4
|
-
version: "6.
|
|
4
|
+
version: "6.3.0", // x-release-please-version
|
|
5
5
|
serverSdkVersion: "2.3.1",
|
|
6
6
|
clientSdkVersion: "2.3.1",
|
|
7
7
|
coreSdkVersion: "2.3.1",
|
|
8
|
-
skillVersion: "
|
|
8
|
+
skillVersion: "34",
|
|
9
9
|
};
|
|
@@ -8,7 +8,7 @@ export const resolveGhidraAnalysisProfile = (target, identity, installation, sig
|
|
|
8
8
|
if (signal?.aborted === true)
|
|
9
9
|
return Promise.resolve(err(new AnalysisCancelledError("open_binary")));
|
|
10
10
|
if (target.kind !== "executable")
|
|
11
|
-
return Promise.resolve(ok({ profile: null
|
|
11
|
+
return Promise.resolve(ok({ profile: null }));
|
|
12
12
|
if (installation.status === "unavailable")
|
|
13
13
|
return Promise.resolve(err(new ProviderAdapterError(identity.id, "resolve_analysis_profile")));
|
|
14
14
|
const provider = { ...identity, version: installation.providerVersion };
|
|
@@ -28,7 +28,8 @@ export const resolveGhidraAnalysisProfile = (target, identity, installation, sig
|
|
|
28
28
|
load_image_observations: "source-mappings-entry-context-v2",
|
|
29
29
|
function_body_evidence: "complete-inclusive-ranges-v1",
|
|
30
30
|
function_references: "complete-body-and-entry-reference-manager-v2",
|
|
31
|
-
location_resolution: "explicit-address-exact-
|
|
31
|
+
location_resolution: "explicit-address-exact-entry-symbol-first-v3",
|
|
32
|
+
instruction_flow_evidence: "decoded-return-pcode-v1",
|
|
32
33
|
process_launch: installation.platform === "win32"
|
|
33
34
|
? "official-headless-script-v1"
|
|
34
35
|
: "inspected-jvm-launch-support-v1",
|
|
@@ -68,9 +69,5 @@ export const resolveGhidraAnalysisProfile = (target, identity, installation, sig
|
|
|
68
69
|
: {}),
|
|
69
70
|
analyzer_preset: "ghidra-default",
|
|
70
71
|
}),
|
|
71
|
-
compatibility: {
|
|
72
|
-
languageId: dos ? "x86:LE:16:Real Mode" : "auto",
|
|
73
|
-
compilerSpecId: dos ? "default" : "auto",
|
|
74
|
-
},
|
|
75
72
|
}));
|
|
76
73
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { randomBytes, randomUUID } from "node:crypto";
|
|
2
|
-
import {
|
|
2
|
+
import { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
3
|
+
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
|
|
3
4
|
import { err, ok } from "../domain/result.js";
|
|
4
5
|
import { silentLogger } from "../logger.js";
|
|
5
6
|
import { PendingOperations } from "../process/PendingOperations.js";
|
|
@@ -9,6 +10,7 @@ import { ProviderRunLineage } from "../process/ProviderRunLineage.js";
|
|
|
9
10
|
import { ProviderProcessSupervisor, } from "../process/ProviderProcess.js";
|
|
10
11
|
import { DEFAULT_GHIDRA_STARTUP_TIMEOUT_MS } from "../config/ghidraStartupTimeout.js";
|
|
11
12
|
import { createGhidraDiagnostics } from "./GhidraDiagnostics.js";
|
|
13
|
+
import { GhidraLaunchError } from "./GhidraLauncher.js";
|
|
12
14
|
import { GhidraResponseBuffer } from "./GhidraResponseBuffer.js";
|
|
13
15
|
import { GhidraResponseRouter } from "./GhidraResponseRouter.js";
|
|
14
16
|
import { GhidraRequestQueue } from "./GhidraRequestQueue.js";
|
|
@@ -20,8 +22,9 @@ import { connectGhidraSocket } from "./GhidraSocketConnection.js";
|
|
|
20
22
|
import { createGhidraEndpoint, } from "./GhidraTransport.js";
|
|
21
23
|
import { GhidraWire } from "./GhidraClientWire.js";
|
|
22
24
|
import { completeGhidraStartupHandshake } from "./GhidraClientStartup.js";
|
|
25
|
+
import { ghidraSessionRoot } from "./GhidraSessionRoot.js";
|
|
23
26
|
const SHUTDOWN_TIMEOUT_MS = 10_000;
|
|
24
|
-
const SESSION_ROOT =
|
|
27
|
+
const SESSION_ROOT = ghidraSessionRoot();
|
|
25
28
|
/** Owns an authenticated private Ghidra session with transport-bound mutation authority. */
|
|
26
29
|
export class GhidraClient {
|
|
27
30
|
#options;
|
|
@@ -91,10 +94,12 @@ export class GhidraClient {
|
|
|
91
94
|
/** Launch Ghidra once and require its exact post-analysis handshake. */
|
|
92
95
|
start(signal) {
|
|
93
96
|
if (this.#closePromise !== undefined)
|
|
94
|
-
return this.#closePromise.then(() => this.start(signal));
|
|
97
|
+
return this.#closePromise.then(() => this.start(signal), (cause) => err(new GhidraSessionError("process", "Ghidra cleanup remains incomplete", this.#diagnostics(), { cause, cleanupFailure: this.#cleanupError(cause) })));
|
|
95
98
|
if (this.#startPromise !== undefined) {
|
|
96
99
|
if (this.#startupController?.signal.aborted && !signal?.aborted)
|
|
97
|
-
return this.#startPromise.then((result) => result.ok
|
|
100
|
+
return this.#startPromise.then((result) => result.ok || result.error.cleanupFailure !== undefined
|
|
101
|
+
? result
|
|
102
|
+
: this.start(signal));
|
|
98
103
|
return this.#startPromise;
|
|
99
104
|
}
|
|
100
105
|
const controller = new AbortController();
|
|
@@ -153,8 +158,43 @@ export class GhidraClient {
|
|
|
153
158
|
}
|
|
154
159
|
}
|
|
155
160
|
/** Stop the owned process group and remove all project/runtime artifacts. */
|
|
156
|
-
close() {
|
|
157
|
-
|
|
161
|
+
async close() {
|
|
162
|
+
try {
|
|
163
|
+
await this.#requestClose(false);
|
|
164
|
+
return ok(null);
|
|
165
|
+
}
|
|
166
|
+
catch (cause) {
|
|
167
|
+
return err(this.#cleanupError(cause));
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
#cleanupError(cause) {
|
|
171
|
+
if (cause instanceof AnalysisError && cause.cleanupIncomplete)
|
|
172
|
+
return cause;
|
|
173
|
+
return new ProviderCleanupError("ghidra", [
|
|
174
|
+
...(this.#process === undefined ? [] : ["ghidra-process"]),
|
|
175
|
+
...[this.#runtimeRoot, this.#socketRoot].flatMap((root) => root === undefined ? [] : [root.path]),
|
|
176
|
+
], {
|
|
177
|
+
reason: cause instanceof Error ? cause.message : String(cause),
|
|
178
|
+
diagnostics: this.#diagnostics(),
|
|
179
|
+
}, { cause });
|
|
180
|
+
}
|
|
181
|
+
async #startupFailure(primary) {
|
|
182
|
+
try {
|
|
183
|
+
await this.#cleanup();
|
|
184
|
+
return err(primary);
|
|
185
|
+
}
|
|
186
|
+
catch (cause) {
|
|
187
|
+
return err(new GhidraSessionError(primary.kind, primary.message, primary.diagnostics, {
|
|
188
|
+
...(primary.cause === undefined ? {} : { cause: primary.cause }),
|
|
189
|
+
...(primary.timeoutMs === undefined
|
|
190
|
+
? {}
|
|
191
|
+
: { timeoutMs: primary.timeoutMs }),
|
|
192
|
+
...(primary.remoteCode === undefined
|
|
193
|
+
? {}
|
|
194
|
+
: { remoteCode: primary.remoteCode }),
|
|
195
|
+
cleanupFailure: this.#cleanupError(cause),
|
|
196
|
+
}));
|
|
197
|
+
}
|
|
158
198
|
}
|
|
159
199
|
#requestClose(forceStop) {
|
|
160
200
|
const starting = this.#startPromise;
|
|
@@ -218,8 +258,7 @@ export class GhidraClient {
|
|
|
218
258
|
}
|
|
219
259
|
catch (cause) {
|
|
220
260
|
const failure = this.#failure("start", "Ghidra private endpoint allocation failed", cause);
|
|
221
|
-
|
|
222
|
-
return err(failure);
|
|
261
|
+
return this.#startupFailure(failure);
|
|
223
262
|
}
|
|
224
263
|
try {
|
|
225
264
|
const snapshot = await createGhidraTargetSnapshot(this.#options.targetPath, this.#runtimeRoot.path, this.#options.targetSha256, { signal: deadline.signal, platform: this.#options.platform });
|
|
@@ -230,8 +269,7 @@ export class GhidraClient {
|
|
|
230
269
|
if (deadline.signal.aborted)
|
|
231
270
|
return this.#startupInterrupted(deadline);
|
|
232
271
|
const failure = this.#failure("start", "Ghidra target snapshot failed admission", cause);
|
|
233
|
-
|
|
234
|
-
return err(failure);
|
|
272
|
+
return this.#startupFailure(failure);
|
|
235
273
|
}
|
|
236
274
|
if (deadline.signal.aborted)
|
|
237
275
|
return this.#startupInterrupted(deadline);
|
|
@@ -253,13 +291,21 @@ export class GhidraClient {
|
|
|
253
291
|
}, { signal: deadline.signal })
|
|
254
292
|
.catch((cause) => err(this.#failure("start", "Ghidra launcher failed", cause)));
|
|
255
293
|
if (!launched.ok) {
|
|
294
|
+
const partialLaunch = launched.error instanceof GhidraLaunchError
|
|
295
|
+
? launched.error.partialLaunch
|
|
296
|
+
: undefined;
|
|
297
|
+
if (partialLaunch !== undefined) {
|
|
298
|
+
this.#launch = partialLaunch;
|
|
299
|
+
this.#process = new ProviderProcessSupervisor(partialLaunch, {
|
|
300
|
+
onDiagnostic: (event) => this.#onProcessDiagnostic(event),
|
|
301
|
+
});
|
|
302
|
+
}
|
|
256
303
|
const failure = deadline.signal.aborted
|
|
257
|
-
? this.#interruptionFailure(deadline)
|
|
304
|
+
? this.#interruptionFailure(deadline, launched.error)
|
|
258
305
|
: launched.error instanceof GhidraSessionError
|
|
259
306
|
? launched.error
|
|
260
307
|
: this.#failure("start", launched.error.message, launched.error);
|
|
261
|
-
|
|
262
|
-
return err(failure);
|
|
308
|
+
return this.#startupFailure(failure);
|
|
263
309
|
}
|
|
264
310
|
this.#launch = launched.value;
|
|
265
311
|
this.#process = new ProviderProcessSupervisor(launched.value, {
|
|
@@ -268,21 +314,19 @@ export class GhidraClient {
|
|
|
268
314
|
const connected = await this.#connect(endpoint, deadline);
|
|
269
315
|
if (!connected.ok) {
|
|
270
316
|
const failure = connected.error;
|
|
271
|
-
|
|
272
|
-
return err(failure);
|
|
317
|
+
return this.#startupFailure(failure);
|
|
273
318
|
}
|
|
274
319
|
const completed = await completeGhidraStartupHandshake({
|
|
275
320
|
deadline,
|
|
276
321
|
request: (method, params, requestOptions) => this.#wire.request(method, params, requestOptions),
|
|
277
322
|
parseSessionInfo: (value) => this.#parseSessionInfo(value),
|
|
278
|
-
cleanup: () => this.#cleanup(),
|
|
279
323
|
failure: this.#failure,
|
|
280
324
|
startupTimeoutMs: this.#options.startupTimeoutMs,
|
|
281
325
|
});
|
|
282
|
-
if (completed.ok)
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
326
|
+
if (!completed.ok)
|
|
327
|
+
return this.#startupFailure(completed.error);
|
|
328
|
+
await this.#lineage.observe(this.#launch);
|
|
329
|
+
this.#requestQueue.reopen();
|
|
286
330
|
return completed;
|
|
287
331
|
}
|
|
288
332
|
async #connect(endpoint, deadline) {
|
|
@@ -389,18 +433,8 @@ export class GhidraClient {
|
|
|
389
433
|
this.#lastDiagnostics = this.#diagnostics();
|
|
390
434
|
this.#process = undefined;
|
|
391
435
|
this.#launch = undefined;
|
|
392
|
-
const runtimeRoot = this.#runtimeRoot;
|
|
393
|
-
const socketRoot = this.#socketRoot;
|
|
394
|
-
this.#runtimeRoot = undefined;
|
|
395
|
-
this.#socketRoot = undefined;
|
|
396
436
|
try {
|
|
397
|
-
|
|
398
|
-
runtimeRoot?.close(),
|
|
399
|
-
socketRoot?.close(),
|
|
400
|
-
]);
|
|
401
|
-
const failed = removed.find((result) => result.status === "rejected");
|
|
402
|
-
if (failed?.status === "rejected")
|
|
403
|
-
throw failed.reason;
|
|
437
|
+
await this.#removeRuntimeRoots();
|
|
404
438
|
}
|
|
405
439
|
catch (cause) {
|
|
406
440
|
if (forceStop)
|
|
@@ -420,6 +454,42 @@ export class GhidraClient {
|
|
|
420
454
|
this.#closing = false;
|
|
421
455
|
}
|
|
422
456
|
}
|
|
457
|
+
/**
|
|
458
|
+
* Remove the runtime and socket roots, keeping each one that could not be
|
|
459
|
+
* removed so a later close retries it rather than reporting success.
|
|
460
|
+
*/
|
|
461
|
+
async #removeRuntimeRoots() {
|
|
462
|
+
const roots = [
|
|
463
|
+
{
|
|
464
|
+
root: this.#runtimeRoot,
|
|
465
|
+
release: () => (this.#runtimeRoot = undefined),
|
|
466
|
+
},
|
|
467
|
+
{ root: this.#socketRoot, release: () => (this.#socketRoot = undefined) },
|
|
468
|
+
];
|
|
469
|
+
const leftovers = [];
|
|
470
|
+
let firstCause;
|
|
471
|
+
for (const { root, release } of roots) {
|
|
472
|
+
if (root === undefined)
|
|
473
|
+
continue;
|
|
474
|
+
try {
|
|
475
|
+
await root.close();
|
|
476
|
+
release();
|
|
477
|
+
}
|
|
478
|
+
catch (cause) {
|
|
479
|
+
firstCause ??= cause;
|
|
480
|
+
leftovers.push({
|
|
481
|
+
path: root.path,
|
|
482
|
+
reason: cause instanceof Error ? cause.message : String(cause),
|
|
483
|
+
});
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
if (leftovers.length > 0)
|
|
487
|
+
throw new ProviderCleanupError("ghidra", leftovers.map(({ path }) => path), {
|
|
488
|
+
reason: "Ghidra's private runtime directory could not be removed; it is retained for a later close.",
|
|
489
|
+
leftover_paths: leftovers.map(({ path }) => path),
|
|
490
|
+
failures: leftovers.map(({ path, reason }) => `${path}: ${reason}`),
|
|
491
|
+
}, { cause: firstCause });
|
|
492
|
+
}
|
|
423
493
|
#redactAuthentication(value) {
|
|
424
494
|
for (const token of this.#authenticationTokens)
|
|
425
495
|
value = value.replaceAll(token, "[REDACTED]");
|
|
@@ -457,13 +527,12 @@ export class GhidraClient {
|
|
|
457
527
|
}
|
|
458
528
|
async #startupInterrupted(deadline) {
|
|
459
529
|
const failure = this.#interruptionFailure(deadline);
|
|
460
|
-
|
|
461
|
-
return err(failure);
|
|
530
|
+
return this.#startupFailure(failure);
|
|
462
531
|
}
|
|
463
|
-
#interruptionFailure(deadline) {
|
|
532
|
+
#interruptionFailure(deadline, cause) {
|
|
464
533
|
return deadline.interruption === "cancelled"
|
|
465
|
-
? this.#failure("cancelled", "Ghidra startup was cancelled")
|
|
466
|
-
: this.#failure("timeout", "Ghidra startup deadline elapsed",
|
|
534
|
+
? this.#failure("cancelled", "Ghidra startup was cancelled", cause)
|
|
535
|
+
: this.#failure("timeout", "Ghidra startup deadline elapsed", cause, {
|
|
467
536
|
timeoutMs: deadline.timeoutMs,
|
|
468
537
|
});
|
|
469
538
|
}
|
|
@@ -9,7 +9,6 @@ export async function completeGhidraStartupHandshake(options) {
|
|
|
9
9
|
const failure = options.deadline.signal.aborted
|
|
10
10
|
? interruptionFailure(options)
|
|
11
11
|
: ping.error;
|
|
12
|
-
await options.cleanup();
|
|
13
12
|
return err(failure);
|
|
14
13
|
}
|
|
15
14
|
const parsed = options.parseSessionInfo(ping.value);
|
|
@@ -17,7 +16,6 @@ export async function completeGhidraStartupHandshake(options) {
|
|
|
17
16
|
const failure = parsed.ok
|
|
18
17
|
? options.failure("analysis_timeout", "Ghidra auto-analysis reached its per-file deadline")
|
|
19
18
|
: parsed.error;
|
|
20
|
-
await options.cleanup();
|
|
21
19
|
return err(failure);
|
|
22
20
|
}
|
|
23
21
|
return parsed;
|
|
@@ -38,13 +38,14 @@ export const projectGhidraDoctorInspection = (inspection) => {
|
|
|
38
38
|
};
|
|
39
39
|
};
|
|
40
40
|
/** Inspect the process-configured BYO Ghidra installation for `rea doctor`. */
|
|
41
|
-
export const inspectSystemGhidraProvider = () => Promise.resolve(projectGhidraDoctorInspection(inspectGhidraInstallation({
|
|
42
|
-
|
|
41
|
+
export const inspectSystemGhidraProvider = (environment) => Promise.resolve(projectGhidraDoctorInspection(inspectGhidraInstallation({
|
|
42
|
+
environment,
|
|
43
|
+
...(environment.GHIDRA_INSTALL_DIR === undefined
|
|
43
44
|
? {}
|
|
44
|
-
: { installDir:
|
|
45
|
-
...(
|
|
45
|
+
: { installDir: environment.GHIDRA_INSTALL_DIR }),
|
|
46
|
+
...(environment.JAVA_HOME === undefined
|
|
46
47
|
? {}
|
|
47
|
-
: { javaHome:
|
|
48
|
+
: { javaHome: environment.JAVA_HOME }),
|
|
48
49
|
})));
|
|
49
50
|
const selectedChecks = (inspection) => {
|
|
50
51
|
const byName = new Map(inspection.checks.map((candidate) => [candidate.name, candidate]));
|
|
@@ -112,13 +112,11 @@ const procedureReferences = z
|
|
|
112
112
|
procedure: procedureIdentity,
|
|
113
113
|
direction: z.enum(["incoming", "outgoing"]),
|
|
114
114
|
references: z.array(referenceEdge),
|
|
115
|
-
reference_kinds_available: z.boolean()
|
|
116
|
-
unresolved_calls: z
|
|
117
|
-
.array(z.strictObject({
|
|
115
|
+
reference_kinds_available: z.boolean(),
|
|
116
|
+
unresolved_calls: z.array(z.strictObject({
|
|
118
117
|
address: ghidraCanonicalAddressSchema,
|
|
119
118
|
reason: z.string(),
|
|
120
|
-
}))
|
|
121
|
-
.default([]),
|
|
119
|
+
})),
|
|
122
120
|
})
|
|
123
121
|
.strict();
|
|
124
122
|
const procedureInfo = z
|
|
@@ -1,14 +1,84 @@
|
|
|
1
|
+
import { snapshotEnvironment } from "../process/snapshotEnvironment.js";
|
|
1
2
|
import { spawnSync } from "node:child_process";
|
|
2
3
|
import { constants } from "node:fs";
|
|
3
|
-
import { accessSync, readFileSync } from "node:fs";
|
|
4
|
+
import { accessSync, closeSync, fstatSync, openSync, readFileSync, readSync, statSync, } from "node:fs";
|
|
4
5
|
import { posix, win32 } from "node:path";
|
|
6
|
+
import { parseExecutableHeader, } from "../domain/binaryTarget.js";
|
|
5
7
|
import { ghidraApplicationProperties, ghidraJavaMajorAccepted, ghidraJavaRangeLabel, ghidraJavaRequirement, ghidraReleaseAccepted, ghidraReleaseCompatibility, ghidraReleaseLine, ghidraVersionDetail, SUPPORTED_GHIDRA_JAVA_MAJOR, SUPPORTED_GHIDRA_VERSION, } from "./GhidraInstallationPolicy.js";
|
|
6
|
-
export { SUPPORTED_GHIDRA_JAVA_MAJOR, SUPPORTED_GHIDRA_VERSION };
|
|
7
8
|
const NATIVE_PLATFORMS = {
|
|
8
9
|
linux: { x64: "linux_x86_64", arm64: "linux_arm_64" },
|
|
9
10
|
darwin: { x64: "mac_x86_64", arm64: "mac_arm_64" },
|
|
10
11
|
win32: { x64: "win_x86_64" },
|
|
11
12
|
};
|
|
13
|
+
/** Executable format each supported host runs its own Ghidra native tools as. */
|
|
14
|
+
const NATIVE_TOOL_FORMATS = {
|
|
15
|
+
linux: "elf",
|
|
16
|
+
darwin: "mach-o",
|
|
17
|
+
win32: "pe",
|
|
18
|
+
};
|
|
19
|
+
/** Node architecture identifiers as the executable-header parser reports them. */
|
|
20
|
+
const NATIVE_ARCHITECTURES = [
|
|
21
|
+
{ node: "x64", binary: "x86_64" },
|
|
22
|
+
{ node: "ia32", binary: "x86" },
|
|
23
|
+
{ node: "arm", binary: "arm" },
|
|
24
|
+
{ node: "arm64", binary: "arm64" },
|
|
25
|
+
];
|
|
26
|
+
/** Bound installation discovery reads; larger headers remain unknown. */
|
|
27
|
+
const EXECUTABLE_HEADER_PROBE_BYTES = 4096;
|
|
28
|
+
/**
|
|
29
|
+
* Judge a native decompiler by its own executable header instead of the
|
|
30
|
+
* directory name that admits it.
|
|
31
|
+
*
|
|
32
|
+
* Only a header that positively contradicts the host is `incompatible`. An
|
|
33
|
+
* absent, unreadable, truncated, or unrecognized header stays `unknown`, so a
|
|
34
|
+
* file the other checks already accept is never refused on missing evidence.
|
|
35
|
+
*/
|
|
36
|
+
const assessNativeDecompiler = (path, platform, architecture, probe) => {
|
|
37
|
+
const expectedFormat = NATIVE_TOOL_FORMATS[platform];
|
|
38
|
+
const expectedArchitecture = NATIVE_ARCHITECTURES.find(({ node }) => node === architecture)?.binary;
|
|
39
|
+
if (expectedFormat === undefined || expectedArchitecture === undefined)
|
|
40
|
+
return {
|
|
41
|
+
status: "unknown",
|
|
42
|
+
detail: `${path} is executable, but no native tool format is defined for ${platform}/${architecture}`,
|
|
43
|
+
};
|
|
44
|
+
let parsed = probe === undefined
|
|
45
|
+
? undefined
|
|
46
|
+
: parseExecutableHeader(probe.bytes, architecture, probe.size);
|
|
47
|
+
if (probe !== undefined && parsed !== undefined && !parsed.ok) {
|
|
48
|
+
// FAT parsing selects a host slice. A validated foreign slice can still
|
|
49
|
+
// prove that its complete architecture table excludes this host. If the
|
|
50
|
+
// host is listed but its slice is malformed, preserve the unknown outcome.
|
|
51
|
+
for (const { node } of NATIVE_ARCHITECTURES) {
|
|
52
|
+
if (node === architecture)
|
|
53
|
+
continue;
|
|
54
|
+
const alternative = parseExecutableHeader(probe.bytes, node, probe.size);
|
|
55
|
+
if (alternative.ok &&
|
|
56
|
+
!alternative.value.availableArchitectures.includes(expectedArchitecture)) {
|
|
57
|
+
parsed = alternative;
|
|
58
|
+
break;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (parsed === undefined || !parsed.ok)
|
|
63
|
+
return {
|
|
64
|
+
status: "unknown",
|
|
65
|
+
detail: `${path} is executable, but its executable format for ${platform}/${architecture} could not be established`,
|
|
66
|
+
};
|
|
67
|
+
const observed = `${parsed.value.format} ${parsed.value.architecture}`;
|
|
68
|
+
const expected = `${expectedFormat} ${expectedArchitecture}`;
|
|
69
|
+
if (observed === expected)
|
|
70
|
+
return {
|
|
71
|
+
status: "compatible",
|
|
72
|
+
detail: `${path} reports ${observed}, which matches ${platform}/${architecture}`,
|
|
73
|
+
};
|
|
74
|
+
const nativeDirectory = NATIVE_PLATFORMS[platform]?.[architecture];
|
|
75
|
+
const executable = platform === "win32" ? "decompile.exe" : "decompile";
|
|
76
|
+
return {
|
|
77
|
+
status: "incompatible",
|
|
78
|
+
detail: `${path} reports ${observed}, but ${platform}/${architecture} requires ${expected}`,
|
|
79
|
+
remediation: `Provide an executable Ghidra/Features/Decompiler/os/${nativeDirectory ?? "<platform>"}/${executable} built for ${expected}, or its build/os equivalent. REA does not build or install native tools.`,
|
|
80
|
+
};
|
|
81
|
+
};
|
|
12
82
|
/** Inspect an installation without importing a target or modifying Ghidra. */
|
|
13
83
|
export const inspectGhidraInstallation = (options, host = systemGhidraInstallationHost()) => {
|
|
14
84
|
const platform = options.platform ?? process.platform;
|
|
@@ -97,17 +167,15 @@ const installationCoordinates = (options, platform, architecture, host) => {
|
|
|
97
167
|
? undefined
|
|
98
168
|
: ghidraApplicationProperties(properties),
|
|
99
169
|
javaCommand,
|
|
100
|
-
|
|
170
|
+
// The configuration check rejects a relative JAVA_HOME. Probing it would
|
|
171
|
+
// run whatever `bin/java` the current directory holds.
|
|
172
|
+
java: options.javaHome === undefined || path.isAbsolute(options.javaHome)
|
|
173
|
+
? host.probeJava(javaCommand, ghidraJavaEnvironment(options.javaHome, options.environment, platform))
|
|
174
|
+
: undefined,
|
|
101
175
|
};
|
|
102
176
|
};
|
|
103
177
|
const installationChecks = ({ coordinates, platform, architecture, javaHome, host, }) => [
|
|
104
|
-
|
|
105
|
-
name: "configuration",
|
|
106
|
-
passed: coordinates.installDir !== null,
|
|
107
|
-
code: "not_configured",
|
|
108
|
-
detail: coordinates.installDir ?? "GHIDRA_INSTALL_DIR is not set",
|
|
109
|
-
remediation: `Set GHIDRA_INSTALL_DIR to an extracted Ghidra ${ghidraReleaseLine()} release directory.`,
|
|
110
|
-
}),
|
|
178
|
+
configurationCheck(coordinates.installDir, javaHome, platform),
|
|
111
179
|
installationCheck({
|
|
112
180
|
name: "platform",
|
|
113
181
|
passed: NATIVE_PLATFORMS[platform] !== undefined,
|
|
@@ -139,16 +207,38 @@ const installationChecks = ({ coordinates, platform, architecture, javaHome, hos
|
|
|
139
207
|
detail: coordinates.analyzeHeadlessPath ?? "analyzeHeadless unavailable",
|
|
140
208
|
remediation: "Restore support/analyzeHeadless or support/analyzeHeadless.bat from the official Ghidra release.",
|
|
141
209
|
}),
|
|
142
|
-
|
|
143
|
-
name: "native_decompiler",
|
|
144
|
-
passed: coordinates.nativeDecompilerPath !== null,
|
|
145
|
-
code: "executable_missing",
|
|
146
|
-
detail: coordinates.nativeDecompilerPath ??
|
|
147
|
-
`Matching native decompiler for ${platform}/${architecture} was not found`,
|
|
148
|
-
remediation: `Provide an executable Ghidra/Features/Decompiler/os/${NATIVE_PLATFORMS[platform]?.[architecture] ?? "<platform>"}/${platform === "win32" ? "decompile.exe" : "decompile"}, or its build/os equivalent. REA does not build or install native tools.`,
|
|
149
|
-
}),
|
|
210
|
+
nativeDecompilerCheck({ coordinates, platform, architecture, host }),
|
|
150
211
|
javaCheck(coordinates.java, coordinates.javaCommand, javaHome, coordinates.properties),
|
|
151
212
|
];
|
|
213
|
+
/**
|
|
214
|
+
* REA's configuration parser, and so the MCP server and analysis, accept only
|
|
215
|
+
* absolute paths; a relative one that happens to resolve here must not pass.
|
|
216
|
+
*/
|
|
217
|
+
const configurationCheck = (installDir, javaHome, platform) => {
|
|
218
|
+
const { isAbsolute } = platform === "win32" ? win32 : posix;
|
|
219
|
+
const relative = [
|
|
220
|
+
...(installDir !== null && !isAbsolute(installDir)
|
|
221
|
+
? ["GHIDRA_INSTALL_DIR"]
|
|
222
|
+
: []),
|
|
223
|
+
...(javaHome !== undefined && !isAbsolute(javaHome) ? ["JAVA_HOME"] : []),
|
|
224
|
+
];
|
|
225
|
+
if (installDir === null || relative.length === 0)
|
|
226
|
+
return installationCheck({
|
|
227
|
+
name: "configuration",
|
|
228
|
+
passed: installDir !== null,
|
|
229
|
+
code: "not_configured",
|
|
230
|
+
detail: installDir ?? "GHIDRA_INSTALL_DIR is not set",
|
|
231
|
+
remediation: `Set GHIDRA_INSTALL_DIR to an extracted Ghidra ${ghidraReleaseLine()} release directory.`,
|
|
232
|
+
});
|
|
233
|
+
const settings = relative.join(" and ");
|
|
234
|
+
return installationCheck({
|
|
235
|
+
name: "configuration",
|
|
236
|
+
passed: false,
|
|
237
|
+
code: "not_configured",
|
|
238
|
+
detail: `${settings} must be absolute`,
|
|
239
|
+
remediation: `Set ${settings} to ${relative.length === 1 ? "an absolute path" : "absolute paths"}. REA's analysis and MCP server reject relative paths even when they resolve from the current directory.`,
|
|
240
|
+
});
|
|
241
|
+
};
|
|
152
242
|
/** Project an installation probe into caller-visible, secret-free diagnostics. */
|
|
153
243
|
export const ghidraInstallationDiagnostics = (inspection) => ({
|
|
154
244
|
install_dir: inspection.installDir,
|
|
@@ -169,9 +259,10 @@ export const ghidraInstallationDiagnostics = (inspection) => ({
|
|
|
169
259
|
})),
|
|
170
260
|
});
|
|
171
261
|
/** Environment that makes an explicitly selected JDK win over PATH discovery. */
|
|
172
|
-
export const ghidraJavaEnvironment = (javaHome, environment
|
|
262
|
+
export const ghidraJavaEnvironment = (javaHome, environment, platform = process.platform) => {
|
|
263
|
+
const selectedEnvironment = snapshotEnvironment(environment, platform);
|
|
173
264
|
const boundedEnvironment = {
|
|
174
|
-
...
|
|
265
|
+
...selectedEnvironment,
|
|
175
266
|
_JAVA_OPTIONS: "",
|
|
176
267
|
JAVA_TOOL_OPTIONS: "",
|
|
177
268
|
JDK_JAVA_OPTIONS: "",
|
|
@@ -182,7 +273,7 @@ export const ghidraJavaEnvironment = (javaHome, environment = process.env, platf
|
|
|
182
273
|
: {
|
|
183
274
|
...boundedEnvironment,
|
|
184
275
|
JAVA_HOME: javaHome,
|
|
185
|
-
PATH: `${(platform === "win32" ? win32 : posix).join(javaHome, "bin")}${platform === "win32" ? win32.delimiter : posix.delimiter}${
|
|
276
|
+
PATH: `${(platform === "win32" ? win32 : posix).join(javaHome, "bin")}${platform === "win32" ? win32.delimiter : posix.delimiter}${selectedEnvironment.PATH ?? ""}`,
|
|
186
277
|
};
|
|
187
278
|
};
|
|
188
279
|
const installationCheck = (options) => options.passed
|
|
@@ -198,6 +289,23 @@ const installationCheck = (options) => options.passed
|
|
|
198
289
|
detail: options.detail,
|
|
199
290
|
remediation: options.remediation,
|
|
200
291
|
};
|
|
292
|
+
/** Require a present native decompiler without positively incompatible bytes. */
|
|
293
|
+
const nativeDecompilerCheck = ({ coordinates, platform, architecture, host, }) => {
|
|
294
|
+
const path = coordinates.nativeDecompilerPath;
|
|
295
|
+
const compatibility = path === null
|
|
296
|
+
? undefined
|
|
297
|
+
: assessNativeDecompiler(path, platform, architecture, host.executableHeader?.(path));
|
|
298
|
+
return installationCheck({
|
|
299
|
+
name: "native_decompiler",
|
|
300
|
+
passed: path !== null && compatibility?.status !== "incompatible",
|
|
301
|
+
code: "executable_missing",
|
|
302
|
+
detail: compatibility?.detail ??
|
|
303
|
+
`Matching native decompiler for ${platform}/${architecture} was not found`,
|
|
304
|
+
remediation: compatibility?.status === "incompatible"
|
|
305
|
+
? compatibility.remediation
|
|
306
|
+
: `Provide an executable Ghidra/Features/Decompiler/os/${NATIVE_PLATFORMS[platform]?.[architecture] ?? "<platform>"}/${platform === "win32" ? "decompile.exe" : "decompile"}, or its build/os equivalent. REA does not build or install native tools.`,
|
|
307
|
+
});
|
|
308
|
+
};
|
|
201
309
|
const versionCheck = (properties) => {
|
|
202
310
|
const raw = properties?.providerVersion;
|
|
203
311
|
return installationCheck({
|
|
@@ -252,10 +360,31 @@ const systemGhidraInstallationHost = () => ({
|
|
|
252
360
|
return undefined;
|
|
253
361
|
}
|
|
254
362
|
},
|
|
363
|
+
executableHeader(path) {
|
|
364
|
+
let handle;
|
|
365
|
+
try {
|
|
366
|
+
handle = openSync(path, constants.O_RDONLY | constants.O_NONBLOCK | constants.O_NOCTTY);
|
|
367
|
+
const metadata = fstatSync(handle);
|
|
368
|
+
if (!metadata.isFile())
|
|
369
|
+
return undefined;
|
|
370
|
+
const bytes = Buffer.alloc(EXECUTABLE_HEADER_PROBE_BYTES);
|
|
371
|
+
const read = readSync(handle, bytes, 0, bytes.length, 0);
|
|
372
|
+
return { bytes: bytes.subarray(0, read), size: metadata.size };
|
|
373
|
+
}
|
|
374
|
+
catch (cause) {
|
|
375
|
+
// best-effort cleanup: a header that cannot be read stays unknown.
|
|
376
|
+
void cause;
|
|
377
|
+
return undefined;
|
|
378
|
+
}
|
|
379
|
+
finally {
|
|
380
|
+
if (handle !== undefined)
|
|
381
|
+
closeSync(handle);
|
|
382
|
+
}
|
|
383
|
+
},
|
|
255
384
|
executable(path) {
|
|
256
385
|
try {
|
|
257
386
|
accessSync(path, constants.X_OK);
|
|
258
|
-
return
|
|
387
|
+
return statSync(path).isFile();
|
|
259
388
|
}
|
|
260
389
|
catch (cause) {
|
|
261
390
|
// best-effort cleanup: optional executable probing; failure means missing.
|