rea-agents 4.0.0 → 4.1.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 +93 -30
- package/bridge/ghidra/ReaGhidraBridge.java +358 -15
- package/bridge/ghidra/ReaGhidraExtensions.java +113 -0
- package/bridge/ghidra/ReaGhidraPrepareCom.java +32 -0
- package/dist/android/AndroidTargetSnapshot.js +34 -0
- package/dist/android/JadxAnalysis.js +191 -0
- package/dist/android/JadxConfiguration.js +41 -0
- package/dist/android/JadxMcpTransport.js +145 -0
- package/dist/android/JadxProtocol.js +101 -0
- package/dist/android/JadxProvider.js +170 -0
- package/dist/android/JadxRelease.js +19 -0
- package/dist/android/JadxSession.js +97 -0
- package/dist/application/AnalysisContextQueries.js +2 -1
- package/dist/application/AnalysisProviderEvaluation.js +5 -3
- package/dist/application/AnalysisProviderRegistry.js +2 -1
- package/dist/application/AnalysisSnapshotCache.js +4 -1
- package/dist/application/AnalysisSnapshotFiles.js +1 -1
- package/dist/application/AndroidAnalysisPort.js +1 -0
- package/dist/application/AndroidAnalysisService.js +37 -0
- package/dist/application/ArtifactExtraction.js +7 -4
- package/dist/application/ArtifactGraphConstruction.js +10 -17
- package/dist/application/ArtifactInventory/scanCanonical.js +8 -7
- package/dist/application/BinarySession.js +16 -3
- package/dist/application/BinarySessionExecution.js +4 -1
- package/dist/application/BinarySessionOpen.js +3 -2
- package/dist/application/BinarySessionRecords.js +9 -3
- package/dist/application/BinaryTargetResolver.js +25 -6
- package/dist/application/BrowserObservationService.js +2 -1
- package/dist/application/BrowserScenarioCaptureService.js +2 -1
- package/dist/application/BrowserScenarioEvidence.js +2 -2
- package/dist/application/CallPathTracing.js +2 -1
- package/dist/application/CapabilityInventory.js +18 -0
- package/dist/application/ClientConfigPath.js +3 -1
- package/dist/application/ClientConfigurationDocument.js +11 -1
- package/dist/application/ClientRegistrationStatus.js +8 -1
- package/dist/application/CompositeProvider.js +1 -1
- package/dist/application/DirectAnalysis.js +23 -7
- package/dist/application/DirectAnalysisStatus.js +3 -3
- package/dist/application/Doctor.js +48 -8
- package/dist/application/DoctorDiagnostics.js +7 -5
- package/dist/application/DoctorScope.js +1 -1
- package/dist/application/ElectronActiveEvidence.js +2 -2
- package/dist/application/ElectronActiveObservationService.js +2 -1
- package/dist/application/ElectronBoundaryAnalysis.js +1 -1
- package/dist/application/ElectronObservationService.js +2 -1
- package/dist/application/EnhancedLiteralTracing.js +2 -1
- package/dist/application/EnhancedToolTypes.js +2 -1
- package/dist/application/EnhancedTools.js +3 -1
- package/dist/application/EvidenceBundleCommands.js +2 -1
- package/dist/application/EvidenceBundleFiles.js +1 -1
- package/dist/application/EvidenceInputResolver.js +30 -0
- package/dist/application/EvidenceLedger.js +2 -1
- package/dist/application/FirmwareAnalysisPort.js +1 -0
- package/dist/application/FirmwareAnalysisService.js +35 -0
- package/dist/application/FunctionAnalysisEvidence.js +32 -0
- package/dist/application/InventoryProjectionEvidence.js +2 -1
- package/dist/application/JavaScriptApplicationService.js +50 -3
- package/dist/application/JavaScriptApplicationWorkflowService.js +2 -1
- package/dist/application/JavaScriptArtifactAnalysis.js +4 -2
- package/dist/application/JavaScriptArtifactFiles.js +4 -2
- package/dist/application/JavaScriptArtifactPathResolution.js +6 -2
- package/dist/application/JavaScriptJsonModules.js +3 -2
- package/dist/application/JavaScriptModuleRelationships.js +4 -2
- package/dist/application/JavaScriptRuntimeObservationService.js +2 -1
- package/dist/application/JavaScriptRuntimeReconciliationService.js +2 -1
- package/dist/application/JavaScriptSemanticGraphProjection.js +1 -1
- package/dist/application/JavaScriptSemanticTraceService.js +2 -1
- package/dist/application/JsonFiles.js +1 -1
- package/dist/application/LazyAnalysisProvider.js +3 -1
- package/dist/application/LinuxHopper.js +12 -4
- package/dist/application/MacHopper.js +20 -7
- package/dist/application/ManagedApplicationGraphService.js +2 -1
- package/dist/application/ManagedMemberComparisonService.js +3 -1
- package/dist/application/ManagedNativeVerificationService.js +2 -1
- package/dist/application/ManagedReconstructionService.js +2 -1
- package/dist/application/NativeCallRoutes.js +1 -1
- package/dist/application/NativeDispatchMetadataInspection.js +1 -1
- package/dist/application/NativeUiActionTrace.js +2 -1
- package/dist/application/NativeValueTrace.js +1 -1
- package/dist/application/ProcessCaptureError.js +1 -1
- package/dist/application/ProcessCaptureJournal.js +3 -1
- package/dist/application/ProcessCaptureLifecycle.js +6 -3
- package/dist/application/ProcessCli.js +9 -5
- package/dist/application/ProcessEvidence.js +2 -6
- package/dist/application/ProcessHarness.js +3 -2
- package/dist/application/ProcessNormalization.js +12 -5
- package/dist/application/ProcessSampling.js +3 -1
- package/dist/application/ReconstructionCoverageService.js +2 -1
- package/dist/application/ReconstructionObligationLedgerService.js +2 -1
- package/dist/application/ReferenceSourceImportEntries.js +2 -0
- package/dist/application/ReferenceSourceImportPolicy.js +4 -2
- package/dist/application/ReferenceSourceVcsAdapter.js +35 -4
- package/dist/application/SessionProviderRouter.js +4 -1
- package/dist/application/Setup.js +1 -128
- package/dist/application/SetupClientConfiguration.js +17 -6
- package/dist/application/SetupHost.js +111 -0
- package/dist/application/SetupRegistrationEnvironment.js +1 -2
- package/dist/application/SetupSkill.js +9 -3
- package/dist/application/SetupTypes.js +17 -0
- package/dist/application/StoreFileLock.js +7 -2
- package/dist/application/SupportedClients.js +8 -0
- package/dist/application/Uninstall.js +9 -4
- package/dist/application/UpdateRuntime.js +5 -2
- package/dist/application/WindowsCapabilities.js +7 -7
- package/dist/application/runtime.js +3 -1
- package/dist/artifacts/ArtifactProvider.js +3 -1
- package/dist/artifacts/DirectoryArtifactReader.js +2 -0
- package/dist/artifacts/NativeDmgArtifactReader.js +10 -3
- package/dist/artifacts/NibArchive.js +4 -2
- package/dist/artifacts/SafeOutputTree.js +26 -10
- package/dist/artifacts/ZipArtifactReader.js +1 -0
- package/dist/browser/BrowserProcessStartup.js +3 -1
- package/dist/browser/CdpAuthorizedMainFrame.js +1 -1
- package/dist/browser/CdpBrowserProvider.js +4 -1
- package/dist/browser/CdpCaptureDocuments.js +3 -1
- package/dist/browser/CdpCaptureEventHandlers.js +6 -2
- package/dist/browser/CdpCaptureStorageFingerprints.js +1 -1
- package/dist/browser/CdpCaptureValues.js +6 -2
- package/dist/browser/CdpConnection.js +8 -6
- package/dist/browser/CdpElectronInspection.js +3 -3
- package/dist/browser/CdpElectronProvider.js +4 -1
- package/dist/browser/CdpElectronScripts.js +2 -2
- package/dist/browser/CdpEndpoint.js +22 -10
- package/dist/browser/CdpObservationSession.js +2 -1
- package/dist/browser/CdpOptionalCommand.js +1 -1
- package/dist/browser/CdpPageCapture.js +2 -1
- package/dist/browser/CdpSafeMetadata.js +53 -8
- package/dist/browser/CdpScreenshot.js +1 -1
- package/dist/browser/CdpTargetSession.js +8 -5
- package/dist/browser/CdpWebMcpDiscovery.js +1 -1
- package/dist/browser/ElectronFileScope.js +9 -3
- package/dist/browser/JavaScriptRuntimeScope.js +3 -1
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +3 -1
- package/dist/browser/PlaywrightElectronActiveActions.js +1 -1
- package/dist/browser/PlaywrightElectronActiveProvider.js +6 -2
- package/dist/browser/PlaywrightExecutionBoundary.js +1 -1
- package/dist/browser/PlaywrightScenarioArtifacts.js +10 -5
- package/dist/browser/PlaywrightScenarioBrowser.js +3 -1
- package/dist/browser/PlaywrightScenarioEvents.js +6 -2
- package/dist/browser/PlaywrightScenarioSession.js +5 -2
- package/dist/browser/V8InspectorEndpoint.js +2 -1
- package/dist/browser/V8InspectorProvider.js +6 -1
- package/dist/browser/WebSourceMapFetcher.js +24 -11
- package/dist/cli/androidCommands.js +81 -0
- package/dist/{cliApplicationCommands.js → cli/applicationCommands.js} +18 -16
- package/dist/{cliBrowserAdvancedCommands.js → cli/browserAdvancedCommands.js} +13 -16
- package/dist/{cliBrowserCommands.js → cli/browserCommands.js} +9 -9
- package/dist/cli/commandCancellation.js +24 -0
- package/dist/cli/coreAnalysisCommands.js +110 -17
- package/dist/{cliElectronCommands.js → cli/electronCommands.js} +14 -13
- package/dist/cli/firmwareCommands.js +75 -0
- package/dist/{cliSetup.js → cli/interactiveSetup.js} +1 -1
- package/dist/cli/javascriptApplicationAnalysis.js +1 -1
- package/dist/cli/managedCommands.js +1 -1
- package/dist/cli/managedProjectGraphCommand.js +1 -1
- package/dist/cli/options.js +7 -1
- package/dist/{cliProcessCommands.js → cli/processCommands.js} +3 -3
- package/dist/cli/referenceSourceImportStatus.js +10 -0
- package/dist/cli/setupCommands.js +4 -2
- package/dist/cli/utilityCommands.js +3 -2
- package/dist/cli.js +10 -15
- package/dist/cliBrowserContext.js +1 -1
- package/dist/cliBrowserScenarioCommands.js +2 -1
- package/dist/cliCommandNames.js +11 -2
- package/dist/cliEvidenceCommands.js +2 -1
- package/dist/cliJavaScriptRuntimeCommands.js +2 -1
- package/dist/cliJsonInput.js +26 -11
- package/dist/cliLogging.js +2 -1
- package/dist/cliOutput.js +15 -16
- package/dist/config/environment.js +11 -1
- package/dist/config/parseConfig.js +7 -1
- package/dist/config/parsers.js +1 -1
- package/dist/contracts/androidToolContracts.js +77 -0
- package/dist/contracts/applicationToolContracts.js +32 -5
- package/dist/contracts/applicationWorkflowInputContracts.js +13 -13
- package/dist/contracts/artifactComparisonExample.js +7 -14
- package/dist/contracts/enhancedToolContracts.js +31 -0
- package/dist/contracts/errorSchemas.js +4 -2
- package/dist/contracts/evidenceInputContracts.js +13 -0
- package/dist/contracts/firmwareToolContracts.js +38 -0
- package/dist/contracts/officialToolContracts.js +66 -0
- package/dist/contracts/promptContracts.js +1 -1
- package/dist/contracts/sessionLifecycleInputs.js +4 -0
- package/dist/contracts/sessionToolContracts.js +43 -0
- package/dist/contracts/sessionToolSchemas.js +1 -1
- package/dist/contracts/toolContractExamples.js +5 -0
- package/dist/contracts/toolContractTypes.js +2 -0
- package/dist/contracts/toolContracts.js +7 -130
- package/dist/contracts/toolEffects.js +43 -0
- package/dist/contracts/toolOutputSchemaGroups.js +4 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +1 -0
- package/dist/doctorRuntime.js +5 -1
- package/dist/domain/analysisErrorBase.js +33 -0
- package/dist/domain/analysisErrorCore.js +60 -0
- package/dist/domain/analysisErrorPresentation.js +22 -2
- package/dist/domain/analysisErrorProjection.js +24 -3
- package/dist/domain/analysisSnapshot.js +1 -0
- package/dist/domain/androidAnalysis.js +141 -0
- package/dist/domain/appleAssetCatalog.js +1 -1
- package/dist/domain/artifactGraph.js +1 -0
- package/dist/domain/artifactInspection.js +19 -17
- package/dist/domain/artifactInventoryEvidence.js +20 -25
- package/dist/domain/artifactOperationError.js +16 -0
- package/dist/domain/browserObservation.js +12 -4
- package/dist/domain/browserObservationError.js +23 -0
- package/dist/domain/browserScenario.js +1 -1
- package/dist/domain/browserScenarioCapture.js +1 -1
- package/dist/domain/browserScenarioDiff.js +1 -1
- package/dist/domain/browserScenarioNormalization.js +6 -11
- package/dist/domain/browserScenarioValues.js +3 -1
- package/dist/domain/callPath.js +47 -7
- package/dist/domain/canonicalDigest.js +65 -0
- package/dist/domain/canonicalOrdering.js +11 -0
- package/dist/domain/changedBehavior.js +8 -7
- package/dist/domain/comparisonSemantics.js +2 -4
- package/dist/domain/configurationErrors.js +25 -0
- package/dist/domain/dosCom.js +8 -0
- package/dist/domain/electronActiveObservation.js +3 -1
- package/dist/domain/electronStaticAnalysisBrowser.js +13 -23
- package/dist/domain/electronStaticAnalysisNative.js +2 -1
- package/dist/domain/electronStaticAnalysisValues.js +23 -3
- package/dist/domain/evidence.js +3 -11
- package/dist/domain/evidenceErrors.js +30 -0
- package/dist/domain/firmwareAnalysis.js +121 -0
- package/dist/domain/functionComparison.js +4 -2
- package/dist/domain/functionComparisonDimensions.js +6 -4
- package/dist/domain/functionComparisonNormalization.js +8 -1
- package/dist/domain/functionComparisonResults.js +1 -4
- package/dist/domain/hopperErrors.js +78 -0
- package/dist/domain/hopperValues.js +2 -1
- package/dist/domain/interfaceBuilderGraph.js +3 -1
- package/dist/domain/javascriptApplicationChangeGraph.js +2 -2
- package/dist/domain/javascriptApplicationGraph.js +13 -22
- package/dist/domain/javascriptApplicationVersionComparison.js +3 -11
- package/dist/domain/javascriptApplicationVersionItems.js +3 -3
- package/dist/domain/javascriptApplicationVersionKeys.js +1 -1
- package/dist/domain/javascriptAstFingerprint.js +1 -1
- package/dist/domain/javascriptExportShapeComparison.js +1 -2
- package/dist/domain/javascriptExportShapeSelection.js +1 -1
- package/dist/domain/javascriptExportShapeVariants.js +7 -3
- package/dist/domain/javascriptFeatureSeed.js +29 -9
- package/dist/domain/javascriptFeatureTrace.js +9 -13
- package/dist/domain/javascriptFeatureTraversal.js +2 -1
- package/dist/domain/javascriptNativeHandoff.js +2 -1
- package/dist/domain/javascriptRuntimeLoadState.js +2 -2
- package/dist/domain/javascriptRuntimeReconciliationActive.js +3 -10
- package/dist/domain/javascriptRuntimeReconciliationGraph.js +2 -2
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +4 -3
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +8 -14
- package/dist/domain/javascriptRuntimeReconciliationResult.js +4 -4
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +5 -2
- package/dist/domain/javascriptRuntimeStaticCandidates.js +8 -4
- package/dist/domain/javascriptSemanticAnalysis.js +40 -3
- package/dist/domain/javascriptSemanticCallResolution.js +2 -1
- package/dist/domain/javascriptSemanticChildProcesses.js +2 -1
- package/dist/domain/javascriptSemanticDataEffects.js +2 -1
- package/dist/domain/javascriptSemanticFingerprints.js +1 -1
- package/dist/domain/javascriptSemanticGraph.js +23 -28
- package/dist/domain/javascriptSemanticPrimitives.js +9 -2
- package/dist/domain/javascriptSemanticProjection.js +2 -1
- package/dist/domain/javascriptSemanticPromises.js +2 -1
- package/dist/domain/javascriptSemanticProvenance.js +1 -1
- package/dist/domain/javascriptSemanticQuery.js +7 -8
- package/dist/domain/javascriptSemanticQueryAssessment.js +1 -2
- package/dist/domain/javascriptSemanticQueryIdentity.js +1 -2
- package/dist/domain/javascriptSemanticReturns.js +2 -1
- package/dist/domain/javascriptSemanticValues.js +50 -16
- package/dist/domain/javascriptSourceParser.js +4 -2
- package/dist/domain/javascriptStaticAnalysis.js +1 -1
- package/dist/domain/javascriptStaticAnalysisBundler.js +2 -1
- package/dist/domain/javascriptStaticAnalysisCalls.js +14 -6
- package/dist/domain/javascriptStaticAnalysisHelpers.js +31 -4
- package/dist/domain/jsonShape.js +6 -2
- package/dist/domain/managedMemberComparison.js +1 -0
- package/dist/domain/managedMemberComparisonItems.js +2 -0
- package/dist/domain/managedNativeVerificationMatch.js +5 -3
- package/dist/domain/nativeDataType.js +2 -0
- package/dist/domain/nativeFunctionAnnotations.js +43 -0
- package/dist/domain/nativeLoadImage.js +95 -0
- package/dist/domain/nativeMetadataRecovery.js +55 -0
- package/dist/domain/processCapture.js +0 -1
- package/dist/domain/processEvidenceProvider.js +11 -0
- package/dist/domain/processTraceComparison.js +1 -1
- package/dist/domain/providerAdapterError.js +17 -0
- package/dist/domain/providerCleanupError.js +1 -1
- package/dist/domain/providerSelectionError.js +44 -0
- package/dist/domain/reconstructionUnknowns.js +1 -1
- package/dist/domain/reconstructionVerification.js +22 -8
- package/dist/domain/referenceSourceClassification.js +5 -6
- package/dist/domain/referenceSourceGraph.js +9 -17
- package/dist/domain/referenceSourceImportParsing.js +38 -23
- package/dist/domain/runtimeIdentification.js +1 -1
- package/dist/domain/runtimeVersion.js +4 -7
- package/dist/domain/safeJson.js +13 -0
- package/dist/domain/sourceToBundleComparison.js +5 -7
- package/dist/domain/sourceToBundleSignals.js +6 -6
- package/dist/domain/staticRuntimeCorrelation.js +9 -7
- package/dist/domain/unknownRegistryError.js +10 -0
- package/dist/domain/webBundleAnalyzerAst.js +22 -5
- package/dist/domain/webBundleAnalyzerInspection.js +20 -14
- package/dist/dotnet/ManagedMemberRows.js +1 -1
- package/dist/dotnet/ManagedMetadataHeaps.js +3 -2
- package/dist/dotnet/ManagedMetadataInventoryRows.js +4 -2
- package/dist/dotnet/ManagedMethodBodyReader.js +8 -1
- package/dist/dotnet/ManagedStaticProvider.js +3 -1
- package/dist/firmware/FirmwareCommand.js +163 -0
- package/dist/firmware/FirmwareFiles.js +190 -0
- package/dist/firmware/FirmwareProvider.js +258 -0
- package/dist/firmware/FirmwarePublication.js +84 -0
- package/dist/firmware/FirmwareRelease.js +32 -0
- package/dist/firmware/FirmwareReports.js +223 -0
- package/dist/generatedMcpToolCatalog.js +1 -1
- package/dist/generatedPackageMetadata.js +5 -5
- package/dist/ghidra/GhidraAnalysisProfile.js +37 -8
- package/dist/ghidra/GhidraClient.js +52 -6
- package/dist/ghidra/GhidraDiagnostics.js +3 -0
- package/dist/ghidra/GhidraDoctor.js +38 -14
- package/dist/ghidra/GhidraFunctionValues.js +10 -4
- package/dist/ghidra/GhidraInstallation.js +10 -4
- package/dist/ghidra/GhidraInventoryValues.js +39 -2
- package/dist/ghidra/GhidraLauncher.js +91 -26
- package/dist/ghidra/GhidraLoadImageValues.js +199 -0
- package/dist/ghidra/GhidraProvider.js +129 -13
- package/dist/ghidra/GhidraProviderCapabilities.js +52 -15
- package/dist/ghidra/GhidraRequestQueue.js +2 -2
- package/dist/ghidra/GhidraSessionError.js +31 -4
- package/dist/ghidra/GhidraSessionValues.js +10 -7
- package/dist/ghidra/GhidraTargetSnapshot.js +16 -2
- package/dist/ghidra/GhidraTransport.js +12 -0
- package/dist/ghidra/extensions/GhidraExtensionFailures.js +20 -0
- package/dist/ghidra/extensions/GhidraExtensions.js +170 -0
- package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +21 -0
- package/dist/ghidra/extensions/nativeaot/NativeAotReport.js +84 -0
- package/dist/hopper/BridgeLauncher.js +4 -2
- package/dist/hopper/HopperAnalysisProfile.js +7 -2
- package/dist/hopper/HopperCleanup.js +55 -9
- package/dist/hopper/HopperClient.js +14 -4
- package/dist/hopper/HopperProcessDiagnostic.js +1 -1
- package/dist/hopper/HopperProvider.js +8 -4
- package/dist/hopper/HopperRequestQueue.js +7 -3
- package/dist/hopper/HopperSessionValues.js +1 -1
- package/dist/hopper/HopperSocketConnection.js +1 -1
- package/dist/hopper/HopperTargetLease.js +23 -15
- package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +7 -8
- package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -2
- package/dist/hopper/protocol.js +8 -8
- package/dist/ida/IdaConfiguration.js +56 -0
- package/dist/ida/IdaDoctor.js +53 -0
- package/dist/ida/IdaInput.js +62 -0
- package/dist/ida/IdaMcpConnection.js +111 -0
- package/dist/ida/IdaOperationRunner.js +299 -0
- package/dist/ida/IdaProtocolValues.js +178 -0
- package/dist/ida/IdaProvider.js +126 -0
- package/dist/ida/IdaProviderCapabilities.js +60 -0
- package/dist/ida/IdaSessionClient.js +306 -0
- package/dist/ida/IdaWorkspace.js +54 -0
- package/dist/main/shutdown.js +21 -1
- package/dist/main/startup.js +1 -1
- package/dist/main/transport.js +8 -4
- package/dist/main.js +5 -2
- package/dist/native/AppleDispatchMetadata.js +31 -10
- package/dist/native/NativeMacOSProvider.js +87 -15
- package/dist/native/NativeMachoInspection.js +42 -12
- package/dist/native/NativeUiHelperRuntime.js +7 -1
- package/dist/native/NativeUiObservation.js +6 -2
- package/dist/native/parsers/demangle.js +1 -1
- package/dist/native/parsers/dyldInfo.js +3 -3
- package/dist/native/parsers/otool.js +4 -1
- package/dist/native/parsers/plist.js +11 -3
- package/dist/process/PrivateRuntimeRoot.js +13 -3
- package/dist/process/ProcessOwnership.js +5 -73
- package/dist/process/ProcessOwnershipObservation.js +62 -2
- package/dist/process/ProcessOwnershipProcessTree.js +13 -0
- package/dist/process/ProviderProcess.js +24 -7
- package/dist/process/ProviderRunLineage.js +1 -1
- package/dist/process/WindowsAuthority.js +20 -1
- package/dist/reference/ReferenceSourceReaderEntries.js +5 -1
- package/dist/reference/ReferenceSourceReaderFile.js +1 -0
- package/dist/server/createServer.js +25 -2
- package/dist/server/mcpProgress.js +2 -1
- package/dist/server/promptCompletion.js +3 -3
- package/dist/server/registerAndroidTools.js +30 -0
- package/dist/server/registerApplicationTools/compareExportShapes.js +5 -1
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +7 -2
- package/dist/server/registerApplicationTools/compareVersions.js +5 -1
- package/dist/server/registerApplicationTools/traceFeature.js +7 -2
- package/dist/server/registerApplicationTools/traceSemantics.js +7 -2
- package/dist/server/registerEnhancedTools.js +28 -1
- package/dist/server/registerFirmwareTools.js +22 -0
- package/dist/server/registerFunctionComparisonTool.js +1 -1
- package/dist/server/registerInvestigationTools/helpers.js +2 -1
- package/dist/server/registerManagedTools.js +1 -1
- package/dist/server/registerManagedWorkflowTools/evidence.js +1 -1
- package/dist/server/registerOfficialTools.js +4 -1
- package/dist/server/registerProcessComparisonTool.js +5 -2
- package/dist/server/registerSessionTools.js +3 -1
- package/dist/server/runDerivedOperation.js +1 -1
- package/dist/server/sessionAvailabilityPolicy.js +3 -0
- package/dist/server/sessionEvidence.js +1 -1
- package/dist/server/toolResult.js +2 -1
- package/dist/windows/WindowsNativeLoader.js +108 -0
- package/dist/windows/WindowsOwnedProcess.js +168 -0
- package/dist/windows/WindowsPrivateRuntime.js +137 -0
- package/install.sh +4 -6
- package/native/windows/README.md +102 -0
- package/native/windows/build/manifest.json +9 -0
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +38 -24
- package/scripts/rea.mjs +1 -1
- package/scripts/verify-windows-native-artifact.mjs +39 -0
- package/skills/reverse-engineer-anything/SKILL.md +92 -24
- package/skills/reverse-engineer-anything/references/android-applications.md +31 -0
- package/skills/reverse-engineer-anything/references/javascript-applications.md +19 -2
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +52 -4
- package/dist/browser/CdpCanonicalJsonDigest.js +0 -9
- package/dist/domain/errors.js +0 -324
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
+
import { createReadStream, constants } from "node:fs";
|
|
3
|
+
import { copyFile } from "node:fs/promises";
|
|
4
|
+
import { tmpdir } from "node:os";
|
|
5
|
+
import { basename, join, normalize } from "node:path";
|
|
6
|
+
import { AnalysisProtocolError } from "../domain/analysisErrorCore.js";
|
|
7
|
+
import { PrivateRuntimeRoot } from "../process/PrivateRuntimeRoot.js";
|
|
8
|
+
/** Read a file digest with bounded memory rather than retaining binary bytes. */
|
|
9
|
+
export const idaFileDigest = async (path) => {
|
|
10
|
+
const hash = createHash("sha256");
|
|
11
|
+
for await (const chunk of createReadStream(path))
|
|
12
|
+
hash.update(chunk);
|
|
13
|
+
return hash.digest("hex");
|
|
14
|
+
};
|
|
15
|
+
/** Compare host-local paths without confusing Windows paths with POSIX coordinates. */
|
|
16
|
+
export const sameIdaHostPath = (left, right) => process.platform === "win32"
|
|
17
|
+
? normalize(left).toLowerCase() === normalize(right).toLowerCase()
|
|
18
|
+
: normalize(left) === normalize(right);
|
|
19
|
+
/** Private input copy isolates upstream database and sidecar writes from the original. */
|
|
20
|
+
export class IdaWorkspace {
|
|
21
|
+
runtime;
|
|
22
|
+
inputPath;
|
|
23
|
+
sessionId = `rea-${randomUUID()}`;
|
|
24
|
+
constructor(runtime, inputPath) {
|
|
25
|
+
this.runtime = runtime;
|
|
26
|
+
this.inputPath = inputPath;
|
|
27
|
+
}
|
|
28
|
+
/** Filesystem root owned exclusively by this headless session. */
|
|
29
|
+
get directory() {
|
|
30
|
+
return this.runtime.path;
|
|
31
|
+
}
|
|
32
|
+
/** Allocate a protected workspace and copy the admitted input with digest verification. */
|
|
33
|
+
static async create(target, root = tmpdir()) {
|
|
34
|
+
const runtime = await PrivateRuntimeRoot.create({
|
|
35
|
+
parent: normalize(root),
|
|
36
|
+
prefix: "rea-ida-",
|
|
37
|
+
});
|
|
38
|
+
const inputPath = join(runtime.path, basename(target.path));
|
|
39
|
+
try {
|
|
40
|
+
await copyFile(target.path, inputPath, constants.COPYFILE_EXCL);
|
|
41
|
+
if ((await idaFileDigest(inputPath)) !== target.sha256)
|
|
42
|
+
throw new AnalysisProtocolError("IDA target changed between admission and the private input copy; reopen the target.");
|
|
43
|
+
return new IdaWorkspace(runtime, inputPath);
|
|
44
|
+
}
|
|
45
|
+
catch (cause) {
|
|
46
|
+
await runtime.close();
|
|
47
|
+
throw cause;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
/** Delete only this object's privately allocated directory after worker cleanup. */
|
|
51
|
+
async remove() {
|
|
52
|
+
await this.runtime.close();
|
|
53
|
+
}
|
|
54
|
+
}
|
package/dist/main/shutdown.js
CHANGED
|
@@ -13,7 +13,8 @@ export const createShutdown = (input) => {
|
|
|
13
13
|
return shutdownPromise;
|
|
14
14
|
};
|
|
15
15
|
const requestShutdown = () => {
|
|
16
|
-
shutdown().catch(() => {
|
|
16
|
+
shutdown().catch((cause) => {
|
|
17
|
+
serverLogger.debug({ failure_cause: describeShutdownFailure(cause) }, "MCP shutdown rejected");
|
|
17
18
|
dependencies.setExitCode(1);
|
|
18
19
|
serverLogger.error(MCP_SHUTDOWN_FAILED);
|
|
19
20
|
dependencies.writeStderr(`${MCP_SHUTDOWN_FAILED}\n`);
|
|
@@ -22,3 +23,22 @@ export const createShutdown = (input) => {
|
|
|
22
23
|
unregisterShutdown = dependencies.registerShutdown(requestShutdown);
|
|
23
24
|
return { shutdown, request: requestShutdown };
|
|
24
25
|
};
|
|
26
|
+
const describeShutdownFailure = (cause) => {
|
|
27
|
+
if (cause instanceof Error) {
|
|
28
|
+
const code = "code" in cause ? cause.code : undefined;
|
|
29
|
+
return {
|
|
30
|
+
name: cause.name,
|
|
31
|
+
message: cause.message,
|
|
32
|
+
...(typeof code === "string" ||
|
|
33
|
+
(typeof code === "number" && Number.isFinite(code))
|
|
34
|
+
? { code }
|
|
35
|
+
: {}),
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (cause === null ||
|
|
39
|
+
typeof cause === "string" ||
|
|
40
|
+
typeof cause === "boolean" ||
|
|
41
|
+
(typeof cause === "number" && Number.isFinite(cause)))
|
|
42
|
+
return { type: cause === null ? "null" : typeof cause, value: cause };
|
|
43
|
+
return { type: typeof cause };
|
|
44
|
+
};
|
package/dist/main/startup.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { projectAnalysisError } from "../domain/
|
|
1
|
+
import { projectAnalysisError } from "../domain/analysisErrorProjection.js";
|
|
2
2
|
export const openInitialTarget = async (session, config, serverLogger, writeStderr) => {
|
|
3
3
|
if (config.hopperTargetPath === undefined)
|
|
4
4
|
return { ok: true };
|
package/dist/main/transport.js
CHANGED
|
@@ -6,8 +6,10 @@ export const startMcpTransport = async (dependencies, session, serverContext) =>
|
|
|
6
6
|
try {
|
|
7
7
|
optionalProviders = await serverContext.loadOptionalProviders();
|
|
8
8
|
}
|
|
9
|
-
catch {
|
|
10
|
-
serverLogger.warn(
|
|
9
|
+
catch (cause) {
|
|
10
|
+
serverLogger.warn({
|
|
11
|
+
error: cause instanceof Error ? cause.message : String(cause),
|
|
12
|
+
}, "Optional MCP providers could not load; affected tools remain unavailable");
|
|
11
13
|
}
|
|
12
14
|
let handle;
|
|
13
15
|
try {
|
|
@@ -21,9 +23,11 @@ export const startMcpTransport = async (dependencies, session, serverContext) =>
|
|
|
21
23
|
},
|
|
22
24
|
});
|
|
23
25
|
}
|
|
24
|
-
catch {
|
|
26
|
+
catch (cause) {
|
|
25
27
|
await session.close();
|
|
26
|
-
serverLogger.error(
|
|
28
|
+
serverLogger.error({
|
|
29
|
+
error: cause instanceof Error ? cause.message : String(cause),
|
|
30
|
+
}, MCP_CONNECTION_START_FAILED);
|
|
27
31
|
dependencies.writeStderr(`${MCP_CONNECTION_START_FAILED}\n`);
|
|
28
32
|
return { ok: false };
|
|
29
33
|
}
|
package/dist/main.js
CHANGED
|
@@ -5,7 +5,7 @@ import { serveStdio } from "@modelcontextprotocol/server/stdio";
|
|
|
5
5
|
import { parseConfig } from "./config.js";
|
|
6
6
|
import { createBinarySession } from "./application/runtime.js";
|
|
7
7
|
import { createLogger } from "./logger.js";
|
|
8
|
-
import { projectAnalysisError } from "./domain/
|
|
8
|
+
import { projectAnalysisError } from "./domain/analysisErrorProjection.js";
|
|
9
9
|
import { SERVER_START_FAILED } from "./main/messages.js";
|
|
10
10
|
import { createRuntimeState } from "./main/state.js";
|
|
11
11
|
import { openInitialTarget } from "./main/startup.js";
|
|
@@ -98,7 +98,10 @@ export const runEntrypoint = async (start = () => run(), writeStderr = (text) =>
|
|
|
98
98
|
try {
|
|
99
99
|
setExitCode(await start());
|
|
100
100
|
}
|
|
101
|
-
catch {
|
|
101
|
+
catch (cause) {
|
|
102
|
+
// Intentionally redact the startup cause from caller-visible output;
|
|
103
|
+
// unexpected failures must not leak internal details.
|
|
104
|
+
void cause;
|
|
102
105
|
writeStderr(`${SERVER_START_FAILED}\n`);
|
|
103
106
|
setExitCode(1);
|
|
104
107
|
}
|
|
@@ -2,7 +2,8 @@ import { createHash } from "node:crypto";
|
|
|
2
2
|
import { open } from "node:fs/promises";
|
|
3
3
|
import { constants } from "node:fs";
|
|
4
4
|
import { objcSwiftMetadataSchema, nativeDispatchMetadataResultSchema, } from "../domain/objcSwiftMetadata.js";
|
|
5
|
-
import { AnalysisCancelledError
|
|
5
|
+
import { AnalysisCancelledError } from "../domain/analysisErrorCore.js";
|
|
6
|
+
import { EvidenceIntegrityError } from "../domain/evidenceErrors.js";
|
|
6
7
|
import { decodeSwiftClassVtables } from "./AppleSwiftVtables.js";
|
|
7
8
|
import { createObjcProtocolReader } from "./AppleObjcProtocols.js";
|
|
8
9
|
const hex = (value) => `0x${value.toString(16)}`;
|
|
@@ -125,8 +126,9 @@ export const decodeAppleDispatchMetadata = (bytes, maxRecords, provenance, archi
|
|
|
125
126
|
try {
|
|
126
127
|
fileOffset = offset(target);
|
|
127
128
|
}
|
|
128
|
-
catch {
|
|
129
|
-
|
|
129
|
+
catch (cause) {
|
|
130
|
+
// best-effort cleanup: serialized target remains unresolved.
|
|
131
|
+
void cause;
|
|
130
132
|
}
|
|
131
133
|
if (admit())
|
|
132
134
|
result.relative_pointers.push({
|
|
@@ -154,8 +156,9 @@ export const decodeAppleDispatchMetadata = (bytes, maxRecords, provenance, archi
|
|
|
154
156
|
throw new RangeError("Method implementation is not in an executable segment");
|
|
155
157
|
implementationLocation = location(implementation);
|
|
156
158
|
}
|
|
157
|
-
catch {
|
|
158
|
-
|
|
159
|
+
catch (cause) {
|
|
160
|
+
// best-effort cleanup: external/chained pointers remain unresolved.
|
|
161
|
+
void cause;
|
|
159
162
|
}
|
|
160
163
|
result.objc_dispatch_implementations.push({
|
|
161
164
|
class_name: className,
|
|
@@ -213,7 +216,9 @@ export const decodeAppleDispatchMetadata = (bytes, maxRecords, provenance, archi
|
|
|
213
216
|
try {
|
|
214
217
|
superclassName = string(pointer((pointer(superclass + 32n) & ~7n) + 24n));
|
|
215
218
|
}
|
|
216
|
-
catch {
|
|
219
|
+
catch (cause) {
|
|
220
|
+
// Superclass resolution failure is recorded; the cause adds no identity.
|
|
221
|
+
void cause;
|
|
217
222
|
failures.push(`Superclass pointer ${hex(superclass)} of ${name} requires unsupported binding/fixup resolution`);
|
|
218
223
|
}
|
|
219
224
|
}
|
|
@@ -235,7 +240,9 @@ export const decodeAppleDispatchMetadata = (bytes, maxRecords, provenance, archi
|
|
|
235
240
|
try {
|
|
236
241
|
value = u32(encodedOffset);
|
|
237
242
|
}
|
|
238
|
-
catch {
|
|
243
|
+
catch (cause) {
|
|
244
|
+
// Unresolved offsets are recorded; the cause adds no identity.
|
|
245
|
+
void cause;
|
|
239
246
|
failures.push(`Unresolved ivar offset pointer ${hex(encodedOffset)}`);
|
|
240
247
|
}
|
|
241
248
|
result.objc_ivars.push({
|
|
@@ -538,10 +545,10 @@ export const inspectAppleDispatchMetadata = async (target, maxRecords, signal) =
|
|
|
538
545
|
};
|
|
539
546
|
const selectMachoSlice = (bytes, architecture) => {
|
|
540
547
|
const magic = bytes.readUInt32BE(0);
|
|
541
|
-
const
|
|
542
|
-
if (
|
|
548
|
+
const header = fatHeaderFormat(magic);
|
|
549
|
+
if (header === null)
|
|
543
550
|
return { slice: 0, sliceEnd: bytes.length };
|
|
544
|
-
const
|
|
551
|
+
const { littleEndian, fat64 } = header;
|
|
545
552
|
const stride = fat64 ? 32 : 20;
|
|
546
553
|
const readUInt32 = littleEndian
|
|
547
554
|
? (offset) => bytes.readUInt32LE(offset)
|
|
@@ -580,3 +587,17 @@ const selectMachoSlice = (bytes, architecture) => {
|
|
|
580
587
|
throw invalid("Requested FAT architecture is absent");
|
|
581
588
|
return selected;
|
|
582
589
|
};
|
|
590
|
+
const fatHeaderFormat = (magic) => {
|
|
591
|
+
switch (magic) {
|
|
592
|
+
case 0xcafebabe:
|
|
593
|
+
return { littleEndian: false, fat64: false };
|
|
594
|
+
case 0xcafebabf:
|
|
595
|
+
return { littleEndian: false, fat64: true };
|
|
596
|
+
case 0xbebafeca:
|
|
597
|
+
return { littleEndian: true, fat64: false };
|
|
598
|
+
case 0xbfbafeca:
|
|
599
|
+
return { littleEndian: true, fat64: true };
|
|
600
|
+
default:
|
|
601
|
+
return null;
|
|
602
|
+
}
|
|
603
|
+
};
|
|
@@ -6,7 +6,9 @@ import { parse as parseXmlPlist } from "plist";
|
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
|
|
8
8
|
import { NATIVE_TOOL_CONTRACTS, } from "../contracts/nativeToolContracts.js";
|
|
9
|
-
import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisOutputError,
|
|
9
|
+
import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisOutputError, } from "../domain/analysisErrorCore.js";
|
|
10
|
+
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
11
|
+
import { AnalysisError } from "../domain/analysisErrorBase.js";
|
|
10
12
|
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
11
13
|
import { demangleSwiftSchema, inspectPlistSchema, inspectSignatureSchema, listArchitecturesSchema, } from "../domain/nativeInspection.js";
|
|
12
14
|
import { err, ok } from "../domain/result.js";
|
|
@@ -209,28 +211,45 @@ class NativeMacOSClient {
|
|
|
209
211
|
const display = await this.#run("inspect_signature", "codesign", ["-d", "--verbose=4", this.target.path], { signal, acceptNonZero: true });
|
|
210
212
|
if (!display.ok)
|
|
211
213
|
return display;
|
|
212
|
-
const
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
214
|
+
const displayOutput = commandOutput(display.value);
|
|
215
|
+
const unsigned = isUnsignedCodeSignObservation(display.value);
|
|
216
|
+
const displayFailure = codeSignCaptureFailure(display.value);
|
|
217
|
+
if (displayFailure !== null)
|
|
218
|
+
return err(displayFailure);
|
|
219
|
+
const requirements = await this.#run("inspect_signature", "codesign", ["-d", "-r-", this.target.path], { signal, acceptNonZero: true });
|
|
216
220
|
if (!requirements.ok)
|
|
217
221
|
return requirements;
|
|
218
|
-
const
|
|
222
|
+
const requirementsFailure = codeSignCaptureFailure(requirements.value);
|
|
223
|
+
if (requirementsFailure !== null)
|
|
224
|
+
return err(requirementsFailure);
|
|
225
|
+
const entitlements = await this.#run("inspect_signature", "codesign", ["-d", "--entitlements", ":-", this.target.path], { signal, acceptNonZero: true });
|
|
219
226
|
if (!entitlements.ok)
|
|
220
227
|
return entitlements;
|
|
221
|
-
const
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
228
|
+
const entitlementsFailure = codeSignCaptureFailure(entitlements.value);
|
|
229
|
+
if (entitlementsFailure !== null)
|
|
230
|
+
return err(entitlementsFailure);
|
|
231
|
+
const parsed = parseCodeSignature(displayOutput, unsigned);
|
|
232
|
+
const requirementText = /designated\s*=>\s*(.+)$/mu.exec(commandOutput(requirements.value))?.[1] ?? null;
|
|
233
|
+
const entitlementValue = parseEntitlements(commandOutput(entitlements.value));
|
|
234
|
+
const captures = [display.value, requirements.value, entitlements.value];
|
|
235
|
+
const limitations = [...parsed.limitations];
|
|
236
|
+
const mixedSigning = !unsigned &&
|
|
237
|
+
(isNonzeroUnsignedObservation(requirements.value) ||
|
|
238
|
+
isNonzeroUnsignedObservation(entitlements.value));
|
|
239
|
+
if (mixedSigning) {
|
|
240
|
+
const slices = await this.#inspectMixedSignatureSlices(displayOutput, requirements.value.exitCode !== 0, entitlements.value.exitCode !== 0, signal);
|
|
241
|
+
if (!slices.ok)
|
|
242
|
+
return slices;
|
|
243
|
+
captures.push(...slices.value.captures);
|
|
244
|
+
limitations.push(...slices.value.limitations);
|
|
245
|
+
}
|
|
246
|
+
const provenance = captures.map((capture) => invocation(capture, this.target.path));
|
|
229
247
|
const result = inspectSignatureSchema.parse({
|
|
230
248
|
...parsed,
|
|
231
249
|
designated_requirement: requirementText,
|
|
232
250
|
entitlements: entitlementValue,
|
|
233
251
|
provenance,
|
|
252
|
+
limitations,
|
|
234
253
|
});
|
|
235
254
|
return ok({
|
|
236
255
|
result: jsonValueSchema.parse(result),
|
|
@@ -239,6 +258,35 @@ class NativeMacOSClient {
|
|
|
239
258
|
locations: [],
|
|
240
259
|
});
|
|
241
260
|
}
|
|
261
|
+
async #inspectMixedSignatureSlices(displayOutput, requirementsUnavailable, entitlementsUnavailable, signal) {
|
|
262
|
+
const captures = [];
|
|
263
|
+
const unsigned = [];
|
|
264
|
+
const unclassified = [];
|
|
265
|
+
for (const architecture of codeSignArchitectures(displayOutput, this.target)) {
|
|
266
|
+
const slice = await this.#run("inspect_signature", "codesign", ["-d", "-a", architecture, "--verbose=4", this.target.path], { signal, acceptNonZero: true });
|
|
267
|
+
if (!slice.ok)
|
|
268
|
+
return slice;
|
|
269
|
+
captures.push(slice.value);
|
|
270
|
+
if (slice.value.exitCode === 0)
|
|
271
|
+
continue;
|
|
272
|
+
if (isNonzeroUnsignedObservation(slice.value))
|
|
273
|
+
unsigned.push(architecture);
|
|
274
|
+
else
|
|
275
|
+
unclassified.push(architecture);
|
|
276
|
+
}
|
|
277
|
+
const limitations = [
|
|
278
|
+
unsigned.length > 0
|
|
279
|
+
? `Unsigned Mach-O slices: ${unsigned.join(", ")}.`
|
|
280
|
+
: "One or more Mach-O slices are unsigned, but their architectures could not be classified.",
|
|
281
|
+
];
|
|
282
|
+
if (unclassified.length > 0)
|
|
283
|
+
limitations.push(`Signature state could not be classified for Mach-O slices: ${unclassified.join(", ")}.`);
|
|
284
|
+
if (requirementsUnavailable)
|
|
285
|
+
limitations.push("The aggregate designated requirement is unavailable because Mach-O slices have mixed signing states.");
|
|
286
|
+
if (entitlementsUnavailable)
|
|
287
|
+
limitations.push("The aggregate entitlements are unavailable because Mach-O slices have mixed signing states.");
|
|
288
|
+
return ok({ captures, limitations });
|
|
289
|
+
}
|
|
242
290
|
async #inspectPlist(parameters, signal) {
|
|
243
291
|
const requested = parameters.path;
|
|
244
292
|
if (requested !== undefined && typeof requested !== "string")
|
|
@@ -253,6 +301,8 @@ class NativeMacOSClient {
|
|
|
253
301
|
if (!capture.ok)
|
|
254
302
|
return capture;
|
|
255
303
|
const parsed = parsePlistJson(capture.value.stdout);
|
|
304
|
+
if (!parsed.ok)
|
|
305
|
+
return parsed;
|
|
256
306
|
const provenance = [classified.value, capture.value].map((item) => invocation(item, plist.value, "$PLIST"));
|
|
257
307
|
const result = inspectPlistSchema.parse({
|
|
258
308
|
format: /binary property list/iu.test(classified.value.stdout)
|
|
@@ -260,7 +310,7 @@ class NativeMacOSClient {
|
|
|
260
310
|
: /XML|text/iu.test(classified.value.stdout)
|
|
261
311
|
? "xml"
|
|
262
312
|
: "unknown",
|
|
263
|
-
...parsed,
|
|
313
|
+
...parsed.value,
|
|
264
314
|
source_path: plist.value,
|
|
265
315
|
provenance,
|
|
266
316
|
limitations: [],
|
|
@@ -302,6 +352,28 @@ const translateCommandFailure = (operation, failure) => {
|
|
|
302
352
|
return new AnalysisCancelledError(operation);
|
|
303
353
|
return new ProviderAdapterError(IDENTITY.id, operation, { cause: failure });
|
|
304
354
|
};
|
|
355
|
+
const translateCodeSignExitFailure = (capture) => translateCommandFailure("inspect_signature", new NativeCommandFailure("codesign", "nonzero-exit", capture.exitCode));
|
|
356
|
+
const commandOutput = (capture) => `${capture.stdout}\n${capture.stderr}`;
|
|
357
|
+
const isUnsignedCodeSignObservation = (capture) => /not signed at all|code object is not signed/iu.test(commandOutput(capture));
|
|
358
|
+
const isNonzeroUnsignedObservation = (capture) => capture.exitCode !== null &&
|
|
359
|
+
capture.exitCode !== 0 &&
|
|
360
|
+
isUnsignedCodeSignObservation(capture);
|
|
361
|
+
const codeSignCaptureFailure = (capture) => capture.exitCode === 0 || isNonzeroUnsignedObservation(capture)
|
|
362
|
+
? null
|
|
363
|
+
: translateCodeSignExitFailure(capture);
|
|
364
|
+
const codeSignArchitectures = (displayOutput, target) => {
|
|
365
|
+
const universal = /^Format=Mach-O universal \(([^)\r\n]+)\)$/mu.exec(displayOutput)?.[1];
|
|
366
|
+
if (universal !== undefined) {
|
|
367
|
+
const architectures = universal
|
|
368
|
+
.split(/\s+/u)
|
|
369
|
+
.filter((architecture) => /^(?:i386|x86_64|armv7|arm64|arm64e)$/u.test(architecture));
|
|
370
|
+
if (architectures.length > 0)
|
|
371
|
+
return [...new Set(architectures)];
|
|
372
|
+
}
|
|
373
|
+
if (target.kind !== "executable" || target.format !== "mach-o")
|
|
374
|
+
return [];
|
|
375
|
+
return target.availableArchitectures.map((architecture) => architecture === "x86" ? "i386" : architecture);
|
|
376
|
+
};
|
|
305
377
|
const invocation = (capture, artifactPath, alias = "$ARTIFACT") => ({
|
|
306
378
|
tool: capture.tool,
|
|
307
379
|
command: [
|
|
@@ -4,9 +4,11 @@ import { err, ok } from "../domain/result.js";
|
|
|
4
4
|
import { parseDyldSymbols } from "./parsers/dyldInfo.js";
|
|
5
5
|
import { parseLipoArchitectures } from "./parsers/lipo.js";
|
|
6
6
|
import { parseOtoolLoadCommands } from "./parsers/otool.js";
|
|
7
|
-
const
|
|
7
|
+
const DISCOVERY_COMMANDS = [
|
|
8
8
|
["file", ["-b"]],
|
|
9
9
|
["lipo", ["-detailed_info"]],
|
|
10
|
+
];
|
|
11
|
+
const REQUIRED_SLICE_COMMANDS = [
|
|
10
12
|
["otool", ["-h", "-l"]],
|
|
11
13
|
["nm", ["-gjU"]],
|
|
12
14
|
["dyld_info", ["-imports"]],
|
|
@@ -18,10 +20,20 @@ const VTOOL_UNAVAILABLE_LIMITATION = "vtool is unavailable; build metadata is no
|
|
|
18
20
|
/** Inspect one Mach-O with the required native commands and normalized output. */
|
|
19
21
|
export const inspectNativeMacho = async (context) => {
|
|
20
22
|
const captures = [];
|
|
21
|
-
for (const [tool, prefix] of
|
|
23
|
+
for (const [tool, prefix] of DISCOVERY_COMMANDS) {
|
|
24
|
+
const captured = await context.run(tool, [...prefix, context.target.path], context.signal);
|
|
25
|
+
if (!captured.ok)
|
|
26
|
+
return err(captured.error);
|
|
27
|
+
captures.push(captured.value);
|
|
28
|
+
}
|
|
29
|
+
const lipo = captures.find(({ tool }) => tool === "lipo");
|
|
30
|
+
if (lipo === undefined)
|
|
31
|
+
throw new TypeError("Missing lipo capture");
|
|
32
|
+
const selectedArchitecture = selectArchitecture(context.target, parseLipoArchitectures(lipo.stdout).map(({ name }) => name));
|
|
33
|
+
for (const [tool, prefix] of REQUIRED_SLICE_COMMANDS) {
|
|
22
34
|
const captured = await context.run(tool, [
|
|
23
35
|
...prefix,
|
|
24
|
-
...selectedArchitectureArguments(tool,
|
|
36
|
+
...selectedArchitectureArguments(tool, selectedArchitecture),
|
|
25
37
|
context.target.path,
|
|
26
38
|
], context.signal);
|
|
27
39
|
if (!captured.ok)
|
|
@@ -32,7 +44,7 @@ export const inspectNativeMacho = async (context) => {
|
|
|
32
44
|
const [tool, prefix] = OPTIONAL_VTOOL_COMMAND;
|
|
33
45
|
const optional = await context.run(tool, [
|
|
34
46
|
...prefix,
|
|
35
|
-
...selectedArchitectureArguments(tool,
|
|
47
|
+
...selectedArchitectureArguments(tool, selectedArchitecture),
|
|
36
48
|
context.target.path,
|
|
37
49
|
], context.signal);
|
|
38
50
|
if (optional.ok)
|
|
@@ -170,14 +182,32 @@ export const architectureLocations = (architectures) => {
|
|
|
170
182
|
}
|
|
171
183
|
return locations;
|
|
172
184
|
};
|
|
173
|
-
const selectedArchitectureArguments = (tool,
|
|
174
|
-
if (
|
|
175
|
-
target.availableArchitectures.length < 2 ||
|
|
176
|
-
tool === "file" ||
|
|
177
|
-
tool === "lipo")
|
|
185
|
+
const selectedArchitectureArguments = (tool, architecture) => {
|
|
186
|
+
if (architecture === null)
|
|
178
187
|
return [];
|
|
179
|
-
const
|
|
188
|
+
const baseArchitecture = architecture.split(".")[0] ?? architecture;
|
|
189
|
+
// dyld_info distinguishes arm64e ABI variants; the other Apple tools use
|
|
190
|
+
// the base CPU-family spelling for the same slice.
|
|
191
|
+
const toolArchitecture = tool === "dyld_info" ? architecture : baseArchitecture;
|
|
180
192
|
return tool === "dwarfdump"
|
|
181
|
-
? [`--arch=${
|
|
182
|
-
: ["-arch",
|
|
193
|
+
? [`--arch=${toolArchitecture}`]
|
|
194
|
+
: ["-arch", toolArchitecture];
|
|
195
|
+
};
|
|
196
|
+
const selectArchitecture = (target, available) => {
|
|
197
|
+
if (target.kind !== "executable" || target.availableArchitectures.length < 2)
|
|
198
|
+
return null;
|
|
199
|
+
const normalized = target.architecture === "x86" ? "i386" : target.architecture;
|
|
200
|
+
if (available.includes(normalized))
|
|
201
|
+
return normalized;
|
|
202
|
+
// BinaryTarget intentionally normalizes ARM64 CPU subtypes. Recover the
|
|
203
|
+
// concrete arm64e slice name from lipo before invoking slice-aware tools.
|
|
204
|
+
if (normalized === "arm64") {
|
|
205
|
+
const arm64e = available.find((architecture) => architecture === "arm64e");
|
|
206
|
+
if (arm64e !== undefined)
|
|
207
|
+
return arm64e;
|
|
208
|
+
const variant = available.find((architecture) => /^arm64e\.[A-Za-z0-9_]+$/u.test(architecture));
|
|
209
|
+
if (variant !== undefined)
|
|
210
|
+
return variant;
|
|
211
|
+
}
|
|
212
|
+
return normalized;
|
|
183
213
|
};
|
|
@@ -3,6 +3,7 @@ import { tmpdir } from "node:os";
|
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
import { execFileOutput } from "../process/ExecFileOutput.js";
|
|
6
|
+
import { safeParseJson } from "../domain/safeJson.js";
|
|
6
7
|
/** Lazily compile one owned helper per observation/scenario and remove its compiler cache. */
|
|
7
8
|
export const createNativeUiHelperRuntime = () => {
|
|
8
9
|
let root;
|
|
@@ -30,7 +31,12 @@ export const createNativeUiHelperRuntime = () => {
|
|
|
30
31
|
maxBuffer: 16 * 1024 * 1024,
|
|
31
32
|
...(signal === undefined ? {} : { signal }),
|
|
32
33
|
});
|
|
33
|
-
|
|
34
|
+
const parsed = safeParseJson(output.stdout);
|
|
35
|
+
if (!parsed.ok)
|
|
36
|
+
throw new Error(`Native helper returned invalid JSON: ${parsed.error}`, {
|
|
37
|
+
cause: parsed.cause,
|
|
38
|
+
});
|
|
39
|
+
return parsed.value;
|
|
34
40
|
};
|
|
35
41
|
return {
|
|
36
42
|
invoke,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { fileURLToPath } from "node:url";
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { nativeUiObservationInputSchema, nativeUiScenarioInputSchema, nativeUiSnapshotSchema, nativeUiResultSchema, } from "../domain/nativeUiObservation.js";
|
|
4
|
-
import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError,
|
|
4
|
+
import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, } from "../domain/analysisErrorCore.js";
|
|
5
|
+
import { ProviderAdapterError } from "../domain/providerAdapterError.js";
|
|
6
|
+
import {} from "../domain/analysisErrorBase.js";
|
|
5
7
|
import { err, ok } from "../domain/result.js";
|
|
6
8
|
import { createNativeUiHelperRuntime } from "./NativeUiHelperRuntime.js";
|
|
7
9
|
const helper = fileURLToPath(new URL("../../bridge/native/ReaNativeUI.swift", import.meta.url));
|
|
@@ -122,7 +124,9 @@ const observeWithHelper = async (target, operation, parameters, options) => {
|
|
|
122
124
|
abort();
|
|
123
125
|
});
|
|
124
126
|
}
|
|
125
|
-
catch {
|
|
127
|
+
catch (cause) {
|
|
128
|
+
// Cancellation is recorded as a cancelled outcome.
|
|
129
|
+
void cause;
|
|
126
130
|
results.push({
|
|
127
131
|
index,
|
|
128
132
|
kind: step.kind,
|
|
@@ -6,7 +6,7 @@ const resultSchema = z.object({
|
|
|
6
6
|
});
|
|
7
7
|
/** Preserve input ordering while parsing `swift-demangle --compact` lines. */
|
|
8
8
|
export const parseDemangledSymbols = (inputs, output) => {
|
|
9
|
-
const lines = output.
|
|
9
|
+
const lines = output.replace(/\r?\n$/u, "").split(/\r?\n/u);
|
|
10
10
|
if (lines.length !== inputs.length)
|
|
11
11
|
throw new TypeError("swift-demangle output count does not match input");
|
|
12
12
|
return inputs.map((input, index) => {
|
|
@@ -4,7 +4,7 @@ export const parseDyldSymbols = (output, mode, imageBase = null) => {
|
|
|
4
4
|
return output.split(/\r?\n/u).flatMap((rawLine) => {
|
|
5
5
|
const line = rawLine.trim();
|
|
6
6
|
if (mode === "imports") {
|
|
7
|
-
const imported = /^(?:0x[\da-f]+\s+)?(
|
|
7
|
+
const imported = /^(?:0x[\da-f]+\s+)?(.+?)(?:\s+\[([^\]]+)\])?\s+\(from (.+)\)$/iu.exec(line);
|
|
8
8
|
if (imported?.[1] !== undefined)
|
|
9
9
|
return [
|
|
10
10
|
{
|
|
@@ -17,7 +17,7 @@ export const parseDyldSymbols = (output, mode, imageBase = null) => {
|
|
|
17
17
|
];
|
|
18
18
|
return [];
|
|
19
19
|
}
|
|
20
|
-
const reexport = /^\[re-export\]\s+(
|
|
20
|
+
const reexport = /^\[re-export\]\s+(.+?)(?:\s+\(from (.+)\))?$/u.exec(line);
|
|
21
21
|
if (reexport?.[1] !== undefined)
|
|
22
22
|
return [
|
|
23
23
|
{
|
|
@@ -28,7 +28,7 @@ export const parseDyldSymbols = (output, mode, imageBase = null) => {
|
|
|
28
28
|
source: reexport[2] ?? null,
|
|
29
29
|
},
|
|
30
30
|
];
|
|
31
|
-
const exported = /^(0x[\da-f]+)\s+(
|
|
31
|
+
const exported = /^(0x[\da-f]+)\s+(.+?)(?:\s+\[([^\]]+)\])?$/iu.exec(line);
|
|
32
32
|
if (exported?.[1] === undefined || exported[2] === undefined)
|
|
33
33
|
return [];
|
|
34
34
|
const absolute = /\babsolute\b/u.test(exported[3] ?? "");
|
|
@@ -137,7 +137,10 @@ const parseFields = (block) => {
|
|
|
137
137
|
if (match?.[1] === undefined || match[2] === undefined)
|
|
138
138
|
continue;
|
|
139
139
|
const value = match[2].trim();
|
|
140
|
-
fields[match[1]] =
|
|
140
|
+
fields[match[1]] =
|
|
141
|
+
match[1] === "segname" || match[1] === "sectname"
|
|
142
|
+
? value
|
|
143
|
+
: (numeric(value) ?? value);
|
|
141
144
|
}
|
|
142
145
|
return fields;
|
|
143
146
|
};
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { AnalysisOutputError } from "../../domain/analysisErrorCore.js";
|
|
3
|
+
import { err, ok } from "../../domain/result.js";
|
|
4
|
+
import { safeParseJson } from "../../domain/safeJson.js";
|
|
2
5
|
const plistObject = z.record(z.string(), z.unknown());
|
|
3
6
|
/** Parse plutil JSON output and project stable bundle metadata. */
|
|
4
7
|
export const parsePlistJson = (output) => {
|
|
5
8
|
// plutil output can carry a UTF-8 BOM, which JSON.parse rejects outright.
|
|
6
|
-
const
|
|
9
|
+
const parsed = safeParseJson(output.replace(/^\uFEFF/u, ""));
|
|
10
|
+
if (!parsed.ok)
|
|
11
|
+
return err(new AnalysisOutputError("inspect_plist", parsed.error, {
|
|
12
|
+
cause: parsed.cause,
|
|
13
|
+
}));
|
|
14
|
+
const value = parsed.value;
|
|
7
15
|
const object = plistObject.safeParse(value);
|
|
8
16
|
const field = (name) => {
|
|
9
17
|
if (!object.success)
|
|
@@ -11,7 +19,7 @@ export const parsePlistJson = (output) => {
|
|
|
11
19
|
const candidate = object.data[name];
|
|
12
20
|
return typeof candidate === "string" ? candidate : null;
|
|
13
21
|
};
|
|
14
|
-
return {
|
|
22
|
+
return ok({
|
|
15
23
|
value,
|
|
16
24
|
bundle: {
|
|
17
25
|
identifier: field("CFBundleIdentifier"),
|
|
@@ -20,5 +28,5 @@ export const parsePlistJson = (output) => {
|
|
|
20
28
|
version: field("CFBundleVersion"),
|
|
21
29
|
short_version: field("CFBundleShortVersionString"),
|
|
22
30
|
},
|
|
23
|
-
};
|
|
31
|
+
});
|
|
24
32
|
};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { chmod, mkdtemp, rm } from "node:fs/promises";
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
|
+
import { WindowsPrivateRuntime } from "../windows/WindowsPrivateRuntime.js";
|
|
4
5
|
import { windowsNativeCapabilities, } from "./WindowsAuthority.js";
|
|
5
6
|
/** Report whether this process can establish a private runtime root. */
|
|
6
7
|
export const privateRuntimeRootCapability = (platform = process.platform) => platform === "win32"
|
|
@@ -15,7 +16,7 @@ export class PrivateRuntimeRootUnavailableError extends Error {
|
|
|
15
16
|
}
|
|
16
17
|
}
|
|
17
18
|
/**
|
|
18
|
-
* Owns
|
|
19
|
+
* Owns a private temporary runtime root and removes it idempotently.
|
|
19
20
|
*
|
|
20
21
|
* Protocol adapters decide what belongs inside the directory; this primitive
|
|
21
22
|
* establishes a private filesystem boundary on POSIX and deterministic cleanup.
|
|
@@ -23,9 +24,11 @@ export class PrivateRuntimeRootUnavailableError extends Error {
|
|
|
23
24
|
*/
|
|
24
25
|
export class PrivateRuntimeRoot {
|
|
25
26
|
path;
|
|
27
|
+
windowsRuntime;
|
|
26
28
|
#closePromise;
|
|
27
|
-
constructor(path) {
|
|
29
|
+
constructor(path, windowsRuntime) {
|
|
28
30
|
this.path = path;
|
|
31
|
+
this.windowsRuntime = windowsRuntime;
|
|
29
32
|
}
|
|
30
33
|
/** Allocate a new private runtime root without performing protocol work. */
|
|
31
34
|
static async create(options = {}) {
|
|
@@ -33,6 +36,10 @@ export class PrivateRuntimeRoot {
|
|
|
33
36
|
const capability = privateRuntimeRootCapability(platform);
|
|
34
37
|
if (!capability.available)
|
|
35
38
|
throw new PrivateRuntimeRootUnavailableError(capability.reason);
|
|
39
|
+
if (platform === "win32") {
|
|
40
|
+
const runtime = WindowsPrivateRuntime.create(options.parent ?? tmpdir(), options.prefix ?? "rea-provider-");
|
|
41
|
+
return new PrivateRuntimeRoot(runtime.observation.path, runtime);
|
|
42
|
+
}
|
|
36
43
|
const path = await mkdtemp(join(options.parent ?? tmpdir(), options.prefix ?? "rea-provider-"));
|
|
37
44
|
try {
|
|
38
45
|
await chmod(path, 0o700);
|
|
@@ -45,7 +52,10 @@ export class PrivateRuntimeRoot {
|
|
|
45
52
|
}
|
|
46
53
|
/** Remove the runtime root; concurrent and repeated callers share cleanup. */
|
|
47
54
|
close() {
|
|
48
|
-
this.#closePromise ??=
|
|
55
|
+
this.#closePromise ??=
|
|
56
|
+
this.windowsRuntime === undefined
|
|
57
|
+
? rm(this.path, { recursive: true, force: true })
|
|
58
|
+
: Promise.resolve().then(() => this.windowsRuntime?.close());
|
|
49
59
|
return this.#closePromise;
|
|
50
60
|
}
|
|
51
61
|
}
|