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,11 +1,13 @@
|
|
|
1
1
|
import { mkdir } from "node:fs/promises";
|
|
2
2
|
import { basename, dirname, join, win32 } from "node:path";
|
|
3
3
|
import writeFileAtomic from "write-file-atomic";
|
|
4
|
-
import {
|
|
4
|
+
import { windowsPrivateRuntime } from "../windows/WindowsPrivateRuntime.js";
|
|
5
|
+
import { AnalysisCancelledError } from "../domain/analysisErrorCore.js";
|
|
5
6
|
import { err, ok } from "../domain/result.js";
|
|
6
7
|
import { cleanupOwnedProcessGroup, cleanupWindowsProcessTree, } from "../process/ProcessOwnership.js";
|
|
7
8
|
import { spawnOwnedProviderProcess, } from "../process/ProviderProcess.js";
|
|
8
9
|
import { ghidraJavaEnvironment } from "./GhidraInstallation.js";
|
|
10
|
+
import { snapshotGhidraExtensions, } from "./extensions/GhidraExtensions.js";
|
|
9
11
|
/** Local launch failure retained as the cause of a provider-neutral error. */
|
|
10
12
|
export class GhidraLaunchError extends Error {
|
|
11
13
|
constructor(message, options) {
|
|
@@ -26,15 +28,9 @@ export class GhidraHeadlessLauncher {
|
|
|
26
28
|
const platform = this.options.platform ?? process.platform;
|
|
27
29
|
let started;
|
|
28
30
|
try {
|
|
29
|
-
await
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
paths.tempRoot,
|
|
33
|
-
paths.cacheRoot,
|
|
34
|
-
paths.configRoot,
|
|
35
|
-
paths.dataRoot,
|
|
36
|
-
].map((path) => mkdir(path, { recursive: true, mode: 0o700 })));
|
|
37
|
-
await writeFileAtomic(paths.descriptorPath, `${JSON.stringify({
|
|
31
|
+
await createGhidraRuntimeDirectories(paths, platform);
|
|
32
|
+
const extensions = await snapshotGhidraExtensions(this.options.analysisExtensions ?? [], session.runtimeRoot);
|
|
33
|
+
await writeGhidraRuntimeFile(paths.descriptorPath, `${JSON.stringify({
|
|
38
34
|
transport: session.transport,
|
|
39
35
|
endpoint_path: session.endpointPath,
|
|
40
36
|
token: session.token,
|
|
@@ -42,7 +38,10 @@ export class GhidraHeadlessLauncher {
|
|
|
42
38
|
target_sha256: session.targetSha256,
|
|
43
39
|
provider_version: session.providerVersion,
|
|
44
40
|
profile_digest: session.profileDigest,
|
|
45
|
-
|
|
41
|
+
...(extensions.length === 0
|
|
42
|
+
? {}
|
|
43
|
+
: { analysis_extensions: extensions }),
|
|
44
|
+
})}\n`, platform);
|
|
46
45
|
if (isAborted(options.signal))
|
|
47
46
|
return err(new AnalysisCancelledError("open_binary"));
|
|
48
47
|
const headlessArguments = ghidraHeadlessArguments({
|
|
@@ -52,6 +51,9 @@ export class GhidraHeadlessLauncher {
|
|
|
52
51
|
descriptorPath: paths.descriptorPath,
|
|
53
52
|
ghidraLogPath: paths.ghidraLogPath,
|
|
54
53
|
scriptLogPath: paths.scriptLogPath,
|
|
54
|
+
...(this.options.dosCom === undefined
|
|
55
|
+
? {}
|
|
56
|
+
: { dosCom: this.options.dosCom }),
|
|
55
57
|
...(this.options.dosMz === undefined
|
|
56
58
|
? {}
|
|
57
59
|
: { dosMz: this.options.dosMz }),
|
|
@@ -75,17 +77,15 @@ export class GhidraHeadlessLauncher {
|
|
|
75
77
|
platform,
|
|
76
78
|
env: ghidraLaunchEnvironment(paths, this.options.javaHome, platform),
|
|
77
79
|
});
|
|
78
|
-
await
|
|
80
|
+
await writeGhidraRuntimeFile(paths.ownershipPath, `${JSON.stringify({
|
|
79
81
|
run_id: session.runId,
|
|
80
82
|
pid: started.ownership.leaderPid,
|
|
81
83
|
process_group_id: started.ownership.processGroupId,
|
|
82
84
|
parent_pid: process.pid,
|
|
83
|
-
ownership_kind: platform === "win32"
|
|
84
|
-
? "windows-process-tree-p0"
|
|
85
|
-
: "posix-process-group",
|
|
85
|
+
ownership_kind: platform === "win32" ? "windows-job-object" : "posix-process-group",
|
|
86
86
|
launcher: this.options.analyzeHeadlessPath,
|
|
87
87
|
created_at: new Date().toISOString(),
|
|
88
|
-
})}\n`,
|
|
88
|
+
})}\n`, platform);
|
|
89
89
|
if (isAborted(options.signal)) {
|
|
90
90
|
await cleanupStartedProcess(started, platform);
|
|
91
91
|
return err(new AnalysisCancelledError("open_binary"));
|
|
@@ -100,7 +100,10 @@ export class GhidraHeadlessLauncher {
|
|
|
100
100
|
}
|
|
101
101
|
catch (cause) {
|
|
102
102
|
if (started !== undefined)
|
|
103
|
-
await cleanupStartedProcess(started, platform).catch(() =>
|
|
103
|
+
await cleanupStartedProcess(started, platform).catch((cause) => {
|
|
104
|
+
// best-effort cleanup: started-process cleanup must not mask the launch failure.
|
|
105
|
+
void cause;
|
|
106
|
+
});
|
|
104
107
|
return isAborted(options.signal)
|
|
105
108
|
? err(new AnalysisCancelledError("open_binary"))
|
|
106
109
|
: err(new GhidraLaunchError("Ghidra headless launch failed", { cause }));
|
|
@@ -146,9 +149,11 @@ const quoteWindowsBatchToken = (value) => {
|
|
|
146
149
|
throw new GhidraLaunchError("Windows Ghidra P0 paths cannot contain command-interpreter metacharacters");
|
|
147
150
|
return `"${value}"`;
|
|
148
151
|
};
|
|
149
|
-
const cleanupStartedProcess = (started, platform) =>
|
|
150
|
-
?
|
|
151
|
-
:
|
|
152
|
+
const cleanupStartedProcess = (started, platform) => started.cleanup !== undefined
|
|
153
|
+
? started.cleanup()
|
|
154
|
+
: platform === "win32"
|
|
155
|
+
? cleanupWindowsProcessTree(started.ownership.leaderPid)
|
|
156
|
+
: cleanupOwnedProcessGroup(started.ownership);
|
|
152
157
|
/** Build the complete read-only headless invocation in deterministic order. */
|
|
153
158
|
export const ghidraHeadlessArguments = (options) => [
|
|
154
159
|
options.projectRoot,
|
|
@@ -164,7 +169,18 @@ export const ghidraHeadlessArguments = (options) => [
|
|
|
164
169
|
"-cspec",
|
|
165
170
|
"default",
|
|
166
171
|
]
|
|
167
|
-
:
|
|
172
|
+
: options.dosCom === true
|
|
173
|
+
? [
|
|
174
|
+
"-loader",
|
|
175
|
+
"BinaryLoader",
|
|
176
|
+
"-loader-baseAddr",
|
|
177
|
+
"1000:0100",
|
|
178
|
+
"-processor",
|
|
179
|
+
"x86:LE:16:Real Mode",
|
|
180
|
+
"-cspec",
|
|
181
|
+
"default",
|
|
182
|
+
]
|
|
183
|
+
: []),
|
|
168
184
|
"-readOnly",
|
|
169
185
|
"-deleteProject",
|
|
170
186
|
"-log",
|
|
@@ -173,6 +189,9 @@ export const ghidraHeadlessArguments = (options) => [
|
|
|
173
189
|
options.scriptLogPath,
|
|
174
190
|
"-scriptPath",
|
|
175
191
|
dirname(options.bridgeScriptPath),
|
|
192
|
+
...(options.dosCom === true
|
|
193
|
+
? ["-preScript", "ReaGhidraPrepareCom.java"]
|
|
194
|
+
: []),
|
|
176
195
|
"-postScript",
|
|
177
196
|
basename(options.bridgeScriptPath),
|
|
178
197
|
options.descriptorPath,
|
|
@@ -189,18 +208,47 @@ const ghidraRuntimePaths = (runtimeRoot) => ({
|
|
|
189
208
|
ghidraLogPath: join(runtimeRoot, "ghidra.log"),
|
|
190
209
|
scriptLogPath: join(runtimeRoot, "script.log"),
|
|
191
210
|
});
|
|
211
|
+
const createGhidraRuntimeDirectories = async (paths, platform) => {
|
|
212
|
+
if (platform === "win32") {
|
|
213
|
+
const runtime = windowsPrivateRuntime(dirname(paths.projectRoot));
|
|
214
|
+
for (const path of [
|
|
215
|
+
paths.projectRoot,
|
|
216
|
+
paths.homeRoot,
|
|
217
|
+
paths.tempRoot,
|
|
218
|
+
paths.cacheRoot,
|
|
219
|
+
paths.configRoot,
|
|
220
|
+
paths.dataRoot,
|
|
221
|
+
])
|
|
222
|
+
runtime.mkdir(basename(path));
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
await Promise.all([
|
|
226
|
+
paths.projectRoot,
|
|
227
|
+
paths.homeRoot,
|
|
228
|
+
paths.tempRoot,
|
|
229
|
+
paths.cacheRoot,
|
|
230
|
+
paths.configRoot,
|
|
231
|
+
paths.dataRoot,
|
|
232
|
+
].map((path) => mkdir(path, { recursive: true, mode: 0o700 })));
|
|
233
|
+
};
|
|
234
|
+
const writeGhidraRuntimeFile = async (path, content, platform) => {
|
|
235
|
+
if (platform === "win32") {
|
|
236
|
+
windowsPrivateRuntime(dirname(path)).writeFile(basename(path), content);
|
|
237
|
+
return;
|
|
238
|
+
}
|
|
239
|
+
await writeFileAtomic(path, content, { encoding: "utf8", mode: 0o600 });
|
|
240
|
+
};
|
|
192
241
|
const ghidraLaunchEnvironment = (paths, javaHome, platform) => {
|
|
193
|
-
// analyzeHeadless.bat wraps GHIDRA_HEADLESS_JAVA_OPTIONS in its own quotes
|
|
194
|
-
// when it builds VMARG_LIST. Nested quotes break cmd.exe tokenization before
|
|
195
|
-
// Ghidra starts, so keep this option list unquoted on every platform.
|
|
196
|
-
const javaOptions = `-Duser.home=${paths.homeRoot} -Djava.io.tmpdir=${paths.tempRoot}`;
|
|
197
242
|
return {
|
|
198
243
|
...ghidraJavaEnvironment(javaHome, process.env, platform),
|
|
244
|
+
...ghidraHeadlessJavaOptions(paths.homeRoot, paths.tempRoot, platform),
|
|
199
245
|
HOME: paths.homeRoot,
|
|
200
246
|
TMPDIR: paths.tempRoot,
|
|
201
247
|
...(platform === "win32"
|
|
202
248
|
? {
|
|
203
249
|
USERPROFILE: paths.homeRoot,
|
|
250
|
+
APPDATA: paths.configRoot,
|
|
251
|
+
LOCALAPPDATA: paths.cacheRoot,
|
|
204
252
|
TEMP: paths.tempRoot,
|
|
205
253
|
TMP: paths.tempRoot,
|
|
206
254
|
}
|
|
@@ -208,7 +256,24 @@ const ghidraLaunchEnvironment = (paths, javaHome, platform) => {
|
|
|
208
256
|
XDG_CACHE_HOME: paths.cacheRoot,
|
|
209
257
|
XDG_CONFIG_HOME: paths.configRoot,
|
|
210
258
|
XDG_DATA_HOME: paths.dataRoot,
|
|
211
|
-
GHIDRA_HEADLESS_JAVA_OPTIONS: javaOptions,
|
|
212
259
|
};
|
|
213
260
|
};
|
|
261
|
+
/** Encode provider-owned JVM paths for the parser that actually consumes them. */
|
|
262
|
+
export const ghidraHeadlessJavaOptions = (homeRoot, tempRoot, platform) => {
|
|
263
|
+
const options = [`-Duser.home=${homeRoot}`, `-Djava.io.tmpdir=${tempRoot}`];
|
|
264
|
+
// analyzeHeadless.bat quotes VMARG_LIST, then launch.bat expands it again.
|
|
265
|
+
// Inner quotes fail in cmd.exe; unquoted paths with spaces split at the JVM.
|
|
266
|
+
// JDK_JAVA_OPTIONS is parsed by Java itself, outside that batch expansion.
|
|
267
|
+
return platform === "win32"
|
|
268
|
+
? {
|
|
269
|
+
JDK_JAVA_OPTIONS: [...options, "-XX:-UsePerfData"]
|
|
270
|
+
.map(quoteWindowsBatchToken)
|
|
271
|
+
.join(" "),
|
|
272
|
+
GHIDRA_HEADLESS_JAVA_OPTIONS: "",
|
|
273
|
+
}
|
|
274
|
+
: {
|
|
275
|
+
JDK_JAVA_OPTIONS: "",
|
|
276
|
+
GHIDRA_HEADLESS_JAVA_OPTIONS: options.join(" "),
|
|
277
|
+
};
|
|
278
|
+
};
|
|
214
279
|
const isAborted = (signal) => signal?.aborted === true;
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { nativeLoadImageSchema, } from "../domain/nativeLoadImage.js";
|
|
3
|
+
import { parseDosMzHeader } from "../domain/dosMz.js";
|
|
4
|
+
import { validateDosComLength } from "../domain/dosCom.js";
|
|
5
|
+
import { err, ok } from "../domain/result.js";
|
|
6
|
+
const sha256 = (bytes) => createHash("sha256").update(bytes).digest("hex");
|
|
7
|
+
const address = (offset) => `0x${offset.toString(16)}`;
|
|
8
|
+
const limitations = [
|
|
9
|
+
"Verification covers original/modified FileBytes, every initialized target-backed header/module mapping, relocation records and the external entry point. Mapping ends are inclusive.",
|
|
10
|
+
"Appended overlay bytes are identified by file extent and included in FileBytes identity; they must not be mapped as initialized header/module memory. Uninitialized allocations are reported but their contents and DOS runtime behavior are not verified.",
|
|
11
|
+
"The fixed load segment 0x1000 describes Ghidra's analysis image, not a running DOS process. Verified import does not establish original source ownership or recovered program behavior.",
|
|
12
|
+
"A mismatching memory digest identifies the reported source range; it does not locate the first differing byte inside that range.",
|
|
13
|
+
];
|
|
14
|
+
/** Verify measured MZ import state against the session's immutable snapshot. */
|
|
15
|
+
export const attestGhidraDosLoadImage = (bytes, targetSha256, observations) => {
|
|
16
|
+
if (sha256(bytes) !== targetSha256)
|
|
17
|
+
return err("Ghidra load-image snapshot digest does not match the admitted target");
|
|
18
|
+
const parsed = parseDosMzHeader(bytes);
|
|
19
|
+
if (!parsed.ok)
|
|
20
|
+
return parsed;
|
|
21
|
+
const header = parsed.value;
|
|
22
|
+
const loadSegment = 0x1000;
|
|
23
|
+
const modified = Buffer.from(bytes);
|
|
24
|
+
const expectedRelocations = [];
|
|
25
|
+
for (let index = 0; index < header.relocationCount; index += 1) {
|
|
26
|
+
const table = header.relocationTableOffset + index * 4;
|
|
27
|
+
const offset = bytes.readUInt16LE(table);
|
|
28
|
+
const segment = bytes.readUInt16LE(table + 2);
|
|
29
|
+
const fileOffset = header.headerBytes + segment * 16 + offset;
|
|
30
|
+
const original = modified
|
|
31
|
+
.subarray(fileOffset, fileOffset + 2)
|
|
32
|
+
.toString("hex");
|
|
33
|
+
const relocated = (modified.readUInt16LE(fileOffset) + loadSegment) & 0xffff;
|
|
34
|
+
modified.writeUInt16LE(relocated, fileOffset);
|
|
35
|
+
expectedRelocations.push({
|
|
36
|
+
address: address(loadSegment * 16 + segment * 16 + offset),
|
|
37
|
+
segment: (loadSegment + segment) & 0xffff,
|
|
38
|
+
offset,
|
|
39
|
+
status: "APPLIED",
|
|
40
|
+
type: 0,
|
|
41
|
+
values: [segment, offset, relocated],
|
|
42
|
+
original_bytes_hex: original,
|
|
43
|
+
memory_bytes_hex: modified
|
|
44
|
+
.subarray(fileOffset, fileOffset + 2)
|
|
45
|
+
.toString("hex"),
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
const checks = [];
|
|
49
|
+
const check = (name, expected, observed, fileOffset = null, location = null) => {
|
|
50
|
+
checks.push({
|
|
51
|
+
name,
|
|
52
|
+
matched: JSON.stringify(expected) === JSON.stringify(observed),
|
|
53
|
+
expected,
|
|
54
|
+
observed,
|
|
55
|
+
file_offset: fileOffset,
|
|
56
|
+
address: location,
|
|
57
|
+
});
|
|
58
|
+
};
|
|
59
|
+
check("executable_format", "Old-style DOS Executable (MZ)", observations.executable_format);
|
|
60
|
+
check("language_id", "x86:LE:16:Real Mode", observations.language_id);
|
|
61
|
+
check("compiler_spec_id", "default", observations.compiler_spec_id);
|
|
62
|
+
check("image_base", "0x0", observations.image_base);
|
|
63
|
+
check("default_address_space", "ram", observations.default_address_space);
|
|
64
|
+
check("source_file_count", 1, observations.source_files.length);
|
|
65
|
+
const source = observations.source_files[0];
|
|
66
|
+
check("source_file_size", bytes.length, source?.size ?? null);
|
|
67
|
+
check("original_file_sha256", targetSha256, source?.original_sha256 ?? null);
|
|
68
|
+
check("modified_file_sha256", sha256(modified), source?.modified_sha256 ?? null);
|
|
69
|
+
const entryAddress = address(((loadSegment + header.entrySegment) & 0xffff) * 16 + header.entryOffset);
|
|
70
|
+
check("entry_points", [entryAddress], [...observations.entry_points].sort());
|
|
71
|
+
// A multiset preserves duplicate relocations and aliases; iteration order is not semantic.
|
|
72
|
+
const rows = (values) => values
|
|
73
|
+
.map(({ segment: _segment, offset: _offset, ...value }) => JSON.stringify(value))
|
|
74
|
+
.sort();
|
|
75
|
+
check("relocation_address_aliases", [], observations.relocations.filter((row) => row.segment === null ||
|
|
76
|
+
row.offset === null ||
|
|
77
|
+
address(row.segment * 16 + row.offset) !== row.address));
|
|
78
|
+
check("relocation_records", rows(expectedRelocations), rows(observations.relocations));
|
|
79
|
+
checkMappings(header, loadSegment * 16, bytes, modified, observations, check);
|
|
80
|
+
return ok(nativeLoadImageSchema.parse({
|
|
81
|
+
status: checks.every((item) => item.matched) ? "verified" : "mismatch",
|
|
82
|
+
format: "dos-mz",
|
|
83
|
+
target_sha256: targetSha256,
|
|
84
|
+
load_segment: loadSegment,
|
|
85
|
+
header_bytes: header.headerBytes,
|
|
86
|
+
module_bytes: header.moduleBytes,
|
|
87
|
+
overlay_bytes: header.overlayBytes,
|
|
88
|
+
entry: {
|
|
89
|
+
relative_segment: header.entrySegment,
|
|
90
|
+
offset: header.entryOffset,
|
|
91
|
+
linear_address: entryAddress,
|
|
92
|
+
},
|
|
93
|
+
observations,
|
|
94
|
+
checks,
|
|
95
|
+
limitations,
|
|
96
|
+
}));
|
|
97
|
+
};
|
|
98
|
+
const checkMappings = (header, loadBase, bytes, modified, observations, check) => {
|
|
99
|
+
const backed = observations.mappings.filter((mapping) => mapping.source_file_index !== null);
|
|
100
|
+
const sorted = [...backed].sort((left, right) => (left.file_offset ?? -1) - (right.file_offset ?? -1));
|
|
101
|
+
let covered = 0;
|
|
102
|
+
for (let index = 0; index < sorted.length; index += 1) {
|
|
103
|
+
const mapping = sorted[index];
|
|
104
|
+
if (mapping === undefined)
|
|
105
|
+
continue;
|
|
106
|
+
const start = mapping.file_offset;
|
|
107
|
+
const end = start === null ? null : start + mapping.length;
|
|
108
|
+
const headerMapping = start !== null && end !== null && start >= 0 && end <= header.headerBytes;
|
|
109
|
+
const moduleMapping = start !== null &&
|
|
110
|
+
end !== null &&
|
|
111
|
+
start >= header.headerBytes &&
|
|
112
|
+
end <= header.imageBytes;
|
|
113
|
+
const at = `mapping[${index}]`;
|
|
114
|
+
check(`${at}.source_file_index`, 0, mapping.source_file_index, start, mapping.start);
|
|
115
|
+
check(`${at}.file_coverage_start`, covered, start, start, mapping.start);
|
|
116
|
+
check(`${at}.partition`, true, headerMapping || moduleMapping, start, mapping.start);
|
|
117
|
+
check(`${at}.initialized`, true, mapping.initialized, start, mapping.start);
|
|
118
|
+
check(`${at}.loaded`, moduleMapping, mapping.loaded, start, mapping.start);
|
|
119
|
+
check(`${at}.overlay`, headerMapping, mapping.overlay, start, mapping.start);
|
|
120
|
+
check(`${at}.address_space`, headerMapping ? "HEADER" : observations.default_address_space, mapping.address_space, start, mapping.start);
|
|
121
|
+
const expectedStart = start === null
|
|
122
|
+
? null
|
|
123
|
+
: headerMapping
|
|
124
|
+
? `HEADER:${address(start)}`
|
|
125
|
+
: address(loadBase + start - header.headerBytes);
|
|
126
|
+
const expectedEnd = start === null
|
|
127
|
+
? null
|
|
128
|
+
: headerMapping
|
|
129
|
+
? `HEADER:${address(start + mapping.length - 1)}`
|
|
130
|
+
: address(loadBase + start - header.headerBytes + mapping.length - 1);
|
|
131
|
+
check(`${at}.start`, expectedStart, mapping.start, start, mapping.start);
|
|
132
|
+
check(`${at}.end`, expectedEnd, mapping.end, start, mapping.end);
|
|
133
|
+
check(`${at}.memory_sha256`, start !== null && end !== null && end <= bytes.length
|
|
134
|
+
? sha256(modified.subarray(start, end))
|
|
135
|
+
: null, mapping.sha256, start, mapping.start);
|
|
136
|
+
covered = end ?? covered;
|
|
137
|
+
}
|
|
138
|
+
check("initialized_file_coverage_end", header.imageBytes, covered);
|
|
139
|
+
check("initialized_unbacked_mappings", [], observations.mappings.filter((mapping) => mapping.initialized && mapping.source_file_index === null));
|
|
140
|
+
};
|
|
141
|
+
/** Verify the explicit DOS COM interpretation against measured bytes and context. */
|
|
142
|
+
export const attestGhidraDosComLoadImage = (bytes, targetSha256, observations) => {
|
|
143
|
+
if (sha256(bytes) !== targetSha256)
|
|
144
|
+
return err("Ghidra COM snapshot digest does not match the admitted target");
|
|
145
|
+
const length = validateDosComLength(bytes.length);
|
|
146
|
+
if (!length.ok)
|
|
147
|
+
return length;
|
|
148
|
+
const checks = [];
|
|
149
|
+
const check = (name, expected, observed, fileOffset = null, location = null) => {
|
|
150
|
+
checks.push({
|
|
151
|
+
name,
|
|
152
|
+
matched: JSON.stringify(expected) === JSON.stringify(observed),
|
|
153
|
+
expected,
|
|
154
|
+
observed,
|
|
155
|
+
file_offset: fileOffset,
|
|
156
|
+
address: location,
|
|
157
|
+
});
|
|
158
|
+
};
|
|
159
|
+
const source = observations.source_files[0];
|
|
160
|
+
check("executable_format", "Raw Binary", observations.executable_format);
|
|
161
|
+
check("language_id", "x86:LE:16:Real Mode", observations.language_id);
|
|
162
|
+
check("compiler_spec_id", "default", observations.compiler_spec_id);
|
|
163
|
+
check("image_base", "0x0", observations.image_base);
|
|
164
|
+
check("default_address_space", "ram", observations.default_address_space);
|
|
165
|
+
check("source_file_count", 1, observations.source_files.length);
|
|
166
|
+
check("source_file_size", bytes.length, source?.size ?? null);
|
|
167
|
+
check("original_file_sha256", targetSha256, source?.original_sha256 ?? null);
|
|
168
|
+
check("modified_file_sha256", targetSha256, source?.modified_sha256 ?? null);
|
|
169
|
+
check("entry_points", ["0x10100"], [...observations.entry_points].sort());
|
|
170
|
+
check("entry_context", [
|
|
171
|
+
{
|
|
172
|
+
address: "0x10100",
|
|
173
|
+
registers: ["CS", "DS", "ES", "SS"].map((name) => ({
|
|
174
|
+
name,
|
|
175
|
+
value_hex: "0x1000",
|
|
176
|
+
})),
|
|
177
|
+
},
|
|
178
|
+
], observations.entry_context);
|
|
179
|
+
check("relocation_records", [], observations.relocations);
|
|
180
|
+
checkMappings({ headerBytes: 0, imageBytes: bytes.length }, 0x10100, bytes, bytes, observations, check);
|
|
181
|
+
return ok(nativeLoadImageSchema.parse({
|
|
182
|
+
status: checks.every((item) => item.matched) ? "verified" : "mismatch",
|
|
183
|
+
format: "dos-com",
|
|
184
|
+
target_sha256: targetSha256,
|
|
185
|
+
load_segment: 0x1000,
|
|
186
|
+
header_bytes: 0,
|
|
187
|
+
module_bytes: bytes.length,
|
|
188
|
+
overlay_bytes: 0,
|
|
189
|
+
entry: { relative_segment: 0, offset: 0x100, linear_address: "0x10100" },
|
|
190
|
+
observations,
|
|
191
|
+
checks,
|
|
192
|
+
limitations: [
|
|
193
|
+
"DOS COM is a headerless interpretation explicitly selected by the caller, not format identification from file bytes.",
|
|
194
|
+
"Verification covers complete original/modified source identity, mapped file bytes, entry and measured CS/DS/ES/SS entry context. Context 0x1000 is imposed for analysis; it is not an observed running process.",
|
|
195
|
+
"The PSP, initial stack contents/registers, DOS interrupts, PC-98 devices and runtime behavior are not modeled or verified. No original executable bytes are changed.",
|
|
196
|
+
"Mapping ends are inclusive; a mismatching digest identifies its source range, not the first differing byte.",
|
|
197
|
+
],
|
|
198
|
+
}));
|
|
199
|
+
};
|