rea-agents 3.1.0 → 3.2.1
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 +72 -95
- package/bridge/ghidra/ReaGhidraBridge.java +609 -841
- package/bridge/hopper_bridge.py +99 -344
- package/dist/application/AbortablePromise.js +6 -3
- package/dist/application/AnalysisSnapshotCache.js +0 -1
- package/dist/application/AnalysisSnapshotFiles.js +7 -7
- package/dist/application/AndroidApplicationService.js +1 -1
- package/dist/application/AppleApplicationService.js +1 -1
- package/dist/application/ArtifactExtraction.js +35 -54
- package/dist/application/ArtifactExtractionDestination.js +17 -0
- package/dist/application/ArtifactGraphConstruction.js +2 -17
- package/dist/application/ArtifactInventory/classify.js +2 -6
- package/dist/application/ArtifactInventory/hash.js +2 -20
- package/dist/application/ArtifactInventory/scanCanonical.js +8 -12
- package/dist/application/ArtifactInventory/scanReader.js +69 -51
- package/dist/application/ArtifactInventory.js +6 -14
- package/dist/application/AuthorizedArtifactInventory.js +3 -13
- package/dist/application/BinarySession.js +41 -13
- package/dist/application/BinarySessionComposition.js +0 -11
- package/dist/application/BinarySessionOpen.js +2 -1
- package/dist/application/BinarySessionRecords.js +5 -93
- package/dist/application/BinarySessionStatus.js +5 -16
- package/dist/application/BinaryTargetResolver.js +216 -0
- package/dist/application/BrowserEvidence.js +42 -58
- package/dist/application/BrowserObservationService.js +3 -6
- package/dist/application/BrowserScenarioCaptureService.js +3 -6
- package/dist/application/BrowserScenarioEvidence.js +3 -3
- package/dist/application/CallPathTracing.js +2 -36
- package/dist/application/CapabilityInventory.js +10 -15
- package/dist/application/ClientConfigurationDocument.js +27 -0
- package/dist/application/ClientRegistrationStatus.js +16 -13
- package/dist/application/CommandShimReplay.js +14 -1
- package/dist/application/DirectAnalysis.js +22 -46
- package/dist/application/DirectAnalysisStatus.js +5 -61
- package/dist/application/Doctor.js +11 -32
- package/dist/application/DoctorDiagnostics.js +1 -2
- package/dist/application/DoctorScope.js +1 -1
- package/dist/application/ElectronActiveEvidence.js +3 -8
- package/dist/application/ElectronActiveObservationService.js +3 -6
- package/dist/application/ElectronBoundaryAnalysis.js +7 -8
- package/dist/application/ElectronBoundaryGraphContext.js +1 -1
- package/dist/application/ElectronBoundaryGraphIpc.js +3 -3
- package/dist/application/ElectronBoundaryGraphNative.js +1 -2
- package/dist/application/ElectronBoundaryGraphWindows.js +6 -8
- package/dist/application/ElectronEvidence.js +4 -7
- package/dist/application/ElectronObservationService.js +5 -9
- package/dist/application/EnhancedLiteralTracing.js +42 -65
- package/dist/application/EnhancedTools.js +76 -44
- package/dist/application/EvidenceBundleCommands.js +11 -11
- package/dist/application/EvidenceBundleFiles.js +9 -15
- package/dist/application/EvidenceLedger.js +6 -41
- package/dist/application/FilesystemSnapshot.js +2 -3
- package/dist/application/InterfaceBuilderAnalysis.js +266 -0
- package/dist/application/InventoryProjectionEvidence.js +4 -2
- package/dist/application/InvestigationProviders.js +1 -1
- package/dist/application/JavaScriptApplicationEvidence.js +2 -5
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +6 -10
- package/dist/application/JavaScriptApplicationService.js +6 -29
- package/dist/application/JavaScriptApplicationWorkflowEvidence.js +5 -5
- package/dist/application/JavaScriptApplicationWorkflowService.js +0 -8
- package/dist/application/JavaScriptArtifactAnalysis.js +38 -127
- package/dist/application/JavaScriptArtifactFiles.js +67 -107
- package/dist/application/JavaScriptArtifactGraphAccumulator.js +0 -7
- package/dist/application/JavaScriptArtifactGraphBuilder.js +7 -58
- package/dist/application/JavaScriptArtifactGraphBundlers.js +1 -6
- package/dist/application/JavaScriptArtifactGraphContext.js +12 -39
- package/dist/application/JavaScriptArtifactGraphDocuments.js +4 -11
- package/dist/application/JavaScriptArtifactGraphEvidence.js +0 -14
- package/dist/application/JavaScriptArtifactGraphFindings.js +3 -3
- package/dist/application/JavaScriptArtifactGraphStructure.js +16 -17
- package/dist/application/JavaScriptArtifactPathResolution.js +61 -49
- package/dist/application/JavaScriptArtifactReconstruction.js +5 -10
- package/dist/application/JavaScriptArtifactReconstructionInput.js +2 -14
- package/dist/application/JavaScriptJsonModules.js +2 -2
- package/dist/application/JavaScriptModuleRelationships.js +22 -27
- package/dist/application/JavaScriptReplayPlanning.js +9 -3
- package/dist/application/JavaScriptReplayService.js +6 -32
- package/dist/application/JavaScriptReturnShapeProjection.js +12 -42
- package/dist/application/JavaScriptRuntimeObservationEvidence.js +7 -8
- package/dist/application/JavaScriptRuntimeObservationService.js +4 -8
- package/dist/application/JavaScriptRuntimeReconciliationEvidence.js +2 -3
- package/dist/application/JavaScriptSemanticGraphBuilder.js +11 -41
- package/dist/application/JavaScriptSemanticGraphConstruction.js +5 -29
- package/dist/application/JavaScriptSemanticGraphEvidence.js +1 -1
- package/dist/application/JavaScriptSemanticGraphFingerprintProjection.js +1 -1
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +0 -13
- package/dist/application/JavaScriptSemanticGraphProjection.js +1 -3
- package/dist/application/JavaScriptSemanticTraceService.js +1 -10
- package/dist/application/JsonFiles.js +79 -0
- package/dist/application/LinuxHopper.js +11 -9
- package/dist/application/LoopbackReplay.js +26 -23
- package/dist/application/LoopbackReplayRecorder.js +29 -1
- package/dist/application/ManagedApplicationGraphService.js +1 -2
- package/dist/application/ManagedMemberComparisonService.js +11 -41
- package/dist/application/ManagedNativeVerificationService.js +1 -2
- package/dist/application/ManagedReconstructionService.js +1 -1
- package/dist/application/ManagedRuntimeCorrelationService.js +5 -8
- package/dist/application/NativeApiInspection.js +2 -7
- package/dist/application/NativeUiActionTrace.js +394 -0
- package/dist/application/NodeRuntimeCharacterizationService.js +3 -7
- package/dist/application/PermissionAuthority.js +15 -7
- package/dist/application/PermissionFailure.js +5 -0
- package/dist/application/ProcessCaptureAuthority.js +5 -7
- package/dist/application/ProcessCaptureJournal.js +3 -2
- package/dist/application/ProcessCaptureLifecycle.js +5 -12
- package/dist/application/ProcessCheckpoints.js +29 -11
- package/dist/application/ProcessCli.js +6 -16
- package/dist/application/ProcessEvidence.js +5 -7
- package/dist/application/ProcessHarness.js +52 -17
- package/dist/application/ProcessReactiveCoordinator.js +2 -4
- package/dist/application/ProcessReactiveEffects.js +9 -3
- package/dist/application/ProcessReactiveHarness.js +13 -7
- package/dist/application/ProcessSampling.js +2 -4
- package/dist/application/ProcessTimer.js +39 -0
- package/dist/application/ProjectPermissionStore.js +39 -96
- package/dist/application/RealHopperAssertions.js +20 -66
- package/dist/application/ReconstructionCoverageService.js +12 -58
- package/dist/application/ReconstructionObligationAuthority.js +2 -2
- package/dist/application/ReconstructionObligationCandidates.js +4 -4
- package/dist/application/ReconstructionObligationLedgerEvaluation.js +8 -15
- package/dist/application/ReconstructionObligationLedgerProjection.js +3 -7
- package/dist/application/ReconstructionObligationLedgerService.js +19 -38
- package/dist/application/ReferenceSourceImport.js +19 -45
- package/dist/application/ReferenceSourceImportEntries.js +2 -4
- package/dist/application/ReferenceSourceImportPolicy.js +5 -32
- package/dist/application/ReferenceSourceImportTypes.js +0 -16
- package/dist/application/RuntimeExecutableDiagnostics.js +55 -29
- package/dist/application/SessionProviderRouter.js +2 -2
- package/dist/application/Setup.js +1 -3
- package/dist/application/SetupClientConfiguration.js +22 -93
- package/dist/application/SetupRegistrationEnvironment.js +0 -7
- package/dist/application/StoreFileLock.js +119 -0
- package/dist/application/TerminalRenderer.js +2 -3
- package/dist/application/Uninstall.js +9 -14
- package/dist/application/UnknownEvidence.js +1 -1
- package/dist/artifacts/ArtifactPaths.js +2 -5
- package/dist/artifacts/ArtifactProvider.js +36 -58
- package/dist/artifacts/DirectoryArtifactReader.js +13 -8
- package/dist/artifacts/MachOSliceArtifactReader.js +1 -5
- package/dist/artifacts/NativeDmgArtifactReader.js +11 -11
- package/dist/artifacts/NibArchive.js +269 -0
- package/dist/artifacts/SafeOutputTree.js +15 -24
- package/dist/browser/BrowserProcessStartup.js +1 -2
- package/dist/browser/CdpAuthorizedMainFrame.js +16 -0
- package/dist/browser/CdpBrowserProvider.js +3 -13
- package/dist/browser/CdpCanonicalJsonDigest.js +9 -0
- package/dist/browser/CdpCaptureDocuments.js +28 -76
- package/dist/browser/CdpCaptureEventBodyShapes.js +13 -33
- package/dist/browser/CdpCaptureEventHandlers.js +22 -87
- package/dist/browser/CdpCaptureEvents.js +2 -8
- package/dist/browser/CdpCaptureStorage.js +9 -20
- package/dist/browser/CdpCaptureStorageFingerprints.js +85 -98
- package/dist/browser/CdpCaptureValues.js +21 -21
- package/dist/browser/CdpConnection.js +10 -25
- package/dist/browser/CdpElectronInspection.js +26 -50
- package/dist/browser/CdpElectronProvider.js +10 -35
- package/dist/browser/CdpElectronScriptEvents.js +8 -16
- package/dist/browser/CdpElectronScripts.js +6 -35
- package/dist/browser/CdpElectronWorkers.js +6 -10
- package/dist/browser/CdpEndpoint.js +25 -41
- package/dist/browser/CdpObservationSession.js +14 -26
- package/dist/browser/CdpPageCapture.js +34 -48
- package/dist/browser/CdpPageCaptureScripts.js +1 -19
- package/dist/browser/CdpPageCaptureWorkers.js +6 -10
- package/dist/browser/CdpSafeMetadata.js +19 -22
- package/dist/browser/CdpScreenshot.js +3 -5
- package/dist/browser/CdpTargetSession.js +1 -2
- package/dist/browser/CdpWebMcpDiscovery.js +13 -22
- package/dist/browser/ElectronFileScope.js +8 -19
- package/dist/browser/JavaScriptRuntimeScope.js +9 -14
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +31 -64
- package/dist/browser/PlaywrightElectronActiveActions.js +54 -69
- package/dist/browser/PlaywrightElectronActiveProvider.js +14 -34
- package/dist/browser/PlaywrightExecutionBoundary.js +16 -5
- package/dist/browser/PlaywrightScenarioActions.js +3 -7
- package/dist/browser/PlaywrightScenarioArtifacts.js +23 -92
- package/dist/browser/PlaywrightScenarioBrowser.js +3 -5
- package/dist/browser/PlaywrightScenarioEvents.js +45 -94
- package/dist/browser/PlaywrightScenarioSession.js +14 -30
- package/dist/browser/PngVisualDiff.js +22 -14
- package/dist/browser/SensitiveTextCapture.js +0 -17
- package/dist/browser/V8InspectorCaptureProjection.js +7 -8
- package/dist/browser/V8InspectorEndpoint.js +12 -14
- package/dist/browser/V8InspectorProvider.js +20 -61
- package/dist/browser/WebSourceMapFetcher.js +56 -176
- package/dist/catalogIdentity.js +0 -54
- package/dist/cli/artifactCommands.js +49 -77
- package/dist/cli/coreAnalysisCommands.js +83 -133
- package/dist/cli/javascriptApplicationAnalysis.js +1 -9
- package/dist/cli/managedCommands.js +5 -270
- package/dist/cli/setupCommands.js +3 -12
- package/dist/cli/utilityCommands.js +7 -41
- package/dist/cli.js +0 -2
- package/dist/cliApplicationCommands.js +42 -112
- package/dist/cliBrowserAdvancedCommands.js +10 -106
- package/dist/cliBrowserCommands.js +15 -127
- package/dist/cliBrowserContext.js +30 -0
- package/dist/cliCommandNames.js +4 -5
- package/dist/cliElectronCommands.js +8 -72
- package/dist/cliEvidenceCommands.js +8 -77
- package/dist/cliJavaScriptRuntimeCommands.js +9 -91
- package/dist/cliJsonInput.js +4 -14
- package/dist/cliObservationOptions.js +11 -96
- package/dist/cliPolicyCommands.js +2 -17
- package/dist/cliProcessCommands.js +3 -3
- package/dist/cliSetup.js +0 -13
- package/dist/config/browserScenario.js +2 -2
- package/dist/config/environment.js +0 -9
- package/dist/config/parseConfig.js +1 -33
- package/dist/config/parsers.js +6 -27
- package/dist/config/passiveObservation.js +7 -77
- package/dist/config/permissions.js +0 -7
- package/dist/contracts/analysisSearchContract.js +2 -5
- package/dist/contracts/applicationToolContracts.js +56 -109
- package/dist/contracts/applicationWorkflowInputContracts.js +27 -102
- package/dist/contracts/artifactComparisonExample.js +58 -60
- package/dist/contracts/artifactToolContracts.js +20 -67
- package/dist/contracts/browserScenarioToolContracts.js +6 -51
- package/dist/contracts/browserToolContracts.js +8 -73
- package/dist/contracts/electronToolContracts.js +8 -108
- package/dist/contracts/enhancedInputs.js +23 -54
- package/dist/contracts/errorSchemas.js +0 -1
- package/dist/contracts/functionComparisonExample.js +10 -24
- package/dist/contracts/functionInstructionContract.js +1 -3
- package/dist/contracts/functionWorkflowToolContracts.js +2 -2
- package/dist/contracts/hopperMemoryContracts.js +3 -3
- package/dist/contracts/investigationExamples.js +14 -11
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +12 -19
- package/dist/contracts/javascriptRuntimeObservationToolContracts.js +2 -20
- package/dist/contracts/javascriptRuntimeReconciliationExample.js +45 -12
- package/dist/contracts/managedToolContracts.js +6 -95
- package/dist/contracts/managedWorkflowExamples.js +77 -128
- package/dist/contracts/managedWorkflowToolContracts.js +51 -77
- package/dist/contracts/nativeToolContracts.js +7 -11
- package/dist/contracts/processCaptureExample.js +2 -69
- package/dist/contracts/promptContracts.js +49 -67
- package/dist/contracts/providerSelection.js +0 -1
- package/dist/contracts/reconstructionReadinessExample.js +1 -6
- package/dist/contracts/sessionStatusContract.js +1 -17
- package/dist/contracts/sessionToolSchemas.js +6 -15
- package/dist/contracts/toolContractExamples.js +11 -11
- package/dist/contracts/toolContractHelpers.js +0 -4
- package/dist/contracts/toolContracts.js +60 -71
- package/dist/contracts/toolEffects.js +5 -13
- package/dist/contracts/toolOutputSchemaGroups.js +37 -91
- package/dist/contracts/toolOutputSchemaPrimitives.js +16 -56
- package/dist/contracts/toolSchemaMetadata.js +8 -19
- package/dist/contracts/unknownContractExamples.js +0 -2
- package/dist/domain/analysisErrorPresentation.js +46 -54
- package/dist/domain/analysisErrorProjection.js +28 -37
- package/dist/domain/analysisProfile.js +3 -31
- package/dist/domain/analysisSnapshot.js +3 -12
- package/dist/domain/androidApplication.js +15 -54
- package/dist/domain/appleApplication.js +24 -67
- package/dist/domain/artifactComparison.js +11 -29
- package/dist/domain/artifactGraph.js +14 -44
- package/dist/domain/artifactInspection.js +38 -69
- package/dist/domain/artifactInventoryEvidence.js +27 -21
- package/dist/domain/binaryTarget.js +2 -221
- package/dist/domain/browserCaptureComparison.js +47 -24
- package/dist/domain/browserObservation.js +28 -193
- package/dist/domain/browserObservationSchemas.js +5 -23
- package/dist/domain/browserScenario.js +11 -14
- package/dist/domain/browserScenarioCapture.js +11 -12
- package/dist/domain/browserScenarioCaptureValues.js +146 -84
- package/dist/domain/browserScenarioDiff.js +2 -59
- package/dist/domain/browserScenarioDiffEvidence.js +51 -0
- package/dist/domain/browserScenarioDiffValues.js +21 -38
- package/dist/domain/browserScenarioValues.js +80 -109
- package/dist/domain/browserSession.js +4 -7
- package/dist/domain/bundleComparison.js +6 -32
- package/dist/domain/bytecodeProvider.js +20 -19
- package/dist/domain/callPath.js +47 -167
- package/dist/domain/callPathSchemas.js +79 -0
- package/dist/domain/changedBehavior.js +34 -60
- package/dist/domain/completionLedgerGeneration.js +8 -14
- package/dist/domain/conformancePackage.js +126 -97
- package/dist/domain/conformanceReplay.js +36 -8
- package/dist/domain/conformanceTrustGate.js +23 -14
- package/dist/domain/customProtocolCapture.js +1 -1
- package/dist/domain/electronActiveObservation.js +70 -103
- package/dist/domain/electronObservation.js +14 -80
- package/dist/domain/electronStaticAnalysisBrowser.js +36 -46
- package/dist/domain/electronStaticAnalysisIpc.js +38 -14
- package/dist/domain/electronStaticAnalysisNative.js +1 -8
- package/dist/domain/electronStaticAnalysisValues.js +10 -17
- package/dist/domain/errors.js +33 -54
- package/dist/domain/eventProcessTree.js +20 -12
- package/dist/domain/evidence.js +2 -10
- package/dist/domain/evidenceBundle.js +3 -5
- package/dist/domain/evidenceCompletionLedger.js +6 -8
- package/dist/domain/functionComparison.js +4 -14
- package/dist/domain/functionComparisonNormalization.js +4 -11
- package/dist/domain/functionComparisonResults.js +25 -15
- package/dist/domain/functionComparisonSchemas.js +49 -33
- package/dist/domain/functionDossierEvidence.js +31 -156
- package/dist/domain/hopperStartupFailure.js +1 -1
- package/dist/domain/hopperValues.js +15 -136
- package/dist/domain/interfaceBuilderGraph.js +654 -0
- package/dist/domain/javascriptApplicationAnalysis.js +8 -112
- package/dist/domain/javascriptApplicationChangeGraph.js +22 -82
- package/dist/domain/javascriptApplicationEvidenceSchemas.js +59 -47
- package/dist/domain/javascriptApplicationGraph.js +3 -13
- package/dist/domain/javascriptApplicationGraphSchemas.js +12 -34
- package/dist/domain/javascriptApplicationVersionComparison.js +26 -30
- package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +123 -68
- package/dist/domain/javascriptApplicationVersionItems.js +120 -53
- package/dist/domain/javascriptApplicationVersionKeys.js +24 -11
- package/dist/domain/javascriptAstFingerprint.js +25 -58
- package/dist/domain/javascriptAstValues.js +9 -0
- package/dist/domain/javascriptExportInstrumentation.js +2 -4
- package/dist/domain/javascriptExportShapeComparison.js +6 -7
- package/dist/domain/javascriptExportShapeComparisonSchemas.js +68 -75
- package/dist/domain/javascriptExportShapeSelection.js +17 -19
- package/dist/domain/javascriptFeatureSeed.js +20 -12
- package/dist/domain/javascriptFeatureTrace.js +13 -67
- package/dist/domain/javascriptFeatureTraceSchemas.js +24 -52
- package/dist/domain/javascriptFeatureTraversal.js +1 -44
- package/dist/domain/javascriptNativeHandoff.js +1 -1
- package/dist/domain/javascriptReplay.js +24 -41
- package/dist/domain/javascriptRuntimeLoadState.js +3 -8
- package/dist/domain/javascriptRuntimeObservation.js +42 -103
- package/dist/domain/javascriptRuntimeReconciliation.js +1 -3
- package/dist/domain/javascriptRuntimeReconciliationActive.js +8 -17
- package/dist/domain/javascriptRuntimeReconciliationGraph.js +10 -23
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +18 -12
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +16 -45
- package/dist/domain/javascriptRuntimeReconciliationResult.js +4 -5
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +8 -12
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +33 -48
- package/dist/domain/javascriptRuntimeStaticCandidates.js +3 -3
- package/dist/domain/javascriptSemanticAnalysis.js +12 -45
- package/dist/domain/javascriptSemanticAsyncEffects.js +1 -9
- package/dist/domain/javascriptSemanticCallResolution.js +6 -16
- package/dist/domain/javascriptSemanticCalls.js +5 -32
- package/dist/domain/javascriptSemanticChildProcesses.js +1 -11
- package/dist/domain/javascriptSemanticCoverage.js +11 -0
- package/dist/domain/javascriptSemanticDataEffectHelpers.js +1 -8
- package/dist/domain/javascriptSemanticDataEffects.js +1 -11
- package/dist/domain/javascriptSemanticFingerprints.js +3 -5
- package/dist/domain/javascriptSemanticGraphSchemas.js +25 -51
- package/dist/domain/javascriptSemanticGraphSerialization.js +2 -13
- package/dist/domain/javascriptSemanticIr.js +1 -29
- package/dist/domain/javascriptSemanticObjects.js +1 -5
- package/dist/domain/javascriptSemanticPrimitives.js +2 -9
- package/dist/domain/javascriptSemanticProjection.js +0 -18
- package/dist/domain/javascriptSemanticPromises.js +9 -16
- package/dist/domain/javascriptSemanticProvenance.js +16 -19
- package/dist/domain/javascriptSemanticQuery.js +17 -139
- package/dist/domain/javascriptSemanticQueryAssessment.js +9 -37
- package/dist/domain/javascriptSemanticQueryIdentity.js +2 -23
- package/dist/domain/javascriptSemanticQuerySchemas.js +14 -107
- package/dist/domain/javascriptSemanticResources.js +1 -6
- package/dist/domain/javascriptSemanticReturns.js +10 -27
- package/dist/domain/javascriptSemanticValueTypes.js +1 -0
- package/dist/domain/javascriptSemanticValues.js +44 -62
- package/dist/domain/javascriptStaticAnalysis.js +21 -43
- package/dist/domain/javascriptStaticAnalysisBundler.js +34 -93
- package/dist/domain/javascriptStaticAnalysisCalls.js +17 -16
- package/dist/domain/javascriptStaticAnalysisFindings.js +3 -19
- package/dist/domain/javascriptStaticAnalysisHelpers.js +47 -88
- package/dist/domain/javascriptStaticAnalysisState.js +1 -5
- package/dist/domain/javascriptStaticAnalysisTypes.js +1 -0
- package/dist/domain/jsonShape.js +7 -33
- package/dist/domain/localPath.js +7 -0
- package/dist/domain/managedApplicationGraph.js +9 -41
- package/dist/domain/managedApplicationGraphCoverage.js +24 -156
- package/dist/domain/managedApplicationGraphNodes.js +10 -13
- package/dist/domain/managedArtifact.js +14 -27
- package/dist/domain/managedMemberComparison.js +90 -92
- package/dist/domain/managedMemberComparisonCoverage.js +11 -33
- package/dist/domain/managedMemberComparisonItems.js +221 -0
- package/dist/domain/managedMemberComparisonMatch.js +8 -208
- package/dist/domain/managedNativeVerification.js +3 -6
- package/dist/domain/managedNativeVerificationMatch.js +55 -59
- package/dist/domain/managedNativeVerificationSchemas.js +83 -47
- package/dist/domain/managedReconstruction.js +19 -23
- package/dist/domain/managedRuntimeCorrelation.js +6 -9
- package/dist/domain/nativeApiBoundary.js +2 -7
- package/dist/domain/nativeInspection.js +0 -2
- package/dist/domain/nativeInvestigationGraph.js +351 -0
- package/dist/domain/nativeValueFlow.js +61 -0
- package/dist/domain/nodeRuntimeCharacterization.js +1 -5
- package/dist/domain/objcSwiftMetadata.js +254 -0
- package/dist/domain/peInspection.js +1 -1
- package/dist/domain/permissionPolicy.js +13 -0
- package/dist/domain/processCapture.js +76 -113
- package/dist/domain/processCaptureExample.js +68 -0
- package/dist/domain/processCaptureParsing.js +21 -0
- package/dist/domain/processCaptureReactiveSchema.js +68 -0
- package/dist/domain/processCaptureValidation.js +1 -7
- package/dist/domain/processComparison.js +3 -12
- package/dist/domain/processReactiveMatching.js +29 -50
- package/dist/domain/processReactiveRuntime.js +4 -8
- package/dist/domain/processReactiveScenario.js +28 -94
- package/dist/domain/processReactiveScenarioPreflight.js +5 -30
- package/dist/domain/processReactiveTransition.js +33 -18
- package/dist/domain/processScenario.js +56 -90
- package/dist/domain/processTraceComparison.js +0 -8
- package/dist/domain/processTraceEvaluation.js +14 -4
- package/dist/domain/processTraceSpecification.js +11 -17
- package/dist/domain/protocolCapture.js +3 -3
- package/dist/domain/reconstructionCoverage.js +62 -129
- package/dist/domain/reconstructionCoverageEvaluation.js +17 -17
- package/dist/domain/reconstructionObligationLedgerSchemas.js +45 -72
- package/dist/domain/reconstructionReadiness.js +1 -2
- package/dist/domain/reconstructionReadinessSchemas.js +36 -38
- package/dist/domain/reconstructionUnknowns.js +3 -3
- package/dist/domain/reconstructionVerification.js +13 -47
- package/dist/domain/reconstructionVerificationSchemas.js +50 -38
- package/dist/domain/referenceSourceGraph.js +53 -61
- package/dist/domain/referenceSourceImportParsing.js +1 -5
- package/dist/domain/replayMachine.js +19 -31
- package/dist/domain/replayMachineRun.js +15 -63
- package/dist/domain/replayMachineRuntime.js +41 -41
- package/dist/domain/replayMachineValues.js +84 -0
- package/dist/domain/residualUnknown.js +25 -30
- package/dist/domain/runtimeCharacterization.js +15 -16
- package/dist/domain/runtimeIdentification.js +48 -47
- package/dist/domain/sourceToBundleComparison.js +9 -85
- package/dist/domain/sourceToBundleComparisonSchemas.js +17 -42
- package/dist/domain/sourceToBundleSignals.js +4 -15
- package/dist/domain/staticRuntimeCorrelation.js +37 -49
- package/dist/domain/symbolAnalysis.js +10 -19
- package/dist/domain/unicodeCodePointOrder.js +12 -0
- package/dist/domain/webBundleAnalysis.js +70 -99
- package/dist/domain/webBundleAnalyzer.js +2 -4
- package/dist/domain/webBundleAnalyzerAst.js +0 -13
- package/dist/domain/webBundleAnalyzerInspection.js +26 -52
- package/dist/domain/webBundleAnalyzerResult.js +7 -24
- package/dist/domain/webCaptureDiff.js +33 -73
- package/dist/domain/webCaptureDiffSchemas.js +86 -0
- package/dist/domain/webContentArtifact.js +1 -10
- package/dist/domain/webMcpDiscovery.js +3 -14
- package/dist/domain/webScreenshot.js +58 -34
- package/dist/domain/zipPackageFormat.js +7 -0
- package/dist/dotnet/ManagedArtifactInspector.js +17 -50
- package/dist/dotnet/ManagedMemberInspector.js +27 -58
- package/dist/dotnet/ManagedMemberInspectorCore.js +14 -51
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +2 -2
- package/dist/dotnet/ManagedMemberRows.js +16 -16
- package/dist/dotnet/ManagedMetadataHeaps.js +26 -8
- package/dist/dotnet/ManagedMetadataInventory.js +21 -30
- package/dist/dotnet/ManagedMetadataInventoryRows.js +57 -63
- package/dist/dotnet/ManagedMetadataLayout.js +3 -5
- package/dist/dotnet/ManagedMethodBodyReader.js +5 -30
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +19 -49
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +13 -41
- package/dist/dotnet/ManagedPeReader.js +2 -2
- package/dist/dotnet/ManagedStaticProvider.js +13 -71
- package/dist/generatedMcpToolCatalog.js +1 -1
- package/dist/generatedPackageMetadata.js +1 -1
- package/dist/ghidra/GhidraAnalysisProfile.js +3 -8
- package/dist/ghidra/GhidraClient.js +4 -12
- package/dist/ghidra/GhidraClientWire.js +9 -5
- package/dist/ghidra/GhidraDefaults.js +0 -18
- package/dist/ghidra/GhidraDiagnostics.js +0 -2
- package/dist/ghidra/GhidraDoctor.js +16 -12
- package/dist/ghidra/GhidraFunctionValues.js +65 -108
- package/dist/ghidra/GhidraInstallation.js +98 -42
- package/dist/ghidra/GhidraInventoryValues.js +16 -85
- package/dist/ghidra/GhidraLauncher.js +0 -8
- package/dist/ghidra/GhidraProvider.js +15 -22
- package/dist/ghidra/GhidraProviderCapabilities.js +6 -47
- package/dist/ghidra/GhidraRequestQueue.js +6 -30
- package/dist/ghidra/GhidraResponseBuffer.js +1 -7
- package/dist/ghidra/GhidraSessionValues.js +0 -2
- package/dist/ghidra/GhidraTransport.js +4 -7
- package/dist/ghidra/protocol.js +2 -2
- package/dist/hopper/BridgeLauncher.js +112 -36
- package/dist/hopper/HopperAnalysisProfile.js +1 -1
- package/dist/hopper/HopperCleanup.js +6 -3
- package/dist/hopper/HopperClient.js +4 -7
- package/dist/hopper/HopperProcessDiagnostic.js +2 -2
- package/dist/hopper/HopperProvider.js +0 -16
- package/dist/hopper/HopperRequestQueue.js +21 -40
- package/dist/hopper/HopperResponseStream.js +1 -9
- package/dist/hopper/HopperSessionValues.js +3 -2
- package/dist/hopper/HopperTargetLease.js +119 -0
- package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +24 -31
- package/dist/hopper/LinuxPrivateDisplayProbe.js +5 -16
- package/dist/hopper/protocol.js +6 -4
- package/dist/main/reload.js +0 -3
- package/dist/main/shutdown.js +1 -1
- package/dist/main/state.js +0 -9
- package/dist/main/transport.js +0 -5
- package/dist/mcpDoctor.js +25 -45
- package/dist/native/CommandRunner.js +18 -25
- package/dist/native/NativeMacOSProvider.js +13 -38
- package/dist/native/NativeMachoInspection.js +1 -1
- package/dist/process/BoundedFileBytes.js +17 -0
- package/dist/process/ExecFileOutput.js +11 -0
- package/dist/process/PendingOperations.js +8 -6
- package/dist/process/ProcessOwnership.js +3 -2
- package/dist/process/ProcessOwnershipObservation.js +0 -1
- package/dist/process/ProviderProcess.js +7 -28
- package/dist/reference/ReferenceSourceReader.js +8 -24
- package/dist/reference/ReferenceSourceReaderEntries.js +11 -39
- package/dist/reference/ReferenceSourceReaderFile.js +13 -31
- package/dist/reference/ReferenceSourceReaderPaths.js +3 -18
- package/dist/reference/ReferenceSourceReaderValidate.js +3 -6
- package/dist/replay/JavaScriptReplayWorker.js +3 -5
- package/dist/replay/LinuxJavaScriptReplayRunner.js +33 -29
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +0 -19
- package/dist/replay/LinuxRuntimeClosure.js +1 -3
- package/dist/replay/ReplayOutcome.js +1 -3
- package/dist/replay/ReplayProcessLifecycle.js +32 -7
- package/dist/replay/ReplaySeccompFile.js +29 -0
- package/dist/replay/ReplayWorkerProtocol.js +0 -2
- package/dist/replay/SystemJavaScriptReplayHost.js +45 -74
- package/dist/server/ProcessCaptureElicitation.js +4 -8
- package/dist/server/createServer.js +6 -44
- package/dist/server/promptCompletion.js +37 -61
- package/dist/server/recordDerivedEvidence.js +1 -1
- package/dist/server/registerApplicationTools/characterization.js +4 -8
- package/dist/server/registerApplicationTools/compareExportShapes.js +5 -10
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +6 -10
- package/dist/server/registerApplicationTools/compareVersions.js +5 -10
- package/dist/server/registerApplicationTools/controlledReplay.js +3 -5
- package/dist/server/registerApplicationTools/coverage.js +6 -71
- package/dist/server/registerApplicationTools/helpers.js +1 -13
- package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
- package/dist/server/registerApplicationTools/traceFeature.js +5 -9
- package/dist/server/registerApplicationTools/traceSemantics.js +5 -8
- package/dist/server/registerApplicationTools.js +0 -2
- package/dist/server/registerArtifactComparisonTool.js +23 -27
- package/dist/server/registerBrowserScenarioTool.js +4 -4
- package/dist/server/registerBrowserTools.js +5 -8
- package/dist/server/registerBundleComparisonTool.js +5 -7
- package/dist/server/registerCloseLifecycleTool.js +2 -16
- package/dist/server/registerElectronTools.js +10 -29
- package/dist/server/registerEnhancedTools.js +10 -11
- package/dist/server/registerEvidenceTools.js +15 -22
- package/dist/server/registerFunctionComparisonTool.js +30 -25
- package/dist/server/registerInvestigationTools/helpers.js +3 -32
- package/dist/server/registerInvestigationTools.js +20 -116
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -4
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +15 -17
- package/dist/server/registerManagedWorkflowTools/evidence.js +19 -35
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -8
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +3 -8
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +10 -14
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +9 -15
- package/dist/server/registerOfficialTools.js +1 -43
- package/dist/server/registerProcessComparisonTool.js +33 -23
- package/dist/server/registerPrompts.js +19 -17
- package/dist/server/registerSessionRecordTools.js +10 -156
- package/dist/server/registerSessionStatusTool.js +6 -69
- package/dist/server/registerSessionTools.js +10 -51
- package/dist/server/sessionAvailabilityPolicy.js +0 -2
- package/dist/server/sessionEvidence.js +9 -15
- package/dist/server/sessionToolPolicies.js +0 -8
- package/dist/server/toolResult.js +14 -50
- package/dist/serverIdentity.js +0 -20
- package/install.sh +1 -1
- package/package.json +11 -7
- package/scripts/electron-active-hook.cjs +23 -55
- package/scripts/hopper-demo-x11.py +13 -32
- package/skills/reverse-engineer-anything/SKILL.md +47 -12
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +6 -4
- package/skills/reverse-engineer-anything/references/javascript-applications.md +13 -13
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +12 -8
- package/dist/application/ApplicationWorkflowEvidenceResolver.js +0 -188
- package/dist/application/BoundedJsonFiles.js +0 -86
- package/dist/application/CrossVersionInventory.js +0 -129
- package/dist/application/CrossVersionInvestigation.js +0 -301
- package/dist/application/CrossVersionInvestigationCollections.js +0 -23
- package/dist/application/CrossVersionInvestigationEvidence.js +0 -64
- package/dist/application/CrossVersionInvestigationReplay.js +0 -170
- package/dist/application/DeferredFileAuthorization.js +0 -61
- package/dist/application/DoctorProjection.js +0 -43
- package/dist/application/EnhancedToolPagination.js +0 -22
- package/dist/application/EvidenceReferenceResolver.js +0 -26
- package/dist/application/InvestigationWorkspaceStore.js +0 -204
- package/dist/application/ProcessPairedExperiment.js +0 -72
- package/dist/application/ReconstructionCoverageWorkspaceStore.js +0 -31
- package/dist/application/ReconstructionReadinessService.js +0 -48
- package/dist/cliInvestigationCommands.js +0 -173
- package/dist/domain/boundedCartesianProjection.js +0 -15
- package/dist/domain/investigationWorkspace.js +0 -347
- package/dist/domain/jsonLimits.js +0 -26
- package/dist/domain/knownPageCoverage.js +0 -29
- package/dist/domain/processPairedExperiment.js +0 -128
- package/dist/server/javascriptApplicationResult.js +0 -106
- package/dist/server/permissionFailure.js +0 -12
- package/dist/server/registerApplicationTools/readiness.js +0 -50
- package/dist/server/registerEvidenceResources.js +0 -315
- package/dist/server/registerJavaScriptApplicationGraphResource.js +0 -65
- package/dist/server/registerReconstructionObligationLedgerResource.js +0 -32
- package/dist/server/registerReconstructionReadinessResource.js +0 -32
|
@@ -1,17 +1,7 @@
|
|
|
1
1
|
import { realpath } from "node:fs/promises";
|
|
2
|
-
import { ArtifactReaderFailure } from "../artifacts/ArtifactReader.js";
|
|
3
|
-
import { withinRoot } from "../reference/ReferenceSourceReaderPaths.js";
|
|
4
2
|
import { scanCanonicalArtifactInventory, } from "./ArtifactInventory.js";
|
|
5
|
-
import { canonicalizeConfiguredRoots } from "./ConfiguredRoots.js";
|
|
6
3
|
/** Resolve, authorize, and scan one artifact without a second path resolution. */
|
|
7
|
-
export const scanAuthorizedArtifactInventory = async (inputPath,
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
const [path, approved] = await Promise.all([
|
|
11
|
-
realpath(inputPath),
|
|
12
|
-
canonicalizeConfiguredRoots(roots),
|
|
13
|
-
]);
|
|
14
|
-
if (!approved.some((root) => withinRoot(root, path)))
|
|
15
|
-
throw new ArtifactReaderFailure("path", "Artifact path is outside approved input roots");
|
|
16
|
-
return scanCanonicalArtifactInventory(path, limits, options);
|
|
4
|
+
export const scanAuthorizedArtifactInventory = async (inputPath, options = {}) => {
|
|
5
|
+
const path = await realpath(inputPath);
|
|
6
|
+
return scanCanonicalArtifactInventory(path, options);
|
|
17
7
|
};
|
|
@@ -19,20 +19,15 @@ const ENHANCED_OPERATIONS = new Set(GENERATED_MCP_TOOL_CATALOG.filter(({ kind })
|
|
|
19
19
|
* of retaining a client whose resources were already shut down.
|
|
20
20
|
*/
|
|
21
21
|
export class BinarySession extends BinarySessionRecords {
|
|
22
|
-
provider;
|
|
23
22
|
#active;
|
|
24
23
|
#transition = Promise.resolve();
|
|
25
24
|
#calls = new Set();
|
|
26
25
|
#providerRouter;
|
|
27
26
|
#runtimeUnavailability = new Map();
|
|
28
27
|
#availabilityListeners = new Set();
|
|
29
|
-
constructor(
|
|
28
|
+
constructor(providerRouter) {
|
|
30
29
|
super();
|
|
31
|
-
this
|
|
32
|
-
this.#providerRouter =
|
|
33
|
-
provider instanceof SessionProviderRouter
|
|
34
|
-
? provider
|
|
35
|
-
: SessionProviderRouter.legacy(provider, options);
|
|
30
|
+
this.#providerRouter = providerRouter;
|
|
36
31
|
}
|
|
37
32
|
/** Identify the provider producing evidence for this session. */
|
|
38
33
|
providerIdentity(operation) {
|
|
@@ -173,7 +168,14 @@ export class BinarySession extends BinarySessionRecords {
|
|
|
173
168
|
await this.#drainCalls();
|
|
174
169
|
const closed = previous === undefined
|
|
175
170
|
? ok(null)
|
|
176
|
-
: await closeAnalysisClient(previous.client, previous.route.identity.id,
|
|
171
|
+
: await closeAnalysisClient(previous.client, previous.route.identity.id, {
|
|
172
|
+
...(options.progress === undefined
|
|
173
|
+
? {}
|
|
174
|
+
: { progress: options.progress }),
|
|
175
|
+
...(options.retainProviderDocuments === true
|
|
176
|
+
? { retainDocument: true }
|
|
177
|
+
: {}),
|
|
178
|
+
});
|
|
177
179
|
this.clearSessionRecords();
|
|
178
180
|
this.#clearRuntimeAvailability();
|
|
179
181
|
return closed;
|
|
@@ -214,7 +216,9 @@ export class BinarySession extends BinarySessionRecords {
|
|
|
214
216
|
operation: name,
|
|
215
217
|
parameters: arguments_,
|
|
216
218
|
unboundOperationError: (operation, route) => this.#providerRouter.unboundOperationError(operation, route),
|
|
217
|
-
lookupSnapshot: (target, profile, operation, parameters) =>
|
|
219
|
+
lookupSnapshot: (target, profile, operation, parameters) => operation === "decode_interface_builder"
|
|
220
|
+
? undefined
|
|
221
|
+
: this.lookupSnapshot(target, profile, operation, parameters),
|
|
218
222
|
});
|
|
219
223
|
if (!prepared.ok)
|
|
220
224
|
return prepared;
|
|
@@ -225,9 +229,12 @@ export class BinarySession extends BinarySessionRecords {
|
|
|
225
229
|
this.#calls.add(call);
|
|
226
230
|
try {
|
|
227
231
|
const result = await call;
|
|
228
|
-
const profiled = commitExecutionProfile(name, result, profile);
|
|
232
|
+
const profiled = bindExecutionTarget(commitExecutionProfile(name, result, profile), name, active.target);
|
|
229
233
|
this.#observeRuntimeAvailability(name, profiled);
|
|
230
|
-
if (profiled.ok &&
|
|
234
|
+
if (profiled.ok &&
|
|
235
|
+
cacheable &&
|
|
236
|
+
profile !== undefined &&
|
|
237
|
+
name !== "decode_interface_builder")
|
|
231
238
|
this.recordSnapshot({
|
|
232
239
|
target: active.target,
|
|
233
240
|
profile,
|
|
@@ -259,7 +266,6 @@ export class BinarySession extends BinarySessionRecords {
|
|
|
259
266
|
"ProviderAdapterError",
|
|
260
267
|
"HopperProcessError",
|
|
261
268
|
"HopperStartError",
|
|
262
|
-
"HopperRemoteError",
|
|
263
269
|
].includes(result.error._tag)) {
|
|
264
270
|
const capabilities = this.#active?.route.capabilities;
|
|
265
271
|
const providerId = capabilities?.get(operation)?.provider.id;
|
|
@@ -267,7 +273,7 @@ export class BinarySession extends BinarySessionRecords {
|
|
|
267
273
|
for (const descriptor of capabilities?.values() ?? [])
|
|
268
274
|
if (providerId !== undefined && descriptor.provider.id === providerId)
|
|
269
275
|
changed =
|
|
270
|
-
this.#markRuntimeUnavailable(descriptor.operation,
|
|
276
|
+
this.#markRuntimeUnavailable(descriptor.operation, `${result.error._tag}: ${result.error.message}`) || changed;
|
|
271
277
|
if (changed)
|
|
272
278
|
this.#emitAvailabilityChanged();
|
|
273
279
|
}
|
|
@@ -370,3 +376,25 @@ const commitExecutionProfile = (operation, result, profile) => {
|
|
|
370
376
|
analysisProfile: structuredClone(profile),
|
|
371
377
|
});
|
|
372
378
|
};
|
|
379
|
+
const bindExecutionTarget = (result, operation, target) => {
|
|
380
|
+
if (!result.ok)
|
|
381
|
+
return result;
|
|
382
|
+
const subject = {
|
|
383
|
+
path: target.path,
|
|
384
|
+
sha256: target.sha256,
|
|
385
|
+
format: target.format === "analysis-database"
|
|
386
|
+
? "analysis-database"
|
|
387
|
+
: target.format,
|
|
388
|
+
...(target.architecture === undefined
|
|
389
|
+
? {}
|
|
390
|
+
: { architecture: target.architecture }),
|
|
391
|
+
};
|
|
392
|
+
if (result.value.subject !== null &&
|
|
393
|
+
result.value.subject.sha256 !== target.sha256) {
|
|
394
|
+
if (!isArtifactInventorySubject(operation, result.value.subject, target))
|
|
395
|
+
return err(new ProviderAdapterError(result.value.provider.id, `${operation}:subject`));
|
|
396
|
+
}
|
|
397
|
+
return ok({ ...result.value, subject: result.value.subject ?? subject });
|
|
398
|
+
};
|
|
399
|
+
const isArtifactInventorySubject = (operation, subject, target) => (operation === "inventory_artifact" || operation === "inspect_artifact") &&
|
|
400
|
+
subject.path === (target.sourcePath ?? target.path);
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
import { AnalysisProviderRegistry } from "./AnalysisProviderRegistry.js";
|
|
2
2
|
import { BinarySession } from "./BinarySession.js";
|
|
3
3
|
import { SessionProviderRouter } from "./SessionProviderRouter.js";
|
|
4
|
-
const normalizeBinarySessionOptions = (optionsOrResolver) => typeof optionsOrResolver === "function"
|
|
5
|
-
? { resolveAnalysisProfile: optionsOrResolver }
|
|
6
|
-
: (optionsOrResolver ?? {});
|
|
7
4
|
/**
|
|
8
5
|
* Compose one provider-neutral session from deep-provider selection and
|
|
9
6
|
* disjoint auxiliary operation families.
|
|
@@ -11,11 +8,3 @@ const normalizeBinarySessionOptions = (optionsOrResolver) => typeof optionsOrRes
|
|
|
11
8
|
export const composeBinarySession = (registry, auxiliaryProviders = []) => new BinarySession(registry instanceof SessionProviderRouter
|
|
12
9
|
? registry
|
|
13
10
|
: SessionProviderRouter.selectable(registry, auxiliaryProviders));
|
|
14
|
-
/**
|
|
15
|
-
* Compose a session through the same internal seam for focused adapter tests.
|
|
16
|
-
* The constructor remains private to this composition module, so callers test
|
|
17
|
-
* provider behavior without coupling to BinarySession construction.
|
|
18
|
-
*/
|
|
19
|
-
export const composeBinarySessionFromFactory = (provider, optionsOrResolver) => new BinarySession(provider, normalizeBinarySessionOptions(optionsOrResolver));
|
|
20
|
-
/** Compose a focused session from any provider-shaped test seam. */
|
|
21
|
-
export const composeBinarySessionFromProvider = (provider, optionsOrResolver) => new BinarySession(provider, normalizeBinarySessionOptions(optionsOrResolver));
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { snapshotMatchesBinding, snapshotMatchesTarget, snapshotTarget, } from "../domain/analysisSnapshot.js";
|
|
2
|
-
import { parseBinaryTarget
|
|
2
|
+
import { parseBinaryTarget } from "./BinaryTargetResolver.js";
|
|
3
|
+
import {} from "../domain/binaryTarget.js";
|
|
3
4
|
import { EvidenceIntegrityError, } from "../domain/errors.js";
|
|
4
5
|
import { err } from "../domain/result.js";
|
|
5
6
|
import { SessionProviderRouter } from "./SessionProviderRouter.js";
|
|
@@ -1,25 +1,14 @@
|
|
|
1
1
|
import { createEvidence } from "../domain/evidence.js";
|
|
2
|
-
import { evidenceBundleForTarget
|
|
3
|
-
import { EvidenceIntegrityError,
|
|
4
|
-
import { parseInvestigationWorkspace, } from "../domain/investigationWorkspace.js";
|
|
5
|
-
import { parseReconstructionCoverageWorkspace, } from "../domain/reconstructionCoverage.js";
|
|
2
|
+
import { evidenceBundleForTarget } from "../domain/evidenceBundle.js";
|
|
3
|
+
import { EvidenceIntegrityError, } from "../domain/errors.js";
|
|
6
4
|
import { err, ok } from "../domain/result.js";
|
|
7
5
|
import { AnalysisSnapshotCache } from "./AnalysisSnapshotCache.js";
|
|
8
6
|
import { EvidenceLedger } from "./EvidenceLedger.js";
|
|
9
7
|
import { UNKNOWN_REGISTRY_PROVIDER, unknownEvidenceLinks, unknownMutationEvidence, } from "./UnknownEvidence.js";
|
|
10
|
-
/** Owns session evidence, snapshots,
|
|
8
|
+
/** Owns session evidence, snapshots, and residual unknowns. */
|
|
11
9
|
export class BinarySessionRecords {
|
|
12
|
-
|
|
13
|
-
static MAX_RETAINED_BUNDLE_BYTES = 64 * 1024 * 1024;
|
|
14
|
-
#evidence = new EvidenceLedger({
|
|
15
|
-
maxRecords: 10_000,
|
|
16
|
-
maxBytes: 64 * 1024 * 1024,
|
|
17
|
-
});
|
|
10
|
+
#evidence = new EvidenceLedger();
|
|
18
11
|
#snapshot = new AnalysisSnapshotCache();
|
|
19
|
-
#retainedBundles = new Map();
|
|
20
|
-
#retainedBundleBytes = 0;
|
|
21
|
-
#investigationWorkspaces = new Map();
|
|
22
|
-
#coverageWorkspaces = new Map();
|
|
23
12
|
#snapshotInvalidated = false;
|
|
24
13
|
#snapshotListeners = new Set();
|
|
25
14
|
/** Observe changes to the mutable current analysis snapshot resource. */
|
|
@@ -42,45 +31,6 @@ export class BinarySessionRecords {
|
|
|
42
31
|
exportEvidenceBundle() {
|
|
43
32
|
return this.#evidence.export();
|
|
44
33
|
}
|
|
45
|
-
snapshotEvidenceBundle() {
|
|
46
|
-
const bundle = this.#evidence.export();
|
|
47
|
-
const encoded = serializeEvidenceBundle(bundle);
|
|
48
|
-
const digest = createHash("sha256").update(encoded).digest("hex");
|
|
49
|
-
const existing = this.#retainedBundles.get(digest);
|
|
50
|
-
if (existing === undefined) {
|
|
51
|
-
if (this.#retainedBundles.size >= BinarySessionRecords.MAX_RETAINED_BUNDLES)
|
|
52
|
-
return err(new EvidenceLimitError("records", BinarySessionRecords.MAX_RETAINED_BUNDLES));
|
|
53
|
-
const bytes = Buffer.byteLength(encoded);
|
|
54
|
-
if (this.#retainedBundleBytes + bytes >
|
|
55
|
-
BinarySessionRecords.MAX_RETAINED_BUNDLE_BYTES)
|
|
56
|
-
return err(new EvidenceLimitError("bytes", BinarySessionRecords.MAX_RETAINED_BUNDLE_BYTES));
|
|
57
|
-
this.#retainedBundles.set(digest, encoded);
|
|
58
|
-
this.#retainedBundleBytes += bytes;
|
|
59
|
-
}
|
|
60
|
-
return ok({
|
|
61
|
-
bundleDigest: digest,
|
|
62
|
-
bundleVersion: 2,
|
|
63
|
-
bytes: Buffer.byteLength(existing ?? encoded),
|
|
64
|
-
records: bundle.records.length,
|
|
65
|
-
unknowns: bundle.unknowns.length,
|
|
66
|
-
scope: "session",
|
|
67
|
-
survivesSession: false,
|
|
68
|
-
uri: `rea://evidence-bundle/${digest}`,
|
|
69
|
-
});
|
|
70
|
-
}
|
|
71
|
-
retainedEvidenceBundle(digest) {
|
|
72
|
-
return this.#retainedBundles.get(digest);
|
|
73
|
-
}
|
|
74
|
-
/** Release one immutable bundle so bounded retention has an explicit recovery path. */
|
|
75
|
-
releaseEvidenceBundle(bundleDigest) {
|
|
76
|
-
const encoded = this.#retainedBundles.get(bundleDigest);
|
|
77
|
-
if (encoded === undefined)
|
|
78
|
-
return false;
|
|
79
|
-
this.#retainedBundles.delete(bundleDigest);
|
|
80
|
-
this.#retainedBundleBytes -= Buffer.byteLength(encoded);
|
|
81
|
-
this.#emitSnapshotChanged();
|
|
82
|
-
return true;
|
|
83
|
-
}
|
|
84
34
|
importEvidenceBundle(bundle) {
|
|
85
35
|
const imported = this.#evidence.import(bundle);
|
|
86
36
|
if (!imported.ok)
|
|
@@ -148,8 +98,6 @@ export class BinarySessionRecords {
|
|
|
148
98
|
this.#evidence.clear();
|
|
149
99
|
this.#snapshot.clear();
|
|
150
100
|
this.#snapshotInvalidated = false;
|
|
151
|
-
this.#retainedBundles.clear();
|
|
152
|
-
this.#retainedBundleBytes = 0;
|
|
153
101
|
this.#emitSnapshotChanged();
|
|
154
102
|
}
|
|
155
103
|
#emitSnapshotChanged() {
|
|
@@ -165,36 +113,6 @@ export class BinarySessionRecords {
|
|
|
165
113
|
}
|
|
166
114
|
}
|
|
167
115
|
}
|
|
168
|
-
retainInvestigationWorkspace(workspace) {
|
|
169
|
-
const parsed = parseInvestigationWorkspace(workspace);
|
|
170
|
-
const key = workspaceKey(parsed.workspace_id, parsed.revision);
|
|
171
|
-
if (this.#investigationWorkspaces.has(key))
|
|
172
|
-
return "duplicate";
|
|
173
|
-
this.#investigationWorkspaces.set(key, parsed);
|
|
174
|
-
return "added";
|
|
175
|
-
}
|
|
176
|
-
investigationWorkspace(workspaceId, revision) {
|
|
177
|
-
const workspace = this.#investigationWorkspaces.get(workspaceKey(workspaceId, revision));
|
|
178
|
-
return workspace === undefined ? undefined : structuredClone(workspace);
|
|
179
|
-
}
|
|
180
|
-
investigationWorkspaces() {
|
|
181
|
-
return sortedWorkspaces(this.#investigationWorkspaces.values());
|
|
182
|
-
}
|
|
183
|
-
retainReconstructionCoverageWorkspace(workspace) {
|
|
184
|
-
const parsed = parseReconstructionCoverageWorkspace(workspace);
|
|
185
|
-
const key = workspaceKey(parsed.workspace_id, parsed.revision);
|
|
186
|
-
if (this.#coverageWorkspaces.has(key))
|
|
187
|
-
return "duplicate";
|
|
188
|
-
this.#coverageWorkspaces.set(key, parsed);
|
|
189
|
-
return "added";
|
|
190
|
-
}
|
|
191
|
-
reconstructionCoverageWorkspace(workspaceId, revision) {
|
|
192
|
-
const workspace = this.#coverageWorkspaces.get(workspaceKey(workspaceId, revision));
|
|
193
|
-
return workspace === undefined ? undefined : structuredClone(workspace);
|
|
194
|
-
}
|
|
195
|
-
reconstructionCoverageWorkspaces() {
|
|
196
|
-
return sortedWorkspaces(this.#coverageWorkspaces.values());
|
|
197
|
-
}
|
|
198
116
|
recordUnknown(input) {
|
|
199
117
|
const target = this.activeAnalysisBinding()?.target;
|
|
200
118
|
const recorded = this.#evidence.recordUnknown(input, unknownMutationEvidence(target, input));
|
|
@@ -211,7 +129,7 @@ export class BinarySessionRecords {
|
|
|
211
129
|
updateUnknown(input) {
|
|
212
130
|
const target = this.activeAnalysisBinding()?.target;
|
|
213
131
|
const evidence = createEvidence(target, UNKNOWN_REGISTRY_PROVIDER, {
|
|
214
|
-
predicateType: "rea.residual-unknown-mutation
|
|
132
|
+
predicateType: "rea.residual-unknown-mutation",
|
|
215
133
|
operation: "update_unknown",
|
|
216
134
|
parameters: {
|
|
217
135
|
unknown_id: input.unknown_id,
|
|
@@ -237,9 +155,3 @@ export class BinarySessionRecords {
|
|
|
237
155
|
return this.#evidence.verifyUnknownResolution(unknownId);
|
|
238
156
|
}
|
|
239
157
|
}
|
|
240
|
-
const workspaceKey = (workspaceId, revision) => `${workspaceId}:${String(revision)}`;
|
|
241
|
-
const sortedWorkspaces = (workspaces) => [...workspaces]
|
|
242
|
-
.sort((left, right) => left.workspace_id.localeCompare(right.workspace_id) ||
|
|
243
|
-
left.revision - right.revision)
|
|
244
|
-
.map((workspace) => structuredClone(workspace));
|
|
245
|
-
import { createHash } from "node:crypto";
|
|
@@ -4,6 +4,7 @@ export const binarySessionStatus = ({ target, route, router, runtimeUnavailabili
|
|
|
4
4
|
const provider = providerSummary(configuredProvider);
|
|
5
5
|
const providers = router.providerIdentities(route).map(providerSummary);
|
|
6
6
|
const capabilities = [...(route.capabilities?.values() ?? [])]
|
|
7
|
+
.filter(({ operation }) => operation !== "inventory_artifact")
|
|
7
8
|
.sort((left, right) => left.operation.localeCompare(right.operation))
|
|
8
9
|
.map((descriptor) => {
|
|
9
10
|
const unavailable = runtimeUnavailability.get(descriptor.operation);
|
|
@@ -32,6 +33,7 @@ export const binarySessionStatus = ({ target, route, router, runtimeUnavailabili
|
|
|
32
33
|
selected: candidate.selected,
|
|
33
34
|
capabilities: candidate.capabilities
|
|
34
35
|
.slice()
|
|
36
|
+
.filter(({ operation }) => operation !== "inventory_artifact")
|
|
35
37
|
.sort((left, right) => left.operation.localeCompare(right.operation))
|
|
36
38
|
.map(capabilityStatus),
|
|
37
39
|
}));
|
|
@@ -73,7 +75,6 @@ const requestActivityStatus = (snapshots) => {
|
|
|
73
75
|
request_id: active.requestId,
|
|
74
76
|
operation: active.operation,
|
|
75
77
|
elapsed_ms: active.elapsedMs,
|
|
76
|
-
timeout_ms: active.timeoutMs,
|
|
77
78
|
caller_state: active.callerState,
|
|
78
79
|
},
|
|
79
80
|
queued_requests: queuedRequests,
|
|
@@ -82,11 +83,9 @@ const requestActivityStatus = (snapshots) => {
|
|
|
82
83
|
return {
|
|
83
84
|
status: snapshots.length === 0
|
|
84
85
|
? "not_observed"
|
|
85
|
-
: active.
|
|
86
|
-
? "
|
|
87
|
-
:
|
|
88
|
-
? "busy"
|
|
89
|
-
: "idle",
|
|
86
|
+
: active.length > 0
|
|
87
|
+
? "busy"
|
|
88
|
+
: "idle",
|
|
90
89
|
providers,
|
|
91
90
|
};
|
|
92
91
|
};
|
|
@@ -111,7 +110,6 @@ const processLineageStatus = (snapshots) => snapshots.length === 0
|
|
|
111
110
|
: {
|
|
112
111
|
status: observation.status,
|
|
113
112
|
observed_at: observation.observedAt,
|
|
114
|
-
schema_version: observation.lineage.schemaVersion,
|
|
115
113
|
launcher_pid: observation.lineage.launcherPid,
|
|
116
114
|
launcher_parent_pid: observation.lineage.launcherParentPid,
|
|
117
115
|
process_group_id: observation.lineage.processGroupId,
|
|
@@ -128,10 +126,6 @@ const capabilityStatus = (descriptor) => ({
|
|
|
128
126
|
available: descriptor.available,
|
|
129
127
|
reason: descriptor.reason,
|
|
130
128
|
availability_code: descriptor.availabilityCode ?? null,
|
|
131
|
-
input_contract_version: descriptor.inputContractVersion,
|
|
132
|
-
output_contract_version: descriptor.outputContractVersion,
|
|
133
|
-
pagination: descriptor.pagination,
|
|
134
|
-
exhaustive: descriptor.exhaustive,
|
|
135
129
|
effects: {
|
|
136
130
|
mutates_artifact: descriptor.effects.mutatesArtifact,
|
|
137
131
|
launches_process: descriptor.effects.launchesProcess,
|
|
@@ -141,10 +135,5 @@ const capabilityStatus = (descriptor) => ({
|
|
|
141
135
|
changes_permissions: descriptor.effects.changesPermissions,
|
|
142
136
|
requires_root: descriptor.effects.requiresRoot,
|
|
143
137
|
},
|
|
144
|
-
limits: {
|
|
145
|
-
max_results: descriptor.limits.maxResults,
|
|
146
|
-
max_payload_bytes: descriptor.limits.maxPayloadBytes,
|
|
147
|
-
timeout_ms: descriptor.limits.timeoutMs,
|
|
148
|
-
},
|
|
149
138
|
limitations: [...descriptor.limitations],
|
|
150
139
|
});
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { constants } from "node:fs";
|
|
2
|
+
import { createHash } from "node:crypto";
|
|
3
|
+
import { access, open, readFile, realpath, stat, } from "node:fs/promises";
|
|
4
|
+
import { execFile } from "node:child_process";
|
|
5
|
+
import { extname, isAbsolute, join, resolve } from "node:path";
|
|
6
|
+
import { promisify } from "node:util";
|
|
7
|
+
import { isPathWithinRoot } from "../domain/localPath.js";
|
|
8
|
+
import { BinaryTargetError } from "../domain/errors.js";
|
|
9
|
+
import { err, ok } from "../domain/result.js";
|
|
10
|
+
import { hasZipSignature, zipPackageFormatForPath, } from "../domain/zipPackageFormat.js";
|
|
11
|
+
import { parseExecutableHeader, parsePeRecord, } from "../domain/binaryTarget.js";
|
|
12
|
+
const execFileAsync = promisify(execFile);
|
|
13
|
+
/**
|
|
14
|
+
* Resolve and classify a readable local target before a provider is selected.
|
|
15
|
+
* FAT Mach-O inputs select only a host-compatible architecture so setup remains
|
|
16
|
+
* non-interactive; unsupported or ambiguous inputs are returned as typed errors.
|
|
17
|
+
*/
|
|
18
|
+
export const parseBinaryTarget = async (input, cwd = process.cwd(), hostArchitecture = process.arch, targetKind) => {
|
|
19
|
+
const candidate = isAbsolute(input) ? input : resolve(cwd, input);
|
|
20
|
+
try {
|
|
21
|
+
await access(candidate, constants.R_OK);
|
|
22
|
+
const canonical = await realpath(candidate);
|
|
23
|
+
const resolved = await resolveAppBundle(canonical);
|
|
24
|
+
if (!resolved.ok)
|
|
25
|
+
return err(resolved.error);
|
|
26
|
+
const path = resolved.value;
|
|
27
|
+
const handle = await open(path, "r");
|
|
28
|
+
try {
|
|
29
|
+
if (!(await handle.stat()).isFile())
|
|
30
|
+
return err(new BinaryTargetError(path, "target is not a regular file"));
|
|
31
|
+
if (targetKind === "database" ||
|
|
32
|
+
(targetKind === undefined && path.toLowerCase().endsWith(".hop")))
|
|
33
|
+
return ok({
|
|
34
|
+
path,
|
|
35
|
+
sourcePath: canonical,
|
|
36
|
+
sha256: await sha256Handle(handle),
|
|
37
|
+
kind: "database",
|
|
38
|
+
format: "analysis-database",
|
|
39
|
+
});
|
|
40
|
+
const artifactFormat = await detectArtifactFormat(path, handle);
|
|
41
|
+
if (artifactFormat !== undefined) {
|
|
42
|
+
const identity = {
|
|
43
|
+
path,
|
|
44
|
+
sourcePath: canonical,
|
|
45
|
+
sha256: await sha256Handle(handle),
|
|
46
|
+
};
|
|
47
|
+
return isArchiveFormat(artifactFormat)
|
|
48
|
+
? ok({ ...identity, kind: "archive", format: artifactFormat })
|
|
49
|
+
: ok({ ...identity, kind: "artifact", format: artifactFormat });
|
|
50
|
+
}
|
|
51
|
+
const detected = await readExecutableMetadata(handle, hostArchitecture);
|
|
52
|
+
if (!detected.ok)
|
|
53
|
+
return err(new BinaryTargetError(path, detected.error));
|
|
54
|
+
return ok({
|
|
55
|
+
path,
|
|
56
|
+
sourcePath: canonical,
|
|
57
|
+
sha256: await sha256Handle(handle),
|
|
58
|
+
kind: "executable",
|
|
59
|
+
...detected.value,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
finally {
|
|
63
|
+
await handle.close();
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch (cause) {
|
|
67
|
+
return err(new BinaryTargetError(candidate, "path is not readable", { cause }));
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
const detectArtifactFormat = async (path, handle) => {
|
|
71
|
+
const lower = path.toLowerCase();
|
|
72
|
+
const magic = Buffer.alloc(8);
|
|
73
|
+
const observed = await handle.read(magic, 0, magic.length, 0);
|
|
74
|
+
if (hasZipSignature(magic.subarray(0, observed.bytesRead))) {
|
|
75
|
+
return zipPackageFormatForPath(lower) ?? "zip";
|
|
76
|
+
}
|
|
77
|
+
const named = namedArtifactFormat(lower);
|
|
78
|
+
if (named !== undefined)
|
|
79
|
+
return named;
|
|
80
|
+
if (lower.endsWith(".pkg") &&
|
|
81
|
+
observed.bytesRead >= 4 &&
|
|
82
|
+
magic.subarray(0, 4).toString("ascii") === "xar!")
|
|
83
|
+
return "pkg";
|
|
84
|
+
if (lower.endsWith(".dmg")) {
|
|
85
|
+
const size = (await handle.stat()).size;
|
|
86
|
+
if (size >= 512) {
|
|
87
|
+
const trailer = Buffer.alloc(4);
|
|
88
|
+
const read = await handle.read(trailer, 0, trailer.length, size - 512);
|
|
89
|
+
if (read.bytesRead === 4 && trailer.toString("ascii") === "koly")
|
|
90
|
+
return "dmg";
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return undefined;
|
|
94
|
+
};
|
|
95
|
+
const namedArtifactFormat = (lowerPath) => {
|
|
96
|
+
if (lowerPath.endsWith(".asar"))
|
|
97
|
+
return "asar";
|
|
98
|
+
if (lowerPath.endsWith(".plist"))
|
|
99
|
+
return "plist";
|
|
100
|
+
if (lowerPath.endsWith(".map"))
|
|
101
|
+
return "source-map";
|
|
102
|
+
return /\.(?:m?js|cjs)$/u.test(lowerPath) ? "javascript" : undefined;
|
|
103
|
+
};
|
|
104
|
+
const isArchiveFormat = (format) => ["zip", "ipa", "apk", "msix", "appx", "asar", "dmg", "pkg"].includes(format);
|
|
105
|
+
const sha256Handle = async (handle) => {
|
|
106
|
+
const hash = createHash("sha256");
|
|
107
|
+
const chunk = Buffer.allocUnsafe(64 * 1024);
|
|
108
|
+
let position = 0;
|
|
109
|
+
while (true) {
|
|
110
|
+
const observed = await handle.read(chunk, 0, chunk.length, position);
|
|
111
|
+
if (observed.bytesRead === 0)
|
|
112
|
+
break;
|
|
113
|
+
hash.update(chunk.subarray(0, observed.bytesRead));
|
|
114
|
+
position += observed.bytesRead;
|
|
115
|
+
}
|
|
116
|
+
return hash.digest("hex");
|
|
117
|
+
};
|
|
118
|
+
const resolveAppBundle = async (path) => {
|
|
119
|
+
const metadata = await stat(path);
|
|
120
|
+
if (!metadata.isDirectory())
|
|
121
|
+
return ok(path);
|
|
122
|
+
if (extname(path).toLowerCase() !== ".app")
|
|
123
|
+
return err(new BinaryTargetError(path, "target is not an app or file"));
|
|
124
|
+
const plistPath = join(path, "Contents", "Info.plist");
|
|
125
|
+
let name;
|
|
126
|
+
try {
|
|
127
|
+
const plist = await readFile(plistPath);
|
|
128
|
+
name =
|
|
129
|
+
plist.subarray(0, 6).toString("ascii") === "bplist"
|
|
130
|
+
? await readBinaryPlistExecutable(plistPath)
|
|
131
|
+
: parseXmlPlistExecutable(plist.toString("utf8"));
|
|
132
|
+
}
|
|
133
|
+
catch (cause) {
|
|
134
|
+
return err(new BinaryTargetError(path, "app has no readable CFBundleExecutable", {
|
|
135
|
+
cause,
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
if (!isSafeExecutableName(name))
|
|
139
|
+
return err(new BinaryTargetError(path, "app has an unsafe CFBundleExecutable"));
|
|
140
|
+
const programs = join(path, "Contents", "MacOS");
|
|
141
|
+
const executable = join(programs, name);
|
|
142
|
+
try {
|
|
143
|
+
const [canonicalPrograms, canonicalExecutable] = await Promise.all([
|
|
144
|
+
realpath(programs),
|
|
145
|
+
realpath(executable),
|
|
146
|
+
]);
|
|
147
|
+
if (!isPathWithinRoot(canonicalPrograms, canonicalExecutable))
|
|
148
|
+
return err(new BinaryTargetError(path, "app program file leaves Contents/MacOS"));
|
|
149
|
+
return ok(canonicalExecutable);
|
|
150
|
+
}
|
|
151
|
+
catch (cause) {
|
|
152
|
+
return err(new BinaryTargetError(path, "app program file is missing", { cause }));
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
const parseXmlPlistExecutable = (plist) => {
|
|
156
|
+
const match = /<key>\s*CFBundleExecutable\s*<\/key>\s*<string>([^<]+)<\/string>/u.exec(plist);
|
|
157
|
+
if (match?.[1] === undefined)
|
|
158
|
+
throw new Error("CFBundleExecutable is missing");
|
|
159
|
+
return decodeXml(match[1].trim());
|
|
160
|
+
};
|
|
161
|
+
const readBinaryPlistExecutable = async (plistPath) => (await execFileAsync("/usr/bin/plutil", [
|
|
162
|
+
"-extract",
|
|
163
|
+
"CFBundleExecutable",
|
|
164
|
+
"raw",
|
|
165
|
+
"-o",
|
|
166
|
+
"-",
|
|
167
|
+
plistPath,
|
|
168
|
+
])).stdout.trim();
|
|
169
|
+
const isSafeExecutableName = (name) => name.length > 0 &&
|
|
170
|
+
name !== "." &&
|
|
171
|
+
name !== ".." &&
|
|
172
|
+
!name.includes("\0") &&
|
|
173
|
+
!/[/\\]/u.test(name);
|
|
174
|
+
const decodeXml = (value) => value
|
|
175
|
+
.replaceAll("&", "&")
|
|
176
|
+
.replaceAll("<", "<")
|
|
177
|
+
.replaceAll(">", ">")
|
|
178
|
+
.replaceAll(""", '"')
|
|
179
|
+
.replaceAll("'", "'");
|
|
180
|
+
const readExecutableMetadata = async (handle, hostArchitecture) => {
|
|
181
|
+
const prefix = Buffer.alloc(4096);
|
|
182
|
+
const prefixRead = await handle.read(prefix, 0, prefix.length, 0);
|
|
183
|
+
const bytes = prefix.subarray(0, prefixRead.bytesRead);
|
|
184
|
+
if (bytes.length >= 64 && bytes[0] === 0x4d && bytes[1] === 0x5a) {
|
|
185
|
+
const offset = bytes.readUInt32LE(0x3c);
|
|
186
|
+
return readPeMetadata(handle, offset);
|
|
187
|
+
}
|
|
188
|
+
if (bytes.length >= 8) {
|
|
189
|
+
const magic = bytes.readUInt32BE(0);
|
|
190
|
+
if ([0xcafebabf, 0xbfbafeca].includes(magic)) {
|
|
191
|
+
const little = magic === 0xbfbafeca;
|
|
192
|
+
const count = little ? bytes.readUInt32LE(4) : bytes.readUInt32BE(4);
|
|
193
|
+
const required = 8 + count * 32;
|
|
194
|
+
if (count <= 128 && required > bytes.length) {
|
|
195
|
+
const header = Buffer.alloc(required);
|
|
196
|
+
const headerRead = await handle.read(header, 0, header.length, 0);
|
|
197
|
+
return parseExecutableHeader(header.subarray(0, headerRead.bytesRead), hostArchitecture);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return parseExecutableHeader(bytes, hostArchitecture);
|
|
202
|
+
};
|
|
203
|
+
const readPeMetadata = async (handle, offset) => {
|
|
204
|
+
const fileHeader = Buffer.alloc(24);
|
|
205
|
+
const fileHeaderRead = await handle.read(fileHeader, 0, fileHeader.length, offset);
|
|
206
|
+
if (fileHeaderRead.bytesRead !== fileHeader.length)
|
|
207
|
+
return err("invalid or truncated PE header");
|
|
208
|
+
const optionalHeaderSize = fileHeader.readUInt16LE(20);
|
|
209
|
+
if (optionalHeaderSize > 4096)
|
|
210
|
+
return err("invalid PE optional header size");
|
|
211
|
+
const record = Buffer.alloc(24 + optionalHeaderSize);
|
|
212
|
+
const recordRead = await handle.read(record, 0, record.length, offset);
|
|
213
|
+
return recordRead.bytesRead === record.length
|
|
214
|
+
? parsePeRecord(record)
|
|
215
|
+
: err("invalid or truncated PE header");
|
|
216
|
+
};
|