rea-agents 4.0.0 → 4.1.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 +93 -30
- package/bridge/ghidra/ReaGhidraBridge.java +358 -15
- package/bridge/ghidra/ReaGhidraExtensions.java +113 -0
- package/bridge/ghidra/ReaGhidraPrepareCom.java +32 -0
- package/dist/android/AndroidTargetSnapshot.js +34 -0
- package/dist/android/JadxAnalysis.js +191 -0
- package/dist/android/JadxConfiguration.js +41 -0
- package/dist/android/JadxMcpTransport.js +145 -0
- package/dist/android/JadxProtocol.js +101 -0
- package/dist/android/JadxProvider.js +170 -0
- package/dist/android/JadxRelease.js +19 -0
- package/dist/android/JadxSession.js +97 -0
- package/dist/application/AnalysisContextQueries.js +2 -1
- package/dist/application/AnalysisProviderEvaluation.js +5 -3
- package/dist/application/AnalysisProviderRegistry.js +2 -1
- package/dist/application/AnalysisSnapshotCache.js +4 -1
- package/dist/application/AnalysisSnapshotFiles.js +1 -1
- package/dist/application/AndroidAnalysisPort.js +1 -0
- package/dist/application/AndroidAnalysisService.js +37 -0
- package/dist/application/ArtifactExtraction.js +7 -4
- package/dist/application/ArtifactGraphConstruction.js +10 -17
- package/dist/application/ArtifactInventory/scanCanonical.js +8 -7
- package/dist/application/BinarySession.js +16 -3
- package/dist/application/BinarySessionExecution.js +4 -1
- package/dist/application/BinarySessionOpen.js +3 -2
- package/dist/application/BinarySessionRecords.js +9 -3
- package/dist/application/BinaryTargetResolver.js +25 -6
- package/dist/application/BrowserObservationService.js +2 -1
- package/dist/application/BrowserScenarioCaptureService.js +2 -1
- package/dist/application/BrowserScenarioEvidence.js +2 -2
- package/dist/application/CallPathTracing.js +2 -1
- package/dist/application/CapabilityInventory.js +18 -0
- package/dist/application/ClientConfigPath.js +3 -1
- package/dist/application/ClientConfigurationDocument.js +11 -1
- package/dist/application/ClientRegistrationStatus.js +8 -1
- package/dist/application/CompositeProvider.js +1 -1
- package/dist/application/DirectAnalysis.js +23 -7
- package/dist/application/DirectAnalysisStatus.js +3 -3
- package/dist/application/Doctor.js +48 -8
- package/dist/application/DoctorDiagnostics.js +7 -5
- package/dist/application/DoctorScope.js +1 -1
- package/dist/application/ElectronActiveEvidence.js +2 -2
- package/dist/application/ElectronActiveObservationService.js +2 -1
- package/dist/application/ElectronBoundaryAnalysis.js +1 -1
- package/dist/application/ElectronObservationService.js +2 -1
- package/dist/application/EnhancedLiteralTracing.js +2 -1
- package/dist/application/EnhancedToolTypes.js +2 -1
- package/dist/application/EnhancedTools.js +3 -1
- package/dist/application/EvidenceBundleCommands.js +2 -1
- package/dist/application/EvidenceBundleFiles.js +1 -1
- package/dist/application/EvidenceInputResolver.js +30 -0
- package/dist/application/EvidenceLedger.js +2 -1
- package/dist/application/FirmwareAnalysisPort.js +1 -0
- package/dist/application/FirmwareAnalysisService.js +35 -0
- package/dist/application/FunctionAnalysisEvidence.js +32 -0
- package/dist/application/InventoryProjectionEvidence.js +2 -1
- package/dist/application/JavaScriptApplicationService.js +50 -3
- package/dist/application/JavaScriptApplicationWorkflowService.js +2 -1
- package/dist/application/JavaScriptArtifactAnalysis.js +4 -2
- package/dist/application/JavaScriptArtifactFiles.js +4 -2
- package/dist/application/JavaScriptArtifactPathResolution.js +6 -2
- package/dist/application/JavaScriptJsonModules.js +3 -2
- package/dist/application/JavaScriptModuleRelationships.js +4 -2
- package/dist/application/JavaScriptRuntimeObservationService.js +2 -1
- package/dist/application/JavaScriptRuntimeReconciliationService.js +2 -1
- package/dist/application/JavaScriptSemanticGraphProjection.js +1 -1
- package/dist/application/JavaScriptSemanticTraceService.js +2 -1
- package/dist/application/JsonFiles.js +1 -1
- package/dist/application/LazyAnalysisProvider.js +3 -1
- package/dist/application/LinuxHopper.js +12 -4
- package/dist/application/MacHopper.js +20 -7
- package/dist/application/ManagedApplicationGraphService.js +2 -1
- package/dist/application/ManagedMemberComparisonService.js +3 -1
- package/dist/application/ManagedNativeVerificationService.js +2 -1
- package/dist/application/ManagedReconstructionService.js +2 -1
- package/dist/application/NativeCallRoutes.js +1 -1
- package/dist/application/NativeDispatchMetadataInspection.js +1 -1
- package/dist/application/NativeUiActionTrace.js +2 -1
- package/dist/application/NativeValueTrace.js +1 -1
- package/dist/application/ProcessCaptureError.js +1 -1
- package/dist/application/ProcessCaptureJournal.js +3 -1
- package/dist/application/ProcessCaptureLifecycle.js +6 -3
- package/dist/application/ProcessCli.js +9 -5
- package/dist/application/ProcessEvidence.js +2 -6
- package/dist/application/ProcessHarness.js +3 -2
- package/dist/application/ProcessNormalization.js +12 -5
- package/dist/application/ProcessSampling.js +3 -1
- package/dist/application/ReconstructionCoverageService.js +2 -1
- package/dist/application/ReconstructionObligationLedgerService.js +2 -1
- package/dist/application/ReferenceSourceImportEntries.js +2 -0
- package/dist/application/ReferenceSourceImportPolicy.js +4 -2
- package/dist/application/ReferenceSourceVcsAdapter.js +35 -4
- package/dist/application/SessionProviderRouter.js +4 -1
- package/dist/application/Setup.js +1 -128
- package/dist/application/SetupClientConfiguration.js +17 -6
- package/dist/application/SetupHost.js +111 -0
- package/dist/application/SetupRegistrationEnvironment.js +1 -2
- package/dist/application/SetupSkill.js +9 -3
- package/dist/application/SetupTypes.js +17 -0
- package/dist/application/StoreFileLock.js +7 -2
- package/dist/application/SupportedClients.js +8 -0
- package/dist/application/Uninstall.js +9 -4
- package/dist/application/UpdateRuntime.js +5 -2
- package/dist/application/WindowsCapabilities.js +7 -7
- package/dist/application/runtime.js +3 -1
- package/dist/artifacts/ArtifactProvider.js +3 -1
- package/dist/artifacts/DirectoryArtifactReader.js +2 -0
- package/dist/artifacts/NativeDmgArtifactReader.js +10 -3
- package/dist/artifacts/NibArchive.js +4 -2
- package/dist/artifacts/SafeOutputTree.js +26 -10
- package/dist/artifacts/ZipArtifactReader.js +1 -0
- package/dist/browser/BrowserProcessStartup.js +3 -1
- package/dist/browser/CdpAuthorizedMainFrame.js +1 -1
- package/dist/browser/CdpBrowserProvider.js +4 -1
- package/dist/browser/CdpCaptureDocuments.js +3 -1
- package/dist/browser/CdpCaptureEventHandlers.js +6 -2
- package/dist/browser/CdpCaptureStorageFingerprints.js +1 -1
- package/dist/browser/CdpCaptureValues.js +6 -2
- package/dist/browser/CdpConnection.js +8 -6
- package/dist/browser/CdpElectronInspection.js +3 -3
- package/dist/browser/CdpElectronProvider.js +4 -1
- package/dist/browser/CdpElectronScripts.js +2 -2
- package/dist/browser/CdpEndpoint.js +22 -10
- package/dist/browser/CdpObservationSession.js +2 -1
- package/dist/browser/CdpOptionalCommand.js +1 -1
- package/dist/browser/CdpPageCapture.js +2 -1
- package/dist/browser/CdpSafeMetadata.js +53 -8
- package/dist/browser/CdpScreenshot.js +1 -1
- package/dist/browser/CdpTargetSession.js +8 -5
- package/dist/browser/CdpWebMcpDiscovery.js +1 -1
- package/dist/browser/ElectronFileScope.js +9 -3
- package/dist/browser/JavaScriptRuntimeScope.js +3 -1
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +3 -1
- package/dist/browser/PlaywrightElectronActiveActions.js +1 -1
- package/dist/browser/PlaywrightElectronActiveProvider.js +6 -2
- package/dist/browser/PlaywrightExecutionBoundary.js +1 -1
- package/dist/browser/PlaywrightScenarioArtifacts.js +10 -5
- package/dist/browser/PlaywrightScenarioBrowser.js +3 -1
- package/dist/browser/PlaywrightScenarioEvents.js +6 -2
- package/dist/browser/PlaywrightScenarioSession.js +5 -2
- package/dist/browser/V8InspectorEndpoint.js +2 -1
- package/dist/browser/V8InspectorProvider.js +6 -1
- package/dist/browser/WebSourceMapFetcher.js +24 -11
- package/dist/cli/androidCommands.js +81 -0
- package/dist/{cliApplicationCommands.js → cli/applicationCommands.js} +18 -16
- package/dist/{cliBrowserAdvancedCommands.js → cli/browserAdvancedCommands.js} +13 -16
- package/dist/{cliBrowserCommands.js → cli/browserCommands.js} +9 -9
- package/dist/cli/commandCancellation.js +24 -0
- package/dist/cli/coreAnalysisCommands.js +110 -17
- package/dist/{cliElectronCommands.js → cli/electronCommands.js} +14 -13
- package/dist/cli/firmwareCommands.js +75 -0
- package/dist/{cliSetup.js → cli/interactiveSetup.js} +1 -1
- package/dist/cli/javascriptApplicationAnalysis.js +1 -1
- package/dist/cli/managedCommands.js +1 -1
- package/dist/cli/managedProjectGraphCommand.js +1 -1
- package/dist/cli/options.js +7 -1
- package/dist/{cliProcessCommands.js → cli/processCommands.js} +3 -3
- package/dist/cli/referenceSourceImportStatus.js +10 -0
- package/dist/cli/setupCommands.js +4 -2
- package/dist/cli/utilityCommands.js +3 -2
- package/dist/cli.js +10 -15
- package/dist/cliBrowserContext.js +1 -1
- package/dist/cliBrowserScenarioCommands.js +2 -1
- package/dist/cliCommandNames.js +11 -2
- package/dist/cliEvidenceCommands.js +2 -1
- package/dist/cliJavaScriptRuntimeCommands.js +2 -1
- package/dist/cliJsonInput.js +26 -11
- package/dist/cliLogging.js +2 -1
- package/dist/cliOutput.js +15 -16
- package/dist/config/environment.js +11 -1
- package/dist/config/parseConfig.js +7 -1
- package/dist/config/parsers.js +1 -1
- package/dist/contracts/androidToolContracts.js +77 -0
- package/dist/contracts/applicationToolContracts.js +32 -5
- package/dist/contracts/applicationWorkflowInputContracts.js +13 -13
- package/dist/contracts/artifactComparisonExample.js +7 -14
- package/dist/contracts/enhancedToolContracts.js +31 -0
- package/dist/contracts/errorSchemas.js +4 -2
- package/dist/contracts/evidenceInputContracts.js +13 -0
- package/dist/contracts/firmwareToolContracts.js +38 -0
- package/dist/contracts/officialToolContracts.js +66 -0
- package/dist/contracts/promptContracts.js +1 -1
- package/dist/contracts/sessionLifecycleInputs.js +4 -0
- package/dist/contracts/sessionToolContracts.js +43 -0
- package/dist/contracts/sessionToolSchemas.js +1 -1
- package/dist/contracts/toolContractExamples.js +5 -0
- package/dist/contracts/toolContractTypes.js +2 -0
- package/dist/contracts/toolContracts.js +7 -130
- package/dist/contracts/toolEffects.js +43 -0
- package/dist/contracts/toolOutputSchemaGroups.js +4 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +1 -0
- package/dist/doctorRuntime.js +5 -1
- package/dist/domain/analysisErrorBase.js +33 -0
- package/dist/domain/analysisErrorCore.js +60 -0
- package/dist/domain/analysisErrorPresentation.js +22 -2
- package/dist/domain/analysisErrorProjection.js +24 -3
- package/dist/domain/analysisSnapshot.js +1 -0
- package/dist/domain/androidAnalysis.js +141 -0
- package/dist/domain/appleAssetCatalog.js +1 -1
- package/dist/domain/artifactGraph.js +1 -0
- package/dist/domain/artifactInspection.js +19 -17
- package/dist/domain/artifactInventoryEvidence.js +20 -25
- package/dist/domain/artifactOperationError.js +16 -0
- package/dist/domain/browserObservation.js +12 -4
- package/dist/domain/browserObservationError.js +23 -0
- package/dist/domain/browserScenario.js +1 -1
- package/dist/domain/browserScenarioCapture.js +1 -1
- package/dist/domain/browserScenarioDiff.js +1 -1
- package/dist/domain/browserScenarioNormalization.js +6 -11
- package/dist/domain/browserScenarioValues.js +3 -1
- package/dist/domain/callPath.js +47 -7
- package/dist/domain/canonicalDigest.js +65 -0
- package/dist/domain/canonicalOrdering.js +11 -0
- package/dist/domain/changedBehavior.js +8 -7
- package/dist/domain/comparisonSemantics.js +2 -4
- package/dist/domain/configurationErrors.js +25 -0
- package/dist/domain/dosCom.js +8 -0
- package/dist/domain/electronActiveObservation.js +3 -1
- package/dist/domain/electronStaticAnalysisBrowser.js +13 -23
- package/dist/domain/electronStaticAnalysisNative.js +2 -1
- package/dist/domain/electronStaticAnalysisValues.js +23 -3
- package/dist/domain/evidence.js +3 -11
- package/dist/domain/evidenceErrors.js +30 -0
- package/dist/domain/firmwareAnalysis.js +121 -0
- package/dist/domain/functionComparison.js +4 -2
- package/dist/domain/functionComparisonDimensions.js +6 -4
- package/dist/domain/functionComparisonNormalization.js +8 -1
- package/dist/domain/functionComparisonResults.js +1 -4
- package/dist/domain/hopperErrors.js +78 -0
- package/dist/domain/hopperValues.js +2 -1
- package/dist/domain/interfaceBuilderGraph.js +3 -1
- package/dist/domain/javascriptApplicationChangeGraph.js +2 -2
- package/dist/domain/javascriptApplicationGraph.js +13 -22
- package/dist/domain/javascriptApplicationVersionComparison.js +3 -11
- package/dist/domain/javascriptApplicationVersionItems.js +3 -3
- package/dist/domain/javascriptApplicationVersionKeys.js +1 -1
- package/dist/domain/javascriptAstFingerprint.js +1 -1
- package/dist/domain/javascriptExportShapeComparison.js +1 -2
- package/dist/domain/javascriptExportShapeSelection.js +1 -1
- package/dist/domain/javascriptExportShapeVariants.js +7 -3
- package/dist/domain/javascriptFeatureSeed.js +29 -9
- package/dist/domain/javascriptFeatureTrace.js +9 -13
- package/dist/domain/javascriptFeatureTraversal.js +2 -1
- package/dist/domain/javascriptNativeHandoff.js +2 -1
- package/dist/domain/javascriptRuntimeLoadState.js +2 -2
- package/dist/domain/javascriptRuntimeReconciliationActive.js +3 -10
- package/dist/domain/javascriptRuntimeReconciliationGraph.js +2 -2
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +4 -3
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +8 -14
- package/dist/domain/javascriptRuntimeReconciliationResult.js +4 -4
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +5 -2
- package/dist/domain/javascriptRuntimeStaticCandidates.js +8 -4
- package/dist/domain/javascriptSemanticAnalysis.js +40 -3
- package/dist/domain/javascriptSemanticCallResolution.js +2 -1
- package/dist/domain/javascriptSemanticChildProcesses.js +2 -1
- package/dist/domain/javascriptSemanticDataEffects.js +2 -1
- package/dist/domain/javascriptSemanticFingerprints.js +1 -1
- package/dist/domain/javascriptSemanticGraph.js +23 -28
- package/dist/domain/javascriptSemanticPrimitives.js +9 -2
- package/dist/domain/javascriptSemanticProjection.js +2 -1
- package/dist/domain/javascriptSemanticPromises.js +2 -1
- package/dist/domain/javascriptSemanticProvenance.js +1 -1
- package/dist/domain/javascriptSemanticQuery.js +7 -8
- package/dist/domain/javascriptSemanticQueryAssessment.js +1 -2
- package/dist/domain/javascriptSemanticQueryIdentity.js +1 -2
- package/dist/domain/javascriptSemanticReturns.js +2 -1
- package/dist/domain/javascriptSemanticValues.js +50 -16
- package/dist/domain/javascriptSourceParser.js +4 -2
- package/dist/domain/javascriptStaticAnalysis.js +1 -1
- package/dist/domain/javascriptStaticAnalysisBundler.js +2 -1
- package/dist/domain/javascriptStaticAnalysisCalls.js +14 -6
- package/dist/domain/javascriptStaticAnalysisHelpers.js +31 -4
- package/dist/domain/jsonShape.js +6 -2
- package/dist/domain/managedMemberComparison.js +1 -0
- package/dist/domain/managedMemberComparisonItems.js +2 -0
- package/dist/domain/managedNativeVerificationMatch.js +5 -3
- package/dist/domain/nativeDataType.js +2 -0
- package/dist/domain/nativeFunctionAnnotations.js +43 -0
- package/dist/domain/nativeLoadImage.js +95 -0
- package/dist/domain/nativeMetadataRecovery.js +55 -0
- package/dist/domain/processCapture.js +0 -1
- package/dist/domain/processEvidenceProvider.js +11 -0
- package/dist/domain/processTraceComparison.js +1 -1
- package/dist/domain/providerAdapterError.js +17 -0
- package/dist/domain/providerCleanupError.js +1 -1
- package/dist/domain/providerSelectionError.js +44 -0
- package/dist/domain/reconstructionUnknowns.js +1 -1
- package/dist/domain/reconstructionVerification.js +22 -8
- package/dist/domain/referenceSourceClassification.js +5 -6
- package/dist/domain/referenceSourceGraph.js +9 -17
- package/dist/domain/referenceSourceImportParsing.js +38 -23
- package/dist/domain/runtimeIdentification.js +1 -1
- package/dist/domain/runtimeVersion.js +4 -7
- package/dist/domain/safeJson.js +13 -0
- package/dist/domain/sourceToBundleComparison.js +5 -7
- package/dist/domain/sourceToBundleSignals.js +6 -6
- package/dist/domain/staticRuntimeCorrelation.js +9 -7
- package/dist/domain/unknownRegistryError.js +10 -0
- package/dist/domain/webBundleAnalyzerAst.js +22 -5
- package/dist/domain/webBundleAnalyzerInspection.js +20 -14
- package/dist/dotnet/ManagedMemberRows.js +1 -1
- package/dist/dotnet/ManagedMetadataHeaps.js +3 -2
- package/dist/dotnet/ManagedMetadataInventoryRows.js +4 -2
- package/dist/dotnet/ManagedMethodBodyReader.js +8 -1
- package/dist/dotnet/ManagedStaticProvider.js +3 -1
- package/dist/firmware/FirmwareCommand.js +163 -0
- package/dist/firmware/FirmwareFiles.js +190 -0
- package/dist/firmware/FirmwareProvider.js +258 -0
- package/dist/firmware/FirmwarePublication.js +84 -0
- package/dist/firmware/FirmwareRelease.js +32 -0
- package/dist/firmware/FirmwareReports.js +223 -0
- package/dist/generatedMcpToolCatalog.js +1 -1
- package/dist/generatedPackageMetadata.js +5 -5
- package/dist/ghidra/GhidraAnalysisProfile.js +37 -8
- package/dist/ghidra/GhidraClient.js +52 -6
- package/dist/ghidra/GhidraDiagnostics.js +3 -0
- package/dist/ghidra/GhidraDoctor.js +38 -14
- package/dist/ghidra/GhidraFunctionValues.js +10 -4
- package/dist/ghidra/GhidraInstallation.js +10 -4
- package/dist/ghidra/GhidraInventoryValues.js +39 -2
- package/dist/ghidra/GhidraLauncher.js +91 -26
- package/dist/ghidra/GhidraLoadImageValues.js +199 -0
- package/dist/ghidra/GhidraProvider.js +129 -13
- package/dist/ghidra/GhidraProviderCapabilities.js +52 -15
- package/dist/ghidra/GhidraRequestQueue.js +2 -2
- package/dist/ghidra/GhidraSessionError.js +31 -4
- package/dist/ghidra/GhidraSessionValues.js +10 -7
- package/dist/ghidra/GhidraTargetSnapshot.js +16 -2
- package/dist/ghidra/GhidraTransport.js +12 -0
- package/dist/ghidra/extensions/GhidraExtensionFailures.js +20 -0
- package/dist/ghidra/extensions/GhidraExtensions.js +170 -0
- package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +21 -0
- package/dist/ghidra/extensions/nativeaot/NativeAotReport.js +84 -0
- package/dist/hopper/BridgeLauncher.js +4 -2
- package/dist/hopper/HopperAnalysisProfile.js +7 -2
- package/dist/hopper/HopperCleanup.js +55 -9
- package/dist/hopper/HopperClient.js +14 -4
- package/dist/hopper/HopperProcessDiagnostic.js +1 -1
- package/dist/hopper/HopperProvider.js +8 -4
- package/dist/hopper/HopperRequestQueue.js +7 -3
- package/dist/hopper/HopperSessionValues.js +1 -1
- package/dist/hopper/HopperSocketConnection.js +1 -1
- package/dist/hopper/HopperTargetLease.js +23 -15
- package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +7 -8
- package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -2
- package/dist/hopper/protocol.js +8 -8
- package/dist/ida/IdaConfiguration.js +56 -0
- package/dist/ida/IdaDoctor.js +53 -0
- package/dist/ida/IdaInput.js +62 -0
- package/dist/ida/IdaMcpConnection.js +111 -0
- package/dist/ida/IdaOperationRunner.js +299 -0
- package/dist/ida/IdaProtocolValues.js +178 -0
- package/dist/ida/IdaProvider.js +126 -0
- package/dist/ida/IdaProviderCapabilities.js +60 -0
- package/dist/ida/IdaSessionClient.js +306 -0
- package/dist/ida/IdaWorkspace.js +54 -0
- package/dist/main/shutdown.js +21 -1
- package/dist/main/startup.js +1 -1
- package/dist/main/transport.js +8 -4
- package/dist/main.js +5 -2
- package/dist/native/AppleDispatchMetadata.js +31 -10
- package/dist/native/NativeMacOSProvider.js +87 -15
- package/dist/native/NativeMachoInspection.js +42 -12
- package/dist/native/NativeUiHelperRuntime.js +7 -1
- package/dist/native/NativeUiObservation.js +6 -2
- package/dist/native/parsers/demangle.js +1 -1
- package/dist/native/parsers/dyldInfo.js +3 -3
- package/dist/native/parsers/otool.js +4 -1
- package/dist/native/parsers/plist.js +11 -3
- package/dist/process/PrivateRuntimeRoot.js +13 -3
- package/dist/process/ProcessOwnership.js +5 -73
- package/dist/process/ProcessOwnershipObservation.js +62 -2
- package/dist/process/ProcessOwnershipProcessTree.js +13 -0
- package/dist/process/ProviderProcess.js +24 -7
- package/dist/process/ProviderRunLineage.js +1 -1
- package/dist/process/WindowsAuthority.js +20 -1
- package/dist/reference/ReferenceSourceReaderEntries.js +5 -1
- package/dist/reference/ReferenceSourceReaderFile.js +1 -0
- package/dist/server/createServer.js +25 -2
- package/dist/server/mcpProgress.js +2 -1
- package/dist/server/promptCompletion.js +3 -3
- package/dist/server/registerAndroidTools.js +30 -0
- package/dist/server/registerApplicationTools/compareExportShapes.js +5 -1
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +7 -2
- package/dist/server/registerApplicationTools/compareVersions.js +5 -1
- package/dist/server/registerApplicationTools/traceFeature.js +7 -2
- package/dist/server/registerApplicationTools/traceSemantics.js +7 -2
- package/dist/server/registerEnhancedTools.js +28 -1
- package/dist/server/registerFirmwareTools.js +22 -0
- package/dist/server/registerFunctionComparisonTool.js +1 -1
- package/dist/server/registerInvestigationTools/helpers.js +2 -1
- package/dist/server/registerManagedTools.js +1 -1
- package/dist/server/registerManagedWorkflowTools/evidence.js +1 -1
- package/dist/server/registerOfficialTools.js +4 -1
- package/dist/server/registerProcessComparisonTool.js +5 -2
- package/dist/server/registerSessionTools.js +3 -1
- package/dist/server/runDerivedOperation.js +1 -1
- package/dist/server/sessionAvailabilityPolicy.js +3 -0
- package/dist/server/sessionEvidence.js +1 -1
- package/dist/server/toolResult.js +2 -1
- package/dist/windows/WindowsNativeLoader.js +108 -0
- package/dist/windows/WindowsOwnedProcess.js +168 -0
- package/dist/windows/WindowsPrivateRuntime.js +137 -0
- package/install.sh +4 -6
- package/native/windows/README.md +102 -0
- package/native/windows/build/manifest.json +9 -0
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +38 -24
- package/scripts/rea.mjs +1 -1
- package/scripts/verify-windows-native-artifact.mjs +39 -0
- package/skills/reverse-engineer-anything/SKILL.md +92 -24
- package/skills/reverse-engineer-anything/references/android-applications.md +31 -0
- package/skills/reverse-engineer-anything/references/javascript-applications.md +19 -2
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +52 -4
- package/dist/browser/CdpCanonicalJsonDigest.js +0 -9
- package/dist/domain/errors.js +0 -324
|
@@ -1,7 +1,13 @@
|
|
|
1
|
+
import { ghidraExtensionFailure } from "./extensions/GhidraExtensionFailures.js";
|
|
1
2
|
import { fileURLToPath } from "node:url";
|
|
2
3
|
import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
4
|
+
import { createAnalysisProfile } from "../domain/analysisProfile.js";
|
|
5
|
+
import { jsonObjectSchema, jsonValueSchema, } from "../domain/jsonValue.js";
|
|
6
|
+
import { nativeLoadImageObservationSchema, nativeLoadImageSchema, } from "../domain/nativeLoadImage.js";
|
|
7
|
+
import { attestGhidraDosLoadImage, attestGhidraDosComLoadImage, } from "./GhidraLoadImageValues.js";
|
|
8
|
+
import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
|
|
9
|
+
import {} from "../domain/analysisErrorBase.js";
|
|
10
|
+
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
5
11
|
import { err, ok } from "../domain/result.js";
|
|
6
12
|
import { GhidraClient } from "./GhidraClient.js";
|
|
7
13
|
import { GHIDRA_STARTUP_TIMEOUT_MS } from "./GhidraDefaults.js";
|
|
@@ -10,11 +16,12 @@ import { isGhidraInventoryOperation, parseGhidraInventoryInput, parseGhidraInven
|
|
|
10
16
|
import { ghidraInstallationDiagnostics, inspectGhidraInstallation, } from "./GhidraInstallation.js";
|
|
11
17
|
import { GhidraHeadlessLauncher } from "./GhidraLauncher.js";
|
|
12
18
|
import { resolveGhidraAnalysisProfile } from "./GhidraAnalysisProfile.js";
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
19
|
+
import { ghidraExtensionSchema, resolveGhidraExtensions, validateGhidraExtensionProfile, ghidraExtensionLimitations, } from "./extensions/GhidraExtensions.js";
|
|
20
|
+
import { CAPABILITIES, windowsP0Capabilities, GHIDRA_PROVIDER_IDENTITY, GHIDRA_PROVIDER_TOOL_CONTRACTS, healthLimitations, windowsP0Limitations, limitationsFor, } from "./GhidraProviderCapabilities.js";
|
|
21
|
+
import { windowsNativeAuthorityUnavailableReason, hasWindowsNativeAuthority, windowsNativeCapabilities, } from "../process/WindowsAuthority.js";
|
|
15
22
|
export { GHIDRA_PROVIDER_IDENTITY, GHIDRA_PROVIDER_TOOL_CONTRACTS };
|
|
16
23
|
const SUPPORTED_ARCHITECTURES = new Set(["x86", "x86_64", "arm", "arm64"]);
|
|
17
|
-
/** Ghidra candidate backed by an isolated
|
|
24
|
+
/** Ghidra candidate backed by an isolated ephemeral headless import. */
|
|
18
25
|
export class GhidraProvider {
|
|
19
26
|
config;
|
|
20
27
|
logger;
|
|
@@ -32,7 +39,7 @@ export class GhidraProvider {
|
|
|
32
39
|
}
|
|
33
40
|
capabilities() {
|
|
34
41
|
return (this.installationHost?.platform ?? process.platform) === "win32"
|
|
35
|
-
?
|
|
42
|
+
? windowsP0Capabilities()
|
|
36
43
|
: CAPABILITIES;
|
|
37
44
|
}
|
|
38
45
|
inspectAvailability() {
|
|
@@ -44,7 +51,7 @@ export class GhidraProvider {
|
|
|
44
51
|
return {
|
|
45
52
|
status: "unavailable",
|
|
46
53
|
code: "unsupported_host",
|
|
47
|
-
reason:
|
|
54
|
+
reason: windowsNativeAuthorityUnavailableReason(installation.platform),
|
|
48
55
|
diagnostics: {
|
|
49
56
|
...diagnostics,
|
|
50
57
|
windows_security: jsonObjectSchema.parse(windowsNativeCapabilities(installation.platform)),
|
|
@@ -71,6 +78,9 @@ export class GhidraProvider {
|
|
|
71
78
|
target_kind: target.kind,
|
|
72
79
|
target_format: target.format,
|
|
73
80
|
architecture: target.architecture ?? null,
|
|
81
|
+
available_architectures: target.kind === "executable"
|
|
82
|
+
? [...target.availableArchitectures]
|
|
83
|
+
: null,
|
|
74
84
|
executable_role: target.executableRole ?? null,
|
|
75
85
|
managed: target.managed ?? null,
|
|
76
86
|
};
|
|
@@ -83,6 +93,13 @@ export class GhidraProvider {
|
|
|
83
93
|
};
|
|
84
94
|
if (hostPlatform === "win32")
|
|
85
95
|
return inspectWindowsP0TargetSupport(target, diagnostics);
|
|
96
|
+
if (target.format === "mach-o" && target.availableArchitectures.length > 1)
|
|
97
|
+
return {
|
|
98
|
+
status: "unsupported",
|
|
99
|
+
code: "architecture_unsupported",
|
|
100
|
+
reason: "Ghidra v1 cannot enforce the selected architecture when importing a universal Mach-O; analyze a thinned Mach-O slice instead.",
|
|
101
|
+
diagnostics,
|
|
102
|
+
};
|
|
86
103
|
if (!SUPPORTED_ARCHITECTURES.has(target.architecture))
|
|
87
104
|
return {
|
|
88
105
|
status: "unsupported",
|
|
@@ -97,8 +114,23 @@ export class GhidraProvider {
|
|
|
97
114
|
diagnostics,
|
|
98
115
|
};
|
|
99
116
|
}
|
|
100
|
-
resolveAnalysisProfile(target, options) {
|
|
101
|
-
|
|
117
|
+
async resolveAnalysisProfile(target, options) {
|
|
118
|
+
const installation = this.#inspectInstallation();
|
|
119
|
+
const resolved = await resolveGhidraAnalysisProfile(target, GHIDRA_PROVIDER_IDENTITY, installation, options?.signal);
|
|
120
|
+
if (!resolved.ok || resolved.value.profile === null)
|
|
121
|
+
return resolved;
|
|
122
|
+
const extensions = await resolveGhidraExtensions(this.config, target, installation.platform, options?.signal);
|
|
123
|
+
if (!extensions.ok)
|
|
124
|
+
return extensions;
|
|
125
|
+
if (extensions.value.length === 0)
|
|
126
|
+
return resolved;
|
|
127
|
+
return ok({
|
|
128
|
+
...resolved.value,
|
|
129
|
+
profile: createAnalysisProfile(resolved.value.profile.provider, {
|
|
130
|
+
...resolved.value.profile.parameters,
|
|
131
|
+
analysis_extensions: jsonValueSchema.parse(extensions.value),
|
|
132
|
+
}),
|
|
133
|
+
});
|
|
102
134
|
}
|
|
103
135
|
createClient(target, profile, context) {
|
|
104
136
|
const installation = this.#inspectInstallation();
|
|
@@ -106,6 +138,24 @@ export class GhidraProvider {
|
|
|
106
138
|
if (!prerequisites.ok)
|
|
107
139
|
return unavailableClient(prerequisites.error);
|
|
108
140
|
const committedProfile = prerequisites.value.profile;
|
|
141
|
+
const extensionProfile = ghidraExtensionSchema
|
|
142
|
+
.array()
|
|
143
|
+
.safeParse(committedProfile.parameters.analysis_extensions ?? []);
|
|
144
|
+
if (!extensionProfile.success ||
|
|
145
|
+
(this.config.ghidraNativeAotJar !== undefined &&
|
|
146
|
+
extensionProfile.data.length === 0))
|
|
147
|
+
return unavailableClient(new ProviderAdapterError("ghidra", "open_binary", {
|
|
148
|
+
diagnostics: {
|
|
149
|
+
reason: "Resolve the configured Ghidra extensions into an analysis profile before opening the session.",
|
|
150
|
+
},
|
|
151
|
+
}));
|
|
152
|
+
const extensions = extensionProfile.data;
|
|
153
|
+
const invalidProfile = validateGhidraExtensionProfile(extensions, this.config, target, installation.platform);
|
|
154
|
+
if (invalidProfile !== null)
|
|
155
|
+
return unavailableClient(new ProviderAdapterError("ghidra", "open_binary", {
|
|
156
|
+
diagnostics: { reason: invalidProfile },
|
|
157
|
+
}));
|
|
158
|
+
let extensionFailure;
|
|
109
159
|
const targetLimitations = target.format === "dos-mz"
|
|
110
160
|
? [
|
|
111
161
|
"DOS MZ uses 16-bit x86 real mode with the Ghidra load segment 0x1000. Returned addresses are linear byte coordinates; they do not identify a unique segment:offset alias.",
|
|
@@ -120,6 +170,7 @@ export class GhidraProvider {
|
|
|
120
170
|
]
|
|
121
171
|
: [];
|
|
122
172
|
const client = this.clientFactory({
|
|
173
|
+
platform: installation.platform,
|
|
123
174
|
launcher: new GhidraHeadlessLauncher({
|
|
124
175
|
analyzeHeadlessPath: prerequisites.value.analyzeHeadlessPath,
|
|
125
176
|
...(this.config.ghidraJavaHome === undefined
|
|
@@ -127,16 +178,20 @@ export class GhidraProvider {
|
|
|
127
178
|
: { javaHome: this.config.ghidraJavaHome }),
|
|
128
179
|
bridgeScriptPath: fileURLToPath(new URL("../../bridge/ghidra/ReaGhidraBridge.java", import.meta.url)),
|
|
129
180
|
...(target.format === "dos-mz" ? { dosMz: true } : {}),
|
|
181
|
+
...(target.format === "dos-com" ? { dosCom: true } : {}),
|
|
130
182
|
platform: installation.platform,
|
|
183
|
+
...(extensions.length === 0 ? {} : { analysisExtensions: extensions }),
|
|
131
184
|
}),
|
|
132
|
-
targetPath:
|
|
185
|
+
targetPath: installation.platform === "win32"
|
|
186
|
+
? (target.sourcePath ?? target.path)
|
|
187
|
+
: target.path,
|
|
133
188
|
targetSha256: target.sha256,
|
|
134
189
|
transport: installation.platform === "win32"
|
|
135
190
|
? "authenticated-loopback-tcp"
|
|
136
191
|
: "unix-socket",
|
|
137
192
|
providerVersion: prerequisites.value.providerVersion,
|
|
138
193
|
profileDigest: committedProfile.digest,
|
|
139
|
-
...(
|
|
194
|
+
...(["dos-mz", "dos-com"].includes(target.format)
|
|
140
195
|
? {
|
|
141
196
|
expectedLanguageId: "x86:LE:16:Real Mode",
|
|
142
197
|
expectedCompilerSpecId: "default",
|
|
@@ -145,8 +200,17 @@ export class GhidraProvider {
|
|
|
145
200
|
...(context === undefined ? {} : { runId: context.runId }),
|
|
146
201
|
logger: this.logger.child({ layer: "ghidra-bridge" }),
|
|
147
202
|
});
|
|
203
|
+
const checkExtensions = async (operation, info) => {
|
|
204
|
+
extensionFailure = ghidraExtensionFailure(extensions, info.analysis_extensions ?? [], operation);
|
|
205
|
+
if (extensionFailure === undefined)
|
|
206
|
+
return undefined;
|
|
207
|
+
await client.close();
|
|
208
|
+
return extensionFailure;
|
|
209
|
+
};
|
|
148
210
|
return {
|
|
149
211
|
execute: async (operation, parameters, options) => {
|
|
212
|
+
if (extensionFailure !== undefined)
|
|
213
|
+
return err(extensionFailure);
|
|
150
214
|
if (operation !== "health" &&
|
|
151
215
|
!isGhidraInventoryOperation(operation) &&
|
|
152
216
|
!isGhidraFunctionOperation(operation))
|
|
@@ -155,12 +219,16 @@ export class GhidraProvider {
|
|
|
155
219
|
const started = await client.start(options?.signal);
|
|
156
220
|
if (!started.ok)
|
|
157
221
|
return err(projectSessionError(operation, started.error));
|
|
222
|
+
const failed = await checkExtensions(operation, started.value);
|
|
223
|
+
if (failed !== undefined)
|
|
224
|
+
return err(failed);
|
|
158
225
|
return ok(createAnalysisExecution(started.value, committedProfile.provider, {
|
|
159
226
|
analysisProfile: committedProfile,
|
|
160
227
|
limitations: [
|
|
161
228
|
...healthLimitations,
|
|
162
229
|
...providerLimitations,
|
|
163
230
|
...targetLimitations,
|
|
231
|
+
...ghidraExtensionLimitations(extensions),
|
|
164
232
|
],
|
|
165
233
|
}));
|
|
166
234
|
}
|
|
@@ -169,6 +237,14 @@ export class GhidraProvider {
|
|
|
169
237
|
: parseGhidraInventoryInput(operation, parameters);
|
|
170
238
|
if (!input.ok)
|
|
171
239
|
return input;
|
|
240
|
+
if (extensions.length > 0) {
|
|
241
|
+
const started = await client.start(options?.signal);
|
|
242
|
+
if (!started.ok)
|
|
243
|
+
return err(projectSessionError(operation, started.error));
|
|
244
|
+
const failed = await checkExtensions(operation, started.value);
|
|
245
|
+
if (failed !== undefined)
|
|
246
|
+
return err(failed);
|
|
247
|
+
}
|
|
172
248
|
const called = await client.callTool(operation, input.value, options?.signal === undefined ? {} : { signal: options.signal });
|
|
173
249
|
if (!called.ok)
|
|
174
250
|
return err(projectSessionError(operation, called.error));
|
|
@@ -177,13 +253,47 @@ export class GhidraProvider {
|
|
|
177
253
|
: parseGhidraInventoryResult(operation, called.value);
|
|
178
254
|
if (!result.ok)
|
|
179
255
|
return result;
|
|
180
|
-
|
|
256
|
+
let normalized = result.value;
|
|
257
|
+
if (operation === "inspect_native_load_image") {
|
|
258
|
+
const observations = nativeLoadImageObservationSchema.parse(result.value);
|
|
259
|
+
if (target.format !== "dos-mz" && target.format !== "dos-com") {
|
|
260
|
+
normalized = jsonValueSchema.parse(nativeLoadImageSchema.parse({
|
|
261
|
+
status: "unsupported",
|
|
262
|
+
reason: "Independent load-image verification currently supports DOS MZ and explicit DOS COM targets only.",
|
|
263
|
+
observations,
|
|
264
|
+
limitations: [
|
|
265
|
+
"Other formats expose measured mappings and source identities; no format-specific verification was performed.",
|
|
266
|
+
],
|
|
267
|
+
}));
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
if (client.readTargetSnapshot === undefined)
|
|
271
|
+
return err(new ProviderAdapterError("ghidra", operation, {
|
|
272
|
+
diagnostics: {
|
|
273
|
+
reason: "The Ghidra client does not expose its immutable target snapshot for independent load-image verification.",
|
|
274
|
+
},
|
|
275
|
+
}));
|
|
276
|
+
const snapshot = await client.readTargetSnapshot();
|
|
277
|
+
if (!snapshot.ok)
|
|
278
|
+
return err(projectSessionError(operation, snapshot.error));
|
|
279
|
+
const attested = (target.format === "dos-com"
|
|
280
|
+
? attestGhidraDosComLoadImage
|
|
281
|
+
: attestGhidraDosLoadImage)(snapshot.value, target.sha256 ?? "", observations);
|
|
282
|
+
if (!attested.ok)
|
|
283
|
+
return err(new ProviderAdapterError("ghidra", operation, {
|
|
284
|
+
diagnostics: { reason: attested.error },
|
|
285
|
+
}));
|
|
286
|
+
normalized = jsonValueSchema.parse(attested.value);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return ok(createAnalysisExecution(normalized, committedProfile.provider, {
|
|
181
290
|
rawResult: called.value,
|
|
182
291
|
analysisProfile: committedProfile,
|
|
183
292
|
limitations: [
|
|
184
293
|
...limitationsFor(operation),
|
|
185
294
|
...providerLimitations,
|
|
186
295
|
...targetLimitations,
|
|
296
|
+
...ghidraExtensionLimitations(extensions),
|
|
187
297
|
],
|
|
188
298
|
}));
|
|
189
299
|
},
|
|
@@ -263,7 +373,7 @@ const ghidraClientPrerequisites = (target, profile, installation) => {
|
|
|
263
373
|
}));
|
|
264
374
|
if (installation.platform === "win32" &&
|
|
265
375
|
!hasWindowsNativeAuthority(installation.platform))
|
|
266
|
-
return err(new AnalysisCapabilityUnavailableError("ghidra", "health",
|
|
376
|
+
return err(new AnalysisCapabilityUnavailableError("ghidra", "health", windowsNativeAuthorityUnavailableReason(installation.platform)));
|
|
267
377
|
if (profile === undefined || profile.provider.id !== "ghidra")
|
|
268
378
|
return err(new ProviderAdapterError("ghidra", "health"));
|
|
269
379
|
return ok({
|
|
@@ -277,6 +387,12 @@ const unavailableClient = (failure) => ({
|
|
|
277
387
|
close: () => Promise.resolve(),
|
|
278
388
|
});
|
|
279
389
|
const projectSessionError = (operation, failure) => {
|
|
390
|
+
if (operation === "annotate_native_function" &&
|
|
391
|
+
failure.kind === "remote" &&
|
|
392
|
+
failure.remoteCode === "invalid_function_name")
|
|
393
|
+
return new AnalysisInputError(operation, { cause: failure }, [
|
|
394
|
+
{ path: ["name"], reason: "invalid_value", message: failure.message },
|
|
395
|
+
]);
|
|
280
396
|
if (failure.kind === "cancelled")
|
|
281
397
|
return new AnalysisCancelledError(operation);
|
|
282
398
|
if (failure.kind === "timeout" || failure.kind === "analysis_timeout")
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { hasWindowsNativeAuthority, windowsNativeAuthorityUnavailableReason, } from "../process/WindowsAuthority.js";
|
|
2
2
|
import { GENERATED_MCP_TOOL_CATALOG } from "../generatedMcpToolCatalog.js";
|
|
3
3
|
import { GHIDRA_FUNCTION_OPERATIONS } from "./GhidraFunctionValues.js";
|
|
4
4
|
import { GHIDRA_INVENTORY_OPERATIONS } from "./GhidraInventoryValues.js";
|
|
@@ -9,7 +9,7 @@ export const GHIDRA_PROVIDER_IDENTITY = Object.freeze({
|
|
|
9
9
|
version: null,
|
|
10
10
|
});
|
|
11
11
|
const providerContractByName = new Map(GENERATED_MCP_TOOL_CATALOG.filter(({ kind }) => kind === "official-proxy" || kind === "enhanced").map((contract) => [contract.name, contract]));
|
|
12
|
-
/** Provider-neutral
|
|
12
|
+
/** Provider-neutral contracts implemented by the Ghidra adapter. */
|
|
13
13
|
export const GHIDRA_PROVIDER_TOOL_CONTRACTS = Object.freeze([...GHIDRA_INVENTORY_OPERATIONS, ...GHIDRA_FUNCTION_OPERATIONS].map((operation) => {
|
|
14
14
|
const contract = providerContractByName.get(operation);
|
|
15
15
|
if (contract === undefined)
|
|
@@ -19,13 +19,13 @@ export const GHIDRA_PROVIDER_TOOL_CONTRACTS = Object.freeze([...GHIDRA_INVENTORY
|
|
|
19
19
|
/** Health limitations shared by every Ghidra-backed capability. */
|
|
20
20
|
export const healthLimitations = Object.freeze([
|
|
21
21
|
"The session serves operations only after Ghidra reports default auto-analysis complete; incomplete analysis does not expose partial results.",
|
|
22
|
-
"The imported Program and temporary project are ephemeral
|
|
22
|
+
"The imported Program and temporary project are ephemeral and deleted on close. Annotation operations edit session database metadata; original executable bytes are never written.",
|
|
23
23
|
]);
|
|
24
24
|
/** Additional limitations applied to the experimental Windows x64 P0 boundary. */
|
|
25
25
|
export const windowsP0Limitations = Object.freeze([
|
|
26
26
|
"Windows Ghidra P0 accepts approved native x86-64 PE applications only; DLL, managed, hostile, sensitive, and mutable-path targets are unsupported.",
|
|
27
27
|
"The Windows bridge uses authenticated IPv4 loopback because Node path-based IPC does not expose Java AF_UNIX sockets; the endpoint file contains no bearer token.",
|
|
28
|
-
"Windows
|
|
28
|
+
"Windows sessions require the matching packaged Windows x64 native addon, local NTFS targets and runtimes, and Windows 10 or later. Native handles enforce path admission, private DACLs, and Job Object ownership automatically.",
|
|
29
29
|
]);
|
|
30
30
|
/** Limitation text for one admitted operation, including the common base. */
|
|
31
31
|
export const limitationsFor = (operation) => {
|
|
@@ -34,6 +34,27 @@ export const limitationsFor = (operation) => {
|
|
|
34
34
|
"Default-space addresses use lowercase 0x-prefixed hexadecimal; other address spaces use <percent-encoded-space>:0x<hex>.",
|
|
35
35
|
];
|
|
36
36
|
switch (operation) {
|
|
37
|
+
case "annotate_native_function":
|
|
38
|
+
return [
|
|
39
|
+
...common,
|
|
40
|
+
"Names use Ghidra USER_DEFINED source. Name writes preserve the existing namespace; readback uses the fully qualified name. Regular comments map to PRE and inline comments to EOL at the exact function entry. Changes commit together after readback and refreshed analysis; failure rolls them all back.",
|
|
41
|
+
"Metadata edits invalidate immutable analysis snapshots and are discarded on close. CLI returns the updated dossier before session cleanup; this is not a saved Ghidra project.",
|
|
42
|
+
];
|
|
43
|
+
case "inspect_native_load_image":
|
|
44
|
+
return [
|
|
45
|
+
...common,
|
|
46
|
+
"Independent verification supports DOS MZ and explicitly selected COM, including measured COM entry context. Measured source mappings use inclusive end addresses and complete region digests; no target execution or project mutation occurs.",
|
|
47
|
+
];
|
|
48
|
+
case "read_bytes":
|
|
49
|
+
return [
|
|
50
|
+
...common,
|
|
51
|
+
"Bytes reflect Ghidra's initialized memory, including loader fixups. Reads stop at an unmapped or uninitialized byte and report completeness explicitly.",
|
|
52
|
+
];
|
|
53
|
+
case "address_to_file_offset":
|
|
54
|
+
return [
|
|
55
|
+
...common,
|
|
56
|
+
"Offsets come from Ghidra source-byte mappings, not virtual-address arithmetic. Uninitialized memory, missing mappings and ambiguous mappings fail explicitly.",
|
|
57
|
+
];
|
|
37
58
|
case "list_documents":
|
|
38
59
|
return [
|
|
39
60
|
...common,
|
|
@@ -121,7 +142,7 @@ export const CAPABILITIES = Object.freeze(GHIDRA_PROVIDER_TOOL_CONTRACTS.map((co
|
|
|
121
142
|
available: true,
|
|
122
143
|
reason: null,
|
|
123
144
|
effects: Object.freeze({
|
|
124
|
-
mutatesArtifact:
|
|
145
|
+
mutatesArtifact: operation === "annotate_native_function",
|
|
125
146
|
launchesProcess: true,
|
|
126
147
|
mayShowUi: false,
|
|
127
148
|
mayAccessNetwork: false,
|
|
@@ -133,13 +154,29 @@ export const CAPABILITIES = Object.freeze(GHIDRA_PROVIDER_TOOL_CONTRACTS.map((co
|
|
|
133
154
|
});
|
|
134
155
|
}));
|
|
135
156
|
/** Capabilities advertised for the experimental Windows x64 P0 boundary. */
|
|
136
|
-
export const
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
157
|
+
export const windowsP0Capabilities = () => {
|
|
158
|
+
const available = hasWindowsNativeAuthority("win32");
|
|
159
|
+
return Object.freeze(CAPABILITIES.map((capability) => {
|
|
160
|
+
const limitations = Object.freeze([
|
|
161
|
+
...capability.limitations,
|
|
162
|
+
...windowsP0Limitations,
|
|
163
|
+
]);
|
|
164
|
+
if (capability.effects.mutatesArtifact)
|
|
165
|
+
return Object.freeze({
|
|
166
|
+
...capability,
|
|
167
|
+
available: false,
|
|
168
|
+
reason: "Windows Ghidra P0 does not admit database mutation.",
|
|
169
|
+
availabilityCode: "unsupported_host",
|
|
170
|
+
limitations,
|
|
171
|
+
});
|
|
172
|
+
return available
|
|
173
|
+
? Object.freeze({ ...capability, limitations })
|
|
174
|
+
: Object.freeze({
|
|
175
|
+
...capability,
|
|
176
|
+
available: false,
|
|
177
|
+
reason: windowsNativeAuthorityUnavailableReason("win32"),
|
|
178
|
+
availabilityCode: "unsupported_host",
|
|
179
|
+
limitations,
|
|
180
|
+
});
|
|
181
|
+
}));
|
|
182
|
+
};
|
|
@@ -88,9 +88,9 @@ export class GhidraRequestQueue {
|
|
|
88
88
|
executionSettled = true;
|
|
89
89
|
entry.resolve(result);
|
|
90
90
|
})
|
|
91
|
-
.catch(() => {
|
|
91
|
+
.catch((cause) => {
|
|
92
92
|
executionSettled = true;
|
|
93
|
-
entry.resolve(err(this.failure("protocol", "Ghidra serial request execution rejected unexpectedly")));
|
|
93
|
+
entry.resolve(err(this.failure("protocol", "Ghidra serial request execution rejected unexpectedly", cause)));
|
|
94
94
|
})
|
|
95
95
|
.finally(() => {
|
|
96
96
|
if (entry.signal !== undefined && onAbort !== undefined)
|
|
@@ -18,7 +18,7 @@ const createGhidraSessionError = (failure) => new GhidraSessionError(failure.kin
|
|
|
18
18
|
? failure.diagnostics
|
|
19
19
|
: {
|
|
20
20
|
...failure.diagnostics,
|
|
21
|
-
remote_code: failure.remoteCode,
|
|
21
|
+
remote_code: failure.redact(failure.remoteCode),
|
|
22
22
|
remote_message: failure.message,
|
|
23
23
|
}, {
|
|
24
24
|
...(failure.cause === undefined ? {} : { cause: failure.cause }),
|
|
@@ -30,10 +30,37 @@ const createGhidraSessionError = (failure) => new GhidraSessionError(failure.kin
|
|
|
30
30
|
: { remoteCode: failure.remoteCode }),
|
|
31
31
|
});
|
|
32
32
|
/** Bind session-failure construction to a live, token-redacted diagnostic view. */
|
|
33
|
-
export const bindGhidraSessionFailure = (diagnostics) => (kind, message, cause, options = {}) => createGhidraSessionError({
|
|
33
|
+
export const bindGhidraSessionFailure = (diagnostics, redact = (value) => value) => (kind, message, cause, options = {}) => createGhidraSessionError({
|
|
34
34
|
kind,
|
|
35
|
-
message,
|
|
36
|
-
diagnostics:
|
|
35
|
+
message: redact(message),
|
|
36
|
+
diagnostics: {
|
|
37
|
+
...diagnostics(),
|
|
38
|
+
...(cause === undefined
|
|
39
|
+
? {}
|
|
40
|
+
: { failure_cause: describeCause(cause, redact) }),
|
|
41
|
+
},
|
|
42
|
+
redact,
|
|
37
43
|
...(cause === undefined ? {} : { cause }),
|
|
38
44
|
...options,
|
|
39
45
|
});
|
|
46
|
+
const describeCause = (cause, redact) => {
|
|
47
|
+
if (cause instanceof Error) {
|
|
48
|
+
const code = "code" in cause ? cause.code : undefined;
|
|
49
|
+
return {
|
|
50
|
+
name: redact(cause.name),
|
|
51
|
+
message: redact(cause.message),
|
|
52
|
+
...(typeof code === "string"
|
|
53
|
+
? { code: redact(code) }
|
|
54
|
+
: typeof code === "number" && Number.isFinite(code)
|
|
55
|
+
? { code }
|
|
56
|
+
: {}),
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
if (typeof cause === "string")
|
|
60
|
+
return { type: "string", message: redact(cause) };
|
|
61
|
+
if (cause === null || typeof cause === "boolean")
|
|
62
|
+
return { type: cause === null ? "null" : "boolean", value: cause };
|
|
63
|
+
if (typeof cause === "number" && Number.isFinite(cause))
|
|
64
|
+
return { type: "number", value: cause };
|
|
65
|
+
return { type: typeof cause };
|
|
66
|
+
};
|
|
@@ -2,6 +2,7 @@ import { z } from "zod";
|
|
|
2
2
|
import { err, ok } from "../domain/result.js";
|
|
3
3
|
import { GHIDRA_INVENTORY_OPERATIONS } from "./GhidraInventoryValues.js";
|
|
4
4
|
import { GHIDRA_FUNCTION_OPERATIONS } from "./GhidraFunctionValues.js";
|
|
5
|
+
import { ghidraExtensionResultSchema } from "./extensions/GhidraExtensions.js";
|
|
5
6
|
/** Exact methods proved by the bridge handshake after auto-analysis. */
|
|
6
7
|
export const GHIDRA_SESSION_CAPABILITIES = [
|
|
7
8
|
"ping",
|
|
@@ -21,12 +22,11 @@ const sessionInfoSchema = z
|
|
|
21
22
|
version: z.string().min(1),
|
|
22
23
|
})
|
|
23
24
|
.strict(),
|
|
24
|
-
read_only: z.
|
|
25
|
+
read_only: z.boolean(),
|
|
25
26
|
analysis_complete: z.boolean(),
|
|
26
27
|
analysis_timed_out: z.boolean(),
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
.length(GHIDRA_SESSION_CAPABILITIES.length),
|
|
28
|
+
analysis_extensions: z.array(ghidraExtensionResultSchema).optional(),
|
|
29
|
+
capabilities: z.array(capabilitySchema),
|
|
30
30
|
target: z
|
|
31
31
|
.object({
|
|
32
32
|
name: z.string().min(1),
|
|
@@ -42,8 +42,12 @@ const sessionInfoSchema = z
|
|
|
42
42
|
/** Require exact run, provider, and profile identity from the Java bridge. */
|
|
43
43
|
export const parseGhidraSessionInfo = (value, expected) => {
|
|
44
44
|
const parsed = sessionInfoSchema.safeParse(value);
|
|
45
|
+
const readOnly = expected.expectedReadOnly ?? false;
|
|
46
|
+
const expectedCapabilities = GHIDRA_SESSION_CAPABILITIES.filter((capability) => !readOnly || capability !== "annotate_native_function");
|
|
45
47
|
if (!parsed.success ||
|
|
46
48
|
parsed.data.run_id !== expected.runId ||
|
|
49
|
+
parsed.data.read_only !== readOnly ||
|
|
50
|
+
parsed.data.capabilities.length !== expectedCapabilities.length ||
|
|
47
51
|
parsed.data.provider.version !== expected.providerVersion ||
|
|
48
52
|
parsed.data.profile_digest !== expected.profileDigest ||
|
|
49
53
|
parsed.data.target.sha256 !== expected.targetSha256 ||
|
|
@@ -52,9 +56,8 @@ export const parseGhidraSessionInfo = (value, expected) => {
|
|
|
52
56
|
(expected.expectedCompilerSpecId !== undefined &&
|
|
53
57
|
parsed.data.target.compiler_spec_id !==
|
|
54
58
|
expected.expectedCompilerSpecId) ||
|
|
55
|
-
new Set(parsed.data.capabilities).size !==
|
|
56
|
-
|
|
57
|
-
GHIDRA_SESSION_CAPABILITIES.some((capability) => !parsed.data.capabilities.includes(capability)) ||
|
|
59
|
+
new Set(parsed.data.capabilities).size !== expectedCapabilities.length ||
|
|
60
|
+
expectedCapabilities.some((capability) => !parsed.data.capabilities.includes(capability)) ||
|
|
58
61
|
parsed.data.analysis_complete === parsed.data.analysis_timed_out)
|
|
59
62
|
return err(new Error("Ghidra bridge handshake identity is invalid"));
|
|
60
63
|
return ok(parsed.data);
|
|
@@ -2,12 +2,23 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { constants, createReadStream } from "node:fs";
|
|
3
3
|
import { chmod, copyFile, rm } from "node:fs/promises";
|
|
4
4
|
import { extname, join } from "node:path";
|
|
5
|
+
import { windowsPrivateRuntime } from "../windows/WindowsPrivateRuntime.js";
|
|
5
6
|
/** Copy one target and require its bytes to match the parsed target identity. */
|
|
6
|
-
export const createGhidraTargetSnapshot = async (sourcePath, runtimeRoot, expectedSha256) => {
|
|
7
|
+
export const createGhidraTargetSnapshot = async (sourcePath, runtimeRoot, expectedSha256, options = {}) => {
|
|
7
8
|
if (!/^[a-f0-9]{64}$/u.test(expectedSha256))
|
|
8
9
|
throw new TypeError("Ghidra target SHA-256 commitment is invalid");
|
|
9
10
|
const suffix = safeExtension(sourcePath);
|
|
10
11
|
const snapshotPath = join(runtimeRoot, `target-${expectedSha256.slice(0, 12)}${suffix}`);
|
|
12
|
+
if ((options.platform ?? process.platform) === "win32") {
|
|
13
|
+
const observed = await windowsPrivateRuntime(runtimeRoot).snapshot(sourcePath, `target-${expectedSha256.slice(0, 12)}${suffix}`, options.signal);
|
|
14
|
+
if (observed.sha256 !== expectedSha256)
|
|
15
|
+
throw new Error(`Ghidra target snapshot digest mismatch: expected ${expectedSha256}, observed ${observed.sha256}`);
|
|
16
|
+
return {
|
|
17
|
+
path: snapshotPath,
|
|
18
|
+
sha256: observed.sha256,
|
|
19
|
+
admission: { source: observed.source, snapshot: observed.snapshot },
|
|
20
|
+
};
|
|
21
|
+
}
|
|
11
22
|
try {
|
|
12
23
|
await copyFile(sourcePath, snapshotPath, constants.COPYFILE_EXCL);
|
|
13
24
|
await chmod(snapshotPath, 0o600);
|
|
@@ -20,7 +31,10 @@ export const createGhidraTargetSnapshot = async (sourcePath, runtimeRoot, expect
|
|
|
20
31
|
return { path: snapshotPath, sha256: observedSha256 };
|
|
21
32
|
}
|
|
22
33
|
catch (cause) {
|
|
23
|
-
await rm(snapshotPath, { force: true }).catch(() =>
|
|
34
|
+
await rm(snapshotPath, { force: true }).catch((cause) => {
|
|
35
|
+
// best-effort cleanup: snapshot removal must not mask the copy failure.
|
|
36
|
+
void cause;
|
|
37
|
+
});
|
|
24
38
|
throw cause;
|
|
25
39
|
}
|
|
26
40
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { access, open } from "node:fs/promises";
|
|
2
|
+
import { readWindowsPrivateRuntimeFile } from "../windows/WindowsPrivateRuntime.js";
|
|
2
3
|
import { err, ok } from "../domain/result.js";
|
|
3
4
|
import { GhidraSessionError } from "./GhidraSessionError.js";
|
|
4
5
|
/** Observe a ready endpoint, returning null while its bridge is not listening. */
|
|
@@ -14,6 +15,16 @@ export const observeGhidraEndpoint = async (endpoint) => {
|
|
|
14
15
|
: err(endpointFailure(endpoint, "Ghidra socket observation failed", cause));
|
|
15
16
|
}
|
|
16
17
|
}
|
|
18
|
+
if (process.platform === "win32") {
|
|
19
|
+
try {
|
|
20
|
+
return parseTcpEndpoint(endpoint, readWindowsPrivateRuntimeFile(endpoint.path));
|
|
21
|
+
}
|
|
22
|
+
catch (cause) {
|
|
23
|
+
return isMissing(cause) || isWindowsEndpointWriterBusy(cause)
|
|
24
|
+
? ok(null)
|
|
25
|
+
: err(endpointFailure(endpoint, "Ghidra endpoint observation failed", cause));
|
|
26
|
+
}
|
|
27
|
+
}
|
|
17
28
|
let handle;
|
|
18
29
|
try {
|
|
19
30
|
handle = await open(endpoint.path, "r");
|
|
@@ -66,3 +77,4 @@ const endpointFailure = (endpoint, message, cause) => new GhidraSessionError("st
|
|
|
66
77
|
...(cause instanceof Error ? { error: cause.message } : {}),
|
|
67
78
|
}, cause instanceof Error ? { cause } : undefined);
|
|
68
79
|
const isMissing = (cause) => cause instanceof Error && "code" in cause && cause.code === "ENOENT";
|
|
80
|
+
const isWindowsEndpointWriterBusy = (cause) => cause instanceof Error && "win32Code" in cause && cause.win32Code === 32;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { AnalysisCapabilityUnavailableError } from "../../domain/analysisErrorCore.js";
|
|
2
|
+
import { ProviderAdapterError } from "../../domain/providerAdapterError.js";
|
|
3
|
+
import { jsonValueSchema } from "../../domain/jsonValue.js";
|
|
4
|
+
import { validateGhidraExtensionResults, } from "./GhidraExtensions.js";
|
|
5
|
+
/** Preserve unsupported recovery separately from malformed or failed producers. */
|
|
6
|
+
export const ghidraExtensionFailure = (extensions, results, operation) => {
|
|
7
|
+
const reports = results;
|
|
8
|
+
const invalid = validateGhidraExtensionResults(extensions, reports);
|
|
9
|
+
const failed = reports.find((value) => value.status === "unsupported" || value.status === "failed");
|
|
10
|
+
if (invalid === null && failed === undefined)
|
|
11
|
+
return undefined;
|
|
12
|
+
return invalid === null && failed?.status === "unsupported"
|
|
13
|
+
? new AnalysisCapabilityUnavailableError("ghidra", operation, `${failed.id}: ${failed.reason}. Omit REA_GHIDRA_NATIVEAOT_JAR to continue ordinary native analysis.`)
|
|
14
|
+
: new ProviderAdapterError("ghidra", operation, {
|
|
15
|
+
diagnostics: {
|
|
16
|
+
reason: invalid ?? failed?.reason ?? "Ghidra extension failed",
|
|
17
|
+
analysis_extensions: jsonValueSchema.parse(reports),
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
};
|