rea-agents 3.2.0 → 4.0.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 +183 -332
- package/bridge/ghidra/ReaGhidraBridge.java +561 -74
- package/bridge/hopper_bridge.py +70 -27
- package/bridge/native/ReaNativeUI.swift +157 -0
- package/dist/application/AnalysisContextQueries.js +19 -5
- package/dist/application/AnalysisSnapshotCache.js +30 -11
- package/dist/application/AppleAssetCatalogAnalysis.js +171 -0
- package/dist/application/ArtifactExtractionDestination.js +0 -12
- package/dist/application/ArtifactGraphConstruction.js +44 -11
- package/dist/application/ArtifactInventory/classify.js +7 -15
- package/dist/application/ArtifactInventory/hash.js +4 -2
- package/dist/application/ArtifactInventory/policy.js +2 -17
- package/dist/application/ArtifactInventory/reader.js +3 -3
- package/dist/application/ArtifactInventory/scanCanonical.js +2 -2
- package/dist/application/ArtifactInventory/scanReader.js +12 -4
- package/dist/application/ArtifactInventory/types.js +0 -3
- package/dist/application/BinarySession.js +28 -43
- package/dist/application/BinarySessionExecution.js +37 -1
- package/dist/application/BinaryTargetResolver.js +50 -4
- package/dist/application/BrowserEvidence.js +36 -7
- package/dist/application/BrowserObservationService.js +17 -44
- package/dist/application/BrowserScenarioCaptureService.js +2 -35
- package/dist/application/BrowserScenarioEvidence.js +13 -9
- package/dist/application/CapabilityClientRequirements.js +2 -11
- package/dist/application/CapabilityInventory.js +21 -35
- package/dist/application/ClientConfigurationDocument.js +84 -7
- package/dist/application/ClientRegistrationIdentity.js +32 -0
- package/dist/application/ClientRegistrationStatus.js +59 -6
- package/dist/application/DirectAnalysis.js +37 -58
- package/dist/application/DirectAnalysisStatus.js +4 -4
- package/dist/application/Doctor.js +89 -80
- package/dist/application/DoctorDiagnostics.js +2 -26
- package/dist/application/DoctorScope.js +8 -14
- package/dist/application/ElectronActiveEvidence.js +10 -27
- package/dist/application/ElectronActiveObservationService.js +9 -36
- package/dist/application/ElectronBoundaryAnalysis.js +2 -0
- package/dist/application/ElectronBoundaryGraphNative.js +1 -1
- package/dist/application/ElectronEvidence.js +8 -3
- package/dist/application/ElectronObservationService.js +9 -25
- package/dist/application/EnhancedLiteralTracing.js +4 -8
- package/dist/application/EnhancedTools.js +15 -35
- package/dist/application/FilesystemSnapshot.js +7 -8
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +2 -1
- package/dist/application/JavaScriptApplicationWorkflowService.js +31 -7
- package/dist/application/JavaScriptArtifactAnalysis.js +6 -4
- package/dist/application/JavaScriptArtifactFiles.js +5 -0
- package/dist/application/JavaScriptArtifactPathResolution.js +179 -47
- package/dist/application/JavaScriptRuntimeObservationEvidence.js +6 -3
- package/dist/application/JavaScriptRuntimeObservationService.js +9 -25
- package/dist/application/JavaScriptRuntimeReconciliationService.js +45 -4
- package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphDataProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +14 -5
- package/dist/application/JsonFiles.js +1 -1
- package/dist/application/LazyAnalysisProvider.js +27 -6
- package/dist/application/ManagedMemberComparisonService.js +19 -6
- package/dist/application/NativeApiInspection.js +2 -0
- package/dist/application/NativeCallRoutes.js +72 -0
- package/dist/application/NativeDispatchMetadataInspection.js +33 -0
- package/dist/application/NativeUiActionTrace.js +73 -49
- package/dist/application/NativeValueTrace.js +320 -0
- package/dist/application/ProcessCaptureCapability.js +32 -5
- package/dist/application/ProcessCaptureEnvironment.js +9 -26
- package/dist/application/ProcessCaptureError.js +1 -5
- package/dist/application/ProcessCaptureJournal.js +3 -40
- package/dist/application/ProcessCaptureLifecycle.js +102 -111
- package/dist/application/ProcessCli.js +18 -25
- package/dist/application/ProcessEvidence.js +5 -7
- package/dist/application/ProcessFilesystemEffects.js +36 -0
- package/dist/application/ProcessHarness.js +41 -120
- package/dist/application/ProcessNormalization.js +2 -17
- package/dist/application/ProcessScenarioRuntimeValidation.js +76 -0
- package/dist/application/ReferenceSourceImport.js +3 -4
- package/dist/application/Setup.js +236 -84
- package/dist/application/SetupClientConfiguration.js +14 -9
- package/dist/application/SetupPlan.js +138 -86
- package/dist/application/SetupSkill.js +0 -1
- package/dist/application/SupportedClients.js +102 -21
- package/dist/application/Uninstall.js +31 -20
- package/dist/application/Update.js +93 -0
- package/dist/application/UpdateMaintenance.js +108 -0
- package/dist/application/UpdateRuntime.js +126 -0
- package/dist/application/runtime.js +13 -2
- package/dist/artifacts/ArtifactPaths.js +6 -8
- package/dist/artifacts/ArtifactProvider.js +94 -41
- package/dist/artifacts/AsarArtifactReader.js +19 -4
- package/dist/artifacts/KeyedArchiveReader.js +110 -0
- package/dist/artifacts/MachOSliceArtifactReader.js +53 -5
- package/dist/artifacts/ZipArtifactReader.js +18 -1
- package/dist/browser/BrowserScenarioSecrets.js +28 -1
- package/dist/browser/CdpBrowserProvider.js +36 -15
- package/dist/browser/CdpCaptureDocuments.js +22 -8
- package/dist/browser/CdpCaptureEventHandlers.js +14 -5
- package/dist/browser/CdpCaptureEventHelpers.js +13 -0
- package/dist/browser/CdpCaptureEvents.js +10 -1
- package/dist/browser/CdpElectronInspection.js +5 -10
- package/dist/browser/CdpElectronProvider.js +1 -5
- package/dist/browser/CdpElectronScripts.js +1 -1
- package/dist/browser/CdpEndpoint.js +3 -2
- package/dist/browser/CdpObservationSession.js +14 -10
- package/dist/browser/CdpPageCapture.js +1 -1
- package/dist/browser/CdpPageCaptureScripts.js +1 -1
- package/dist/browser/CdpSafeMetadata.js +5 -4
- package/dist/browser/CdpScreenshot.js +16 -5
- package/dist/browser/CdpTargetSession.js +25 -4
- package/dist/browser/CdpWebMcpDiscovery.js +93 -20
- package/dist/browser/JavaScriptRuntimeScope.js +28 -2
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +9 -8
- package/dist/browser/PlaywrightElectronActiveActions.js +3 -10
- package/dist/browser/PlaywrightElectronActiveProvider.js +5 -5
- package/dist/browser/PlaywrightScenarioActions.js +1 -1
- package/dist/browser/PlaywrightScenarioArtifacts.js +13 -25
- package/dist/browser/PlaywrightScenarioBrowser.js +28 -25
- package/dist/browser/PlaywrightScenarioEvents.js +82 -93
- package/dist/browser/PlaywrightScenarioSession.js +27 -123
- package/dist/browser/PngVisualDiff.js +22 -3
- package/dist/browser/V8InspectorCaptureProjection.js +7 -1
- package/dist/browser/V8InspectorProvider.js +60 -7
- package/dist/browser/WebSourceMapFetcher.js +99 -53
- package/dist/cli/artifactCommands.js +56 -12
- package/dist/cli/coreAnalysisCommands.js +110 -0
- package/dist/cli/managedCommands.js +1 -31
- package/dist/cli/setupCommands.js +16 -14
- package/dist/cli/utilityCommands.js +61 -4
- package/dist/cli.js +5 -7
- package/dist/cliApplicationCommands.js +0 -83
- package/dist/cliBrowserAdvancedCommands.js +7 -11
- package/dist/cliBrowserCommands.js +15 -23
- package/dist/cliBrowserContext.js +3 -24
- package/dist/cliBrowserScenarioCommands.js +2 -10
- package/dist/cliCommandNames.js +82 -7
- package/dist/cliElectronCommands.js +10 -36
- package/dist/cliJavaScriptRuntimeCommands.js +6 -30
- package/dist/cliJsonInput.js +4 -2
- package/dist/cliLogging.js +16 -7
- package/dist/cliObservationOptions.js +1 -1
- package/dist/cliOutput.js +2 -4
- package/dist/cliProcessCommands.js +6 -33
- package/dist/cliSetup.js +90 -160
- package/dist/config/environment.js +2 -78
- package/dist/config/parseConfig.js +18 -109
- package/dist/config/parsers.js +0 -23
- package/dist/contracts/applicationToolContracts.js +1 -118
- package/dist/contracts/artifactToolContracts.js +11 -19
- package/dist/contracts/browserScenarioToolContracts.js +1 -5
- package/dist/contracts/browserToolContracts.js +9 -16
- package/dist/contracts/electronToolContracts.js +5 -6
- package/dist/contracts/enhancedInputs.js +3 -2
- package/dist/contracts/errorSchemas.js +16 -40
- package/dist/contracts/functionWorkflowToolContracts.js +2 -2
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +2 -2
- package/dist/contracts/javascriptRuntimeObservationToolContracts.js +4 -4
- package/dist/contracts/javascriptRuntimeReconciliationExample.js +1 -1
- package/dist/contracts/managedToolContracts.js +7 -4
- package/dist/contracts/managedWorkflowExamples.js +0 -22
- package/dist/contracts/managedWorkflowToolContracts.js +16 -31
- package/dist/contracts/nativeToolContracts.js +9 -0
- package/dist/contracts/promptContracts.js +6 -6
- package/dist/contracts/sessionToolSchemas.js +3 -3
- package/dist/contracts/toolContractExamples.js +4 -3
- package/dist/contracts/toolContracts.js +18 -7
- package/dist/contracts/toolEffects.js +34 -21
- package/dist/contracts/toolOutputSchemaGroups.js +18 -5
- package/dist/contracts/toolOutputSchemaPrimitives.js +9 -6
- package/dist/contracts/toolSchemaMetadata.js +5 -8
- package/dist/doctorRuntime.js +0 -41
- package/dist/domain/analysisErrorPresentation.js +4 -28
- package/dist/domain/analysisErrorProjection.js +33 -50
- package/dist/domain/analysisProfile.js +1 -1
- package/dist/domain/analysisSnapshot.js +77 -3
- package/dist/domain/androidApplication.js +5 -4
- package/dist/domain/appleApplication.js +5 -4
- package/dist/domain/appleAssetCatalog.js +127 -0
- package/dist/domain/artifactComparison.js +7 -11
- package/dist/domain/artifactGraph.js +8 -6
- package/dist/domain/artifactInspection.js +13 -12
- package/dist/domain/binaryTarget.js +23 -9
- package/dist/domain/browserObservation.js +43 -24
- package/dist/domain/browserObservationSchemas.js +2 -1
- package/dist/domain/browserScenario.js +7 -107
- package/dist/domain/browserScenarioCapture.js +0 -1
- package/dist/domain/browserScenarioCaptureValues.js +5 -4
- package/dist/domain/browserScenarioDiff.js +1 -3
- package/dist/domain/browserScenarioValues.js +16 -107
- package/dist/domain/bundleComparison.js +18 -17
- package/dist/domain/callPathSchemas.js +17 -7
- package/dist/domain/changedBehavior.js +2 -3
- package/dist/domain/comparisonSemantics.js +19 -0
- package/dist/domain/completionLedgerGeneration.js +3 -2
- package/dist/domain/conformancePackage.js +2 -1
- package/dist/domain/conformanceTrustGate.js +3 -5
- package/dist/domain/customProtocolCapture.js +2 -2
- package/dist/domain/digests.js +30 -0
- package/dist/domain/dosMz.js +83 -0
- package/dist/domain/electronActiveObservation.js +7 -5
- package/dist/domain/electronObservation.js +3 -2
- package/dist/domain/electronStaticAnalysisNative.js +15 -6
- package/dist/domain/emptyArraySchema.js +3 -0
- package/dist/domain/errors.js +10 -28
- package/dist/domain/evidence.js +5 -3
- package/dist/domain/evidenceCompletionLedger.js +3 -2
- package/dist/domain/functionComparisonNormalization.js +24 -18
- package/dist/domain/functionComparisonResults.js +3 -7
- package/dist/domain/functionComparisonSchemas.js +3 -2
- package/dist/domain/hopperValues.js +108 -8
- package/dist/domain/javascriptApplicationAnalysis.js +4 -7
- package/dist/domain/javascriptApplicationEvidenceSchemas.js +4 -3
- package/dist/domain/javascriptApplicationGraphSchemas.js +8 -7
- package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +9 -7
- package/dist/domain/javascriptApplicationVersionItems.js +12 -18
- package/dist/domain/javascriptAstValues.js +4 -0
- package/dist/domain/javascriptExportShapeComparison.js +1 -6
- package/dist/domain/javascriptExportShapeComparisonSchemas.js +6 -10
- package/dist/domain/javascriptExportShapeVariants.js +15 -2
- package/dist/domain/javascriptFeatureTraceSchemas.js +8 -7
- package/dist/domain/javascriptRuntimeObservation.js +14 -2
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +8 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +4 -2
- package/dist/domain/javascriptRuntimeReconciliationResult.js +6 -4
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +15 -4
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +19 -18
- package/dist/domain/javascriptRuntimeStaticCandidates.js +18 -6
- package/dist/domain/javascriptSemanticAnalysis.js +57 -19
- package/dist/domain/javascriptSemanticAsyncEffects.js +39 -40
- package/dist/domain/javascriptSemanticCalls.js +46 -27
- package/dist/domain/javascriptSemanticChildProcesses.js +43 -50
- package/dist/domain/javascriptSemanticDataEffectHelpers.js +91 -18
- package/dist/domain/javascriptSemanticDataEffects.js +22 -10
- package/dist/domain/javascriptSemanticGraphSchemas.js +8 -6
- package/dist/domain/javascriptSemanticObjects.js +13 -3
- package/dist/domain/javascriptSemanticProjection.js +144 -38
- package/dist/domain/javascriptSemanticPromises.js +14 -27
- package/dist/domain/javascriptSemanticQuerySchemas.js +6 -9
- package/dist/domain/javascriptSemanticResources.js +2 -5
- package/dist/domain/javascriptSemanticState.js +4 -0
- package/dist/domain/javascriptSemanticTraceSchemas.js +2 -1
- package/dist/domain/javascriptSemanticTraversal.js +13 -5
- package/dist/domain/javascriptSemanticValues.js +10 -9
- package/dist/domain/javascriptSourceParser.js +5 -1
- package/dist/domain/javascriptStaticAnalysisCalls.js +8 -5
- package/dist/domain/javascriptStaticAnalysisHelpers.js +16 -7
- package/dist/domain/keyedArchive.js +181 -0
- package/dist/domain/managedApplicationGraph.js +4 -3
- package/dist/domain/managedArtifact.js +2 -1
- package/dist/domain/managedMemberComparison.js +18 -13
- package/dist/domain/managedMemberComparisonCoverage.js +2 -1
- package/dist/domain/managedMemberComparisonItems.js +27 -7
- package/dist/domain/managedMemberComparisonMatch.js +22 -6
- package/dist/domain/managedNativeVerificationMatch.js +2 -2
- package/dist/domain/managedNativeVerificationSchemas.js +7 -5
- package/dist/domain/managedReconstruction.js +6 -5
- package/dist/domain/nativeApiBoundary.js +7 -0
- package/dist/domain/nativeDataType.js +51 -0
- package/dist/domain/nativeInspection.js +0 -1
- package/dist/domain/nativeInstruction.js +82 -0
- package/dist/domain/nativeInvestigationGraph.js +9 -5
- package/dist/domain/nativeUiObservation.js +123 -0
- package/dist/domain/nativeValueFlow.js +17 -0
- package/dist/domain/nativeValueTrace.js +64 -0
- package/dist/domain/objcSwiftMetadata.js +39 -0
- package/dist/domain/peInspection.js +1 -0
- package/dist/domain/processCapture.js +5 -55
- package/dist/domain/processCaptureExample.js +0 -9
- package/dist/domain/processCaptureValidation.js +13 -144
- package/dist/domain/processComparison.js +3 -25
- package/dist/domain/processObservation.js +0 -29
- package/dist/domain/processScenario.js +28 -228
- package/dist/domain/processTraceDimensionProjection.js +0 -15
- package/dist/domain/processTraceEvaluation.js +0 -6
- package/dist/domain/protocolCapture.js +8 -36
- package/dist/domain/reconstructionCoverage.js +3 -2
- package/dist/domain/reconstructionObligationLedgerSchemas.js +4 -12
- package/dist/domain/reconstructionReadinessSchemas.js +4 -3
- package/dist/domain/reconstructionVerification.js +2 -1
- package/dist/domain/reconstructionVerificationSchemas.js +6 -13
- package/dist/domain/referenceSourceClassification.js +0 -110
- package/dist/domain/referenceSourceGraph.js +15 -5
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/runtimeIdentification.js +6 -5
- package/dist/domain/sourceMapContents.js +5 -0
- package/dist/domain/sourceToBundleComparison.js +3 -10
- package/dist/domain/sourceToBundleComparisonSchemas.js +7 -6
- package/dist/domain/sourceToBundleSignals.js +9 -3
- package/dist/domain/staticRuntimeCorrelation.js +5 -11
- package/dist/domain/webBundleAnalysis.js +17 -9
- package/dist/domain/webBundleAnalyzer.js +1 -1
- package/dist/domain/webCaptureDiff.js +5 -11
- package/dist/domain/webCaptureDiffSchemas.js +2 -1
- package/dist/domain/webMcpDiscovery.js +2 -1
- package/dist/dotnet/ManagedMemberInspectorCore.js +15 -7
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +57 -40
- package/dist/dotnet/ManagedMemberRows.js +2 -0
- package/dist/dotnet/ManagedMethodBodyReader.js +15 -8
- package/dist/dotnet/ManagedPeReader.js +2 -0
- package/dist/generatedMcpToolCatalog.js +1 -1
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +15 -5
- package/dist/ghidra/GhidraClient.js +38 -8
- package/dist/ghidra/GhidraFunctionValues.js +56 -20
- package/dist/ghidra/GhidraInstallation.js +7 -4
- package/dist/ghidra/GhidraInventoryValues.js +44 -9
- package/dist/ghidra/GhidraLauncher.js +18 -3
- package/dist/ghidra/GhidraProvider.js +23 -2
- package/dist/ghidra/GhidraRequestQueue.js +45 -4
- package/dist/ghidra/GhidraSessionValues.js +5 -0
- package/dist/hopper/HopperAnalysisProfile.js +2 -0
- package/dist/hopper/HopperProvider.js +29 -6
- package/dist/hopper/HopperTargetLease.js +18 -4
- package/dist/logger.js +0 -13
- package/dist/main/messages.js +0 -1
- package/dist/main/reload.js +3 -32
- package/dist/main/shutdown.js +1 -2
- package/dist/main/transport.js +0 -17
- package/dist/main.js +0 -10
- package/dist/native/AppleDispatchMetadata.js +582 -0
- package/dist/native/AppleObjcProtocols.js +88 -0
- package/dist/native/AppleSwiftVtables.js +86 -0
- package/dist/native/CommandRunner.js +1 -1
- package/dist/native/NativeHostCapabilities.js +23 -0
- package/dist/native/NativeMacOSProvider.js +61 -9
- package/dist/native/NativeMachoInspection.js +39 -6
- package/dist/native/NativeUiHelperRuntime.js +42 -0
- package/dist/native/NativeUiObservation.js +174 -0
- package/dist/native/parsers/codesign.js +4 -1
- package/dist/native/parsers/dyldInfo.js +51 -25
- package/dist/native/parsers/lipo.js +13 -4
- package/dist/native/parsers/otool.js +84 -39
- package/dist/native/parsers/plist.js +2 -1
- package/dist/process/ExecFileOutput.js +5 -1
- package/dist/process/ProcessOwnership.js +69 -33
- package/dist/process/ProcessOwnershipObservation.js +31 -12
- package/dist/process/ProviderProcess.js +4 -2
- package/dist/reference/ReferenceSourceReaderEntries.js +48 -31
- package/dist/reference/ReferenceSourceReaderErrors.js +24 -0
- package/dist/reference/ReferenceSourceReaderFile.js +11 -5
- package/dist/reference/ReferenceSourceReaderValidate.js +22 -8
- package/dist/server/createServer.js +7 -62
- package/dist/server/registerApplicationTools/helpers.js +2 -9
- package/dist/server/registerApplicationTools.js +0 -4
- package/dist/server/registerArtifactComparisonTool.js +1 -1
- package/dist/server/registerBrowserScenarioTool.js +4 -2
- package/dist/server/registerBrowserTools.js +7 -7
- package/dist/server/registerBundleComparisonTool.js +1 -1
- package/dist/server/registerCloseLifecycleTool.js +1 -1
- package/dist/server/registerElectronTools.js +10 -4
- package/dist/server/registerEnhancedTools.js +20 -12
- package/dist/server/registerEvidenceTools.js +4 -28
- package/dist/server/registerFunctionComparisonTool.js +1 -1
- package/dist/server/registerInvestigationTools.js +6 -6
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -2
- package/dist/server/registerManagedTools.js +28 -14
- package/dist/server/registerManagedWorkflowTools.js +0 -2
- package/dist/server/registerProcessComparisonTool.js +1 -3
- package/dist/server/registerSessionRecordTools.js +9 -9
- package/dist/server/registerSessionStatusTool.js +1 -1
- package/dist/server/registerSessionTools.js +28 -57
- package/dist/server/sessionAvailabilityPolicy.js +2 -3
- package/dist/server/sessionToolPolicies.js +0 -4
- package/dist/server/toolResult.js +8 -10
- package/package.json +32 -22
- package/skills/reverse-engineer-anything/SKILL.md +15 -11
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +3 -2
- package/skills/reverse-engineer-anything/references/javascript-applications.md +3 -2
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +8 -6
- package/skills/reverse-engineer-anything/references/runtime-observation.md +15 -11
- package/dist/application/CommandShimReplay.js +0 -152
- package/dist/application/ConfiguredRoots.js +0 -19
- package/dist/application/InstrumentedJavaScriptReplayHost.js +0 -36
- package/dist/application/JavaScriptReplayPermission.js +0 -16
- package/dist/application/JavaScriptReplayPlanning.js +0 -207
- package/dist/application/JavaScriptReplayService.js +0 -274
- package/dist/application/LoopbackReplay.js +0 -389
- package/dist/application/LoopbackReplayRecorder.js +0 -129
- package/dist/application/ManagedRuntimeCorrelationService.js +0 -104
- package/dist/application/NodeRuntimeCharacterizationService.js +0 -191
- package/dist/application/PermissionAuthority.js +0 -268
- package/dist/application/PermissionConfiguration.js +0 -26
- package/dist/application/PermissionFailure.js +0 -5
- package/dist/application/ProcessCaptureAuthority.js +0 -24
- package/dist/application/ProcessCapturePermission.js +0 -13
- package/dist/application/ProcessCheckpoints.js +0 -178
- package/dist/application/ProcessReactiveCoordinator.js +0 -223
- package/dist/application/ProcessReactiveEffects.js +0 -153
- package/dist/application/ProcessReactiveHarness.js +0 -106
- package/dist/application/ProcessReactiveObservations.js +0 -105
- package/dist/application/ProjectPermissionStore.js +0 -199
- package/dist/application/RuntimeExecutableDiagnostics.js +0 -198
- package/dist/application/Upgrade.js +0 -134
- package/dist/browser/SensitiveTextCapture.js +0 -8
- package/dist/cliPolicyCommands.js +0 -185
- package/dist/config/browserScenario.js +0 -77
- package/dist/config/electronAutomation.js +0 -35
- package/dist/config/javascriptReplay.js +0 -41
- package/dist/config/managedRuntime.js +0 -25
- package/dist/config/passiveObservation.js +0 -87
- package/dist/config/permissions.js +0 -23
- package/dist/config/processCapture.js +0 -47
- package/dist/contracts/replayMachineExample.js +0 -37
- package/dist/domain/javascriptExportInstrumentation.js +0 -95
- package/dist/domain/javascriptReplay.js +0 -360
- package/dist/domain/managedRuntimeCorrelation.js +0 -181
- package/dist/domain/nodeRuntimeCharacterization.js +0 -63
- package/dist/domain/permissionPolicy.js +0 -176
- package/dist/domain/processCaptureReactiveSchema.js +0 -68
- package/dist/domain/processCaptureReactiveValidation.js +0 -180
- package/dist/domain/processReactiveCheckpointDataflow.js +0 -32
- package/dist/domain/processReactiveMatching.js +0 -196
- package/dist/domain/processReactiveRuntime.js +0 -116
- package/dist/domain/processReactiveScenario.js +0 -296
- package/dist/domain/processReactiveScenarioPreflight.js +0 -95
- package/dist/domain/processReactiveTransition.js +0 -187
- package/dist/domain/replayMachine.js +0 -320
- package/dist/domain/replayMachineRun.js +0 -168
- package/dist/domain/replayMachineRuntime.js +0 -296
- package/dist/domain/replayMachineValues.js +0 -84
- package/dist/domain/runtimeCharacterization.js +0 -84
- package/dist/replay/JavaScriptReplayWorker.js +0 -382
- package/dist/replay/JavaScriptReplayWorkerTypes.js +0 -1
- package/dist/replay/LinuxJavaScriptReplayRunner.js +0 -216
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +0 -121
- package/dist/replay/LinuxRuntimeClosure.js +0 -44
- package/dist/replay/LinuxSeccompPolicy.js +0 -40
- package/dist/replay/ReplayOutcome.js +0 -104
- package/dist/replay/ReplayProcessLifecycle.js +0 -96
- package/dist/replay/ReplaySeccompFile.js +0 -29
- package/dist/replay/ReplayWorkerProtocol.js +0 -58
- package/dist/replay/SystemJavaScriptReplayHost.js +0 -153
- package/dist/server/ProcessCaptureElicitation.js +0 -153
- package/dist/server/registerApplicationTools/characterization.js +0 -46
- package/dist/server/registerApplicationTools/controlledReplay.js +0 -31
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +0 -29
- package/dist/server/registerReplayMachineTool.js +0 -14
- package/skills/reverse-engineer-anything/references/controlled-replay.md +0 -12
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/** Generated from package.json and package-lock.json; do not edit. */
|
|
2
2
|
export const PACKAGE_METADATA = {
|
|
3
3
|
name: "rea-agents",
|
|
4
|
-
version: "
|
|
4
|
+
version: "4.0.0", // x-release-please-version
|
|
5
5
|
serverSdkVersion: "2.0.0",
|
|
6
6
|
clientSdkVersion: "2.0.0",
|
|
7
7
|
coreSdkVersion: "2.0.0",
|
|
8
|
-
skillVersion: "
|
|
8
|
+
skillVersion: "24",
|
|
9
9
|
};
|
|
@@ -10,6 +10,7 @@ export const resolveGhidraAnalysisProfile = (target, identity, installation, sig
|
|
|
10
10
|
if (installation.status === "unavailable")
|
|
11
11
|
return Promise.resolve(err(new ProviderAdapterError(identity.id, "resolve_analysis_profile")));
|
|
12
12
|
const provider = { ...identity, version: installation.providerVersion };
|
|
13
|
+
const dosMz = target.format === "dos-mz";
|
|
13
14
|
return Promise.resolve(ok({
|
|
14
15
|
profile: createAnalysisProfile(provider, {
|
|
15
16
|
target_kind: target.kind,
|
|
@@ -19,14 +20,23 @@ export const resolveGhidraAnalysisProfile = (target, identity, installation, sig
|
|
|
19
20
|
...(target.availableArchitectures ?? []),
|
|
20
21
|
].sort(),
|
|
21
22
|
import_mode: "ephemeral-read-only",
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
function_body_evidence: "complete-inclusive-ranges-v1",
|
|
24
|
+
jump_table_evidence: "typed-case-default-blocks-v1",
|
|
25
|
+
decompiler_jump_loads: true,
|
|
26
|
+
loader: dosMz ? "MzLoader" : "auto-from-header",
|
|
27
|
+
language_id: dosMz ? "x86:LE:16:Real Mode" : "auto-from-header",
|
|
28
|
+
compiler_spec_id: dosMz ? "default" : "auto-default",
|
|
29
|
+
...(dosMz
|
|
30
|
+
? {
|
|
31
|
+
load_segment: "0x1000",
|
|
32
|
+
address_coordinates: "linear-byte-offset",
|
|
33
|
+
}
|
|
34
|
+
: {}),
|
|
25
35
|
analyzer_preset: "ghidra-default",
|
|
26
36
|
}),
|
|
27
37
|
compatibility: {
|
|
28
|
-
languageId: "auto",
|
|
29
|
-
compilerSpecId: "auto",
|
|
38
|
+
languageId: dosMz ? "x86:LE:16:Real Mode" : "auto",
|
|
39
|
+
compilerSpecId: dosMz ? "default" : "auto",
|
|
30
40
|
},
|
|
31
41
|
}));
|
|
32
42
|
};
|
|
@@ -79,7 +79,7 @@ export class GhidraClient {
|
|
|
79
79
|
logger: this.#logger,
|
|
80
80
|
failure: this.#failure,
|
|
81
81
|
});
|
|
82
|
-
this.#requestQueue = new GhidraRequestQueue((method, parameters, requestOptions) => this.#wire.request(method, parameters, requestOptions), (kind, message) => this.#failure(kind, message));
|
|
82
|
+
this.#requestQueue = new GhidraRequestQueue((method, parameters, requestOptions) => this.#wire.request(method, parameters, requestOptions), (kind, message, cause) => this.#failure(kind, message, cause), () => this.#stopAfterActiveCancellation());
|
|
83
83
|
}
|
|
84
84
|
/** Launch Ghidra once and require its exact post-analysis handshake. */
|
|
85
85
|
start(signal) {
|
|
@@ -130,12 +130,21 @@ export class GhidraClient {
|
|
|
130
130
|
}
|
|
131
131
|
/** Stop the owned process group and remove all project/runtime artifacts. */
|
|
132
132
|
close() {
|
|
133
|
+
return this.#requestClose(false);
|
|
134
|
+
}
|
|
135
|
+
#requestClose(forceStop) {
|
|
133
136
|
const starting = this.#startPromise;
|
|
134
137
|
const controller = this.#startupController;
|
|
135
138
|
controller?.abort();
|
|
136
|
-
this.#closePromise ??= Promise.resolve().then(() => this.#close(starting, controller));
|
|
139
|
+
this.#closePromise ??= Promise.resolve().then(() => this.#close(starting, controller, forceStop));
|
|
137
140
|
return this.#closePromise;
|
|
138
141
|
}
|
|
142
|
+
#stopAfterActiveCancellation() {
|
|
143
|
+
return this.#requestClose(true).catch((cause) => {
|
|
144
|
+
this.#logger.error({ error: cause instanceof Error ? cause.message : String(cause) }, "Ghidra cleanup after active request cancellation failed");
|
|
145
|
+
throw cause;
|
|
146
|
+
});
|
|
147
|
+
}
|
|
139
148
|
/** Latest bounded local diagnostics, with bearer material redacted. */
|
|
140
149
|
diagnostics() {
|
|
141
150
|
return structuredClone(this.#diagnostics());
|
|
@@ -229,8 +238,10 @@ export class GhidraClient {
|
|
|
229
238
|
failure: this.#failure,
|
|
230
239
|
startupTimeoutMs: this.#options.startupTimeoutMs,
|
|
231
240
|
});
|
|
232
|
-
if (completed.ok)
|
|
241
|
+
if (completed.ok) {
|
|
233
242
|
await this.#lineage.observe(this.#launch);
|
|
243
|
+
this.#requestQueue.reopen();
|
|
244
|
+
}
|
|
234
245
|
return completed;
|
|
235
246
|
}
|
|
236
247
|
async #connect(endpoint, deadline) {
|
|
@@ -262,15 +273,21 @@ export class GhidraClient {
|
|
|
262
273
|
providerVersion: this.#options.providerVersion,
|
|
263
274
|
profileDigest: this.#options.profileDigest,
|
|
264
275
|
targetSha256: this.#options.targetSha256,
|
|
276
|
+
...(this.#options.expectedLanguageId === undefined
|
|
277
|
+
? {}
|
|
278
|
+
: { expectedLanguageId: this.#options.expectedLanguageId }),
|
|
279
|
+
...(this.#options.expectedCompilerSpecId === undefined
|
|
280
|
+
? {}
|
|
281
|
+
: { expectedCompilerSpecId: this.#options.expectedCompilerSpecId }),
|
|
265
282
|
});
|
|
266
283
|
if (parsed.ok)
|
|
267
284
|
return parsed;
|
|
268
285
|
return err(this.#failure("protocol", "Ghidra bridge handshake is invalid", parsed.error));
|
|
269
286
|
}
|
|
270
|
-
async #close(starting, controller) {
|
|
287
|
+
async #close(starting, controller, forceStop) {
|
|
271
288
|
try {
|
|
272
289
|
await starting?.catch(() => undefined);
|
|
273
|
-
await this.#cleanup();
|
|
290
|
+
await this.#cleanup(forceStop);
|
|
274
291
|
}
|
|
275
292
|
finally {
|
|
276
293
|
if (this.#startPromise === starting)
|
|
@@ -280,12 +297,13 @@ export class GhidraClient {
|
|
|
280
297
|
this.#closePromise = undefined;
|
|
281
298
|
}
|
|
282
299
|
}
|
|
283
|
-
async #cleanup() {
|
|
300
|
+
async #cleanup(forceStop = false) {
|
|
284
301
|
this.#closing = true;
|
|
302
|
+
let forcedStopFailure;
|
|
285
303
|
try {
|
|
286
304
|
this.#requestQueue.failQueued(this.#failure("process", "Ghidra session closed"));
|
|
287
305
|
const socket = this.#socket;
|
|
288
|
-
if (socket !== undefined && !socket.destroyed) {
|
|
306
|
+
if (!forceStop && socket !== undefined && !socket.destroyed) {
|
|
289
307
|
const shutdown = await this.#wire
|
|
290
308
|
.request("shutdown", {}, { timeoutMs: SHUTDOWN_TIMEOUT_MS })
|
|
291
309
|
.catch(() => err(this.#failure("process", "Ghidra shutdown request failed")));
|
|
@@ -308,6 +326,8 @@ export class GhidraClient {
|
|
|
308
326
|
reason: stopped.reason,
|
|
309
327
|
});
|
|
310
328
|
this.#logger.warn({ reason: stopped.reason }, "Ghidra process cleanup failed closed");
|
|
329
|
+
if (forceStop)
|
|
330
|
+
forcedStopFailure = this.#failure("process", `Ghidra process cleanup after cancellation was incomplete: ${stopped.reason}`);
|
|
311
331
|
}
|
|
312
332
|
}
|
|
313
333
|
this.#lastDiagnostics = this.#diagnostics();
|
|
@@ -315,11 +335,21 @@ export class GhidraClient {
|
|
|
315
335
|
this.#launch = undefined;
|
|
316
336
|
const runtimeRoot = this.#runtimeRoot;
|
|
317
337
|
this.#runtimeRoot = undefined;
|
|
318
|
-
|
|
338
|
+
try {
|
|
339
|
+
await runtimeRoot?.close();
|
|
340
|
+
}
|
|
341
|
+
catch (cause) {
|
|
342
|
+
if (forceStop)
|
|
343
|
+
forcedStopFailure ??= this.#failure("process", "Ghidra runtime cleanup after cancellation failed", cause);
|
|
344
|
+
else
|
|
345
|
+
throw cause;
|
|
346
|
+
}
|
|
319
347
|
this.#snapshotPath = undefined;
|
|
320
348
|
this.#token = undefined;
|
|
321
349
|
this.#runId = undefined;
|
|
322
350
|
this.#responseBuffer.reset();
|
|
351
|
+
if (forcedStopFailure !== undefined)
|
|
352
|
+
throw forcedStopFailure;
|
|
323
353
|
}
|
|
324
354
|
finally {
|
|
325
355
|
this.#closing = false;
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { nativeDataTypeSchema } from "../domain/nativeDataType.js";
|
|
3
|
+
import { nativeInstructionSchema, nativeCallTargetsSchema, } from "../domain/nativeInstruction.js";
|
|
2
4
|
import { AnalysisInputError, AnalysisOutputError } from "../domain/errors.js";
|
|
3
|
-
import { functionInstructionWindowSchema, functionDossierSchema, } from "../domain/hopperValues.js";
|
|
5
|
+
import { functionBodyEntryAgrees, functionInstructionWindowSchema, functionDossierSchema, } from "../domain/hopperValues.js";
|
|
6
|
+
import { jsonObjectSchema } from "../domain/jsonValue.js";
|
|
4
7
|
import { nativeApiBoundarySchema } from "../domain/nativeApiBoundary.js";
|
|
5
8
|
import { nativeValueFlowSchema } from "../domain/nativeValueFlow.js";
|
|
6
9
|
import { err, ok } from "../domain/result.js";
|
|
7
|
-
import { ghidraIdentifierSchema, ghidraCanonicalAddressSchema, } from "./GhidraInventoryValues.js";
|
|
10
|
+
import { ghidraIdentifierSchema, ghidraCanonicalAddressSchema, ghidraFunctionClassificationSchema as classification, ghidraFunctionBodySchema as ghidraFunctionBody, ghidraProcedureIdentitySchema as procedureIdentity, } from "./GhidraInventoryValues.js";
|
|
8
11
|
/** Read-only function operations admitted by the Ghidra adapter. */
|
|
9
12
|
export const GHIDRA_FUNCTION_OPERATIONS = [
|
|
13
|
+
"inspect_native_data_type",
|
|
14
|
+
"inspect_native_instruction",
|
|
15
|
+
"resolve_native_call_targets",
|
|
10
16
|
"analyze_function",
|
|
11
17
|
"procedure_assembly",
|
|
12
18
|
"procedure_callees",
|
|
@@ -24,6 +30,20 @@ const document = ghidraIdentifierSchema.nullable().default(null);
|
|
|
24
30
|
const procedure = ghidraIdentifierSchema;
|
|
25
31
|
const directProcedure = { document, procedure };
|
|
26
32
|
const inputSchemas = {
|
|
33
|
+
inspect_native_data_type: z
|
|
34
|
+
.object({
|
|
35
|
+
document,
|
|
36
|
+
type: z.string().min(1).nullable().default(null),
|
|
37
|
+
address: ghidraCanonicalAddressSchema.nullable().default(null),
|
|
38
|
+
})
|
|
39
|
+
.strict()
|
|
40
|
+
.refine((value) => (value.type === null) !== (value.address === null), "Supply exactly one of type or address"),
|
|
41
|
+
inspect_native_instruction: z
|
|
42
|
+
.object({ document, address: ghidraCanonicalAddressSchema })
|
|
43
|
+
.strict(),
|
|
44
|
+
resolve_native_call_targets: z
|
|
45
|
+
.object({ document, address: ghidraCanonicalAddressSchema })
|
|
46
|
+
.strict(),
|
|
27
47
|
analyze_function: z.object({ procedure }).strict(),
|
|
28
48
|
procedure_assembly: z.object(directProcedure).strict(),
|
|
29
49
|
procedure_callees: z.object(directProcedure).strict(),
|
|
@@ -43,24 +63,9 @@ const inputSchemas = {
|
|
|
43
63
|
export const parseGhidraFunctionInput = (operation, value) => {
|
|
44
64
|
const parsed = inputSchemas[operation].safeParse(value);
|
|
45
65
|
return parsed.success
|
|
46
|
-
? ok(parsed.data)
|
|
66
|
+
? ok(jsonObjectSchema.parse(Object.fromEntries(Object.entries(parsed.data).filter(([, value]) => value !== undefined))))
|
|
47
67
|
: err(new AnalysisInputError(operation, { cause: parsed.error }));
|
|
48
68
|
};
|
|
49
|
-
const classification = z
|
|
50
|
-
.object({
|
|
51
|
-
external: z.boolean(),
|
|
52
|
-
thunk: z.boolean(),
|
|
53
|
-
thunk_target: ghidraCanonicalAddressSchema.nullable(),
|
|
54
|
-
provenance: z.literal("ghidra-function-manager"),
|
|
55
|
-
})
|
|
56
|
-
.strict();
|
|
57
|
-
const procedureIdentity = z
|
|
58
|
-
.object({
|
|
59
|
-
address: ghidraCanonicalAddressSchema,
|
|
60
|
-
name: z.string().min(1),
|
|
61
|
-
classification,
|
|
62
|
-
})
|
|
63
|
-
.strict();
|
|
64
69
|
const localVariable = z
|
|
65
70
|
.object({
|
|
66
71
|
description: z.string(),
|
|
@@ -101,6 +106,13 @@ const procedureReferences = z
|
|
|
101
106
|
procedure: procedureIdentity,
|
|
102
107
|
direction: z.enum(["incoming", "outgoing"]),
|
|
103
108
|
references: z.array(referenceEdge),
|
|
109
|
+
reference_kinds_available: z.boolean().default(true),
|
|
110
|
+
unresolved_calls: z
|
|
111
|
+
.array(z.strictObject({
|
|
112
|
+
address: ghidraCanonicalAddressSchema,
|
|
113
|
+
reason: z.string(),
|
|
114
|
+
}))
|
|
115
|
+
.default([]),
|
|
104
116
|
})
|
|
105
117
|
.strict();
|
|
106
118
|
const procedureInfo = z
|
|
@@ -112,8 +124,19 @@ const procedureInfo = z
|
|
|
112
124
|
signature: z.string().nullable(),
|
|
113
125
|
locals: z.array(localVariable),
|
|
114
126
|
classification,
|
|
127
|
+
body: ghidraFunctionBody,
|
|
115
128
|
})
|
|
116
|
-
.strict()
|
|
129
|
+
.strict()
|
|
130
|
+
.superRefine((value, context) => {
|
|
131
|
+
if (!functionBodyEntryAgrees(value.body, value.entrypoint) ||
|
|
132
|
+
(value.body.available &&
|
|
133
|
+
(value.length !== value.body.total_bytes ||
|
|
134
|
+
(!value.classification.external && !value.body.contains_entry))))
|
|
135
|
+
context.addIssue({
|
|
136
|
+
code: "custom",
|
|
137
|
+
message: "Ghidra function body disagrees with entry point or length",
|
|
138
|
+
});
|
|
139
|
+
});
|
|
117
140
|
const ghidraNativeApiBoundary = nativeApiBoundarySchema.superRefine((value, context) => {
|
|
118
141
|
if (!value.available)
|
|
119
142
|
return;
|
|
@@ -126,6 +149,7 @@ const ghidraNativeApiBoundary = nativeApiBoundarySchema.superRefine((value, cont
|
|
|
126
149
|
table.dispatch_address,
|
|
127
150
|
...table.data_sources.map(({ address }) => address),
|
|
128
151
|
...table.mappings.map(({ target_address }) => target_address),
|
|
152
|
+
...table.default_targets.map(({ target_address }) => target_address),
|
|
129
153
|
]);
|
|
130
154
|
if (addresses.some((address) => !ghidraCanonicalAddressSchema.safeParse(address).success))
|
|
131
155
|
context.addIssue({
|
|
@@ -172,6 +196,10 @@ const ghidraNativeValueFlow = nativeValueFlowSchema.superRefine((value, context)
|
|
|
172
196
|
});
|
|
173
197
|
const ghidraFunctionDossier = functionDossierSchema
|
|
174
198
|
.extend({
|
|
199
|
+
procedure: functionDossierSchema.shape.procedure.safeExtend({
|
|
200
|
+
classification,
|
|
201
|
+
body: ghidraFunctionBody,
|
|
202
|
+
}),
|
|
175
203
|
native_api: ghidraNativeApiBoundary,
|
|
176
204
|
native_value_flow: ghidraNativeValueFlow,
|
|
177
205
|
})
|
|
@@ -210,7 +238,12 @@ const ghidraFunctionDossier = functionDossierSchema
|
|
|
210
238
|
...value.incoming_references.flatMap(referenceProcedures),
|
|
211
239
|
...value.outgoing_references.flatMap(referenceProcedures),
|
|
212
240
|
];
|
|
213
|
-
if (identities.some((
|
|
241
|
+
if (identities.some((identity) => !classification.safeParse(identity.classification).success ||
|
|
242
|
+
!ghidraFunctionBody.safeParse(identity.body).success ||
|
|
243
|
+
!functionBodyEntryAgrees(identity.body, identity.address) ||
|
|
244
|
+
(identity.body.available &&
|
|
245
|
+
identity.classification?.external === false &&
|
|
246
|
+
!identity.body.contains_entry)))
|
|
214
247
|
context.addIssue({
|
|
215
248
|
code: "custom",
|
|
216
249
|
message: "Ghidra dossier omitted function classification",
|
|
@@ -239,6 +272,9 @@ const resultSchemas = {
|
|
|
239
272
|
procedure_info: procedureInfo,
|
|
240
273
|
procedure_pseudo_code: z.string().nullable(),
|
|
241
274
|
read_function_instructions: ghidraFunctionInstructionWindow,
|
|
275
|
+
inspect_native_instruction: nativeInstructionSchema,
|
|
276
|
+
inspect_native_data_type: nativeDataTypeSchema,
|
|
277
|
+
resolve_native_call_targets: nativeCallTargetsSchema,
|
|
242
278
|
procedure_references: procedureReferences,
|
|
243
279
|
xrefs: z.array(ghidraCanonicalAddressSchema),
|
|
244
280
|
};
|
|
@@ -110,17 +110,20 @@ const installationChecks = ({ coordinates, platform, architecture, javaHome, hos
|
|
|
110
110
|
}),
|
|
111
111
|
installationCheck({
|
|
112
112
|
name: "platform",
|
|
113
|
-
passed: platform === "linux" || platform === "win32",
|
|
113
|
+
passed: platform === "linux" || platform === "win32" || platform === "darwin",
|
|
114
114
|
code: "unsupported_host",
|
|
115
115
|
detail: platform,
|
|
116
|
-
remediation: "Use
|
|
116
|
+
remediation: "Use Linux or Windows x64, or macOS x64/arm64 with matching native Ghidra tools.",
|
|
117
117
|
}),
|
|
118
118
|
installationCheck({
|
|
119
119
|
name: "architecture",
|
|
120
|
-
passed: (platform === "linux" || platform === "win32") &&
|
|
120
|
+
passed: ((platform === "linux" || platform === "win32") &&
|
|
121
|
+
architecture === "x64") ||
|
|
122
|
+
(platform === "darwin" &&
|
|
123
|
+
(architecture === "x64" || architecture === "arm64")),
|
|
121
124
|
code: "unsupported_host",
|
|
122
125
|
detail: architecture,
|
|
123
|
-
remediation: "Use x64 on Linux or Windows.",
|
|
126
|
+
remediation: "Use x64 on Linux or Windows, or x64/arm64 on macOS.",
|
|
124
127
|
}),
|
|
125
128
|
installationCheck({
|
|
126
129
|
name: "installation",
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { AnalysisInputError, AnalysisOutputError } from "../domain/errors.js";
|
|
3
|
+
import { functionBodySchema, functionBodyEntryAgrees, } from "../domain/hopperValues.js";
|
|
3
4
|
import { err, ok } from "../domain/result.js";
|
|
4
5
|
/** Read-only direct inventory operations admitted by the Ghidra adapter. */
|
|
5
6
|
export const GHIDRA_INVENTORY_OPERATIONS = [
|
|
@@ -69,9 +70,40 @@ const procedureFacts = z
|
|
|
69
70
|
thunk_target: canonicalAddress.nullable(),
|
|
70
71
|
})
|
|
71
72
|
.strict();
|
|
72
|
-
|
|
73
|
+
/** Ghidra FunctionManager classification, independent of body ownership inference. */
|
|
74
|
+
export const ghidraFunctionClassificationSchema = procedureFacts
|
|
73
75
|
.extend({ provenance: z.literal("ghidra-function-manager") })
|
|
74
76
|
.strict();
|
|
77
|
+
/** Require complete canonical AddressSet evidence on every Ghidra function identity. */
|
|
78
|
+
export const ghidraFunctionBodySchema = functionBodySchema.superRefine((body, context) => {
|
|
79
|
+
if (!body.available ||
|
|
80
|
+
body.provenance !== "ghidra-function-body-address-set" ||
|
|
81
|
+
body.ranges.some(({ start, end }) => !ghidraCanonicalAddressSchema.safeParse(start).success ||
|
|
82
|
+
!ghidraCanonicalAddressSchema.safeParse(end).success))
|
|
83
|
+
context.addIssue({
|
|
84
|
+
code: "custom",
|
|
85
|
+
message: "Ghidra omitted complete canonical function-body AddressSet evidence",
|
|
86
|
+
});
|
|
87
|
+
});
|
|
88
|
+
/** Strict provider identity shared by inventory and function-analysis results. */
|
|
89
|
+
export const ghidraProcedureIdentitySchema = z
|
|
90
|
+
.object({
|
|
91
|
+
address: ghidraCanonicalAddressSchema,
|
|
92
|
+
name: z.string().min(1),
|
|
93
|
+
classification: ghidraFunctionClassificationSchema,
|
|
94
|
+
body: ghidraFunctionBodySchema,
|
|
95
|
+
})
|
|
96
|
+
.strict()
|
|
97
|
+
.superRefine((value, context) => {
|
|
98
|
+
if (!functionBodyEntryAgrees(value.body, value.address) ||
|
|
99
|
+
(value.body.available &&
|
|
100
|
+
!value.classification.external &&
|
|
101
|
+
!value.body.contains_entry))
|
|
102
|
+
context.addIssue({
|
|
103
|
+
code: "custom",
|
|
104
|
+
message: "Ghidra function body disagrees with its entry point",
|
|
105
|
+
});
|
|
106
|
+
});
|
|
75
107
|
const stringFacts = z
|
|
76
108
|
.object({
|
|
77
109
|
encoding: z.string().min(1),
|
|
@@ -119,15 +151,18 @@ const containingProcedure = z.discriminatedUnion("found", [
|
|
|
119
151
|
.object({
|
|
120
152
|
query_address: canonicalAddress,
|
|
121
153
|
found: z.literal(true),
|
|
122
|
-
procedure:
|
|
123
|
-
.object({
|
|
124
|
-
address: canonicalAddress,
|
|
125
|
-
name: z.string().min(1),
|
|
126
|
-
classification: functionClassification,
|
|
127
|
-
})
|
|
128
|
-
.strict(),
|
|
154
|
+
procedure: ghidraProcedureIdentitySchema,
|
|
129
155
|
})
|
|
130
|
-
.strict()
|
|
156
|
+
.strict()
|
|
157
|
+
.superRefine((value, context) => {
|
|
158
|
+
const body = value.procedure.body;
|
|
159
|
+
if (body.available &&
|
|
160
|
+
!functionBodyEntryAgrees({ ...body, contains_entry: true }, value.query_address))
|
|
161
|
+
context.addIssue({
|
|
162
|
+
code: "custom",
|
|
163
|
+
message: "Found containing procedure body does not contain the query address",
|
|
164
|
+
});
|
|
165
|
+
}),
|
|
131
166
|
z
|
|
132
167
|
.object({
|
|
133
168
|
query_address: canonicalAddress,
|
|
@@ -52,6 +52,9 @@ export class GhidraHeadlessLauncher {
|
|
|
52
52
|
descriptorPath: paths.descriptorPath,
|
|
53
53
|
ghidraLogPath: paths.ghidraLogPath,
|
|
54
54
|
scriptLogPath: paths.scriptLogPath,
|
|
55
|
+
...(this.options.dosMz === undefined
|
|
56
|
+
? {}
|
|
57
|
+
: { dosMz: this.options.dosMz }),
|
|
55
58
|
});
|
|
56
59
|
const command = ghidraHeadlessCommand({
|
|
57
60
|
platform,
|
|
@@ -69,6 +72,7 @@ export class GhidraHeadlessLauncher {
|
|
|
69
72
|
// the per-process run token remain the cleanup authority.
|
|
70
73
|
expectedCommand: null,
|
|
71
74
|
windowsVerbatimArguments: platform === "win32",
|
|
75
|
+
platform,
|
|
72
76
|
env: ghidraLaunchEnvironment(paths, this.options.javaHome, platform),
|
|
73
77
|
});
|
|
74
78
|
await writeFileAtomic(paths.ownershipPath, `${JSON.stringify({
|
|
@@ -151,6 +155,16 @@ export const ghidraHeadlessArguments = (options) => [
|
|
|
151
155
|
"rea-project",
|
|
152
156
|
"-import",
|
|
153
157
|
options.targetPath,
|
|
158
|
+
...(options.dosMz === true
|
|
159
|
+
? [
|
|
160
|
+
"-loader",
|
|
161
|
+
"MzLoader",
|
|
162
|
+
"-processor",
|
|
163
|
+
"x86:LE:16:Real Mode",
|
|
164
|
+
"-cspec",
|
|
165
|
+
"default",
|
|
166
|
+
]
|
|
167
|
+
: []),
|
|
154
168
|
"-readOnly",
|
|
155
169
|
"-deleteProject",
|
|
156
170
|
"-log",
|
|
@@ -176,9 +190,10 @@ const ghidraRuntimePaths = (runtimeRoot) => ({
|
|
|
176
190
|
scriptLogPath: join(runtimeRoot, "script.log"),
|
|
177
191
|
});
|
|
178
192
|
const ghidraLaunchEnvironment = (paths, javaHome, platform) => {
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
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}`;
|
|
182
197
|
return {
|
|
183
198
|
...ghidraJavaEnvironment(javaHome, process.env, platform),
|
|
184
199
|
HOME: paths.homeRoot,
|
|
@@ -106,6 +106,12 @@ export class GhidraProvider {
|
|
|
106
106
|
if (!prerequisites.ok)
|
|
107
107
|
return unavailableClient(prerequisites.error);
|
|
108
108
|
const committedProfile = prerequisites.value.profile;
|
|
109
|
+
const targetLimitations = target.format === "dos-mz"
|
|
110
|
+
? [
|
|
111
|
+
"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.",
|
|
112
|
+
"Static DOS analysis does not emulate BIOS, DOS interrupts, device ports, or self-modifying unpacking code. Packed targets require a separately identified unpacked artifact for original-program analysis; appended overlays are not the initialized load module.",
|
|
113
|
+
]
|
|
114
|
+
: [];
|
|
109
115
|
const providerLimitations = installation.platform === "win32"
|
|
110
116
|
? windowsP0Limitations
|
|
111
117
|
: installation.platform === "darwin"
|
|
@@ -120,6 +126,7 @@ export class GhidraProvider {
|
|
|
120
126
|
? {}
|
|
121
127
|
: { javaHome: this.config.ghidraJavaHome }),
|
|
122
128
|
bridgeScriptPath: fileURLToPath(new URL("../../bridge/ghidra/ReaGhidraBridge.java", import.meta.url)),
|
|
129
|
+
...(target.format === "dos-mz" ? { dosMz: true } : {}),
|
|
123
130
|
platform: installation.platform,
|
|
124
131
|
}),
|
|
125
132
|
targetPath: target.path,
|
|
@@ -129,6 +136,12 @@ export class GhidraProvider {
|
|
|
129
136
|
: "unix-socket",
|
|
130
137
|
providerVersion: prerequisites.value.providerVersion,
|
|
131
138
|
profileDigest: committedProfile.digest,
|
|
139
|
+
...(target.format === "dos-mz"
|
|
140
|
+
? {
|
|
141
|
+
expectedLanguageId: "x86:LE:16:Real Mode",
|
|
142
|
+
expectedCompilerSpecId: "default",
|
|
143
|
+
}
|
|
144
|
+
: {}),
|
|
132
145
|
...(context === undefined ? {} : { runId: context.runId }),
|
|
133
146
|
logger: this.logger.child({ layer: "ghidra-bridge" }),
|
|
134
147
|
});
|
|
@@ -144,7 +157,11 @@ export class GhidraProvider {
|
|
|
144
157
|
return err(projectSessionError(operation, started.error));
|
|
145
158
|
return ok(createAnalysisExecution(started.value, committedProfile.provider, {
|
|
146
159
|
analysisProfile: committedProfile,
|
|
147
|
-
limitations: [
|
|
160
|
+
limitations: [
|
|
161
|
+
...healthLimitations,
|
|
162
|
+
...providerLimitations,
|
|
163
|
+
...targetLimitations,
|
|
164
|
+
],
|
|
148
165
|
}));
|
|
149
166
|
}
|
|
150
167
|
const input = isGhidraFunctionOperation(operation)
|
|
@@ -163,7 +180,11 @@ export class GhidraProvider {
|
|
|
163
180
|
return ok(createAnalysisExecution(result.value, committedProfile.provider, {
|
|
164
181
|
rawResult: called.value,
|
|
165
182
|
analysisProfile: committedProfile,
|
|
166
|
-
limitations: [
|
|
183
|
+
limitations: [
|
|
184
|
+
...limitationsFor(operation),
|
|
185
|
+
...providerLimitations,
|
|
186
|
+
...targetLimitations,
|
|
187
|
+
],
|
|
167
188
|
}));
|
|
168
189
|
},
|
|
169
190
|
runtimeLineageSnapshots: () => {
|
|
@@ -3,14 +3,19 @@ import { err } from "../domain/result.js";
|
|
|
3
3
|
export class GhidraRequestQueue {
|
|
4
4
|
execute;
|
|
5
5
|
failure;
|
|
6
|
+
onActiveCancellation;
|
|
6
7
|
#queue = [];
|
|
7
8
|
#active = false;
|
|
8
|
-
|
|
9
|
+
#closedFailure;
|
|
10
|
+
constructor(execute, failure, onActiveCancellation) {
|
|
9
11
|
this.execute = execute;
|
|
10
12
|
this.failure = failure;
|
|
13
|
+
this.onActiveCancellation = onActiveCancellation;
|
|
11
14
|
}
|
|
12
15
|
/** Queue one request until it completes, is cancelled, or the session closes. */
|
|
13
16
|
run(method, parameters, options) {
|
|
17
|
+
if (this.#closedFailure !== undefined)
|
|
18
|
+
return Promise.resolve(err(this.#closedFailure));
|
|
14
19
|
if (options.signal?.aborted === true)
|
|
15
20
|
return Promise.resolve(err(this.failure("cancelled", "Ghidra request was cancelled")));
|
|
16
21
|
return new Promise((resolve) => {
|
|
@@ -33,11 +38,16 @@ export class GhidraRequestQueue {
|
|
|
33
38
|
}
|
|
34
39
|
/** Fail requests that have not crossed the socket during session cleanup. */
|
|
35
40
|
failQueued(failure) {
|
|
41
|
+
this.#closedFailure = failure;
|
|
36
42
|
for (const entry of this.#queue.splice(0)) {
|
|
37
43
|
this.#release(entry);
|
|
38
44
|
entry.resolve(err(failure));
|
|
39
45
|
}
|
|
40
46
|
}
|
|
47
|
+
/** Admit requests after the owning client completes a new session startup. */
|
|
48
|
+
reopen() {
|
|
49
|
+
this.#closedFailure = undefined;
|
|
50
|
+
}
|
|
41
51
|
#drain() {
|
|
42
52
|
if (this.#active)
|
|
43
53
|
return;
|
|
@@ -51,12 +61,43 @@ export class GhidraRequestQueue {
|
|
|
51
61
|
return;
|
|
52
62
|
}
|
|
53
63
|
this.#active = true;
|
|
64
|
+
let executionSettled = false;
|
|
65
|
+
let activeCancellation;
|
|
66
|
+
const onAbort = entry.signal === undefined
|
|
67
|
+
? undefined
|
|
68
|
+
: () => {
|
|
69
|
+
if (executionSettled)
|
|
70
|
+
return;
|
|
71
|
+
this.failQueued(this.failure("process", "Ghidra session closed after active request cancellation"));
|
|
72
|
+
activeCancellation = this.onActiveCancellation();
|
|
73
|
+
};
|
|
74
|
+
if (onAbort !== undefined)
|
|
75
|
+
entry.signal?.addEventListener("abort", onAbort, { once: true });
|
|
54
76
|
void this.execute(entry.method, entry.parameters, entry.signal === undefined ? {} : { signal: entry.signal })
|
|
55
|
-
.then(
|
|
56
|
-
|
|
77
|
+
.then(async (result) => {
|
|
78
|
+
if (activeCancellation !== undefined) {
|
|
79
|
+
try {
|
|
80
|
+
await activeCancellation;
|
|
81
|
+
}
|
|
82
|
+
catch (cause) {
|
|
83
|
+
result = err(this.failure("process", cause instanceof Error
|
|
84
|
+
? `Ghidra cleanup after cancellation failed: ${cause.message}`
|
|
85
|
+
: "Ghidra cleanup after cancellation failed", cause));
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
executionSettled = true;
|
|
89
|
+
entry.resolve(result);
|
|
90
|
+
})
|
|
91
|
+
.catch(() => {
|
|
92
|
+
executionSettled = true;
|
|
93
|
+
entry.resolve(err(this.failure("protocol", "Ghidra serial request execution rejected unexpectedly")));
|
|
94
|
+
})
|
|
57
95
|
.finally(() => {
|
|
96
|
+
if (entry.signal !== undefined && onAbort !== undefined)
|
|
97
|
+
entry.signal.removeEventListener("abort", onAbort);
|
|
58
98
|
this.#active = false;
|
|
59
|
-
this.#
|
|
99
|
+
if (this.#closedFailure === undefined)
|
|
100
|
+
this.#drain();
|
|
60
101
|
});
|
|
61
102
|
}
|
|
62
103
|
#rejectQueued(entry, result) {
|
|
@@ -47,6 +47,11 @@ export const parseGhidraSessionInfo = (value, expected) => {
|
|
|
47
47
|
parsed.data.provider.version !== expected.providerVersion ||
|
|
48
48
|
parsed.data.profile_digest !== expected.profileDigest ||
|
|
49
49
|
parsed.data.target.sha256 !== expected.targetSha256 ||
|
|
50
|
+
(expected.expectedLanguageId !== undefined &&
|
|
51
|
+
parsed.data.target.language_id !== expected.expectedLanguageId) ||
|
|
52
|
+
(expected.expectedCompilerSpecId !== undefined &&
|
|
53
|
+
parsed.data.target.compiler_spec_id !==
|
|
54
|
+
expected.expectedCompilerSpecId) ||
|
|
50
55
|
new Set(parsed.data.capabilities).size !==
|
|
51
56
|
GHIDRA_SESSION_CAPABILITIES.length ||
|
|
52
57
|
GHIDRA_SESSION_CAPABILITIES.some((capability) => !parsed.data.capabilities.includes(capability)) ||
|
|
@@ -62,6 +62,8 @@ export const hopperLoaderArgsForTarget = (target) => {
|
|
|
62
62
|
return ok(["-l", "ELF", flag]);
|
|
63
63
|
case "pe":
|
|
64
64
|
return ok(["-l", "WinPE", flag]);
|
|
65
|
+
case "dos-mz":
|
|
66
|
+
return err(new ProviderAdapterError("hopper", "resolve_analysis_profile"));
|
|
65
67
|
}
|
|
66
68
|
};
|
|
67
69
|
const hopperArchitectureFlag = (architecture) => {
|