rea-agents 6.2.0 → 6.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -23
- package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
- package/bridge/ghidra/ReaGhidraBridge.java +597 -209
- package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
- package/bridge/hopper_bridge.py +2 -0
- package/dist/adb/AdbConfiguration.js +88 -0
- package/dist/adb/AdbDeviceOutput.js +186 -0
- package/dist/adb/AdbProvider.js +1190 -0
- package/dist/adb/AdbShellOutput.js +309 -0
- package/dist/android/AndroidTargetSnapshot.js +104 -22
- package/dist/android/JadxConfiguration.js +44 -24
- package/dist/android/JadxProvider.js +59 -21
- package/dist/android/JadxSession.js +51 -9
- package/dist/apktool/ApktoolConfiguration.js +84 -0
- package/dist/apktool/ApktoolDecodeOutput.js +59 -0
- package/dist/apktool/ApktoolProvider.js +506 -0
- package/dist/application/AnalysisProvider.js +8 -2
- package/dist/application/AppBundleExecutable.js +27 -22
- package/dist/application/BinaryTargetResolver.js +85 -19
- package/dist/application/BrowserScenarioEvidence.js +2 -2
- package/dist/application/CapabilityInventory.js +11 -1
- package/dist/application/ClientConfigurationDocument.js +98 -0
- package/dist/application/ClientConfigurationFiles.js +91 -0
- package/dist/application/ClientRegistrationEnvironment.js +35 -0
- package/dist/application/ClientRegistrationStatus.js +75 -27
- package/dist/application/DirectAnalysis.js +14 -8
- package/dist/application/DirectAnalysisCleanup.js +1 -2
- package/dist/application/DirectAnalysisStatus.js +3 -6
- package/dist/application/Doctor.js +27 -34
- package/dist/application/DoctorDiagnostics.js +1 -1
- package/dist/application/EvidenceBundleCommands.js +6 -12
- package/dist/application/EvidenceBundleFiles.js +1 -1
- package/dist/application/GeminiClientSettings.js +139 -0
- package/dist/application/HermesClientHome.js +115 -0
- package/dist/application/HopperDownload.js +39 -0
- package/dist/application/InvestigationProviders.js +10 -4
- package/dist/application/JsonFiles.js +16 -15
- package/dist/application/JsonInputFile.js +252 -0
- package/dist/application/LinuxHopper.js +6 -13
- package/dist/application/MacHopper.js +172 -149
- package/dist/application/MipsElfAbiFlags.js +140 -0
- package/dist/application/ProviderOperationExecution.js +31 -0
- package/dist/application/ReconstructionObligationCandidates.js +16 -3
- package/dist/application/ReconstructionObligationLedgerProjection.js +3 -1
- package/dist/application/ReferenceSourceImport.js +76 -29
- package/dist/application/ReferenceSourceImportEntries.js +18 -9
- package/dist/application/ReferenceSourceImportPolicy.js +99 -23
- package/dist/application/ReferenceSourceImportTypes.js +30 -22
- package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
- package/dist/application/RegularFileRead.js +103 -0
- package/dist/application/Setup.js +69 -10
- package/dist/application/SetupClientConfiguration.js +134 -23
- package/dist/application/SetupHost.js +102 -22
- package/dist/application/SetupPlan.js +18 -17
- package/dist/application/SetupSkill.js +81 -13
- package/dist/application/SupportedClients.js +305 -37
- package/dist/application/Uninstall.js +172 -8
- package/dist/application/UpdateMaintenance.js +23 -23
- package/dist/application/Utf8JsonInput.js +71 -0
- package/dist/application/WebScriptExportService.js +130 -57
- package/dist/application/WebSourceLocationService.js +3 -0
- package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
- package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
- package/dist/application/analysisView/AnalysisViewService.js +40 -2
- package/dist/application/android/AndroidAnalysisService.js +1 -1
- package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
- package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
- package/dist/application/binary/AnalysisClientCleanup.js +0 -24
- package/dist/application/binary/AnalysisSnapshotCache.js +5 -4
- package/dist/application/binary/BinarySession.js +18 -1
- package/dist/application/binary/BinarySessionOpen.js +9 -1
- package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
- package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
- package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
- package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
- package/dist/application/evm/EvmInterfaceService.js +3 -0
- package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
- package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
- package/dist/application/javascript/ElectronActiveEvidence.js +2 -2
- package/dist/application/javascript/ElectronBoundaryAnalysis.js +2 -2
- package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
- package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
- package/dist/application/javascript/ElectronBoundaryGraphNative.js +20 -3
- package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +1 -0
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +107 -46
- package/dist/application/javascript/JavaScriptApplicationService.js +23 -11
- package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +59 -45
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -36
- package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +74 -36
- package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
- package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +53 -42
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +293 -238
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +120 -28
- package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -0
- package/dist/application/javascript/JavaScriptJsonModules.js +2 -2
- package/dist/application/javascript/JavaScriptModuleRelationships.js +10 -20
- package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +11 -27
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +11 -5
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +206 -66
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +18 -23
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +5 -2
- package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +2 -2
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +7 -5
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +6 -4
- package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +4 -4
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +1 -1
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +29 -15
- package/dist/application/javascript/JavaScriptSemanticTraceService.js +15 -10
- package/dist/application/jeb/JebAnalysisPort.js +1 -0
- package/dist/application/jeb/JebAnalysisService.js +13 -0
- package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
- package/dist/application/native/NativeCallRoutes.js +2 -4
- package/dist/application/native/NativeUiActionTrace.js +16 -8
- package/dist/application/native/NativeValueTrace.js +23 -6
- package/dist/application/process/ProcessCli.js +25 -20
- package/dist/artifacts/ArtifactPaths.js +129 -8
- package/dist/artifacts/ArtifactProvider.js +34 -31
- package/dist/artifacts/ArtifactProviderMetadata.js +1 -4
- package/dist/artifacts/ArtifactReader.js +23 -0
- package/dist/artifacts/ArtifactResourceScope.js +100 -0
- package/dist/artifacts/AsarArtifactReader.js +218 -80
- package/dist/artifacts/AsarHeader.js +24 -0
- package/dist/artifacts/DirectoryArtifactReader.js +168 -65
- package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
- package/dist/artifacts/NativeDmgArtifactReader.js +179 -87
- package/dist/artifacts/NativeDmgOwnership.js +109 -0
- package/dist/artifacts/SafeOutputTree.js +245 -70
- package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
- package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
- package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
- package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
- package/dist/artifacts/ZipArtifactReader.js +77 -27
- package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
- package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
- package/dist/artifacts/apple/KeyedArchiveReader.js +76 -49
- package/dist/artifacts/apple/MachoLoadCommandReader.js +36 -6
- package/dist/artifacts/extraction/ArtifactExtraction.js +134 -92
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +116 -50
- package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
- package/dist/artifacts/inventory/classify.js +87 -25
- package/dist/artifacts/inventory/hashStableRootArtifact.js +70 -0
- package/dist/artifacts/inventory/reader.js +13 -5
- package/dist/artifacts/inventory/scanCanonical.js +73 -30
- package/dist/artifacts/inventory/scanReader.js +43 -20
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +72 -28
- package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
- package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
- package/dist/browser/BrowserScenarioSecrets.js +52 -37
- package/dist/browser/CdpBrowserProvider.js +9 -3
- package/dist/browser/CdpCaptureDocuments.js +40 -6
- package/dist/browser/CdpCaptureDomSvg.js +210 -0
- package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
- package/dist/browser/CdpCaptureEventHandlers.js +26 -9
- package/dist/browser/CdpCaptureEvents.js +4 -9
- package/dist/browser/CdpCaptureStorageFingerprints.js +3 -3
- package/dist/browser/CdpConnection.js +22 -5
- package/dist/browser/CdpElectronInspection.js +2 -2
- package/dist/browser/CdpElectronProvider.js +4 -3
- package/dist/browser/CdpElectronScripts.js +2 -2
- package/dist/browser/CdpPageCapture.js +1 -1
- package/dist/browser/CdpTargetSession.js +30 -34
- package/dist/browser/CdpWebMcpDiscovery.js +48 -23
- package/dist/browser/ElectronFileScope.js +99 -9
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +63 -7
- package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
- package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
- package/dist/browser/PlaywrightScenarioBrowser.js +208 -43
- package/dist/browser/PlaywrightScenarioSession.js +130 -65
- package/dist/browser/PlaywrightScenarioStorage.js +507 -0
- package/dist/browser/PngVisualDiff.js +198 -29
- package/dist/browser/WebSourceMapFetcher.js +35 -9
- package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
- package/dist/browser/assets/PublishWebScripts.js +75 -20
- package/dist/browser/assets/ScenarioScriptCapture.js +8 -12
- package/dist/browser/assets/WebArtifactReads.js +23 -1
- package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
- package/dist/browser/execution/CdpExecutionCapture.js +3 -3
- package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
- package/dist/browser/history/HarCapture.js +14 -0
- package/dist/browser/history/HarCaptureProcess.js +2 -10
- package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
- package/dist/browser/modules/WebModuleArtifacts.js +1 -0
- package/dist/cli/adbCommands.js +337 -0
- package/dist/cli/analysisViewCommands.js +39 -1
- package/dist/cli/apktoolCommands.js +53 -0
- package/dist/cli/artifactCommands.js +8 -11
- package/dist/cli/binaryDiagnosticsCommands.js +19 -1
- package/dist/cli/browserAdvancedCommands.js +65 -36
- package/dist/cli/coreAnalysisCommands.js +2 -2
- package/dist/cli/coreBinaryCommands.js +12 -13
- package/dist/cli/coreNativeCommands.js +1 -14
- package/dist/cli/electronCommands.js +14 -10
- package/dist/cli/evmCommands.js +13 -4
- package/dist/cli/firmwareCommands.js +7 -2
- package/dist/cli/javascriptApplicationAnalysis.js +19 -13
- package/dist/cli/javascriptRecoveryCommands.js +22 -15
- package/dist/cli/jebCommands.js +99 -0
- package/dist/cli/jsonOutput.js +12 -4
- package/dist/cli/referenceSourceImportStatus.js +7 -0
- package/dist/cli/setupCommands.js +15 -3
- package/dist/cli/streamedJsonOutput.js +83 -4
- package/dist/cli/utilityCommands.js +68 -22
- package/dist/cli/webScriptCommands.js +20 -1
- package/dist/cli/webSourceLocationCommands.js +21 -9
- package/dist/cli.js +11 -2
- package/dist/cliBrowserScenarioCommands.js +2 -1
- package/dist/cliCommandNames.js +32 -0
- package/dist/cliJsonInput.js +47 -34
- package/dist/cliObservationOptions.js +7 -0
- package/dist/composition/adb.js +3 -0
- package/dist/composition/apktool.js +3 -0
- package/dist/composition/auxiliaryAnalysisProviders.js +5 -4
- package/dist/composition/binaryDiagnostics.js +4 -0
- package/dist/composition/browserScenario.js +2 -2
- package/dist/composition/directAnalysis.js +14 -7
- package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
- package/dist/composition/jeb.js +6 -0
- package/dist/config/environment.js +10 -0
- package/dist/config/ghidraLanguageOverride.js +9 -0
- package/dist/config/mcpInputSchemaProfile.js +27 -0
- package/dist/config/parseConfig.js +28 -1
- package/dist/contracts/adb/adbToolContracts.js +353 -0
- package/dist/contracts/advertisedInputExamples.js +48 -0
- package/dist/contracts/analysisDetail.js +10 -0
- package/dist/contracts/analysisViewToolContracts.js +17 -2
- package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
- package/dist/contracts/artifactComparisonExample.js +5 -5
- package/dist/contracts/artifactToolContracts.js +8 -5
- package/dist/contracts/browserToolContracts.js +1 -1
- package/dist/contracts/compactInputSchema.js +256 -0
- package/dist/contracts/errorSchemas.js +3 -1
- package/dist/contracts/functionComparisonExample.js +8 -0
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/inputSchemaPresentation.js +104 -13
- package/dist/contracts/javascript/electronToolContracts.js +16 -3
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +3 -2
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +6 -3
- package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
- package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +8 -7
- package/dist/contracts/jeb/jebToolContracts.js +64 -0
- package/dist/contracts/managed/managedToolContracts.js +3 -2
- package/dist/contracts/mobileApplicationGraphExamples.js +5 -5
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
- package/dist/contracts/native/nativeToolContracts.js +1 -1
- package/dist/contracts/officialToolContracts.js +5 -5
- package/dist/contracts/sessionLifecycleInputs.js +4 -3
- package/dist/contracts/sessionStatusContract.js +3 -2
- package/dist/contracts/sessionToolContracts.js +5 -4
- package/dist/contracts/sessionToolSchemas.js +9 -4
- package/dist/contracts/toolContractExamples.js +6 -0
- package/dist/contracts/toolContractTypes.js +3 -0
- package/dist/contracts/toolContracts.js +6 -0
- package/dist/contracts/toolEffects.js +167 -0
- package/dist/contracts/toolOutputSchemaGroups.js +7 -5
- package/dist/contracts/toolOutputSchemaPrimitives.js +2 -5
- package/dist/contracts/toolSchemaMetadata.js +82 -7
- package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
- package/dist/domain/analysisErrorBase.js +5 -0
- package/dist/domain/analysisErrorCleanup.js +29 -0
- package/dist/domain/analysisErrorPresentation.js +18 -4
- package/dist/domain/analysisErrorProjection.js +4 -1
- package/dist/domain/analysisSnapshot.js +5 -2
- package/dist/domain/analysisView/analysisView.js +53 -5
- package/dist/domain/analysisView/binaryLayoutView.js +2 -0
- package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
- package/dist/domain/analysisView/nativeFunctionView.js +155 -0
- package/dist/domain/android/androidApplication.js +25 -20
- package/dist/domain/android/androidPartialObservation.js +36 -0
- package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
- package/dist/domain/apple/appleApplication.js +40 -23
- package/dist/domain/apple/appleBundleAnatomy.js +95 -28
- package/dist/domain/apple/dyldPaths.js +9 -1
- package/dist/domain/apple/dylibResolution.js +3 -3
- package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
- package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
- package/dist/domain/artifactComparison.js +39 -11
- package/dist/domain/artifactGraph.js +6 -4
- package/dist/domain/artifactIdentity.js +37 -9
- package/dist/domain/artifactInspection.js +10 -50
- package/dist/domain/artifactIntegrityPolicy.js +10 -0
- package/dist/domain/artifactInventoryEvidence.js +16 -17
- package/dist/domain/artifactPathSyntax.js +1 -1
- package/dist/domain/binaryTarget.js +16 -0
- package/dist/domain/binaryTargetTypes.js +8 -1
- package/dist/domain/browserCompleteness.js +3 -2
- package/dist/domain/browserObservationSchemas.js +8 -4
- package/dist/domain/browserScenarioCaptureValues.js +2 -2
- package/dist/domain/browserScenarioNormalization.js +3 -3
- package/dist/domain/browserScenarioValues.js +3 -2
- package/dist/domain/callPath.js +8 -10
- package/dist/domain/canonicalDigest.js +7 -1
- package/dist/domain/canonicalJsonDigestSteps.js +34 -12
- package/dist/domain/canonicalOrdering.js +1 -13
- package/dist/domain/changedBehavior.js +2 -3
- package/dist/domain/compactStringIdentity.js +9 -0
- package/dist/domain/comparisonSemantics.js +0 -5
- package/dist/domain/digests.js +0 -3
- package/dist/domain/evidence.js +12 -6
- package/dist/domain/evidenceBundle.js +51 -33
- package/dist/domain/evidenceRecordSummary.js +144 -0
- package/dist/domain/firmware/firmwareAnalysis.js +4 -3
- package/dist/domain/functionComparison.js +2 -1
- package/dist/domain/functionComparisonNormalization.js +4 -3
- package/dist/domain/functionComparisonResults.js +2 -2
- package/dist/domain/functionDossierEvidence.js +2 -1
- package/dist/domain/hopperValues.js +11 -15
- package/dist/domain/inputIssueProjection.js +16 -1
- package/dist/domain/javascript/electronActiveObservation.js +4 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +14 -15
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +20 -21
- package/dist/domain/javascript/electronStaticAnalysisNative.js +73 -41
- package/dist/domain/javascript/electronStaticAnalysisValues.js +24 -4
- package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +6 -1
- package/dist/domain/javascript/javascriptApplicationChangeGraph.js +18 -14
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +4 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +91 -28
- package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
- package/dist/domain/javascript/javascriptApplicationVersionComparison.js +4 -4
- package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +37 -22
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +72 -45
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +16 -8
- package/dist/domain/javascript/javascriptAstFingerprint.js +60 -33
- package/dist/domain/javascript/javascriptAstValues.js +54 -0
- package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
- package/dist/domain/javascript/javascriptExportShapeComparison.js +3 -2
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +31 -23
- package/dist/domain/javascript/javascriptExportShapeSelection.js +2 -2
- package/dist/domain/javascript/javascriptExportShapeVariants.js +3 -2
- package/dist/domain/javascript/javascriptFeatureSeed.js +5 -3
- package/dist/domain/javascript/javascriptFeatureTrace.js +7 -6
- package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +17 -9
- package/dist/domain/javascript/javascriptFeatureTraversal.js +4 -4
- package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
- package/dist/domain/javascript/javascriptNativeHandoff.js +12 -7
- package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
- package/dist/domain/javascript/javascriptRuntimeObservation.js +8 -5
- package/dist/domain/javascript/javascriptRuntimeReconciliation.js +12 -6
- package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +9 -8
- package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +12 -6
- package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +5 -5
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +12 -223
- package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +15 -4
- package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +2 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +15 -17
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +379 -30
- package/dist/domain/javascript/javascriptSemanticCallResolution.js +9 -7
- package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
- package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -2
- package/dist/domain/javascript/javascriptSemanticCoverage.js +20 -0
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +7 -9
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +4 -11
- package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
- package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
- package/dist/domain/javascript/javascriptSemanticFingerprints.js +43 -42
- package/dist/domain/javascript/javascriptSemanticGraph.js +205 -52
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +21 -11
- package/dist/domain/javascript/javascriptSemanticIr.js +0 -4
- package/dist/domain/javascript/javascriptSemanticIterationSources.js +139 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +774 -136
- package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +98 -41
- package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
- package/dist/domain/javascript/javascriptSemanticObjects.js +9 -7
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +7 -2
- package/dist/domain/javascript/javascriptSemanticProjection.js +72 -28
- package/dist/domain/javascript/javascriptSemanticPromises.js +15 -21
- package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +100 -0
- package/dist/domain/javascript/javascriptSemanticProvenance.js +3 -3
- package/dist/domain/javascript/javascriptSemanticQuery.js +33 -29
- package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +4 -5
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -9
- package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +16 -10
- package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
- package/dist/domain/javascript/javascriptSemanticReturns.js +34 -48
- package/dist/domain/javascript/javascriptSemanticState.js +22 -2
- package/dist/domain/javascript/javascriptSemanticTraversal.js +25 -2
- package/dist/domain/javascript/javascriptSemanticValues.js +169 -30
- package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
- package/dist/domain/javascript/javascriptSourceMapPaths.js +11 -1
- package/dist/domain/javascript/javascriptSourceParser.js +34 -9
- package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +13 -12
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
- package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +26 -15
- package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
- package/dist/domain/javascript/sourceToBundleComparison.js +7 -5
- package/dist/domain/javascript/sourceToBundleSignals.js +7 -7
- package/dist/domain/jeb/jebAnalysis.js +114 -0
- package/dist/domain/jsonSerialization.js +109 -55
- package/dist/domain/jsonShape.js +69 -31
- package/dist/domain/jsonValue.js +3 -0
- package/dist/domain/localPath.js +10 -4
- package/dist/domain/managed/managedApplicationGraph.js +47 -6
- package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
- package/dist/domain/managed/managedApplicationGraphNodes.js +94 -59
- package/dist/domain/managed/managedArtifact.js +1 -0
- package/dist/domain/managed/managedInspectionEvidence.js +13 -0
- package/dist/domain/managed/managedMemberComparisonMatch.js +6 -7
- package/dist/domain/native/nativeAotPe.js +1408 -0
- package/dist/domain/native/nativeCallObservation.js +2 -4
- package/dist/domain/native/nativeInstruction.js +21 -0
- package/dist/domain/native/nativeMetadataRecovery.js +79 -6
- package/dist/domain/native/nativeValueFlow.js +5 -11
- package/dist/domain/native/objcSwiftMetadata.js +15 -17
- package/dist/domain/native/peResources.js +94 -0
- package/dist/domain/nativeConvention.js +33 -0
- package/dist/domain/process/processCapture.js +102 -11
- package/dist/domain/process/processCaptureCoverage.js +8 -5
- package/dist/domain/process/processCaptureExample.js +67 -0
- package/dist/domain/process/processCaptureValidation.js +83 -3
- package/dist/domain/process/processComparison.js +0 -23
- package/dist/domain/process/processScenario.js +62 -10
- package/dist/domain/process/processTraceEvaluation.js +4 -4
- package/dist/domain/process/processTraceSpecification.js +1 -3
- package/dist/domain/propertyListKeys.js +3 -1
- package/dist/domain/providerCleanupError.js +6 -2
- package/dist/domain/reconstructionCoverage.js +2 -1
- package/dist/domain/reconstructionUnknowns.js +4 -3
- package/dist/domain/reconstructionVerification.js +3 -2
- package/dist/domain/referenceSourceGraph.js +32 -23
- package/dist/domain/referenceSourceImportParsing.js +40 -48
- package/dist/domain/referenceSourcePathIdentity.js +22 -0
- package/dist/domain/referenceSourceRequireBindings.js +137 -0
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/staticRuntimeCorrelation.js +2 -1
- package/dist/domain/swiftSymbolClassification.js +6 -1
- package/dist/domain/symbolAnalysis.js +17 -2
- package/dist/domain/unicodeCodePointOrder.js +6 -0
- package/dist/domain/webBundleAnalyzerInspection.js +23 -3
- package/dist/domain/webCaptureDiff.js +170 -30
- package/dist/domain/webCaptureDiffSchemas.js +2 -8
- package/dist/domain/webInventory.js +3 -2
- package/dist/domain/webMcpDiscovery.js +4 -3
- package/dist/domain/webScriptExport.js +1 -1
- package/dist/domain/webScriptExportError.js +10 -4
- package/dist/domain/webScriptExportPlan.js +7 -13
- package/dist/domain/zipPackageFormat.js +4 -1
- package/dist/domain/zodCollectionSteps.js +24 -0
- package/dist/dotnet/ManagedArtifactInspector.js +55 -43
- package/dist/dotnet/ManagedDecodeBudget.js +80 -0
- package/dist/dotnet/ManagedMemberInspector.js +13 -6
- package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +5 -4
- package/dist/dotnet/ManagedMemberRows.js +9 -4
- package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
- package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
- package/dist/dotnet/ManagedMetadataLayout.js +10 -4
- package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
- package/dist/dotnet/ManagedPeReader.js +41 -25
- package/dist/dotnet/ManagedReaderFailure.js +2 -1
- package/dist/dotnet/ManagedStaticProvider.js +65 -31
- package/dist/dotnet/ManagedStaticProviderMetadata.js +1 -4
- package/dist/evaluation/AgentEvaluationReport.js +9 -5
- package/dist/evaluation/CodexAgentEval.js +43 -13
- package/dist/evm/EvmoleFailures.js +0 -2
- package/dist/evm/EvmoleInterfaceProvider.js +67 -2
- package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
- package/dist/filesystem/OwnedFileHandle.js +36 -0
- package/dist/filesystem/RegularFile.js +73 -0
- package/dist/filesystem/StableFileHash.js +46 -0
- package/dist/filesystem/readFileHandleChunks.js +26 -0
- package/dist/firmware/FirmwareCommand.js +25 -3
- package/dist/firmware/FirmwareFiles.js +23 -8
- package/dist/firmware/FirmwareProvider.js +156 -32
- package/dist/firmware/FirmwarePublication.js +24 -3
- package/dist/firmware/FirmwareRelease.js +1 -0
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
- package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
- package/dist/ghidra/GhidraClient.js +90 -8
- package/dist/ghidra/GhidraDiagnostics.js +11 -8
- package/dist/ghidra/GhidraFunctionValues.js +26 -2
- package/dist/ghidra/GhidraInstallation.js +111 -10
- package/dist/ghidra/GhidraInventoryValues.js +23 -1
- package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
- package/dist/ghidra/GhidraLauncher.js +123 -58
- package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
- package/dist/ghidra/GhidraMipsProfile.js +79 -0
- package/dist/ghidra/GhidraProvider.js +57 -9
- package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
- package/dist/ghidra/GhidraProviderClient.js +282 -21
- package/dist/ghidra/GhidraSessionValues.js +9 -2
- package/dist/hopper/HopperAnalysisProfile.js +2 -0
- package/dist/hopper/HopperCleanup.js +1 -1
- package/dist/hopper/HopperClient.js +15 -6
- package/dist/hopper/HopperMachOImage.js +2 -0
- package/dist/hopper/HopperProvider.js +13 -2
- package/dist/ida/IdaOperationRunner.js +10 -2
- package/dist/ida/IdaProvider.js +7 -0
- package/dist/ida/IdaSessionClient.js +7 -3
- package/dist/ida/IdaWorkspace.js +4 -2
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -5
- package/dist/inspector/V8InspectorCaptureProjection.js +46 -13
- package/dist/inspector/V8InspectorProvider.js +60 -8
- package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
- package/dist/javascript/recovery/RecoveryFiles.js +18 -7
- package/dist/javascript/recovery/WakaruCommand.js +22 -9
- package/dist/javascript/recovery/WakaruExecution.js +11 -7
- package/dist/javascript/recovery/WakaruProvider.js +139 -16
- package/dist/javascript/recovery/WakaruPublication.js +14 -4
- package/dist/javascript/recovery/WakaruRelease.js +10 -3
- package/dist/javascript/recovery/WakaruReport.js +12 -7
- package/dist/javascript/recovery/WakaruVersion.js +24 -0
- package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
- package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
- package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
- package/dist/jeb/JebMcpConnection.js +179 -0
- package/dist/jeb/JebMcpEndpoint.js +40 -0
- package/dist/jeb/JebProvider.js +299 -0
- package/dist/main/shutdown.js +76 -32
- package/dist/main/transport.js +1 -1
- package/dist/mcpDoctor.js +15 -6
- package/dist/native/AppleDispatchCoverage.js +25 -12
- package/dist/native/AppleDispatchMetadata.js +14 -7
- package/dist/native/AppleMachoFixups.js +71 -15
- package/dist/native/AppleMachoSelection.js +23 -3
- package/dist/native/AppleObjcDispatchFacets.js +3 -3
- package/dist/native/AppleObjcProperties.js +17 -7
- package/dist/native/LldbCallTracer.js +241 -75
- package/dist/native/NativeMacOSProvider.js +100 -20
- package/dist/native/NativeMacOSProviderMetadata.js +1 -2
- package/dist/native/NativeMachoInspection.js +11 -7
- package/dist/native/NativeUiHelperRuntime.js +6 -1
- package/dist/native/NativeUiObservation.js +4 -3
- package/dist/native/pe/PeResourceLayout.js +120 -0
- package/dist/native/pe/PeResourceParser.js +286 -0
- package/dist/native/pe/PeResourcesProvider.js +63 -0
- package/dist/process/BoundedFileBytes.js +30 -7
- package/dist/process/DarwinProcessRunTokenReader.js +8 -3
- package/dist/process/OwnedCommand.js +4 -3
- package/dist/process/ProcessOwnership.js +104 -112
- package/dist/process/ProcessOwnershipObservation.js +104 -51
- package/dist/process/ProcessOwnershipProcessTree.js +4 -4
- package/dist/process/ProcessRunTokenObservations.js +48 -0
- package/dist/process/ProviderDiagnosticRedaction.js +17 -0
- package/dist/process/ProviderProcess.js +4 -3
- package/dist/process/capture/FilesystemSnapshot.js +116 -22
- package/dist/process/capture/ProcessCaptureLifecycle.js +363 -86
- package/dist/process/capture/ProcessCaptureProgress.js +62 -0
- package/dist/process/capture/ProcessFilesystemEffects.js +19 -4
- package/dist/process/capture/ProcessHarness.js +202 -47
- package/dist/process/capture/ProcessNormalization.js +3 -1
- package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
- package/dist/process/capture/TerminalRenderer.js +24 -7
- package/dist/reference/ReferenceSourceReader.js +22 -5
- package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
- package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
- package/dist/reference/ReferenceSourceReaderFile.js +50 -10
- package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
- package/dist/server/EvidenceMcpServer.js +36 -1
- package/dist/server/admittedToolOperation.js +9 -0
- package/dist/server/analysisAdmission.js +8 -0
- package/dist/server/contractToolHandler.js +21 -0
- package/dist/server/createServer.js +118 -47
- package/dist/server/registerAdbTools.js +36 -0
- package/dist/server/registerAnalysisViewTool.js +4 -9
- package/dist/server/registerAndroidTools.js +3 -12
- package/dist/server/registerApktoolTools.js +14 -0
- package/dist/server/registerApplicationTools/compareExportShapes.js +6 -7
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
- package/dist/server/registerApplicationTools/compareVersions.js +3 -2
- package/dist/server/registerApplicationTools/coverage.js +3 -2
- package/dist/server/registerApplicationTools/helpers.js +3 -2
- package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
- package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
- package/dist/server/registerApplicationTools/traceFeature.js +3 -2
- package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
- package/dist/server/registerArtifactComparisonTool.js +5 -2
- package/dist/server/registerArtifactTools.js +2 -2
- package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
- package/dist/server/registerBrowserScenarioTool.js +10 -7
- package/dist/server/registerBrowserTools.js +12 -9
- package/dist/server/registerBundleComparisonTool.js +16 -2
- package/dist/server/registerCloseLifecycleTool.js +36 -5
- package/dist/server/registerElectronTools.js +28 -10
- package/dist/server/registerEnhancedTools.js +78 -73
- package/dist/server/registerEvidenceTools.js +54 -46
- package/dist/server/registerEvmTools.js +4 -9
- package/dist/server/registerFirmwareTools.js +3 -11
- package/dist/server/registerFunctionComparisonTool.js +5 -2
- package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
- package/dist/server/registerJebTools.js +16 -0
- package/dist/server/registerManagedTools.js +7 -4
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
- package/dist/server/registerOfficialTools.js +31 -25
- package/dist/server/registerPeResourcesTool.js +9 -0
- package/dist/server/registerProcessComparisonTool.js +5 -2
- package/dist/server/registerRecordedCrashTools.js +4 -9
- package/dist/server/registerSessionRecordTools.js +2 -1
- package/dist/server/registerSessionTools.js +58 -21
- package/dist/server/registerWebModuleTool.js +4 -9
- package/dist/server/registerWebNetworkCaptureTool.js +4 -9
- package/dist/server/registerWebRuntimeTools.js +6 -5
- package/dist/server/registerWebScriptTool.js +6 -3
- package/dist/server/registerWebSourceLocationTool.js +4 -9
- package/dist/server/toolResult.js +21 -2
- package/dist/windows/WindowsPrivateRuntime.js +12 -5
- package/install.sh +7 -4
- package/licenses/nativeaot-parser-MIT.txt +28 -0
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +38 -7
- package/scripts/rea.mjs +16 -1
- package/skills/reverse-engineer-anything/SKILL.md +52 -51
- package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
- package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +31 -1
- package/dist/artifacts/inventory/policy.js +0 -2
- package/dist/domain/managed/managedApplicationGraphNodeCoverage.js +0 -6
- package/dist/server/registerNativeTools.js +0 -6
|
@@ -29,6 +29,41 @@ const LC_VERSION_MIN_IPHONEOS = 0x25;
|
|
|
29
29
|
const LC_VERSION_MIN_TVOS = 0x2f;
|
|
30
30
|
const LC_VERSION_MIN_WATCHOS = 0x30;
|
|
31
31
|
const LC_BUILD_VERSION = 0x32;
|
|
32
|
+
// `mach-o/loader.h` `PLATFORM_*` numbers observed via Apple linker output.
|
|
33
|
+
const PLATFORM_MACOS = 1;
|
|
34
|
+
const PLATFORM_IOS = 2;
|
|
35
|
+
const PLATFORM_TVOS = 3;
|
|
36
|
+
const PLATFORM_WATCHOS = 4;
|
|
37
|
+
const PLATFORM_IOSSIMULATOR = 7;
|
|
38
|
+
const PLATFORM_TVOSSIMULATOR = 8;
|
|
39
|
+
const PLATFORM_WATCHOSSIMULATOR = 9;
|
|
40
|
+
const CPU_TYPE_I386 = 7;
|
|
41
|
+
const CPU_TYPE_X86_64 = 0x01000007;
|
|
42
|
+
/**
|
|
43
|
+
* Legacy `LC_VERSION_MIN_*` commands predate explicit simulator platform
|
|
44
|
+
* IDs. Per Apple's dyld rules the image CPU type distinguishes simulator
|
|
45
|
+
* from device: Intel images are simulator, ARM images are device
|
|
46
|
+
* (tvOS simulator applies to x86_64 only). `LC_BUILD_VERSION` platform
|
|
47
|
+
* numbers are preserved verbatim; unknown future numbers stay unknown
|
|
48
|
+
* downstream, never mapped to nearest.
|
|
49
|
+
*/
|
|
50
|
+
const legacyVersionMinPlatform = (command, cpuType) => {
|
|
51
|
+
const isIntel = cpuType === CPU_TYPE_I386 || cpuType === CPU_TYPE_X86_64;
|
|
52
|
+
switch (command) {
|
|
53
|
+
case LC_VERSION_MIN_MACOSX:
|
|
54
|
+
return PLATFORM_MACOS;
|
|
55
|
+
case LC_VERSION_MIN_IPHONEOS:
|
|
56
|
+
return isIntel ? PLATFORM_IOSSIMULATOR : PLATFORM_IOS;
|
|
57
|
+
case LC_VERSION_MIN_TVOS:
|
|
58
|
+
return cpuType === CPU_TYPE_X86_64
|
|
59
|
+
? PLATFORM_TVOSSIMULATOR
|
|
60
|
+
: PLATFORM_TVOS;
|
|
61
|
+
case LC_VERSION_MIN_WATCHOS:
|
|
62
|
+
return isIntel ? PLATFORM_WATCHOSSIMULATOR : PLATFORM_WATCHOS;
|
|
63
|
+
default:
|
|
64
|
+
return undefined;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
32
67
|
/** `mach-o/loader.h` `dylib_use_command`: `nameoff == 28` and this marker. */
|
|
33
68
|
const DYLIB_USE_MARKER = 0x1a741800;
|
|
34
69
|
const DYLIB_USE_WEAK_LINK = 0x1;
|
|
@@ -258,12 +293,7 @@ const decodeCommand = (command, body, index, slice) => {
|
|
|
258
293
|
slice.platforms.push(platform);
|
|
259
294
|
return;
|
|
260
295
|
}
|
|
261
|
-
const legacyPlatform =
|
|
262
|
-
[LC_VERSION_MIN_MACOSX, 1],
|
|
263
|
-
[LC_VERSION_MIN_IPHONEOS, 2],
|
|
264
|
-
[LC_VERSION_MIN_TVOS, 3],
|
|
265
|
-
[LC_VERSION_MIN_WATCHOS, 4],
|
|
266
|
-
]).get(command);
|
|
296
|
+
const legacyPlatform = legacyVersionMinPlatform(command, slice.cpu_type);
|
|
267
297
|
if (legacyPlatform !== undefined) {
|
|
268
298
|
if (body.byteLength < 16)
|
|
269
299
|
throw new MachoFormatIssue("malformed", `load command ${index} is too short for a version-min command`);
|
|
@@ -1,50 +1,85 @@
|
|
|
1
1
|
import { lstat, realpath } from "node:fs/promises";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { compareUnicodeCodePoints } from "../../domain/unicodeCodePointOrder.js";
|
|
3
|
+
import { digestCanonicalValue } from "../../domain/canonicalDigest.js";
|
|
4
4
|
import { AsarArtifactReader } from "../AsarArtifactReader.js";
|
|
5
5
|
import { ArtifactPathRegistry, normalizeArtifactPath, } from "../ArtifactPaths.js";
|
|
6
6
|
import { ArtifactReaderFailure, } from "../ArtifactReader.js";
|
|
7
7
|
import { abortIfNeeded } from "../ArtifactHash.js";
|
|
8
8
|
import { DirectoryArtifactReader } from "../DirectoryArtifactReader.js";
|
|
9
9
|
import { SafeOutputTree } from "../SafeOutputTree.js";
|
|
10
|
+
import { SafeOutputTreeCreationFailure } from "../SafeOutputTreeCreationFailure.js";
|
|
10
11
|
import { ZipArtifactReader } from "../ZipArtifactReader.js";
|
|
11
12
|
import { MachOSliceArtifactReader } from "../MachOSliceArtifactReader.js";
|
|
12
13
|
import { artifactExtractionResultSchema, } from "../../domain/artifactGraph.js";
|
|
13
14
|
import { AnalysisUnsupportedTargetError } from "../../domain/analysisErrorCore.js";
|
|
14
|
-
import {
|
|
15
|
+
import {} from "../ArtifactResourceScope.js";
|
|
16
|
+
import { scanArtifactInventoryInScope } from "../inventory/ArtifactInventory.js";
|
|
15
17
|
/** Extract every regular inventory occurrence into an exclusively owned absent root. */
|
|
16
|
-
export const extractArtifact = async (input, signal) =>
|
|
18
|
+
export const extractArtifact = async (input, signal) => input.resourceScope.run(() => extractArtifactInScope(input, signal));
|
|
19
|
+
const extractArtifactInScope = async (input, signal) => {
|
|
17
20
|
// Cancellation wins over every later refusal, including unsupported formats.
|
|
18
21
|
abortIfNeeded(signal);
|
|
19
22
|
const sourcePath = await realpath(input.inputPath);
|
|
20
23
|
await requireExtractableFormat(sourcePath, input);
|
|
21
|
-
const snapshot = await
|
|
24
|
+
const snapshot = await scanArtifactInventoryInScope(sourcePath, {
|
|
25
|
+
resourceScope: input.resourceScope,
|
|
22
26
|
signal,
|
|
23
27
|
environment: input.environment,
|
|
28
|
+
integrity: { mode: input.integrityPolicy },
|
|
24
29
|
});
|
|
30
|
+
return materializeArtifactInventoryInScope(input, sourcePath, snapshot, signal);
|
|
31
|
+
};
|
|
32
|
+
/** Materialize a scanned inventory, verifying every current occurrence against it. */
|
|
33
|
+
export const materializeArtifactInventory = async (input, sourcePath, snapshot, signal) => {
|
|
34
|
+
return input.resourceScope.run(() => materializeArtifactInventoryInScope(input, sourcePath, snapshot, signal));
|
|
35
|
+
};
|
|
36
|
+
const materializeArtifactInventoryInScope = async (input, sourcePath, snapshot, signal) => {
|
|
37
|
+
abortIfNeeded(signal);
|
|
25
38
|
const selectedOccurrences = snapshot.occurrences.filter((occurrence) => (occurrence.entry_kind === "file" || occurrence.entry_kind === "slice") &&
|
|
26
39
|
occurrence.logical_path !== ".");
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
40
|
+
const regularPaths = new Set(selectedOccurrences.map(({ logical_path: path }) => path));
|
|
41
|
+
const activeOccurrences = selectedOccurrences.filter(({ logical_path }) => {
|
|
42
|
+
// Nested members remain represented by their containing regular file;
|
|
43
|
+
// only entries exposed by the active reader are materialized.
|
|
44
|
+
let path = logical_path;
|
|
45
|
+
for (let slash = path.lastIndexOf("/"); slash >= 0; slash = path.lastIndexOf("/")) {
|
|
46
|
+
path = path.slice(0, slash);
|
|
47
|
+
if (regularPaths.has(path))
|
|
48
|
+
return false;
|
|
49
|
+
}
|
|
50
|
+
return true;
|
|
51
|
+
});
|
|
52
|
+
const selectedIds = new Set(activeOccurrences.map(({ occurrence_id: id }) => id));
|
|
53
|
+
const neededNodes = new Set(activeOccurrences.map(({ artifact_id: id }) => id));
|
|
31
54
|
const nodes = new Map();
|
|
32
|
-
|
|
55
|
+
for (const node of snapshot.nodes)
|
|
56
|
+
if (neededNodes.has(node.artifact_id))
|
|
57
|
+
nodes.set(node.artifact_id, node);
|
|
33
58
|
const inventory = {
|
|
34
59
|
manifest: snapshot.manifest,
|
|
35
|
-
|
|
36
|
-
nodes,
|
|
60
|
+
integrityContradictions: snapshot.integrity_contradictions.filter(({ occurrence_id: id }) => selectedIds.has(id)),
|
|
37
61
|
};
|
|
38
|
-
const selected =
|
|
62
|
+
const selected = activeOccurrences.map((occurrence) => {
|
|
39
63
|
// REA never decrypts archive entries, so an encrypted entry makes the
|
|
40
64
|
// complete extraction unsupported rather than the archive invalid.
|
|
41
65
|
if (occurrence.encrypted)
|
|
42
66
|
throw new AnalysisUnsupportedTargetError("extract_artifact", input.inputPath, `Archive entry ${occurrence.logical_path} is encrypted; REA does not decrypt archive entries, so the archive cannot be extracted completely`);
|
|
67
|
+
// Inventory keeps an ASAR unpacked entry whose companion file is absent,
|
|
68
|
+
// but extraction cannot materialize bytes it never observed.
|
|
69
|
+
if (occurrence.entry_kind === "file" &&
|
|
70
|
+
occurrence.artifact_id === null &&
|
|
71
|
+
occurrence.hash_status === "unavailable")
|
|
72
|
+
throw new ArtifactReaderFailure("unavailable", `ASAR unpacked companion bytes are unavailable for ${occurrence.logical_path}`, undefined, {
|
|
73
|
+
logicalPath: occurrence.logical_path,
|
|
74
|
+
declaredSha256: null,
|
|
75
|
+
calculatedSha256: null,
|
|
76
|
+
unpacked: true,
|
|
77
|
+
});
|
|
43
78
|
if ((occurrence.entry_kind !== "file" && occurrence.entry_kind !== "slice") ||
|
|
44
79
|
occurrence.artifact_id === null ||
|
|
45
80
|
occurrence.logical_path === ".")
|
|
46
81
|
throw new ArtifactReaderFailure("format", `Selected occurrence is not an extractable regular child file: ${occurrence.logical_path} (${occurrence.occurrence_id})`);
|
|
47
|
-
const node =
|
|
82
|
+
const node = nodes.get(occurrence.artifact_id);
|
|
48
83
|
if (node === undefined)
|
|
49
84
|
throw new ArtifactReaderFailure("integrity", `Selected occurrence has no inventory node: ${occurrence.occurrence_id}`);
|
|
50
85
|
return { occurrence, node };
|
|
@@ -60,73 +95,36 @@ export const extractArtifact = async (input, signal) => {
|
|
|
60
95
|
const materializeSelection = async ({ input, sourcePath, inventory, selected, signal, }) => {
|
|
61
96
|
const byPath = new Map(selected.map((item) => [item.occurrence.logical_path, item]));
|
|
62
97
|
const reader = await createReader(sourcePath, input);
|
|
98
|
+
const readerOwner = {
|
|
99
|
+
kind: "reader",
|
|
100
|
+
reader,
|
|
101
|
+
resource: `artifact reader for ${sourcePath}`,
|
|
102
|
+
};
|
|
103
|
+
let localReaderOwner = readerOwner;
|
|
63
104
|
let output;
|
|
64
|
-
let
|
|
65
|
-
let readerClosed = false;
|
|
105
|
+
let completed;
|
|
66
106
|
const extracted = [];
|
|
67
107
|
try {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
if (selectedItem === undefined) {
|
|
76
|
-
if (entry.kind === "file" || entry.kind === "slice")
|
|
77
|
-
throw new ArtifactReaderFailure("integrity", `Regular artifact entry is missing from inventory: ${path}`);
|
|
78
|
-
continue;
|
|
79
|
-
}
|
|
80
|
-
preflight(entry);
|
|
81
|
-
const stream = await reader.open(entry, signal);
|
|
82
|
-
const written = await output.write(path, stream, selectedItem.node.sha256, signal);
|
|
83
|
-
extracted.push({
|
|
84
|
-
artifact_id: selectedItem.node.artifact_id,
|
|
85
|
-
relative_path: written.relativePath,
|
|
86
|
-
sha256: written.sha256,
|
|
87
|
-
bytes_written: written.bytesWritten,
|
|
88
|
-
created: true,
|
|
89
|
-
});
|
|
90
|
-
materialized.push(selectedItem);
|
|
108
|
+
try {
|
|
109
|
+
output = await SafeOutputTree.create(input.outputRoot);
|
|
110
|
+
}
|
|
111
|
+
catch (cause) {
|
|
112
|
+
if (cause instanceof SafeOutputTreeCreationFailure)
|
|
113
|
+
output = cause.tree;
|
|
114
|
+
throw cause;
|
|
91
115
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
116
|
+
await writeSelectedEntries({ reader, output, byPath, extracted, signal });
|
|
117
|
+
localReaderOwner = undefined;
|
|
118
|
+
const closeAttempt = await input.resourceScope.release(readerOwner);
|
|
119
|
+
if (closeAttempt.kind === "failed")
|
|
120
|
+
throw ArtifactReaderFailure.withCleanup(closeAttempt.cause, ArtifactReaderFailure.cleanupObservation(closeAttempt.cause, readerOwner.resource));
|
|
121
|
+
extracted.sort((left, right) => compareUnicodeCodePoints(left.relative_path, right.relative_path));
|
|
122
|
+
completed = createExtractionResult(input, inventory, selected, extracted);
|
|
97
123
|
await output.commit();
|
|
98
|
-
return
|
|
124
|
+
return completed;
|
|
99
125
|
}
|
|
100
126
|
catch (cause) {
|
|
101
|
-
const cleanupFailures =
|
|
102
|
-
if (readerCloseAttempted && !readerClosed)
|
|
103
|
-
cleanupFailures.push({
|
|
104
|
-
cause,
|
|
105
|
-
resource: `artifact reader for ${sourcePath}`,
|
|
106
|
-
});
|
|
107
|
-
if (!readerCloseAttempted) {
|
|
108
|
-
try {
|
|
109
|
-
readerCloseAttempted = true;
|
|
110
|
-
await reader.close();
|
|
111
|
-
}
|
|
112
|
-
catch (cleanupCause) {
|
|
113
|
-
cleanupFailures.push({
|
|
114
|
-
cause: cleanupCause,
|
|
115
|
-
resource: `artifact reader for ${sourcePath}`,
|
|
116
|
-
});
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
if (output !== undefined) {
|
|
120
|
-
try {
|
|
121
|
-
await output.rollback();
|
|
122
|
-
}
|
|
123
|
-
catch (cleanupCause) {
|
|
124
|
-
cleanupFailures.push({
|
|
125
|
-
cause: cleanupCause,
|
|
126
|
-
resource: input.outputRoot,
|
|
127
|
-
});
|
|
128
|
-
}
|
|
129
|
-
}
|
|
127
|
+
const cleanupFailures = await releaseExtractionOwners(input.resourceScope, localReaderOwner, output, input.outputRoot);
|
|
130
128
|
if (cleanupFailures.length > 0) {
|
|
131
129
|
const observations = cleanupFailures.map(({ cause: cleanupCause, resource }) => ArtifactReaderFailure.cleanupObservation(cleanupCause, resource));
|
|
132
130
|
throw ArtifactReaderFailure.withCleanup(cause, {
|
|
@@ -134,50 +132,94 @@ const materializeSelection = async ({ input, sourcePath, inventory, selected, si
|
|
|
134
132
|
resources: [
|
|
135
133
|
...new Set(observations.flatMap(({ resources }) => resources)),
|
|
136
134
|
],
|
|
137
|
-
}
|
|
135
|
+
}, output?.published === true && completed !== undefined
|
|
136
|
+
? { kind: "artifact-extraction", extraction: completed }
|
|
137
|
+
: undefined);
|
|
138
138
|
}
|
|
139
|
+
if (output?.published === true && completed !== undefined)
|
|
140
|
+
return completed;
|
|
139
141
|
throw cause;
|
|
140
142
|
}
|
|
141
143
|
};
|
|
144
|
+
const writeSelectedEntries = async ({ reader, output, byPath, extracted, signal, }) => {
|
|
145
|
+
const registry = new ArtifactPathRegistry();
|
|
146
|
+
for await (const entry of reader.entries(signal)) {
|
|
147
|
+
const path = normalizeArtifactPath(entry.path);
|
|
148
|
+
registry.add(path, entry.kind);
|
|
149
|
+
const selectedItem = byPath.get(path);
|
|
150
|
+
if (selectedItem === undefined) {
|
|
151
|
+
if (entry.kind === "file" || entry.kind === "slice")
|
|
152
|
+
throw new ArtifactReaderFailure("integrity", `Regular artifact entry is missing from inventory: ${path}`);
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
preflight(entry);
|
|
156
|
+
const stream = await reader.open(entry, signal);
|
|
157
|
+
const written = await output.write(path, stream, {
|
|
158
|
+
sha256: selectedItem.node.sha256,
|
|
159
|
+
bytes: selectedItem.node.size,
|
|
160
|
+
}, signal);
|
|
161
|
+
extracted.push({
|
|
162
|
+
artifact_id: selectedItem.node.artifact_id,
|
|
163
|
+
relative_path: written.relativePath,
|
|
164
|
+
sha256: written.sha256,
|
|
165
|
+
bytes_written: written.bytesWritten,
|
|
166
|
+
created: true,
|
|
167
|
+
});
|
|
168
|
+
byPath.delete(path);
|
|
169
|
+
}
|
|
170
|
+
if (byPath.size > 0)
|
|
171
|
+
throw new ArtifactReaderFailure("integrity", `Inventoried regular artifact entries were not materialized: ${[...byPath.keys()].sort(compareUnicodeCodePoints).join(", ")}`);
|
|
172
|
+
};
|
|
173
|
+
const releaseExtractionOwners = async (resourceScope, readerOwner, output, outputRoot) => {
|
|
174
|
+
const failures = [];
|
|
175
|
+
if (readerOwner !== undefined) {
|
|
176
|
+
const attempt = await resourceScope.release(readerOwner);
|
|
177
|
+
if (attempt.kind === "failed")
|
|
178
|
+
failures.push({ cause: attempt.cause, resource: readerOwner.resource });
|
|
179
|
+
}
|
|
180
|
+
if (output !== undefined) {
|
|
181
|
+
const owner = {
|
|
182
|
+
kind: "output-tree",
|
|
183
|
+
tree: output,
|
|
184
|
+
resource: outputRoot,
|
|
185
|
+
};
|
|
186
|
+
const attempt = await resourceScope.release(owner);
|
|
187
|
+
if (attempt.kind === "failed")
|
|
188
|
+
failures.push({ cause: attempt.cause, resource: owner.resource });
|
|
189
|
+
}
|
|
190
|
+
return failures;
|
|
191
|
+
};
|
|
142
192
|
const createExtractionResult = (input, inventory, selected, extracted) => {
|
|
143
193
|
const extractionSemantic = {
|
|
144
194
|
source_manifest_id: inventory.manifest.manifest_id,
|
|
145
195
|
selected_occurrence_ids: selected
|
|
146
196
|
.map(({ occurrence }) => occurrence.occurrence_id)
|
|
147
|
-
.sort(
|
|
148
|
-
files_sha256:
|
|
197
|
+
.sort(compareUnicodeCodePoints),
|
|
198
|
+
files_sha256: digestCanonicalValue(extracted, "Artifact"),
|
|
149
199
|
output_root_alias: "$OUTPUT_ROOT",
|
|
150
200
|
};
|
|
151
201
|
return artifactExtractionResultSchema.parse({
|
|
152
202
|
manifest: inventory.manifest,
|
|
153
203
|
extraction_manifest: {
|
|
154
204
|
...extractionSemantic,
|
|
155
|
-
extraction_id: `aex_${
|
|
205
|
+
extraction_id: `aex_${digestCanonicalValue(extractionSemantic, "Artifact")}`,
|
|
156
206
|
},
|
|
157
207
|
output_root: input.outputRoot,
|
|
158
208
|
artifacts: extracted,
|
|
159
209
|
containment_verified: true,
|
|
160
210
|
cleanup: { attempted: false, verified: true, residual_paths: [] },
|
|
161
211
|
provenance: [],
|
|
212
|
+
integrity_contradictions: inventory.integrityContradictions,
|
|
162
213
|
limitations: [
|
|
163
214
|
"All regular files in the active artifact were materialized; nested archive contents remain represented by their containing file.",
|
|
215
|
+
...(inventory.integrityContradictions.length === 0
|
|
216
|
+
? []
|
|
217
|
+
: [
|
|
218
|
+
`${String(inventory.integrityContradictions.length)} extracted file(s) contradict declared integrity metadata; their bytes are observed-untrusted.`,
|
|
219
|
+
]),
|
|
164
220
|
],
|
|
165
221
|
});
|
|
166
222
|
};
|
|
167
|
-
const collectOccurrences = (items, selected, output, neededNodes) => {
|
|
168
|
-
for (const item of items) {
|
|
169
|
-
if (!selected.has(item.occurrence_id))
|
|
170
|
-
continue;
|
|
171
|
-
output.set(item.occurrence_id, item);
|
|
172
|
-
if (item.artifact_id !== null)
|
|
173
|
-
neededNodes.add(item.artifact_id);
|
|
174
|
-
}
|
|
175
|
-
};
|
|
176
|
-
const collectNodes = (items, selected, output) => {
|
|
177
|
-
for (const item of items)
|
|
178
|
-
if (selected.has(item.artifact_id))
|
|
179
|
-
output.set(item.artifact_id, item);
|
|
180
|
-
};
|
|
181
223
|
const ZIP_FORMATS = ["ipa", "apk", "msix", "appx", "zip"];
|
|
182
224
|
const isZipFormat = (format) => ZIP_FORMATS.includes(format);
|
|
183
225
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { compareUnicodeCodePoints } from "../../domain/unicodeCodePointOrder.js";
|
|
2
|
+
import { digestCanonicalValue } from "../../domain/canonicalDigest.js";
|
|
3
3
|
import { artifactEdgeId, artifactIdForContent, occurrenceIdForLocation, } from "../../domain/artifactIdentity.js";
|
|
4
4
|
import { hasZipSignature, zipPackageFormatForPath, } from "../../domain/zipPackageFormat.js";
|
|
5
5
|
import { mzWindowsHeaderOffset, parseDosMzHeader } from "../../domain/dosMz.js";
|
|
@@ -11,32 +11,55 @@ export const indexOccurrencesByPath = (occurrences) => {
|
|
|
11
11
|
byPath.set(occurrence.logical_path, occurrence);
|
|
12
12
|
return byPath;
|
|
13
13
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
?
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
:
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
:
|
|
36
|
-
|
|
37
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Create an occurrence before its bytes are read. A container suffix is not a
|
|
16
|
+
* container family until the bytes are classified, so a member named like a
|
|
17
|
+
* container starts with an unknown format.
|
|
18
|
+
*/
|
|
19
|
+
export const createOccurrence = (entry, path, parent) => {
|
|
20
|
+
const role = entry.kind === "directory"
|
|
21
|
+
? {
|
|
22
|
+
kind: path.toLowerCase().endsWith(".framework")
|
|
23
|
+
? "framework"
|
|
24
|
+
: "container",
|
|
25
|
+
format: "directory",
|
|
26
|
+
}
|
|
27
|
+
: containerSuffixFamily(path) === undefined
|
|
28
|
+
? classifyArtifactPath(path)
|
|
29
|
+
: { kind: "unknown", format: "unknown" };
|
|
30
|
+
return {
|
|
31
|
+
occurrence_id: `occ_${digestCanonicalValue({ path, kind: entry.kind }, "Artifact")}`,
|
|
32
|
+
artifact_id: null,
|
|
33
|
+
parent_occurrence_id: parent,
|
|
34
|
+
logical_path: path,
|
|
35
|
+
entry_kind: entry.kind,
|
|
36
|
+
artifact_kind: role.kind,
|
|
37
|
+
artifact_format: role.format,
|
|
38
|
+
declared_size: entry.declaredSize,
|
|
39
|
+
compressed_size: entry.compressedSize,
|
|
40
|
+
executable: entry.executable,
|
|
41
|
+
encrypted: entry.encrypted,
|
|
42
|
+
hash_status: entry.encrypted ? "unavailable" : "not-hashed",
|
|
43
|
+
source_location: entry.byteOffset === null || entry.declaredSize === null
|
|
44
|
+
? null
|
|
45
|
+
: { offset: entry.byteOffset, length: entry.declaredSize },
|
|
46
|
+
limitations: [...entry.limitations],
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
/** Record that an unread member's container suffix was not checked against bytes. */
|
|
50
|
+
export const noteUnreadContainerSuffix = (occurrence) => {
|
|
51
|
+
if (occurrence.entry_kind === "directory")
|
|
52
|
+
return;
|
|
53
|
+
const family = containerSuffixFamily(occurrence.logical_path);
|
|
54
|
+
if (family === undefined)
|
|
55
|
+
return;
|
|
56
|
+
occurrence.limitations.push(`The path suffix suggests ${family.toUpperCase()}, but these bytes were not read, so the container family is unknown.`);
|
|
57
|
+
};
|
|
58
|
+
const containerSuffixFamily = (path) => {
|
|
59
|
+
const lower = path.toLowerCase();
|
|
60
|
+
return lower.endsWith(".asar") ? "asar" : zipPackageFormatForPath(lower);
|
|
61
|
+
};
|
|
38
62
|
/** Compare exact child names independently of host locale and traversal order. */
|
|
39
|
-
export const compareDirectoryChildNames = compareCodePoints;
|
|
40
63
|
export const materializeDirectoryNodes = (occurrences, nodes) => {
|
|
41
64
|
const directories = occurrences
|
|
42
65
|
.filter(({ entry_kind: kind }) => kind === "directory")
|
|
@@ -59,9 +82,9 @@ export const materializeDirectoryNodes = (occurrences, nodes) => {
|
|
|
59
82
|
artifact_id,
|
|
60
83
|
entry_kind,
|
|
61
84
|
}))
|
|
62
|
-
.sort((left, right) =>
|
|
85
|
+
.sort((left, right) => compareUnicodeCodePoints(left.name, right.name));
|
|
63
86
|
const node = createArtifactNode({
|
|
64
|
-
sha256:
|
|
87
|
+
sha256: digestCanonicalValue({ kind: "directory", children }, "Artifact"),
|
|
65
88
|
size: 0,
|
|
66
89
|
format: "directory",
|
|
67
90
|
contentState: "virtual",
|
|
@@ -73,14 +96,14 @@ export const materializeDirectoryNodes = (occurrences, nodes) => {
|
|
|
73
96
|
};
|
|
74
97
|
export const createRootNode = (input) => createArtifactNode({
|
|
75
98
|
sha256: input.digest?.sha256 ??
|
|
76
|
-
|
|
99
|
+
digestCanonicalValue({
|
|
77
100
|
kind: "directory-root",
|
|
78
101
|
children: input.occurrences
|
|
79
102
|
.map(({ logical_path, artifact_id }) => ({
|
|
80
103
|
logical_path,
|
|
81
104
|
artifact_id,
|
|
82
105
|
}))
|
|
83
|
-
.sort((left, right) =>
|
|
106
|
+
.sort((left, right) => compareUnicodeCodePoints(left.logical_path, right.logical_path)),
|
|
84
107
|
}, "Artifact"),
|
|
85
108
|
size: input.digest?.bytes ?? 0,
|
|
86
109
|
format: input.digest === null
|
|
@@ -154,15 +177,13 @@ export const createArtifactEdges = (rootArtifactId, occurrences, producer) => {
|
|
|
154
177
|
rootArtifactId;
|
|
155
178
|
const semantic = {
|
|
156
179
|
parent_artifact_id: parentArtifactId,
|
|
157
|
-
child_artifact_id: occurrence.artifact_id,
|
|
158
180
|
relation: occurrence.entry_kind === "slice"
|
|
159
181
|
? "slice-of"
|
|
160
182
|
: relationFor(occurrence.logical_path),
|
|
161
183
|
occurrence_id: occurrence.occurrence_id,
|
|
162
|
-
logical_path: occurrence.logical_path,
|
|
163
184
|
};
|
|
164
185
|
edges.push({
|
|
165
|
-
edge_id: artifactEdgeId(semantic),
|
|
186
|
+
edge_id: artifactEdgeId(semantic, occurrence),
|
|
166
187
|
...semantic,
|
|
167
188
|
producer: occurrence.entry_kind === "slice" ? (producer ?? null) : null,
|
|
168
189
|
ordinal: edges.length,
|
|
@@ -170,29 +191,55 @@ export const createArtifactEdges = (rootArtifactId, occurrences, producer) => {
|
|
|
170
191
|
}
|
|
171
192
|
return edges;
|
|
172
193
|
};
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
194
|
+
/** Resolve strict observed ancestors without rebuilding every path prefix. */
|
|
195
|
+
export const resolveOccurrenceParents = (occurrences, byPath, expandedContainerIds) => {
|
|
196
|
+
const root = { children: new Map() };
|
|
197
|
+
for (const occurrence of byPath.values()) {
|
|
198
|
+
if (occurrence.entry_kind !== "directory" &&
|
|
199
|
+
!expandedContainerIds.has(occurrence.occurrence_id))
|
|
200
|
+
continue;
|
|
201
|
+
let branch = root;
|
|
202
|
+
for (const segment of occurrence.logical_path.split("/")) {
|
|
203
|
+
let child = branch.children.get(segment);
|
|
204
|
+
if (child === undefined) {
|
|
205
|
+
child = { children: new Map() };
|
|
206
|
+
branch.children.set(segment, child);
|
|
207
|
+
}
|
|
208
|
+
branch = child;
|
|
209
|
+
}
|
|
210
|
+
branch.occurrence = occurrence;
|
|
211
|
+
}
|
|
212
|
+
for (const occurrence of occurrences) {
|
|
213
|
+
const path = occurrence.logical_path;
|
|
214
|
+
let branch = root;
|
|
215
|
+
let parent;
|
|
216
|
+
// Walk parent segments only. Stop scanning the path once no observed
|
|
217
|
+
// directory or expanded container can be an ancestor.
|
|
218
|
+
for (let start = 0;;) {
|
|
219
|
+
const slash = path.indexOf("/", start);
|
|
220
|
+
if (slash < 0)
|
|
221
|
+
break;
|
|
222
|
+
const segment = path.slice(start, slash);
|
|
223
|
+
const child = branch.children.get(segment);
|
|
224
|
+
if (child === undefined)
|
|
225
|
+
break;
|
|
226
|
+
branch = child;
|
|
227
|
+
parent = branch.occurrence ?? parent;
|
|
228
|
+
start = slash + 1;
|
|
229
|
+
}
|
|
230
|
+
occurrence.parent_occurrence_id = parent?.occurrence_id ?? null;
|
|
182
231
|
}
|
|
183
|
-
return undefined;
|
|
184
232
|
};
|
|
233
|
+
/**
|
|
234
|
+
* Assign a path role hint. Container families are not path roles: ZIP and
|
|
235
|
+
* ASAR families are chosen only after their bytes have been classified.
|
|
236
|
+
*/
|
|
185
237
|
export const classifyArtifactPath = (path) => {
|
|
186
238
|
const lower = path.toLowerCase();
|
|
187
239
|
if (lower.endsWith(".map"))
|
|
188
240
|
return { kind: "source-map", format: "source-map" };
|
|
189
241
|
if (/\.(?:m?js|cjs)$/u.test(lower))
|
|
190
242
|
return { kind: "javascript", format: "javascript-bundle" };
|
|
191
|
-
if (lower.endsWith(".asar"))
|
|
192
|
-
return { kind: "container", format: "asar" };
|
|
193
|
-
const archiveFormat = zipPackageFormatForPath(lower);
|
|
194
|
-
if (archiveFormat !== undefined)
|
|
195
|
-
return { kind: "container", format: archiveFormat };
|
|
196
243
|
if (/\.framework(?:\/|$)/u.test(lower))
|
|
197
244
|
return { kind: "framework", format: "file" };
|
|
198
245
|
if (/\.(?:node|dylib|so)$/u.test(lower))
|
|
@@ -208,7 +255,26 @@ export const classifyArtifactPath = (path) => {
|
|
|
208
255
|
};
|
|
209
256
|
/** Classify executable formats from bytes while retaining path-specific roles. */
|
|
210
257
|
export const classifyArtifactContent = (path, prefix, fileSize = prefix.length) => {
|
|
211
|
-
|
|
258
|
+
const format = classifyArtifactBytes(prefix, fileSize);
|
|
259
|
+
if (format === "file" &&
|
|
260
|
+
path.toLowerCase().endsWith(".asar") &&
|
|
261
|
+
hasAsarHeader(prefix))
|
|
262
|
+
return { kind: "container", format: "asar" };
|
|
263
|
+
return artifactRoleForFormat(path, format);
|
|
264
|
+
};
|
|
265
|
+
/**
|
|
266
|
+
* Electron ASAR starts with a size pickle whose payload is one uint32, then
|
|
267
|
+
* a header pickle whose payload begins with a JSON object.
|
|
268
|
+
*/
|
|
269
|
+
export const hasAsarHeader = (prefix) => {
|
|
270
|
+
if (prefix.length < 17 || prefix.readUInt32LE(0) !== 4)
|
|
271
|
+
return false;
|
|
272
|
+
const headerSize = prefix.readUInt32LE(4);
|
|
273
|
+
const payloadSize = prefix.readUInt32LE(8);
|
|
274
|
+
if (headerSize < 16 || payloadSize !== headerSize - 4)
|
|
275
|
+
return false;
|
|
276
|
+
const stringLength = prefix.readUInt32LE(12);
|
|
277
|
+
return (stringLength >= 2 && stringLength <= payloadSize - 4 && prefix[16] === 0x7b);
|
|
212
278
|
};
|
|
213
279
|
const artifactRoleForFormat = (path, format) => {
|
|
214
280
|
const byPath = classifyArtifactPath(path);
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { realpath } from "node:fs/promises";
|
|
2
2
|
import { artifactInventoryResultSchema, } from "../../domain/artifactGraph.js";
|
|
3
3
|
import { abortIfNeeded } from "../ArtifactHash.js";
|
|
4
|
-
import {
|
|
4
|
+
import { scanCanonicalArtifactInventoryInScope } from "./scanCanonical.js";
|
|
5
5
|
/** Inventory one local artifact and return every graph collection inline. */
|
|
6
|
-
export const inventoryArtifact = async (inputPath, options
|
|
6
|
+
export const inventoryArtifact = async (inputPath, options) => {
|
|
7
7
|
const snapshot = await scanArtifactInventory(inputPath, options);
|
|
8
8
|
return artifactInventoryResultSchema.parse(snapshot);
|
|
9
9
|
};
|
|
10
10
|
/** Scan an artifact once and retain the complete immutable graph for projection. */
|
|
11
|
-
export const scanArtifactInventory = async (inputPath, options
|
|
11
|
+
export const scanArtifactInventory = async (inputPath, options) => options.resourceScope.run(() => scanArtifactInventoryInScope(inputPath, options));
|
|
12
|
+
export const scanArtifactInventoryInScope = async (inputPath, options) => {
|
|
12
13
|
abortIfNeeded(options.signal);
|
|
13
14
|
const path = await realpath(inputPath);
|
|
14
|
-
return
|
|
15
|
+
return scanCanonicalArtifactInventoryInScope(path, options);
|
|
15
16
|
};
|