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
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { AnalysisOutputError } from "../domain/analysisErrorCore.js";
|
|
1
2
|
import { inspectMachoSchema, } from "../domain/native/nativeInspection.js";
|
|
2
3
|
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
3
4
|
import { err, ok } from "../domain/result.js";
|
|
@@ -30,7 +31,11 @@ export const inspectNativeMacho = async (context) => {
|
|
|
30
31
|
const lipo = captures.find(({ tool }) => tool === "lipo");
|
|
31
32
|
if (lipo === undefined)
|
|
32
33
|
throw new TypeError("Missing lipo capture");
|
|
33
|
-
const
|
|
34
|
+
const availableArchitectures = parseLipoArchitectures(lipo.stdout).map(({ name }) => name);
|
|
35
|
+
const selection = selectArchitecture(context.target, availableArchitectures);
|
|
36
|
+
if (selection.status === "absent")
|
|
37
|
+
return err(new AnalysisOutputError("inspect_macho", `lipo did not list ${selection.architecture}; refusing to read another slice`));
|
|
38
|
+
const selectedArchitecture = selection.status === "selected" ? selection.architecture : null;
|
|
34
39
|
for (const [tool, prefix] of REQUIRED_SLICE_COMMANDS) {
|
|
35
40
|
const captured = await context.run(tool, [
|
|
36
41
|
...prefix,
|
|
@@ -67,7 +72,6 @@ export const inspectNativeMacho = async (context) => {
|
|
|
67
72
|
: normalized;
|
|
68
73
|
return ok({
|
|
69
74
|
result: jsonValueSchema.parse(result),
|
|
70
|
-
provenance: result.provenance,
|
|
71
75
|
limitations: result.limitations,
|
|
72
76
|
locations: fileOffsetLocations(result, segmentOffset),
|
|
73
77
|
});
|
|
@@ -226,19 +230,19 @@ const selectedArchitectureArguments = (tool, architecture) => {
|
|
|
226
230
|
};
|
|
227
231
|
const selectArchitecture = (target, available) => {
|
|
228
232
|
if (target.kind !== "executable" || target.availableArchitectures.length < 2)
|
|
229
|
-
return
|
|
233
|
+
return { status: "unfiltered" };
|
|
230
234
|
const normalized = target.architecture === "x86" ? "i386" : target.architecture;
|
|
231
235
|
if (available.includes(normalized))
|
|
232
|
-
return normalized;
|
|
236
|
+
return { status: "selected", architecture: normalized };
|
|
233
237
|
// BinaryTarget intentionally normalizes ARM64 CPU subtypes. Recover the
|
|
234
238
|
// concrete arm64e slice name from lipo before invoking slice-aware tools.
|
|
235
239
|
if (normalized === "arm64") {
|
|
236
240
|
const arm64e = available.find((architecture) => architecture === "arm64e");
|
|
237
241
|
if (arm64e !== undefined)
|
|
238
|
-
return arm64e;
|
|
242
|
+
return { status: "selected", architecture: arm64e };
|
|
239
243
|
const variant = available.find((architecture) => /^arm64e\.[A-Za-z0-9_]+$/u.test(architecture));
|
|
240
244
|
if (variant !== undefined)
|
|
241
|
-
return variant;
|
|
245
|
+
return { status: "selected", architecture: variant };
|
|
242
246
|
}
|
|
243
|
-
return normalized;
|
|
247
|
+
return { status: "absent", architecture: normalized };
|
|
244
248
|
};
|
|
@@ -41,6 +41,7 @@ export const createNativeUiHelperRuntime = (environment) => {
|
|
|
41
41
|
const output = await execFileOutput(executable, [JSON.stringify(parameters)], {
|
|
42
42
|
timeout: 30_000,
|
|
43
43
|
maxBuffer: NATIVE_UI_HELPER_MAX_BUFFER,
|
|
44
|
+
stopSignal: "SIGTERM",
|
|
44
45
|
env: selectedEnvironment,
|
|
45
46
|
...(signal === undefined ? {} : { signal }),
|
|
46
47
|
});
|
|
@@ -54,8 +55,12 @@ export const createNativeUiHelperRuntime = (environment) => {
|
|
|
54
55
|
return {
|
|
55
56
|
invoke,
|
|
56
57
|
close: async () => {
|
|
57
|
-
if (root !== undefined)
|
|
58
|
+
if (root !== undefined) {
|
|
58
59
|
await rm(root, { recursive: true, force: true });
|
|
60
|
+
root = undefined;
|
|
61
|
+
executable = undefined;
|
|
62
|
+
}
|
|
59
63
|
},
|
|
64
|
+
resources: () => (root === undefined ? [] : [root]),
|
|
60
65
|
};
|
|
61
66
|
};
|
|
@@ -5,7 +5,7 @@ import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInp
|
|
|
5
5
|
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
6
6
|
import {} from "../domain/analysisErrorBase.js";
|
|
7
7
|
import { err, ok } from "../domain/result.js";
|
|
8
|
-
import { createNativeUiHelperRuntime } from "./NativeUiHelperRuntime.js";
|
|
8
|
+
import { createNativeUiHelperRuntime, } from "./NativeUiHelperRuntime.js";
|
|
9
9
|
import { NATIVE_UI_OUTPUT_BUDGET_BYTES, NATIVE_UI_OUTPUT_WEIGHT, } from "./NativeUiOutputBudget.js";
|
|
10
10
|
const helper = fileURLToPath(new URL("../../bridge/native/ReaNativeUI.swift", import.meta.url));
|
|
11
11
|
const responseSchema = z.discriminatedUnion("ok", [
|
|
@@ -18,7 +18,7 @@ const responseSchema = z.discriminatedUnion("ok", [
|
|
|
18
18
|
]);
|
|
19
19
|
/** Capture a selected existing app window and run explicitly selected scenarios. */
|
|
20
20
|
export const observeNativeUi = async (target, operation, parameters, options) => {
|
|
21
|
-
const runtime = createNativeUiHelperRuntime(options.environment);
|
|
21
|
+
const runtime = options.runtime ?? createNativeUiHelperRuntime(options.environment);
|
|
22
22
|
try {
|
|
23
23
|
return await observeWithHelper(target, operation, parameters, {
|
|
24
24
|
...options,
|
|
@@ -26,7 +26,8 @@ export const observeNativeUi = async (target, operation, parameters, options) =>
|
|
|
26
26
|
});
|
|
27
27
|
}
|
|
28
28
|
finally {
|
|
29
|
-
|
|
29
|
+
if (options.runtime === undefined)
|
|
30
|
+
await runtime.close();
|
|
30
31
|
}
|
|
31
32
|
};
|
|
32
33
|
const observeWithHelper = async (target, operation, parameters, options) => {
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { ArtifactReaderFailure } from "../../artifacts/ArtifactReader.js";
|
|
2
|
+
export const peFailure = (message) => {
|
|
3
|
+
throw new ArtifactReaderFailure("format", message);
|
|
4
|
+
};
|
|
5
|
+
export const requirePeRange = (bytes, offset, length) => {
|
|
6
|
+
if (!Number.isSafeInteger(offset) ||
|
|
7
|
+
!Number.isSafeInteger(length) ||
|
|
8
|
+
offset < 0 ||
|
|
9
|
+
length < 0 ||
|
|
10
|
+
offset > bytes.length - length)
|
|
11
|
+
peFailure(`PE range ${String(offset)} + ${String(length)} leaves the artifact.`);
|
|
12
|
+
};
|
|
13
|
+
// RVA ownership follows the declared virtual extent. Raw size describes
|
|
14
|
+
// initialized file bytes and can include file-alignment padding; loaders may
|
|
15
|
+
// map page-rounded tails, but those bytes are outside the declared section.
|
|
16
|
+
const virtualExtent = (section) => section.virtualSize === 0 ? section.size : section.virtualSize;
|
|
17
|
+
/** Header admission and unambiguous file-backed RVA mapping, independent of section names. */
|
|
18
|
+
export const readPeResourceLayout = (bytes) => {
|
|
19
|
+
requirePeRange(bytes, 0, 64);
|
|
20
|
+
if (bytes.readUInt16LE(0) !== 0x5a4d)
|
|
21
|
+
peFailure("Expected an MZ PE image.");
|
|
22
|
+
const pe = bytes.readUInt32LE(60);
|
|
23
|
+
requirePeRange(bytes, pe, 24);
|
|
24
|
+
if (bytes.readUInt32LE(pe) !== 0x4550)
|
|
25
|
+
peFailure("Expected a PE signature.");
|
|
26
|
+
const sectionCount = bytes.readUInt16LE(pe + 6);
|
|
27
|
+
const optionalSize = bytes.readUInt16LE(pe + 20);
|
|
28
|
+
const optional = pe + 24;
|
|
29
|
+
requirePeRange(bytes, optional, optionalSize);
|
|
30
|
+
if (optionalSize < 64)
|
|
31
|
+
peFailure("Truncated PE optional header.");
|
|
32
|
+
const magic = bytes.readUInt16LE(optional);
|
|
33
|
+
if (magic !== 0x10b && magic !== 0x20b)
|
|
34
|
+
peFailure("Unsupported PE optional header magic.");
|
|
35
|
+
const countAt = magic === 0x10b ? 92 : 108;
|
|
36
|
+
const directoriesAt = countAt + 4;
|
|
37
|
+
if (optionalSize < directoriesAt)
|
|
38
|
+
peFailure("Truncated PE data directory count.");
|
|
39
|
+
const directoryCount = bytes.readUInt32LE(optional + countAt);
|
|
40
|
+
if (directoryCount > Math.floor((optionalSize - directoriesAt) / 8))
|
|
41
|
+
peFailure("PE directory count exceeds its optional header.");
|
|
42
|
+
const headerSize = bytes.readUInt32LE(optional + 60);
|
|
43
|
+
const table = optional + optionalSize;
|
|
44
|
+
requirePeRange(bytes, table, sectionCount * 40);
|
|
45
|
+
if (headerSize < table + sectionCount * 40 || headerSize > bytes.length)
|
|
46
|
+
peFailure("Invalid PE SizeOfHeaders.");
|
|
47
|
+
const sections = [];
|
|
48
|
+
for (let index = 0; index < sectionCount; index++) {
|
|
49
|
+
const at = table + index * 40;
|
|
50
|
+
const section = {
|
|
51
|
+
rva: bytes.readUInt32LE(at + 12),
|
|
52
|
+
virtualSize: bytes.readUInt32LE(at + 8),
|
|
53
|
+
offset: bytes.readUInt32LE(at + 20),
|
|
54
|
+
size: bytes.readUInt32LE(at + 16),
|
|
55
|
+
};
|
|
56
|
+
if (section.rva + virtualExtent(section) > 0x100000000)
|
|
57
|
+
peFailure("PE section RVA range overflows.");
|
|
58
|
+
if (section.size > 0) {
|
|
59
|
+
requirePeRange(bytes, section.offset, section.size);
|
|
60
|
+
if (section.offset < headerSize)
|
|
61
|
+
peFailure("PE section raw bytes overlap headers.");
|
|
62
|
+
}
|
|
63
|
+
sections.push(section);
|
|
64
|
+
}
|
|
65
|
+
const backed = sections
|
|
66
|
+
.filter(({ size }) => size > 0)
|
|
67
|
+
.sort((left, right) => left.offset - right.offset);
|
|
68
|
+
for (let index = 1; index < backed.length; index++) {
|
|
69
|
+
const previous = backed[index - 1];
|
|
70
|
+
const current = backed[index];
|
|
71
|
+
if (previous !== undefined &&
|
|
72
|
+
current !== undefined &&
|
|
73
|
+
current.offset < previous.offset + previous.size)
|
|
74
|
+
peFailure("PE sections have overlapping raw file ranges.");
|
|
75
|
+
}
|
|
76
|
+
const map = (rva, size) => {
|
|
77
|
+
if (rva + size > 0x100000000)
|
|
78
|
+
peFailure("Resource RVA range overflows.");
|
|
79
|
+
const candidates = sections.filter((section) => rva >= section.rva && rva - section.rva < virtualExtent(section));
|
|
80
|
+
if (rva < headerSize) {
|
|
81
|
+
if (sections.some((section) => section.rva < rva + size &&
|
|
82
|
+
section.rva + virtualExtent(section) > rva) ||
|
|
83
|
+
size > headerSize - rva)
|
|
84
|
+
peFailure("Ambiguous resource header RVA mapping.");
|
|
85
|
+
requirePeRange(bytes, rva, size);
|
|
86
|
+
return rva;
|
|
87
|
+
}
|
|
88
|
+
if (candidates.length !== 1)
|
|
89
|
+
peFailure("Resource RVA has missing or overlapping section mappings.");
|
|
90
|
+
const section = candidates[0];
|
|
91
|
+
if (section === undefined)
|
|
92
|
+
return peFailure("Missing resource section.");
|
|
93
|
+
const within = rva - section.rva;
|
|
94
|
+
if (size > virtualExtent(section) - within)
|
|
95
|
+
peFailure("Resource range leaves its section's virtual size.");
|
|
96
|
+
if (within > section.size || size > section.size - within)
|
|
97
|
+
peFailure("Resource range is not entirely file-backed in one section.");
|
|
98
|
+
// A second section starting inside the requested interval is ambiguous too.
|
|
99
|
+
if (sections.some((other) => other !== section &&
|
|
100
|
+
other.rva < rva + size &&
|
|
101
|
+
other.rva + virtualExtent(other) > rva))
|
|
102
|
+
peFailure("Resource interval intersects overlapping virtual sections.");
|
|
103
|
+
const offset = section.offset + within;
|
|
104
|
+
requirePeRange(bytes, offset, size);
|
|
105
|
+
return offset;
|
|
106
|
+
};
|
|
107
|
+
const directoryAt = optional + directoriesAt + 16;
|
|
108
|
+
const rva = directoryCount > 2 ? bytes.readUInt32LE(directoryAt) : 0;
|
|
109
|
+
const size = directoryCount > 2 ? bytes.readUInt32LE(directoryAt + 4) : 0;
|
|
110
|
+
if ((rva === 0) !== (size === 0))
|
|
111
|
+
peFailure("Inconsistent PE resource directory RVA/size.");
|
|
112
|
+
return {
|
|
113
|
+
format: magic === 0x10b ? "pe32" : "pe32-plus",
|
|
114
|
+
machine: bytes.readUInt16LE(pe + 4),
|
|
115
|
+
directoryAt,
|
|
116
|
+
rva,
|
|
117
|
+
size,
|
|
118
|
+
map,
|
|
119
|
+
};
|
|
120
|
+
};
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { setImmediate } from "node:timers/promises";
|
|
3
|
+
import { ArtifactReaderFailure } from "../../artifacts/ArtifactReader.js";
|
|
4
|
+
import { jsonParts } from "../../domain/jsonSerialization.js";
|
|
5
|
+
import { peFailure, readPeResourceLayout, requirePeRange, } from "./PeResourceLayout.js";
|
|
6
|
+
const METADATA_BYTES = 8 * 1024 * 1024;
|
|
7
|
+
const limit = (message) => {
|
|
8
|
+
throw new ArtifactReaderFailure("limit", message);
|
|
9
|
+
};
|
|
10
|
+
/** Count bytes through the canonical bounded JSON writer. */
|
|
11
|
+
const jsonBytes = (value, maximum) => {
|
|
12
|
+
let size = 0;
|
|
13
|
+
for (const part of jsonParts(value)) {
|
|
14
|
+
size += Buffer.byteLength(part, "utf8");
|
|
15
|
+
if (size > maximum)
|
|
16
|
+
return size;
|
|
17
|
+
}
|
|
18
|
+
return size;
|
|
19
|
+
};
|
|
20
|
+
const identityKey = (id) => id.kind === "id" ? `id:${String(id.id)}` : `name:${id.utf16le_hex}`;
|
|
21
|
+
/** Decode the conventional type/name/language tree; never infer payload meaning or runtime loading. */
|
|
22
|
+
export const parsePeResources = async (bytes, artifact, input, signal) => {
|
|
23
|
+
signal?.throwIfAborted();
|
|
24
|
+
const layout = readPeResourceLayout(bytes);
|
|
25
|
+
const directories = [];
|
|
26
|
+
const resources = [];
|
|
27
|
+
const occupied = [];
|
|
28
|
+
const names = new Map();
|
|
29
|
+
let examined = 0;
|
|
30
|
+
let metadataBytes = 0;
|
|
31
|
+
const ensureCapacity = (projectedBytes) => {
|
|
32
|
+
if (metadataBytes + projectedBytes > METADATA_BYTES)
|
|
33
|
+
limit("PE resource metadata exceeds the 8 MiB complete-result allocation budget.");
|
|
34
|
+
};
|
|
35
|
+
const accountBytes = (projectedBytes) => {
|
|
36
|
+
ensureCapacity(projectedBytes);
|
|
37
|
+
metadataBytes += projectedBytes;
|
|
38
|
+
};
|
|
39
|
+
const account = (value) => {
|
|
40
|
+
// Rows are retained in arrays; reserve a separator along with each row.
|
|
41
|
+
accountBytes(jsonBytes(value, METADATA_BYTES - metadataBytes - 1) + 1);
|
|
42
|
+
};
|
|
43
|
+
const reserveDecodedName = (utf16Units) => {
|
|
44
|
+
// A JSON string can need six ASCII bytes per UTF-16 code unit (for example,
|
|
45
|
+
// a control character encoded as `\\u0000`). The original spelling and
|
|
46
|
+
// its hex form are both retained in the result.
|
|
47
|
+
const projectedBytes = 10 * utf16Units + 256;
|
|
48
|
+
ensureCapacity(projectedBytes);
|
|
49
|
+
};
|
|
50
|
+
const root = layout.size === 0 ? 0 : layout.map(layout.rva, layout.size);
|
|
51
|
+
const relative = (at, length) => {
|
|
52
|
+
if (at > layout.size - length || at < 0)
|
|
53
|
+
peFailure("Resource directory offset leaves the declared resource interval.");
|
|
54
|
+
requirePeRange(bytes, root + at, length);
|
|
55
|
+
return root + at;
|
|
56
|
+
};
|
|
57
|
+
const recordRange = (offset, size, kind) => {
|
|
58
|
+
const range = { offset, bytes: size };
|
|
59
|
+
if (size > 0)
|
|
60
|
+
occupied.push({ ...range, kind });
|
|
61
|
+
return range;
|
|
62
|
+
};
|
|
63
|
+
const readIdentity = (encoded) => {
|
|
64
|
+
if ((encoded & 0x80000000) === 0)
|
|
65
|
+
return { kind: "id", id: encoded };
|
|
66
|
+
const at = encoded & 0x7fffffff;
|
|
67
|
+
const previous = names.get(at);
|
|
68
|
+
if (previous !== undefined)
|
|
69
|
+
return previous;
|
|
70
|
+
if (at % 2 !== 0)
|
|
71
|
+
peFailure("Unaligned PE resource name.");
|
|
72
|
+
const start = relative(at, 2);
|
|
73
|
+
const utf16Units = bytes.readUInt16LE(start);
|
|
74
|
+
reserveDecodedName(utf16Units);
|
|
75
|
+
const length = utf16Units * 2;
|
|
76
|
+
relative(at, 2 + length);
|
|
77
|
+
const raw = bytes.subarray(start + 2, start + 2 + length);
|
|
78
|
+
const value = {
|
|
79
|
+
kind: "name",
|
|
80
|
+
name: raw.toString("utf16le"),
|
|
81
|
+
utf16le_hex: raw.toString("hex"),
|
|
82
|
+
location: recordRange(start, 2 + length, "name"),
|
|
83
|
+
};
|
|
84
|
+
names.set(at, value);
|
|
85
|
+
return value;
|
|
86
|
+
};
|
|
87
|
+
const visit = async (at, path, entryLocations, ancestors) => {
|
|
88
|
+
if (ancestors.has(at))
|
|
89
|
+
peFailure("Cyclic PE resource directory.");
|
|
90
|
+
if (at % 4 !== 0)
|
|
91
|
+
peFailure("Unaligned PE resource directory.");
|
|
92
|
+
const header = relative(at, 16);
|
|
93
|
+
const named = bytes.readUInt16LE(header + 12);
|
|
94
|
+
const ids = bytes.readUInt16LE(header + 14);
|
|
95
|
+
const count = named + ids;
|
|
96
|
+
if (count > input.max_entries - examined)
|
|
97
|
+
limit("PE resource directory entry budget exceeded; no partial inventory was returned.");
|
|
98
|
+
examined += count;
|
|
99
|
+
relative(at, 16 + 8 * count);
|
|
100
|
+
const directory = {
|
|
101
|
+
location: recordRange(header, 16 + 8 * count, "directory"),
|
|
102
|
+
characteristics: bytes.readUInt32LE(header),
|
|
103
|
+
timestamp: bytes.readUInt32LE(header + 4),
|
|
104
|
+
major_version: bytes.readUInt16LE(header + 8),
|
|
105
|
+
minor_version: bytes.readUInt16LE(header + 10),
|
|
106
|
+
named_entries: named,
|
|
107
|
+
id_entries: ids,
|
|
108
|
+
};
|
|
109
|
+
account(directory);
|
|
110
|
+
directories.push(directory);
|
|
111
|
+
const keys = new Set();
|
|
112
|
+
const nested = new Set([...ancestors, at]);
|
|
113
|
+
for (let index = 0; index < count; index++) {
|
|
114
|
+
if (index % 128 === 0) {
|
|
115
|
+
await setImmediate();
|
|
116
|
+
signal?.throwIfAborted();
|
|
117
|
+
}
|
|
118
|
+
const entry = header + 16 + index * 8;
|
|
119
|
+
const encoded = bytes.readUInt32LE(entry);
|
|
120
|
+
if (((encoded & 0x80000000) !== 0) !== index < named)
|
|
121
|
+
peFailure("Resource name/ID entry counts disagree with encoded identities.");
|
|
122
|
+
const identity = readIdentity(encoded);
|
|
123
|
+
const key = identityKey(identity);
|
|
124
|
+
if (keys.has(key))
|
|
125
|
+
peFailure("Duplicate identity within a resource directory.");
|
|
126
|
+
keys.add(key);
|
|
127
|
+
const next = [...path, identity];
|
|
128
|
+
const locations = [...entryLocations, { offset: entry, bytes: 8 }];
|
|
129
|
+
const target = bytes.readUInt32LE(entry + 4);
|
|
130
|
+
const offset = target & 0x7fffffff;
|
|
131
|
+
if ((target & 0x80000000) !== 0) {
|
|
132
|
+
if (next.length >= 3)
|
|
133
|
+
peFailure("Unsupported resource tree deeper than type/name/language.");
|
|
134
|
+
await visit(offset, next, locations, nested);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
if (next.length !== 3)
|
|
138
|
+
peFailure("Unsupported resource leaf outside the type/name/language profile.");
|
|
139
|
+
const data = relative(offset, 16);
|
|
140
|
+
if (offset % 4 !== 0)
|
|
141
|
+
peFailure("Unaligned resource data entry.");
|
|
142
|
+
const rva = bytes.readUInt32LE(data);
|
|
143
|
+
const size = bytes.readUInt32LE(data + 4);
|
|
144
|
+
const payloadOffset = layout.map(rva, size);
|
|
145
|
+
const [type, name, language] = next;
|
|
146
|
+
if (type === undefined || name === undefined || language === undefined)
|
|
147
|
+
return peFailure("Incomplete resource identity.");
|
|
148
|
+
const resource = {
|
|
149
|
+
index: resources.length,
|
|
150
|
+
type,
|
|
151
|
+
name,
|
|
152
|
+
language,
|
|
153
|
+
entry_locations: locations,
|
|
154
|
+
data_entry_location: recordRange(data, 16, "data-entry"),
|
|
155
|
+
code_page: bytes.readUInt32LE(data + 8),
|
|
156
|
+
reserved: bytes.readUInt32LE(data + 12),
|
|
157
|
+
payload: {
|
|
158
|
+
rva,
|
|
159
|
+
location: recordRange(payloadOffset, size, "payload"),
|
|
160
|
+
sha256: "0".repeat(64),
|
|
161
|
+
},
|
|
162
|
+
};
|
|
163
|
+
account(resource);
|
|
164
|
+
resources.push(resource);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
if (layout.size > 0)
|
|
169
|
+
await visit(0, [], [], new Set());
|
|
170
|
+
rejectOverlappingRanges(occupied);
|
|
171
|
+
const hashes = new Map();
|
|
172
|
+
for (const resource of resources) {
|
|
173
|
+
const range = resource.payload.location;
|
|
174
|
+
const key = `${String(range.offset)}:${String(range.bytes)}`;
|
|
175
|
+
let digest = hashes.get(key);
|
|
176
|
+
if (digest === undefined) {
|
|
177
|
+
const hash = createHash("sha256");
|
|
178
|
+
for (let offset = 0; offset < range.bytes; offset += 1048576) {
|
|
179
|
+
await setImmediate();
|
|
180
|
+
signal?.throwIfAborted();
|
|
181
|
+
hash.update(bytes.subarray(range.offset + offset, range.offset + Math.min(range.bytes, offset + 1048576)));
|
|
182
|
+
}
|
|
183
|
+
digest = hash.digest("hex");
|
|
184
|
+
hashes.set(key, digest);
|
|
185
|
+
}
|
|
186
|
+
resource.payload.sha256 = digest;
|
|
187
|
+
}
|
|
188
|
+
const iconGroups = readIconGroups(bytes, resources, account, ensureCapacity);
|
|
189
|
+
const report = {
|
|
190
|
+
artifact,
|
|
191
|
+
format: layout.format,
|
|
192
|
+
machine: layout.machine,
|
|
193
|
+
directory: layout.size === 0
|
|
194
|
+
? null
|
|
195
|
+
: {
|
|
196
|
+
rva: layout.rva,
|
|
197
|
+
location: { offset: root, bytes: layout.size },
|
|
198
|
+
data_directory_location: { offset: layout.directoryAt, bytes: 8 },
|
|
199
|
+
},
|
|
200
|
+
directories,
|
|
201
|
+
resources,
|
|
202
|
+
icon_groups: iconGroups,
|
|
203
|
+
coverage: {
|
|
204
|
+
status: "complete",
|
|
205
|
+
examined_entries: examined,
|
|
206
|
+
resources: resources.length,
|
|
207
|
+
},
|
|
208
|
+
limitations: [
|
|
209
|
+
"Static PE32/PE32+ type/name/language resource inventory; payloads other than RT_GROUP_ICON remain opaque.",
|
|
210
|
+
"Icon candidates are resource-table relationships. Language fallback, image decoding and actual shell/window loading are not observed.",
|
|
211
|
+
"Exact shared byte ranges are retained; non-identical overlapping resource structures or payloads are rejected.",
|
|
212
|
+
],
|
|
213
|
+
};
|
|
214
|
+
signal?.throwIfAborted();
|
|
215
|
+
if (jsonBytes(report, METADATA_BYTES) > METADATA_BYTES)
|
|
216
|
+
limit("PE resource result exceeds the 8 MiB allocation budget.");
|
|
217
|
+
return report;
|
|
218
|
+
};
|
|
219
|
+
const rejectOverlappingRanges = (ranges) => {
|
|
220
|
+
ranges.sort((left, right) => left.offset - right.offset || right.bytes - left.bytes);
|
|
221
|
+
let previous;
|
|
222
|
+
for (const current of ranges) {
|
|
223
|
+
if (previous !== undefined &&
|
|
224
|
+
current.offset < previous.offset + previous.bytes &&
|
|
225
|
+
(current.offset !== previous.offset ||
|
|
226
|
+
current.bytes !== previous.bytes ||
|
|
227
|
+
current.kind !== previous.kind))
|
|
228
|
+
peFailure("Non-identical resource byte ranges overlap.");
|
|
229
|
+
previous = current;
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
const readIconGroups = (bytes, resources, account, ensureCapacity) => {
|
|
233
|
+
const imagesById = new Map();
|
|
234
|
+
for (const resource of resources) {
|
|
235
|
+
if (resource.type.kind !== "id" ||
|
|
236
|
+
resource.type.id !== 3 ||
|
|
237
|
+
resource.name.kind !== "id")
|
|
238
|
+
continue;
|
|
239
|
+
const candidates = imagesById.get(resource.name.id) ?? [];
|
|
240
|
+
candidates.push(resource);
|
|
241
|
+
imagesById.set(resource.name.id, candidates);
|
|
242
|
+
}
|
|
243
|
+
return resources
|
|
244
|
+
.filter((resource) => resource.type.kind === "id" && resource.type.id === 14)
|
|
245
|
+
.map((group) => {
|
|
246
|
+
const { offset, bytes: size } = group.payload.location;
|
|
247
|
+
if (size < 6 ||
|
|
248
|
+
bytes.readUInt16LE(offset) !== 0 ||
|
|
249
|
+
bytes.readUInt16LE(offset + 2) !== 1)
|
|
250
|
+
peFailure("Malformed RT_GROUP_ICON header.");
|
|
251
|
+
const count = bytes.readUInt16LE(offset + 4);
|
|
252
|
+
if (size !== 6 + count * 14)
|
|
253
|
+
peFailure("RT_GROUP_ICON length does not match its image count.");
|
|
254
|
+
const images = [];
|
|
255
|
+
for (let index = 0; index < count; index++) {
|
|
256
|
+
const at = offset + 6 + index * 14;
|
|
257
|
+
const id = bytes.readUInt16LE(at + 12);
|
|
258
|
+
const candidates = imagesById.get(id) ?? [];
|
|
259
|
+
const exact = candidates.find((resource) => identityKey(resource.language) === identityKey(group.language));
|
|
260
|
+
// Indices are uint32 values and each needs at most ten decimal digits
|
|
261
|
+
// plus a comma. Check the expanded candidate list before allocating it.
|
|
262
|
+
ensureCapacity(302 + candidates.length * 11);
|
|
263
|
+
const declaredBytes = bytes.readUInt32LE(at + 8);
|
|
264
|
+
const image = {
|
|
265
|
+
location: { offset: at, bytes: 14 },
|
|
266
|
+
width: bytes[at] ?? 0,
|
|
267
|
+
height: bytes[at + 1] ?? 0,
|
|
268
|
+
color_count: bytes[at + 2] ?? 0,
|
|
269
|
+
reserved: bytes[at + 3] ?? 0,
|
|
270
|
+
planes: bytes.readUInt16LE(at + 4),
|
|
271
|
+
bit_count: bytes.readUInt16LE(at + 6),
|
|
272
|
+
declared_bytes: declaredBytes,
|
|
273
|
+
resource_id: id,
|
|
274
|
+
candidate_resource_indices: candidates.map(({ index }) => index),
|
|
275
|
+
same_language_resource_index: exact?.index ?? null,
|
|
276
|
+
size_matches: exact === undefined
|
|
277
|
+
? null
|
|
278
|
+
: exact.payload.location.bytes === declaredBytes,
|
|
279
|
+
};
|
|
280
|
+
account(image);
|
|
281
|
+
images.push(image);
|
|
282
|
+
}
|
|
283
|
+
account({ resource_index: group.index, images: [] });
|
|
284
|
+
return { resource_index: group.index, images };
|
|
285
|
+
});
|
|
286
|
+
};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { ArtifactReaderFailure } from "../../artifacts/ArtifactReader.js";
|
|
2
|
+
import { readStableArtifact } from "../../artifacts/readStableArtifact.js";
|
|
3
|
+
import { ArtifactOperationError } from "../../domain/artifactOperationError.js";
|
|
4
|
+
import { AnalysisAccessDeniedError, AnalysisArtifactChangedError, AnalysisCancelledError, AnalysisInputError, AnalysisResourceConstraintError, } from "../../domain/analysisErrorCore.js";
|
|
5
|
+
import { err, ok } from "../../domain/result.js";
|
|
6
|
+
import { PE_RESOURCES_PROVIDER } from "../../application/InvestigationProviders.js";
|
|
7
|
+
import { parsePeResources } from "./PeResourceParser.js";
|
|
8
|
+
/** Portable parser over one bounded, identity-checked regular file. */
|
|
9
|
+
export class PeResourcesProvider {
|
|
10
|
+
identity = PE_RESOURCES_PROVIDER;
|
|
11
|
+
async inspect(input, options) {
|
|
12
|
+
try {
|
|
13
|
+
const snapshot = await readStableArtifact(input.path, input.max_file_bytes, options?.signal);
|
|
14
|
+
return ok(await parsePeResources(snapshot.bytes, {
|
|
15
|
+
path: input.path,
|
|
16
|
+
sha256: snapshot.sha256,
|
|
17
|
+
bytes: snapshot.bytes.length,
|
|
18
|
+
}, input, options?.signal));
|
|
19
|
+
}
|
|
20
|
+
catch (cause) {
|
|
21
|
+
return err(peResourcesFailure(cause, input, options?.signal));
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const peResourcesFailure = (cause, input, signal) => {
|
|
26
|
+
const operation = "inspect_pe_resources";
|
|
27
|
+
if (signal?.aborted)
|
|
28
|
+
return new AnalysisCancelledError(operation, { cause });
|
|
29
|
+
if (cause instanceof ArtifactReaderFailure) {
|
|
30
|
+
if (cause.reason === "limit")
|
|
31
|
+
return new AnalysisResourceConstraintError(operation, "memory", cause.message, {
|
|
32
|
+
max_file_bytes: input.max_file_bytes,
|
|
33
|
+
max_entries: input.max_entries,
|
|
34
|
+
}, { cause });
|
|
35
|
+
if (cause.reason === "integrity")
|
|
36
|
+
return new AnalysisArtifactChangedError(operation, input.path, cause.message, { cause });
|
|
37
|
+
if (cause.reason === "path" || cause.reason === "format")
|
|
38
|
+
return new AnalysisInputError(operation, { cause }, [
|
|
39
|
+
{
|
|
40
|
+
path: ["path"],
|
|
41
|
+
reason: "invalid_format",
|
|
42
|
+
message: cause.message,
|
|
43
|
+
},
|
|
44
|
+
]);
|
|
45
|
+
if (cause.reason === "cancelled")
|
|
46
|
+
return new AnalysisCancelledError(operation, { cause });
|
|
47
|
+
}
|
|
48
|
+
if (cause instanceof Error && "code" in cause) {
|
|
49
|
+
if (cause.code === "EACCES" || cause.code === "EPERM")
|
|
50
|
+
return new AnalysisAccessDeniedError(operation, input.path, cause.code, {
|
|
51
|
+
cause,
|
|
52
|
+
});
|
|
53
|
+
if (cause.code === "ENOENT" || cause.code === "ENOTDIR")
|
|
54
|
+
return new AnalysisInputError(operation, { cause }, [
|
|
55
|
+
{
|
|
56
|
+
path: ["path"],
|
|
57
|
+
reason: "invalid_value",
|
|
58
|
+
message: `Selected PE image could not be read (${cause.code}): ${input.path}.`,
|
|
59
|
+
},
|
|
60
|
+
]);
|
|
61
|
+
}
|
|
62
|
+
return new ArtifactOperationError(operation, cause instanceof ArtifactReaderFailure ? cause.reason : "io", undefined, cause instanceof Error ? cause.message : "PE artifact inspection failed.", { cause });
|
|
63
|
+
};
|
|
@@ -1,17 +1,40 @@
|
|
|
1
|
-
/** Read through EOF, returning undefined on overflow;
|
|
2
|
-
export const readBoundedFileBytes = async (handle, maxBytes) => {
|
|
1
|
+
/** Read through EOF, returning undefined on overflow; leave the handle open. */
|
|
2
|
+
export const readBoundedFileBytes = async (handle, maxBytes, signal, expectedSize) => {
|
|
3
3
|
if (!Number.isSafeInteger(maxBytes) || maxBytes < 0)
|
|
4
4
|
throw new RangeError("File byte limit must be a nonnegative safe integer");
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
if (expectedSize !== undefined &&
|
|
6
|
+
(!Number.isSafeInteger(expectedSize) ||
|
|
7
|
+
expectedSize < 0 ||
|
|
8
|
+
expectedSize > maxBytes))
|
|
9
|
+
throw new RangeError("Expected file size must fit the byte limit");
|
|
10
|
+
if (expectedSize === undefined) {
|
|
11
|
+
const chunks = [];
|
|
12
|
+
const buffer = Buffer.allocUnsafe(Math.min(64 * 1_024, maxBytes + 1));
|
|
13
|
+
let total = 0;
|
|
14
|
+
for (;;) {
|
|
15
|
+
signal?.throwIfAborted();
|
|
16
|
+
const { bytesRead } = await handle.read(buffer, 0, Math.min(buffer.length, maxBytes - total + 1), null);
|
|
17
|
+
if (bytesRead === 0)
|
|
18
|
+
return Buffer.concat(chunks, total);
|
|
19
|
+
total += bytesRead;
|
|
20
|
+
if (total > maxBytes)
|
|
21
|
+
return undefined;
|
|
22
|
+
chunks.push(Buffer.from(buffer.subarray(0, bytesRead)));
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
const buffer = Buffer.allocUnsafe(expectedSize);
|
|
26
|
+
if (expectedSize === 0)
|
|
27
|
+
return buffer;
|
|
7
28
|
let total = 0;
|
|
8
29
|
for (;;) {
|
|
9
|
-
|
|
30
|
+
signal?.throwIfAborted();
|
|
31
|
+
const { bytesRead } = await handle.read(buffer, total, expectedSize - total, null);
|
|
10
32
|
if (bytesRead === 0)
|
|
11
|
-
return
|
|
33
|
+
return buffer.subarray(0, total);
|
|
12
34
|
total += bytesRead;
|
|
13
35
|
if (total > maxBytes)
|
|
14
36
|
return undefined;
|
|
15
|
-
|
|
37
|
+
if (total === expectedSize)
|
|
38
|
+
return buffer;
|
|
16
39
|
}
|
|
17
40
|
};
|
|
@@ -223,12 +223,17 @@ export const createDarwinProcessRunTokenReader = (options = {}) => {
|
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
225
|
};
|
|
226
|
-
const read = async (processes) => {
|
|
226
|
+
const read = async (processes, signal) => {
|
|
227
|
+
signal?.throwIfAborted();
|
|
227
228
|
if (processes.length === 0)
|
|
228
229
|
return new Map();
|
|
229
|
-
const binary = await compile();
|
|
230
|
+
const binary = await compile(signal);
|
|
230
231
|
const pids = processes.map(({ pid }) => String(pid));
|
|
231
|
-
const { stdout } = await execFileOutput(binary, pids, {
|
|
232
|
+
const { stdout } = await execFileOutput(binary, pids, {
|
|
233
|
+
timeout: 15_000,
|
|
234
|
+
...(signal === undefined ? {} : { signal }),
|
|
235
|
+
});
|
|
236
|
+
signal?.throwIfAborted();
|
|
232
237
|
const decoded = safeParseJson(stdout);
|
|
233
238
|
if (!decoded.ok)
|
|
234
239
|
throw new Error(`macOS process token helper returned invalid JSON: ${decoded.error}`, { cause: decoded.cause });
|