rea-agents 6.3.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 +7 -4
- package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
- package/bridge/ghidra/ReaGhidraBridge.java +597 -209
- package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -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 +51 -19
- 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 +22 -2
- package/dist/application/CapabilityInventory.js +11 -1
- package/dist/application/ClientConfigurationDocument.js +70 -0
- package/dist/application/ClientConfigurationFiles.js +91 -0
- package/dist/application/ClientRegistrationEnvironment.js +35 -0
- package/dist/application/ClientRegistrationStatus.js +66 -31
- package/dist/application/DirectAnalysis.js +2 -2
- package/dist/application/DirectAnalysisCleanup.js +1 -1
- package/dist/application/DirectAnalysisStatus.js +1 -1
- package/dist/application/Doctor.js +5 -3
- package/dist/application/DoctorDiagnostics.js +1 -1
- package/dist/application/EvidenceBundleCommands.js +6 -12
- 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 +6 -0
- package/dist/application/JsonFiles.js +6 -5
- package/dist/{cliJsonFile.js → application/JsonInputFile.js} +108 -35
- package/dist/application/LinuxHopper.js +4 -12
- 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 +9 -3
- 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 +93 -7
- package/dist/application/Setup.js +54 -6
- package/dist/application/SetupClientConfiguration.js +116 -16
- package/dist/application/SetupHost.js +102 -24
- package/dist/application/SetupPlan.js +5 -8
- package/dist/application/SetupSkill.js +58 -39
- package/dist/application/SupportedClients.js +290 -65
- package/dist/application/Uninstall.js +158 -10
- package/dist/application/UpdateMaintenance.js +17 -21
- package/dist/application/Utf8JsonInput.js +7 -0
- package/dist/application/WebScriptExportService.js +131 -65
- 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/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/BinarySession.js +2 -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/ElectronBoundaryGraphContext.js +3 -2
- package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
- package/dist/application/javascript/ElectronBoundaryGraphNative.js +19 -6
- package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
- package/dist/application/javascript/JavaScriptApplicationService.js +22 -11
- package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -30
- package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +67 -19
- package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
- package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +19 -16
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +258 -235
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +115 -26
- package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -1
- package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -4
- package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +9 -3
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +199 -61
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +12 -19
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +4 -1
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -3
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +5 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +19 -8
- 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/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 +20 -15
- package/dist/artifacts/ArtifactReader.js +23 -0
- package/dist/artifacts/ArtifactResourceScope.js +100 -0
- package/dist/artifacts/AsarArtifactReader.js +176 -102
- 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 +29 -22
- 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 +32 -13
- package/dist/artifacts/extraction/ArtifactExtraction.js +110 -86
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +110 -43
- package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
- package/dist/artifacts/inventory/classify.js +75 -32
- package/dist/artifacts/inventory/hashStableRootArtifact.js +48 -15
- package/dist/artifacts/inventory/reader.js +13 -5
- package/dist/artifacts/inventory/scanCanonical.js +62 -25
- package/dist/artifacts/inventory/scanReader.js +38 -11
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +15 -9
- 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 +5 -0
- 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/CdpConnection.js +22 -5
- package/dist/browser/CdpPageCapture.js +1 -1
- package/dist/browser/CdpTargetSession.js +30 -34
- package/dist/browser/CdpWebMcpDiscovery.js +32 -10
- package/dist/browser/ElectronFileScope.js +99 -9
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +60 -4
- package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
- package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
- package/dist/browser/PlaywrightScenarioBrowser.js +69 -7
- package/dist/browser/PlaywrightScenarioSession.js +127 -54
- package/dist/browser/PlaywrightScenarioStorage.js +507 -0
- package/dist/browser/PngVisualDiff.js +198 -29
- package/dist/browser/WebSourceMapFetcher.js +3 -3
- package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
- package/dist/browser/assets/PublishWebScripts.js +75 -20
- 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/coreBinaryCommands.js +0 -5
- package/dist/cli/coreNativeCommands.js +1 -14
- package/dist/cli/electronCommands.js +6 -1
- package/dist/cli/evmCommands.js +13 -4
- package/dist/cli/firmwareCommands.js +7 -2
- package/dist/cli/javascriptApplicationAnalysis.js +17 -1
- package/dist/cli/javascriptRecoveryCommands.js +22 -15
- package/dist/cli/jebCommands.js +99 -0
- package/dist/cli/jsonOutput.js +11 -4
- package/dist/cli/referenceSourceImportStatus.js +7 -0
- package/dist/cli/setupCommands.js +15 -3
- package/dist/cli/utilityCommands.js +66 -18
- package/dist/cli/webScriptCommands.js +20 -1
- package/dist/cli/webSourceLocationCommands.js +21 -9
- package/dist/cli.js +6 -0
- package/dist/cliBrowserScenarioCommands.js +2 -1
- package/dist/cliCommandNames.js +32 -0
- package/dist/cliJsonInput.js +2 -2
- package/dist/cliObservationOptions.js +3 -0
- package/dist/composition/adb.js +3 -0
- package/dist/composition/apktool.js +3 -0
- package/dist/composition/binaryDiagnostics.js +4 -0
- package/dist/composition/directAnalysis.js +12 -4
- 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/artifactToolContracts.js +8 -5
- package/dist/contracts/browserToolContracts.js +1 -1
- package/dist/contracts/compactInputSchema.js +256 -0
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/inputSchemaPresentation.js +10 -10
- package/dist/contracts/javascript/electronToolContracts.js +15 -3
- package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
- package/dist/contracts/jeb/jebToolContracts.js +64 -0
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
- package/dist/contracts/officialToolContracts.js +5 -5
- package/dist/contracts/sessionToolContracts.js +2 -2
- package/dist/contracts/sessionToolSchemas.js +6 -2
- 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 +5 -3
- package/dist/contracts/toolSchemaMetadata.js +82 -7
- package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
- package/dist/domain/analysisErrorCleanup.js +29 -0
- package/dist/domain/analysisErrorPresentation.js +18 -6
- package/dist/domain/analysisErrorProjection.js +4 -1
- package/dist/domain/analysisSnapshot.js +2 -1
- package/dist/domain/analysisView/analysisView.js +52 -2
- 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/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 +2 -2
- package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
- package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
- package/dist/domain/artifactComparison.js +35 -7
- package/dist/domain/artifactGraph.js +5 -3
- package/dist/domain/artifactIdentity.js +30 -2
- package/dist/domain/artifactInspection.js +3 -43
- package/dist/domain/artifactIntegrityPolicy.js +10 -0
- package/dist/domain/artifactInventoryEvidence.js +11 -12
- package/dist/domain/artifactPathSyntax.js +1 -1
- package/dist/domain/binaryTarget.js +16 -0
- package/dist/domain/binaryTargetTypes.js +8 -1
- package/dist/domain/browserObservationSchemas.js +8 -4
- package/dist/domain/canonicalJsonDigestSteps.js +34 -12
- package/dist/domain/compactStringIdentity.js +9 -0
- package/dist/domain/evidence.js +2 -1
- package/dist/domain/evidenceRecordSummary.js +144 -0
- package/dist/domain/inputIssueProjection.js +16 -1
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -13
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -20
- package/dist/domain/javascript/electronStaticAnalysisNative.js +70 -40
- package/dist/domain/javascript/electronStaticAnalysisValues.js +16 -0
- package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +4 -1
- package/dist/domain/javascript/javascriptApplicationChangeGraph.js +6 -6
- package/dist/domain/javascript/javascriptApplicationGraph.js +79 -18
- package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +28 -12
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -1
- package/dist/domain/javascript/javascriptAstFingerprint.js +58 -31
- package/dist/domain/javascript/javascriptAstValues.js +32 -0
- package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
- package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
- package/dist/domain/javascript/javascriptNativeHandoff.js +6 -1
- package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
- package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +7 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +8 -11
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +190 -33
- package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
- package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
- package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
- package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
- package/dist/domain/javascript/javascriptSemanticFingerprints.js +42 -41
- package/dist/domain/javascript/javascriptSemanticGraph.js +69 -23
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +2 -10
- package/dist/domain/javascript/javascriptSemanticIterationSources.js +40 -7
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +341 -87
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +78 -35
- package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
- package/dist/domain/javascript/javascriptSemanticObjects.js +7 -1
- package/dist/domain/javascript/javascriptSemanticProjection.js +52 -14
- package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +77 -0
- package/dist/domain/javascript/javascriptSemanticQuery.js +27 -29
- package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +1 -3
- package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
- package/dist/domain/javascript/javascriptSemanticReturns.js +13 -23
- package/dist/domain/javascript/javascriptSemanticState.js +22 -2
- package/dist/domain/javascript/javascriptSemanticTraversal.js +19 -1
- package/dist/domain/javascript/javascriptSemanticValues.js +47 -19
- package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
- package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +8 -6
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
- package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
- package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
- package/dist/domain/jeb/jebAnalysis.js +114 -0
- package/dist/domain/jsonShape.js +63 -52
- package/dist/domain/jsonValue.js +3 -0
- package/dist/domain/managed/managedApplicationGraph.js +37 -0
- package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
- package/dist/domain/managed/managedApplicationGraphNodes.js +32 -22
- package/dist/domain/managed/managedArtifact.js +1 -0
- package/dist/domain/managed/managedInspectionEvidence.js +13 -0
- package/dist/domain/native/nativeAotPe.js +1408 -0
- package/dist/domain/native/nativeInstruction.js +21 -0
- package/dist/domain/native/nativeMetadataRecovery.js +79 -6
- package/dist/domain/native/peResources.js +94 -0
- package/dist/domain/nativeConvention.js +33 -0
- package/dist/domain/process/processCapture.js +91 -1
- package/dist/domain/process/processCaptureExample.js +24 -0
- package/dist/domain/process/processCaptureValidation.js +79 -0
- package/dist/domain/process/processScenario.js +59 -7
- package/dist/domain/propertyListKeys.js +3 -1
- package/dist/domain/referenceSourceGraph.js +25 -16
- package/dist/domain/referenceSourceImportParsing.js +6 -3
- package/dist/domain/referenceSourcePathIdentity.js +22 -0
- package/dist/domain/referenceSourceRequireBindings.js +137 -0
- package/dist/domain/webBundleAnalyzerInspection.js +14 -2
- package/dist/domain/webCaptureDiff.js +102 -4
- 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 +4 -2
- 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 +55 -24
- 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 +33 -1
- 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 +76 -4
- package/dist/ghidra/GhidraDiagnostics.js +11 -8
- package/dist/ghidra/GhidraFunctionValues.js +26 -2
- package/dist/ghidra/GhidraInstallation.js +1 -1
- package/dist/ghidra/GhidraInventoryValues.js +23 -1
- package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
- package/dist/ghidra/GhidraLauncher.js +80 -39
- 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/HopperClient.js +15 -6
- package/dist/hopper/HopperMachOImage.js +2 -0
- package/dist/hopper/HopperProvider.js +13 -2
- package/dist/ida/IdaOperationRunner.js +8 -2
- package/dist/ida/IdaProvider.js +7 -0
- package/dist/ida/IdaSessionClient.js +3 -1
- package/dist/ida/IdaWorkspace.js +4 -2
- 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/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/NativeMacOSProvider.js +91 -16
- 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 +96 -39
- 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 +28 -4
- package/dist/process/capture/ProcessCaptureLifecycle.js +350 -59
- package/dist/process/capture/ProcessCaptureProgress.js +62 -0
- package/dist/process/capture/ProcessHarness.js +194 -26
- 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/contractToolHandler.js +21 -0
- package/dist/server/createServer.js +97 -25
- 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 +4 -6
- 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/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/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 +32 -3
- package/dist/server/registerElectronTools.js +28 -10
- 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/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/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 +49 -18
- 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 +33 -5
- 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 +22 -1
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { constants } from "node:fs";
|
|
2
2
|
import { open } from "node:fs/promises";
|
|
3
|
+
import { OwnedFileHandle } from "./OwnedFileHandle.js";
|
|
3
4
|
/** Identifies a selected path that cannot be read as one regular file. */
|
|
4
5
|
export class NonRegularFileReadError extends Error {
|
|
5
6
|
path;
|
|
@@ -11,6 +12,31 @@ export class NonRegularFileReadError extends Error {
|
|
|
11
12
|
this.code = directory ? "EISDIR" : "ENOTFILE";
|
|
12
13
|
}
|
|
13
14
|
}
|
|
15
|
+
/** Admission failed and the opened descriptor could not be confirmed closed. */
|
|
16
|
+
export class RegularFileAdmissionFailure extends Error {
|
|
17
|
+
path;
|
|
18
|
+
cleanupCause;
|
|
19
|
+
owner;
|
|
20
|
+
cause;
|
|
21
|
+
constructor(path, admissionCause, cleanupCause, owner) {
|
|
22
|
+
super(`Selected input failed admission and its descriptor close failed: ${path}`);
|
|
23
|
+
this.path = path;
|
|
24
|
+
this.cleanupCause = cleanupCause;
|
|
25
|
+
this.owner = owner;
|
|
26
|
+
this.name = "RegularFileAdmissionFailure";
|
|
27
|
+
this.cause = admissionCause;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/** A regular input no longer matches the extent or identity admitted for reading. */
|
|
31
|
+
export class RegularFileChangedError extends Error {
|
|
32
|
+
path;
|
|
33
|
+
code = "ESTALE";
|
|
34
|
+
constructor(path) {
|
|
35
|
+
super(`Selected input changed while being read: ${path}`);
|
|
36
|
+
this.path = path;
|
|
37
|
+
this.name = "RegularFileChangedError";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
14
40
|
/** Open and verify the selected file descriptor without blocking on pipes. */
|
|
15
41
|
export const openRegularFile = async (path, options) => {
|
|
16
42
|
options.signal?.throwIfAborted();
|
|
@@ -18,6 +44,7 @@ export const openRegularFile = async (path, options) => {
|
|
|
18
44
|
(constants.O_NONBLOCK ?? 0) |
|
|
19
45
|
(constants.O_NOCTTY ?? 0) |
|
|
20
46
|
(options.symlinks === "reject" ? (constants.O_NOFOLLOW ?? 0) : 0));
|
|
47
|
+
const owner = new OwnedFileHandle(handle);
|
|
21
48
|
try {
|
|
22
49
|
options.signal?.throwIfAborted();
|
|
23
50
|
const metadata = await handle.stat();
|
|
@@ -27,7 +54,12 @@ export const openRegularFile = async (path, options) => {
|
|
|
27
54
|
return handle;
|
|
28
55
|
}
|
|
29
56
|
catch (cause) {
|
|
30
|
-
|
|
57
|
+
try {
|
|
58
|
+
await owner.close();
|
|
59
|
+
}
|
|
60
|
+
catch (cleanupCause) {
|
|
61
|
+
throw new RegularFileAdmissionFailure(path, cause, cleanupCause, owner);
|
|
62
|
+
}
|
|
31
63
|
throw cause;
|
|
32
64
|
}
|
|
33
65
|
};
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { stat } from "node:fs/promises";
|
|
3
|
+
import { openRegularFile, RegularFileChangedError, sameRegularFileState, } from "./RegularFile.js";
|
|
4
|
+
/** Hash one regular file from its admitted descriptor and verify its path state. */
|
|
5
|
+
export const hashStableFile = async (path, signal) => {
|
|
6
|
+
const handle = await openRegularFile(path, {
|
|
7
|
+
symlinks: "follow",
|
|
8
|
+
signal,
|
|
9
|
+
});
|
|
10
|
+
try {
|
|
11
|
+
const initial = await handle.stat();
|
|
12
|
+
if (!Number.isSafeInteger(initial.size) || initial.size < 0)
|
|
13
|
+
throw new RangeError(`Regular file size cannot be represented safely: ${path}`);
|
|
14
|
+
const hash = createHash("sha256");
|
|
15
|
+
const chunk = Buffer.allocUnsafe(64 * 1024);
|
|
16
|
+
let position = 0;
|
|
17
|
+
while (position <= initial.size) {
|
|
18
|
+
signal?.throwIfAborted();
|
|
19
|
+
const length = Math.min(chunk.length, initial.size - position + 1);
|
|
20
|
+
if (length <= 0)
|
|
21
|
+
break;
|
|
22
|
+
const read = await handle.read(chunk, 0, length, position);
|
|
23
|
+
signal?.throwIfAborted();
|
|
24
|
+
if (read.bytesRead === 0)
|
|
25
|
+
break;
|
|
26
|
+
hash.update(chunk.subarray(0, read.bytesRead));
|
|
27
|
+
position += read.bytesRead;
|
|
28
|
+
if (position > initial.size)
|
|
29
|
+
throw new RegularFileChangedError(path);
|
|
30
|
+
}
|
|
31
|
+
signal?.throwIfAborted();
|
|
32
|
+
const [opened, currentPath] = await Promise.all([
|
|
33
|
+
handle.stat(),
|
|
34
|
+
stat(path),
|
|
35
|
+
]);
|
|
36
|
+
signal?.throwIfAborted();
|
|
37
|
+
if (position !== initial.size ||
|
|
38
|
+
!sameRegularFileState(initial, opened) ||
|
|
39
|
+
!sameRegularFileState(initial, currentPath))
|
|
40
|
+
throw new RegularFileChangedError(path);
|
|
41
|
+
return { sha256: hash.digest("hex"), bytes: position };
|
|
42
|
+
}
|
|
43
|
+
finally {
|
|
44
|
+
await handle.close();
|
|
45
|
+
}
|
|
46
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
2
|
+
/** Stream positional reads while leaving descriptor cleanup to its owner. */
|
|
3
|
+
export const readFileHandleChunks = (handle, options = {}) => {
|
|
4
|
+
const start = options.start ?? 0;
|
|
5
|
+
const end = options.end ?? Infinity;
|
|
6
|
+
if (!Number.isSafeInteger(start) ||
|
|
7
|
+
start < 0 ||
|
|
8
|
+
(end !== Infinity && (!Number.isSafeInteger(end) || end < start)))
|
|
9
|
+
throw new RangeError("Invalid file read range");
|
|
10
|
+
return Readable.from((async function* () {
|
|
11
|
+
let position = start;
|
|
12
|
+
while (position <= end) {
|
|
13
|
+
options.signal?.throwIfAborted();
|
|
14
|
+
const chunk = Buffer.allocUnsafe(Math.min(64 * 1024, end - position + 1));
|
|
15
|
+
const { bytesRead } = await handle.read(chunk, 0, chunk.length, position);
|
|
16
|
+
options.signal?.throwIfAborted();
|
|
17
|
+
if (bytesRead === 0)
|
|
18
|
+
return;
|
|
19
|
+
position += bytesRead;
|
|
20
|
+
yield chunk.subarray(0, bytesRead);
|
|
21
|
+
}
|
|
22
|
+
})(), {
|
|
23
|
+
objectMode: false,
|
|
24
|
+
...(options.signal === undefined ? {} : { signal: options.signal }),
|
|
25
|
+
});
|
|
26
|
+
};
|
|
@@ -76,15 +76,35 @@ export const runFirmwareCommand = async (context) => {
|
|
|
76
76
|
NO_COLOR: "1",
|
|
77
77
|
},
|
|
78
78
|
});
|
|
79
|
+
let diagnosticTruncated = false;
|
|
79
80
|
const supervisor = new ProviderProcessSupervisor({
|
|
80
81
|
...spawned,
|
|
81
82
|
ownsProcessLifetime: true,
|
|
82
83
|
cleanup: spawned.cleanup ?? (() => cleanupOwnedProcessGroup(spawned.ownership)),
|
|
84
|
+
}, {
|
|
85
|
+
maxDiagnosticBytes: FIRMWARE_LIMITS.diagnosticBytes,
|
|
86
|
+
onDiagnostic: (event) => {
|
|
87
|
+
if (event.type === "output" && event.truncated === true)
|
|
88
|
+
diagnosticTruncated = true;
|
|
89
|
+
},
|
|
83
90
|
});
|
|
91
|
+
const checkDiagnostics = () => {
|
|
92
|
+
if (diagnosticTruncated) {
|
|
93
|
+
const snapshot = supervisor.snapshot();
|
|
94
|
+
throw new AnalysisOutputError(operation, `Tool diagnostics exceeded the ${FIRMWARE_LIMITS.diagnosticBytes}-byte capture budget`, {
|
|
95
|
+
capturedOutput: {
|
|
96
|
+
stdout: snapshot.stdout.text,
|
|
97
|
+
stderr: snapshot.stderr.text,
|
|
98
|
+
truncated: true,
|
|
99
|
+
},
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
};
|
|
84
103
|
let failure;
|
|
85
104
|
try {
|
|
86
105
|
const deadline = Date.now() + FIRMWARE_LIMITS.timeoutMs;
|
|
87
|
-
while (!(await supervisor.
|
|
106
|
+
while (!(await supervisor.waitForOutputClose(100))) {
|
|
107
|
+
checkDiagnostics();
|
|
88
108
|
if (signal.aborted)
|
|
89
109
|
throw new AnalysisCancelledError(operation);
|
|
90
110
|
if (Date.now() >= deadline)
|
|
@@ -92,6 +112,7 @@ export const runFirmwareCommand = async (context) => {
|
|
|
92
112
|
if (context.outputBudget !== undefined)
|
|
93
113
|
await inventoryFirmwareOutput(context.outputBudget.root, context.outputBudget.bytes, context.outputBudget.entries, operation, signal);
|
|
94
114
|
}
|
|
115
|
+
checkDiagnostics();
|
|
95
116
|
if (signal.aborted)
|
|
96
117
|
throw new AnalysisCancelledError(operation);
|
|
97
118
|
}
|
|
@@ -100,8 +121,8 @@ export const runFirmwareCommand = async (context) => {
|
|
|
100
121
|
}
|
|
101
122
|
const stopped = await supervisor.stop();
|
|
102
123
|
const snapshot = supervisor.snapshot();
|
|
103
|
-
|
|
104
|
-
|
|
124
|
+
if (stopped.status === "incomplete") {
|
|
125
|
+
context.retainCleanup(supervisor);
|
|
105
126
|
throw new ProviderCleanupError(engine, [runId, context.cwd], {
|
|
106
127
|
reason: stopped.reason,
|
|
107
128
|
leader_pid: spawned.ownership.leaderPid,
|
|
@@ -114,6 +135,7 @@ export const runFirmwareCommand = async (context) => {
|
|
|
114
135
|
stderr_bytes: snapshot.stderr.bytes,
|
|
115
136
|
previous_error: failure instanceof Error ? failure.message : null,
|
|
116
137
|
});
|
|
138
|
+
}
|
|
117
139
|
if (failure !== undefined)
|
|
118
140
|
throw failure;
|
|
119
141
|
if (snapshot.exitCode !== 0 &&
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { constants, createReadStream, createWriteStream } from "node:fs";
|
|
3
|
-
import { chmod, lstat,
|
|
3
|
+
import { chmod, lstat, opendir, open, readlink, realpath, } from "node:fs/promises";
|
|
4
4
|
import { isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { Transform } from "node:stream";
|
|
6
6
|
import { pipeline } from "node:stream/promises";
|
|
7
7
|
import { AnalysisCancelledError, AnalysisInputError, AnalysisOutputError, } from "../domain/analysisErrorCore.js";
|
|
8
8
|
import { readBoundedFileBytes } from "../process/BoundedFileBytes.js";
|
|
9
9
|
import { FIRMWARE_LIMITS } from "./FirmwareRelease.js";
|
|
10
|
+
const throwIfFirmwareInventoryCancelled = (signal, operation) => {
|
|
11
|
+
if (signal?.aborted === true)
|
|
12
|
+
throw new AnalysisCancelledError(operation);
|
|
13
|
+
};
|
|
10
14
|
/** Hash a regular tool or extracted file without retaining its bytes in memory. */
|
|
11
15
|
export const hashFirmwareFile = async (path, signal) => {
|
|
12
16
|
const handle = await open(path, constants.O_RDONLY | constants.O_NOFOLLOW);
|
|
@@ -120,8 +124,7 @@ export const inventoryFirmwareOutput = async (root, maxBytes, maxEntries, operat
|
|
|
120
124
|
let bytes = 0;
|
|
121
125
|
let count = 0;
|
|
122
126
|
while (pending.length > 0) {
|
|
123
|
-
|
|
124
|
-
throw new AnalysisCancelledError(operation);
|
|
127
|
+
throwIfFirmwareInventoryCancelled(signal, operation);
|
|
125
128
|
const directory = pending.pop();
|
|
126
129
|
if (directory === undefined)
|
|
127
130
|
break;
|
|
@@ -134,15 +137,27 @@ export const inventoryFirmwareOutput = async (root, maxBytes, maxEntries, operat
|
|
|
134
137
|
!directoryStat.isDirectory() ||
|
|
135
138
|
directoryStat.isSymbolicLink())
|
|
136
139
|
continue;
|
|
137
|
-
const
|
|
140
|
+
const handle = await opendir(directory).catch((cause) => {
|
|
138
141
|
if (cause instanceof Error && "code" in cause && cause.code === "ENOENT")
|
|
139
|
-
return
|
|
142
|
+
return undefined;
|
|
140
143
|
throw cause;
|
|
141
144
|
});
|
|
145
|
+
if (handle === undefined)
|
|
146
|
+
continue;
|
|
147
|
+
const names = [];
|
|
148
|
+
try {
|
|
149
|
+
for await (const entry of handle) {
|
|
150
|
+
throwIfFirmwareInventoryCancelled(signal, operation);
|
|
151
|
+
count++;
|
|
152
|
+
if (count > maxEntries)
|
|
153
|
+
throw new AnalysisOutputError(operation, `Staging entry budget exceeded (${maxEntries})`);
|
|
154
|
+
names.push(entry.name);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
finally {
|
|
158
|
+
await handle.close().catch(() => undefined);
|
|
159
|
+
}
|
|
142
160
|
for (const name of names.sort()) {
|
|
143
|
-
count++;
|
|
144
|
-
if (count > maxEntries)
|
|
145
|
-
throw new AnalysisOutputError(operation, `Staging entry budget exceeded (${maxEntries})`);
|
|
146
161
|
const path = join(directory, name);
|
|
147
162
|
const stat = await lstat(path).catch((cause) => {
|
|
148
163
|
if (cause instanceof Error &&
|
|
@@ -3,9 +3,11 @@ import { z } from "zod";
|
|
|
3
3
|
import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
|
|
4
4
|
import { firmwareResultSchemas, } from "../domain/firmware/firmwareAnalysis.js";
|
|
5
5
|
import { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
6
|
+
import { analysisErrorWithCleanupFailure } from "../domain/analysisErrorCleanup.js";
|
|
6
7
|
import { AnalysisCancelledError, AnalysisInputError, AnalysisOutputError, AnalysisTimeoutError, } from "../domain/analysisErrorCore.js";
|
|
7
8
|
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
8
9
|
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
|
|
10
|
+
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
9
11
|
import { err, ok } from "../domain/result.js";
|
|
10
12
|
import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
|
|
11
13
|
import { publishFirmwareExtraction } from "./FirmwarePublication.js";
|
|
@@ -14,6 +16,19 @@ import { admitFirmwareVersion } from "./FirmwareVersion.js";
|
|
|
14
16
|
import { firmwareToolUnavailable, resolveFirmwareCommand, runFirmwareCommand, readFirmwareCommandReport, } from "./FirmwareCommand.js";
|
|
15
17
|
import { inventoryFirmwareOutput, snapshotFirmware } from "./FirmwareFiles.js";
|
|
16
18
|
import { normalizeBinwalkReport, normalizeUnblobReport, } from "./FirmwareReports.js";
|
|
19
|
+
const combineCleanupFailures = (failures) => {
|
|
20
|
+
if (failures.length < 2)
|
|
21
|
+
return failures[0];
|
|
22
|
+
return new ProviderCleanupError("firmware", failures.flatMap((failure) => [...failure.cleanupResources]), {
|
|
23
|
+
reason: "Multiple owned firmware resources could not be cleaned",
|
|
24
|
+
failures: failures.map((failure) => ({
|
|
25
|
+
engine: failure.providerId,
|
|
26
|
+
operation: failure.operation,
|
|
27
|
+
resources: [...failure.cleanupResources],
|
|
28
|
+
reason: failure.diagnostics?.reason ?? failure.message,
|
|
29
|
+
})),
|
|
30
|
+
}, { operation: "close_firmware", cause: new AggregateError(failures) });
|
|
31
|
+
};
|
|
17
32
|
const waitForPredecessor = (predecessor, operation, signal) => new Promise((resolve, reject) => {
|
|
18
33
|
const abort = () => reject(new AnalysisCancelledError(operation));
|
|
19
34
|
signal?.addEventListener("abort", abort, { once: true });
|
|
@@ -35,13 +50,16 @@ export class FirmwareProvider {
|
|
|
35
50
|
environment;
|
|
36
51
|
launcher;
|
|
37
52
|
#tail = Promise.resolve();
|
|
38
|
-
#
|
|
53
|
+
#closed = false;
|
|
54
|
+
#pendingCleanup = new Map();
|
|
39
55
|
constructor(environment = process.env, launcher) {
|
|
40
56
|
this.environment = environment;
|
|
41
57
|
this.launcher = launcher;
|
|
42
58
|
}
|
|
43
59
|
/** Inspect regions or explicitly extract selected bytes without changing the source. */
|
|
44
60
|
async execute(request, options) {
|
|
61
|
+
if (this.#closed)
|
|
62
|
+
return err(new AnalysisCancelledError(request.operation));
|
|
45
63
|
const predecessor = this.#tail;
|
|
46
64
|
let release = () => { };
|
|
47
65
|
this.#tail = new Promise((resolve) => {
|
|
@@ -58,12 +76,65 @@ export class FirmwareProvider {
|
|
|
58
76
|
: new AnalysisCancelledError(request.operation));
|
|
59
77
|
}
|
|
60
78
|
try {
|
|
79
|
+
if (this.#closed)
|
|
80
|
+
return err(new AnalysisCancelledError(request.operation));
|
|
81
|
+
const cleanup = await this.#retryCleanup();
|
|
82
|
+
if (cleanup.processUnverified && cleanup.failure !== undefined)
|
|
83
|
+
return err(cleanup.failure);
|
|
61
84
|
return await this.#execute(request, options);
|
|
62
85
|
}
|
|
63
86
|
finally {
|
|
64
87
|
release();
|
|
65
88
|
}
|
|
66
89
|
}
|
|
90
|
+
/** Retry every retained owner, reporting failures without discarding other roots. */
|
|
91
|
+
async close() {
|
|
92
|
+
this.#closed = true;
|
|
93
|
+
await this.#tail;
|
|
94
|
+
const cleanup = await this.#retryCleanup();
|
|
95
|
+
if (cleanup.failure !== undefined)
|
|
96
|
+
throw cleanup.failure;
|
|
97
|
+
}
|
|
98
|
+
async #retryCleanup() {
|
|
99
|
+
const failures = [];
|
|
100
|
+
let processUnverified = false;
|
|
101
|
+
for (const [path, pending] of this.#pendingCleanup) {
|
|
102
|
+
try {
|
|
103
|
+
const stopped = await pending.supervisor?.stop();
|
|
104
|
+
if (stopped?.status === "incomplete") {
|
|
105
|
+
processUnverified = true;
|
|
106
|
+
failures.push(new ProviderCleanupError(pending.engine, [path], { reason: stopped.reason }, { operation: pending.operation }));
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
delete pending.supervisor;
|
|
110
|
+
}
|
|
111
|
+
catch (cause) {
|
|
112
|
+
processUnverified = true;
|
|
113
|
+
failures.push(new ProviderCleanupError(pending.engine, [path], { reason: cause instanceof Error ? cause.message : String(cause) }, { operation: pending.operation, cause }));
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
try {
|
|
117
|
+
if (pending.tree !== undefined) {
|
|
118
|
+
await pending.tree.rollback();
|
|
119
|
+
delete pending.tree;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (cause) {
|
|
123
|
+
failures.push(new ProviderCleanupError(pending.engine, [path, pending.tree?.outputRoot ?? path], { reason: cause instanceof Error ? cause.message : String(cause) }, { operation: pending.operation, cause }));
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
await pending.root.close();
|
|
127
|
+
if (pending.tree === undefined)
|
|
128
|
+
this.#pendingCleanup.delete(path);
|
|
129
|
+
}
|
|
130
|
+
catch (cause) {
|
|
131
|
+
// A verified stopped process cannot use this root. Keep ownership for
|
|
132
|
+
// later removal without blocking a new operation's disjoint workspace.
|
|
133
|
+
failures.push(new ProviderCleanupError(pending.engine, [path], { reason: cause instanceof Error ? cause.message : String(cause) }, { operation: pending.operation, cause }));
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return { failure: combineCleanupFailures(failures), processUnverified };
|
|
137
|
+
}
|
|
67
138
|
async #execute(request, options) {
|
|
68
139
|
let root;
|
|
69
140
|
const engineName = request.operation === "inspect_firmware_regions" ? "binwalk" : "unblob";
|
|
@@ -73,12 +144,11 @@ export class FirmwareProvider {
|
|
|
73
144
|
: AbortSignal.any([options.signal, deadline]);
|
|
74
145
|
let outcome;
|
|
75
146
|
try {
|
|
76
|
-
if (this.#cleanupFailure !== undefined)
|
|
77
|
-
return err(this.#cleanupFailure);
|
|
78
147
|
if (signal.aborted)
|
|
79
148
|
throw new AnalysisCancelledError(request.operation);
|
|
80
149
|
const command = await resolveFirmwareCommand(this.environment, engineName, request.operation);
|
|
81
150
|
root = await PrivateRuntimeRoot.create({ prefix: "rea-firmware-" });
|
|
151
|
+
const ownedRoot = root;
|
|
82
152
|
const target = await snapshotFirmware(request, root.path, signal);
|
|
83
153
|
const run = (args, outputBudget) => runFirmwareCommand({
|
|
84
154
|
engine: engineName,
|
|
@@ -88,6 +158,14 @@ export class FirmwareProvider {
|
|
|
88
158
|
cwd: root?.path ?? "",
|
|
89
159
|
environment: this.environment,
|
|
90
160
|
signal,
|
|
161
|
+
retainCleanup: (supervisor) => {
|
|
162
|
+
this.#pendingCleanup.set(ownedRoot.path, {
|
|
163
|
+
supervisor,
|
|
164
|
+
root: ownedRoot,
|
|
165
|
+
engine: engineName,
|
|
166
|
+
operation: request.operation,
|
|
167
|
+
});
|
|
168
|
+
},
|
|
91
169
|
...(this.launcher === undefined ? {} : { launcher: this.launcher }),
|
|
92
170
|
...(outputBudget === undefined
|
|
93
171
|
? {}
|
|
@@ -186,6 +264,15 @@ export class FirmwareProvider {
|
|
|
186
264
|
selection: target.selection,
|
|
187
265
|
engine,
|
|
188
266
|
signal,
|
|
267
|
+
retainCleanup: (tree) => {
|
|
268
|
+
const pending = this.#pendingCleanup.get(ownedRoot.path) ?? {
|
|
269
|
+
root: ownedRoot,
|
|
270
|
+
engine: engineName,
|
|
271
|
+
operation: request.operation,
|
|
272
|
+
};
|
|
273
|
+
pending.tree = tree;
|
|
274
|
+
this.#pendingCleanup.set(ownedRoot.path, pending);
|
|
275
|
+
},
|
|
189
276
|
});
|
|
190
277
|
raw = { report, execution: processRun, version_execution: versionRun };
|
|
191
278
|
}
|
|
@@ -229,36 +316,73 @@ export class FirmwareProvider {
|
|
|
229
316
|
: String(cause),
|
|
230
317
|
},
|
|
231
318
|
}));
|
|
232
|
-
if (!outcome.ok && outcome.error.cleanupIncomplete) {
|
|
233
|
-
this.#cleanupFailure =
|
|
234
|
-
root === undefined ||
|
|
235
|
-
outcome.error.cleanupResources.includes(root.path)
|
|
236
|
-
? outcome.error
|
|
237
|
-
: new ProviderCleanupError(engineName, [...outcome.error.cleanupResources, root.path], outcome.error instanceof ProviderAdapterError
|
|
238
|
-
? (outcome.error.diagnostics ?? {
|
|
239
|
-
reason: outcome.error.message,
|
|
240
|
-
})
|
|
241
|
-
: { reason: outcome.error.message }, { cause: outcome.error });
|
|
242
|
-
}
|
|
243
319
|
}
|
|
244
|
-
|
|
245
|
-
if (
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
...(outcome.ok && request.operation === "extract_firmware"
|
|
254
|
-
? [request.input.output_directory]
|
|
255
|
-
: []),
|
|
256
|
-
], {
|
|
257
|
-
reason: cause instanceof Error ? cause.message : String(cause),
|
|
258
|
-
previous_result: outcome.ok ? outcome.value.result : null,
|
|
320
|
+
const finished = await finishFirmwareWorkspace(root, outcome, engineName, request);
|
|
321
|
+
if (!finished.ok &&
|
|
322
|
+
finished.error.cleanupIncomplete &&
|
|
323
|
+
root !== undefined &&
|
|
324
|
+
!this.#pendingCleanup.has(root.path))
|
|
325
|
+
this.#pendingCleanup.set(root.path, {
|
|
326
|
+
root,
|
|
327
|
+
engine: engineName,
|
|
328
|
+
operation: request.operation,
|
|
259
329
|
});
|
|
260
|
-
|
|
261
|
-
}
|
|
262
|
-
return outcome;
|
|
330
|
+
return finished;
|
|
263
331
|
}
|
|
264
332
|
}
|
|
333
|
+
/** Keep a completed extraction beside cleanup failure, or skip removal when ownership is uncertain. */
|
|
334
|
+
export const finishFirmwareWorkspace = async (root, outcome, engineName, request) => {
|
|
335
|
+
if (!outcome.ok && outcome.error.cleanupIncomplete) {
|
|
336
|
+
if (root === undefined ||
|
|
337
|
+
outcome.error.cleanupResources.includes(root.path))
|
|
338
|
+
return outcome;
|
|
339
|
+
return err(new ProviderCleanupError(engineName, [...outcome.error.cleanupResources, root.path], outcome.error instanceof ProviderAdapterError
|
|
340
|
+
? (outcome.error.diagnostics ?? { reason: outcome.error.message })
|
|
341
|
+
: { reason: outcome.error.message }, {
|
|
342
|
+
cause: outcome.error,
|
|
343
|
+
operation: request.operation,
|
|
344
|
+
...(outcome.error.partialObservation === undefined
|
|
345
|
+
? {}
|
|
346
|
+
: { partialObservation: outcome.error.partialObservation }),
|
|
347
|
+
}));
|
|
348
|
+
}
|
|
349
|
+
try {
|
|
350
|
+
await root?.close();
|
|
351
|
+
}
|
|
352
|
+
catch (cause) {
|
|
353
|
+
const cleanup = new ProviderCleanupError(engineName, [
|
|
354
|
+
root?.path ?? "unknown",
|
|
355
|
+
...(outcome.ok && request.operation === "extract_firmware"
|
|
356
|
+
? [request.input.output_directory]
|
|
357
|
+
: []),
|
|
358
|
+
], { reason: cause instanceof Error ? cause.message : String(cause) }, {
|
|
359
|
+
cause,
|
|
360
|
+
operation: request.operation,
|
|
361
|
+
...(outcome.ok
|
|
362
|
+
? {
|
|
363
|
+
partialObservation: completedFirmwareObservation(outcome.value),
|
|
364
|
+
}
|
|
365
|
+
: outcome.error.partialObservation === undefined
|
|
366
|
+
? {}
|
|
367
|
+
: { partialObservation: outcome.error.partialObservation }),
|
|
368
|
+
});
|
|
369
|
+
return err(outcome.ok
|
|
370
|
+
? cleanup
|
|
371
|
+
: analysisErrorWithCleanupFailure(outcome.error, cleanup, request.operation));
|
|
372
|
+
}
|
|
373
|
+
return outcome;
|
|
374
|
+
};
|
|
375
|
+
const completedFirmwareObservation = (execution) => ({
|
|
376
|
+
kind: "firmware",
|
|
377
|
+
result: execution.result,
|
|
378
|
+
provenance: jsonValueSchema.parse({
|
|
379
|
+
raw_result: execution.rawResult,
|
|
380
|
+
provider: execution.provider,
|
|
381
|
+
subject: execution.subject,
|
|
382
|
+
locations: execution.locations,
|
|
383
|
+
limitations: execution.limitations,
|
|
384
|
+
...(execution.analysisProfile === undefined
|
|
385
|
+
? {}
|
|
386
|
+
: { analysis_profile: execution.analysisProfile }),
|
|
387
|
+
}),
|
|
388
|
+
});
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { createReadStream } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { SafeOutputTree } from "../artifacts/SafeOutputTree.js";
|
|
4
|
+
import { SafeOutputTreeCreationFailure } from "../artifacts/SafeOutputTreeCreationFailure.js";
|
|
4
5
|
import { AnalysisOutputError } from "../domain/analysisErrorCore.js";
|
|
5
6
|
import { ProviderCleanupError } from "../domain/providerCleanupError.js";
|
|
7
|
+
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
6
8
|
import { firmwareResultSchemas } from "../domain/firmware/firmwareAnalysis.js";
|
|
7
9
|
import { hashFirmwareFile } from "./FirmwareFiles.js";
|
|
8
10
|
/** Publish verified regular files, preserving links as metadata and rolling back failed writes. */
|
|
9
11
|
export const publishFirmwareExtraction = async (context) => {
|
|
10
12
|
let tree;
|
|
13
|
+
let result;
|
|
11
14
|
try {
|
|
12
15
|
const materialized = new Set(context.entries
|
|
13
16
|
.filter((entry) => entry.kind === "file")
|
|
@@ -37,7 +40,7 @@ export const publishFirmwareExtraction = async (context) => {
|
|
|
37
40
|
(context.normalized.sizes.has(logicalPath) &&
|
|
38
41
|
context.normalized.sizes.get(logicalPath) !== entry.size))
|
|
39
42
|
throw new AnalysisOutputError("extract_firmware", `Extracted bytes disagree with provider report: ${entry.relativePath}`);
|
|
40
|
-
await tree.write(entry.relativePath, createReadStream(entry.path), sha256, context.signal);
|
|
43
|
+
await tree.write(entry.relativePath, createReadStream(entry.path), { sha256, bytes: entry.size }, context.signal);
|
|
41
44
|
files.push({
|
|
42
45
|
relative_path: entry.relativePath,
|
|
43
46
|
path: join(tree.outputRoot, entry.relativePath),
|
|
@@ -50,7 +53,7 @@ export const publishFirmwareExtraction = async (context) => {
|
|
|
50
53
|
original_file_range: null,
|
|
51
54
|
});
|
|
52
55
|
}
|
|
53
|
-
|
|
56
|
+
result = firmwareResultSchemas.extract_firmware.parse({
|
|
54
57
|
engine: context.engine,
|
|
55
58
|
selection: context.selection,
|
|
56
59
|
output_directory: tree.outputRoot,
|
|
@@ -68,17 +71,35 @@ export const publishFirmwareExtraction = async (context) => {
|
|
|
68
71
|
return result;
|
|
69
72
|
}
|
|
70
73
|
catch (cause) {
|
|
74
|
+
if (cause instanceof SafeOutputTreeCreationFailure)
|
|
75
|
+
tree = cause.tree;
|
|
71
76
|
try {
|
|
72
77
|
await tree?.rollback();
|
|
73
78
|
}
|
|
74
79
|
catch (cleanupCause) {
|
|
80
|
+
if (tree !== undefined)
|
|
81
|
+
context.retainCleanup(tree);
|
|
82
|
+
const publishedResult = tree?.published === true && result !== undefined
|
|
83
|
+
? {
|
|
84
|
+
kind: "firmware",
|
|
85
|
+
result: jsonValueSchema.parse(result),
|
|
86
|
+
}
|
|
87
|
+
: undefined;
|
|
75
88
|
throw new ProviderCleanupError("unblob", [context.outputDirectory], {
|
|
76
89
|
reason: cleanupCause instanceof Error
|
|
77
90
|
? cleanupCause.message
|
|
78
91
|
: String(cleanupCause),
|
|
79
92
|
previous_error: cause instanceof Error ? cause.message : String(cause),
|
|
80
|
-
}, {
|
|
93
|
+
}, {
|
|
94
|
+
cause: cleanupCause,
|
|
95
|
+
operation: "extract_firmware",
|
|
96
|
+
...(publishedResult === undefined
|
|
97
|
+
? {}
|
|
98
|
+
: { partialObservation: publishedResult }),
|
|
99
|
+
});
|
|
81
100
|
}
|
|
101
|
+
if (tree?.published === true && result !== undefined)
|
|
102
|
+
return result;
|
|
82
103
|
throw cause;
|
|
83
104
|
}
|
|
84
105
|
};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/** Generated from package.json and package-lock.json; do not edit. */
|
|
2
2
|
export const PACKAGE_METADATA = {
|
|
3
3
|
name: "rea-agents",
|
|
4
|
-
version: "6.
|
|
4
|
+
version: "6.4.0", // x-release-please-version
|
|
5
5
|
serverSdkVersion: "2.3.1",
|
|
6
6
|
clientSdkVersion: "2.3.1",
|
|
7
7
|
coreSdkVersion: "2.3.1",
|
|
8
|
-
skillVersion: "
|
|
8
|
+
skillVersion: "37",
|
|
9
9
|
};
|