rea-agents 3.2.1 → 4.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +183 -332
- package/bridge/ghidra/ReaGhidraBridge.java +561 -74
- package/bridge/hopper_bridge.py +70 -27
- package/bridge/native/ReaNativeUI.swift +157 -0
- package/dist/application/AnalysisContextQueries.js +19 -5
- package/dist/application/AnalysisSnapshotCache.js +30 -11
- package/dist/application/AppleAssetCatalogAnalysis.js +171 -0
- package/dist/application/ArtifactExtractionDestination.js +0 -12
- package/dist/application/ArtifactGraphConstruction.js +44 -11
- package/dist/application/ArtifactInventory/classify.js +7 -15
- package/dist/application/ArtifactInventory/hash.js +4 -2
- package/dist/application/ArtifactInventory/policy.js +2 -17
- package/dist/application/ArtifactInventory/reader.js +3 -3
- package/dist/application/ArtifactInventory/scanCanonical.js +2 -2
- package/dist/application/ArtifactInventory/scanReader.js +12 -4
- package/dist/application/ArtifactInventory/types.js +0 -3
- package/dist/application/BinarySession.js +28 -43
- package/dist/application/BinarySessionExecution.js +37 -1
- package/dist/application/BinaryTargetResolver.js +50 -4
- package/dist/application/BrowserEvidence.js +36 -7
- package/dist/application/BrowserObservationService.js +17 -44
- package/dist/application/BrowserScenarioCaptureService.js +2 -35
- package/dist/application/BrowserScenarioEvidence.js +13 -9
- package/dist/application/CapabilityClientRequirements.js +2 -11
- package/dist/application/CapabilityInventory.js +21 -35
- package/dist/application/ClientConfigurationDocument.js +84 -7
- package/dist/application/ClientRegistrationIdentity.js +32 -0
- package/dist/application/ClientRegistrationStatus.js +59 -6
- package/dist/application/DirectAnalysis.js +37 -58
- package/dist/application/DirectAnalysisStatus.js +4 -4
- package/dist/application/Doctor.js +89 -80
- package/dist/application/DoctorDiagnostics.js +2 -26
- package/dist/application/DoctorScope.js +8 -14
- package/dist/application/ElectronActiveEvidence.js +10 -27
- package/dist/application/ElectronActiveObservationService.js +9 -36
- package/dist/application/ElectronBoundaryAnalysis.js +2 -0
- package/dist/application/ElectronBoundaryGraphNative.js +1 -1
- package/dist/application/ElectronEvidence.js +8 -3
- package/dist/application/ElectronObservationService.js +9 -25
- package/dist/application/EnhancedLiteralTracing.js +4 -8
- package/dist/application/EnhancedTools.js +15 -35
- package/dist/application/FilesystemSnapshot.js +7 -8
- package/dist/application/JavaScriptApplicationEvidenceGraph.js +2 -1
- package/dist/application/JavaScriptApplicationWorkflowService.js +31 -7
- package/dist/application/JavaScriptArtifactAnalysis.js +6 -4
- package/dist/application/JavaScriptArtifactFiles.js +5 -0
- package/dist/application/JavaScriptArtifactPathResolution.js +179 -47
- package/dist/application/JavaScriptRuntimeObservationEvidence.js +6 -3
- package/dist/application/JavaScriptRuntimeObservationService.js +9 -25
- package/dist/application/JavaScriptRuntimeReconciliationService.js +45 -4
- package/dist/application/JavaScriptSemanticGraphAsyncProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphChildProcessProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphDataProjection.js +11 -0
- package/dist/application/JavaScriptSemanticGraphFlowProjection.js +14 -5
- package/dist/application/JsonFiles.js +1 -1
- package/dist/application/LazyAnalysisProvider.js +27 -6
- package/dist/application/ManagedMemberComparisonService.js +19 -6
- package/dist/application/NativeApiInspection.js +2 -0
- package/dist/application/NativeCallRoutes.js +72 -0
- package/dist/application/NativeDispatchMetadataInspection.js +33 -0
- package/dist/application/NativeUiActionTrace.js +73 -49
- package/dist/application/NativeValueTrace.js +320 -0
- package/dist/application/ProcessCaptureCapability.js +32 -5
- package/dist/application/ProcessCaptureEnvironment.js +9 -26
- package/dist/application/ProcessCaptureError.js +1 -5
- package/dist/application/ProcessCaptureJournal.js +3 -40
- package/dist/application/ProcessCaptureLifecycle.js +102 -111
- package/dist/application/ProcessCli.js +18 -25
- package/dist/application/ProcessEvidence.js +5 -7
- package/dist/application/ProcessFilesystemEffects.js +36 -0
- package/dist/application/ProcessHarness.js +41 -120
- package/dist/application/ProcessNormalization.js +2 -17
- package/dist/application/ProcessScenarioRuntimeValidation.js +76 -0
- package/dist/application/ReferenceSourceImport.js +3 -4
- package/dist/application/Setup.js +236 -84
- package/dist/application/SetupClientConfiguration.js +14 -9
- package/dist/application/SetupPlan.js +138 -86
- package/dist/application/SetupSkill.js +0 -1
- package/dist/application/SupportedClients.js +102 -21
- package/dist/application/Uninstall.js +31 -20
- package/dist/application/Update.js +93 -0
- package/dist/application/UpdateMaintenance.js +108 -0
- package/dist/application/UpdateRuntime.js +126 -0
- package/dist/application/runtime.js +13 -2
- package/dist/artifacts/ArtifactPaths.js +6 -8
- package/dist/artifacts/ArtifactProvider.js +94 -41
- package/dist/artifacts/AsarArtifactReader.js +19 -4
- package/dist/artifacts/KeyedArchiveReader.js +110 -0
- package/dist/artifacts/MachOSliceArtifactReader.js +53 -5
- package/dist/artifacts/ZipArtifactReader.js +18 -1
- package/dist/browser/BrowserScenarioSecrets.js +28 -1
- package/dist/browser/CdpBrowserProvider.js +36 -15
- package/dist/browser/CdpCaptureDocuments.js +22 -8
- package/dist/browser/CdpCaptureEventHandlers.js +14 -5
- package/dist/browser/CdpCaptureEventHelpers.js +13 -0
- package/dist/browser/CdpCaptureEvents.js +10 -1
- package/dist/browser/CdpElectronInspection.js +5 -10
- package/dist/browser/CdpElectronProvider.js +1 -5
- package/dist/browser/CdpElectronScripts.js +1 -1
- package/dist/browser/CdpEndpoint.js +3 -2
- package/dist/browser/CdpObservationSession.js +14 -10
- package/dist/browser/CdpPageCapture.js +1 -1
- package/dist/browser/CdpPageCaptureScripts.js +1 -1
- package/dist/browser/CdpSafeMetadata.js +5 -4
- package/dist/browser/CdpScreenshot.js +16 -5
- package/dist/browser/CdpTargetSession.js +25 -4
- package/dist/browser/CdpWebMcpDiscovery.js +93 -20
- package/dist/browser/JavaScriptRuntimeScope.js +28 -2
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +9 -8
- package/dist/browser/PlaywrightElectronActiveActions.js +3 -10
- package/dist/browser/PlaywrightElectronActiveProvider.js +5 -5
- package/dist/browser/PlaywrightScenarioActions.js +1 -1
- package/dist/browser/PlaywrightScenarioArtifacts.js +13 -25
- package/dist/browser/PlaywrightScenarioBrowser.js +28 -25
- package/dist/browser/PlaywrightScenarioEvents.js +82 -93
- package/dist/browser/PlaywrightScenarioSession.js +27 -123
- package/dist/browser/PngVisualDiff.js +22 -3
- package/dist/browser/V8InspectorCaptureProjection.js +7 -1
- package/dist/browser/V8InspectorProvider.js +60 -7
- package/dist/browser/WebSourceMapFetcher.js +99 -53
- package/dist/cli/artifactCommands.js +56 -12
- package/dist/cli/coreAnalysisCommands.js +110 -0
- package/dist/cli/managedCommands.js +1 -31
- package/dist/cli/setupCommands.js +16 -14
- package/dist/cli/utilityCommands.js +61 -4
- package/dist/cli.js +5 -7
- package/dist/cliApplicationCommands.js +0 -83
- package/dist/cliBrowserAdvancedCommands.js +7 -11
- package/dist/cliBrowserCommands.js +15 -23
- package/dist/cliBrowserContext.js +3 -24
- package/dist/cliBrowserScenarioCommands.js +2 -10
- package/dist/cliCommandNames.js +82 -7
- package/dist/cliElectronCommands.js +10 -36
- package/dist/cliJavaScriptRuntimeCommands.js +6 -30
- package/dist/cliJsonInput.js +4 -2
- package/dist/cliLogging.js +16 -7
- package/dist/cliObservationOptions.js +1 -1
- package/dist/cliOutput.js +2 -4
- package/dist/cliProcessCommands.js +6 -33
- package/dist/cliSetup.js +90 -160
- package/dist/config/environment.js +2 -78
- package/dist/config/parseConfig.js +18 -109
- package/dist/config/parsers.js +0 -23
- package/dist/contracts/applicationToolContracts.js +1 -118
- package/dist/contracts/artifactToolContracts.js +11 -19
- package/dist/contracts/browserScenarioToolContracts.js +1 -5
- package/dist/contracts/browserToolContracts.js +9 -16
- package/dist/contracts/electronToolContracts.js +5 -6
- package/dist/contracts/enhancedInputs.js +3 -2
- package/dist/contracts/errorSchemas.js +16 -40
- package/dist/contracts/functionWorkflowToolContracts.js +2 -2
- package/dist/contracts/javascriptApplicationWorkflowExamples.js +2 -2
- package/dist/contracts/javascriptRuntimeObservationToolContracts.js +4 -4
- package/dist/contracts/javascriptRuntimeReconciliationExample.js +1 -1
- package/dist/contracts/managedToolContracts.js +7 -4
- package/dist/contracts/managedWorkflowExamples.js +0 -22
- package/dist/contracts/managedWorkflowToolContracts.js +16 -31
- package/dist/contracts/nativeToolContracts.js +9 -0
- package/dist/contracts/promptContracts.js +6 -6
- package/dist/contracts/sessionToolSchemas.js +3 -3
- package/dist/contracts/toolContractExamples.js +4 -3
- package/dist/contracts/toolContracts.js +18 -7
- package/dist/contracts/toolEffects.js +34 -21
- package/dist/contracts/toolOutputSchemaGroups.js +18 -5
- package/dist/contracts/toolOutputSchemaPrimitives.js +9 -6
- package/dist/contracts/toolSchemaMetadata.js +5 -8
- package/dist/doctorRuntime.js +0 -41
- package/dist/domain/analysisErrorPresentation.js +4 -28
- package/dist/domain/analysisErrorProjection.js +33 -50
- package/dist/domain/analysisProfile.js +1 -1
- package/dist/domain/analysisSnapshot.js +77 -3
- package/dist/domain/androidApplication.js +5 -4
- package/dist/domain/appleApplication.js +5 -4
- package/dist/domain/appleAssetCatalog.js +127 -0
- package/dist/domain/artifactComparison.js +7 -11
- package/dist/domain/artifactGraph.js +8 -6
- package/dist/domain/artifactInspection.js +13 -12
- package/dist/domain/binaryTarget.js +23 -9
- package/dist/domain/browserObservation.js +43 -24
- package/dist/domain/browserObservationSchemas.js +2 -1
- package/dist/domain/browserScenario.js +7 -107
- package/dist/domain/browserScenarioCapture.js +0 -1
- package/dist/domain/browserScenarioCaptureValues.js +5 -4
- package/dist/domain/browserScenarioDiff.js +1 -3
- package/dist/domain/browserScenarioValues.js +16 -107
- package/dist/domain/bundleComparison.js +18 -17
- package/dist/domain/callPathSchemas.js +17 -7
- package/dist/domain/changedBehavior.js +2 -3
- package/dist/domain/comparisonSemantics.js +19 -0
- package/dist/domain/completionLedgerGeneration.js +3 -2
- package/dist/domain/conformancePackage.js +2 -1
- package/dist/domain/conformanceTrustGate.js +3 -5
- package/dist/domain/customProtocolCapture.js +2 -2
- package/dist/domain/digests.js +30 -0
- package/dist/domain/dosMz.js +83 -0
- package/dist/domain/electronActiveObservation.js +7 -5
- package/dist/domain/electronObservation.js +3 -2
- package/dist/domain/electronStaticAnalysisNative.js +15 -6
- package/dist/domain/emptyArraySchema.js +3 -0
- package/dist/domain/errors.js +10 -28
- package/dist/domain/evidence.js +5 -3
- package/dist/domain/evidenceCompletionLedger.js +3 -2
- package/dist/domain/functionComparisonNormalization.js +24 -18
- package/dist/domain/functionComparisonResults.js +3 -7
- package/dist/domain/functionComparisonSchemas.js +3 -2
- package/dist/domain/hopperValues.js +108 -8
- package/dist/domain/javascriptApplicationAnalysis.js +4 -7
- package/dist/domain/javascriptApplicationEvidenceSchemas.js +4 -3
- package/dist/domain/javascriptApplicationGraphSchemas.js +8 -7
- package/dist/domain/javascriptApplicationVersionComparisonSchemas.js +9 -7
- package/dist/domain/javascriptApplicationVersionItems.js +12 -18
- package/dist/domain/javascriptAstValues.js +4 -0
- package/dist/domain/javascriptExportShapeComparison.js +1 -6
- package/dist/domain/javascriptExportShapeComparisonSchemas.js +6 -10
- package/dist/domain/javascriptExportShapeVariants.js +15 -2
- package/dist/domain/javascriptFeatureTraceSchemas.js +8 -7
- package/dist/domain/javascriptRuntimeObservation.js +14 -2
- package/dist/domain/javascriptRuntimeReconciliationMatching.js +8 -0
- package/dist/domain/javascriptRuntimeReconciliationParsing.js +4 -2
- package/dist/domain/javascriptRuntimeReconciliationResult.js +6 -4
- package/dist/domain/javascriptRuntimeReconciliationRuntime.js +15 -4
- package/dist/domain/javascriptRuntimeReconciliationSchemas.js +19 -18
- package/dist/domain/javascriptRuntimeStaticCandidates.js +18 -6
- package/dist/domain/javascriptSemanticAnalysis.js +57 -19
- package/dist/domain/javascriptSemanticAsyncEffects.js +39 -40
- package/dist/domain/javascriptSemanticCalls.js +46 -27
- package/dist/domain/javascriptSemanticChildProcesses.js +43 -50
- package/dist/domain/javascriptSemanticDataEffectHelpers.js +91 -18
- package/dist/domain/javascriptSemanticDataEffects.js +22 -10
- package/dist/domain/javascriptSemanticGraphSchemas.js +8 -6
- package/dist/domain/javascriptSemanticObjects.js +13 -3
- package/dist/domain/javascriptSemanticProjection.js +144 -38
- package/dist/domain/javascriptSemanticPromises.js +14 -27
- package/dist/domain/javascriptSemanticQuerySchemas.js +6 -9
- package/dist/domain/javascriptSemanticResources.js +2 -5
- package/dist/domain/javascriptSemanticState.js +4 -0
- package/dist/domain/javascriptSemanticTraceSchemas.js +2 -1
- package/dist/domain/javascriptSemanticTraversal.js +13 -5
- package/dist/domain/javascriptSemanticValues.js +10 -9
- package/dist/domain/javascriptSourceParser.js +5 -1
- package/dist/domain/javascriptStaticAnalysisCalls.js +8 -5
- package/dist/domain/javascriptStaticAnalysisHelpers.js +16 -7
- package/dist/domain/keyedArchive.js +181 -0
- package/dist/domain/managedApplicationGraph.js +4 -3
- package/dist/domain/managedArtifact.js +2 -1
- package/dist/domain/managedMemberComparison.js +18 -13
- package/dist/domain/managedMemberComparisonCoverage.js +2 -1
- package/dist/domain/managedMemberComparisonItems.js +27 -7
- package/dist/domain/managedMemberComparisonMatch.js +22 -6
- package/dist/domain/managedNativeVerificationMatch.js +2 -2
- package/dist/domain/managedNativeVerificationSchemas.js +7 -5
- package/dist/domain/managedReconstruction.js +6 -5
- package/dist/domain/nativeApiBoundary.js +7 -0
- package/dist/domain/nativeDataType.js +51 -0
- package/dist/domain/nativeInspection.js +0 -1
- package/dist/domain/nativeInstruction.js +82 -0
- package/dist/domain/nativeInvestigationGraph.js +9 -5
- package/dist/domain/nativeUiObservation.js +123 -0
- package/dist/domain/nativeValueFlow.js +17 -0
- package/dist/domain/nativeValueTrace.js +64 -0
- package/dist/domain/objcSwiftMetadata.js +39 -0
- package/dist/domain/peInspection.js +1 -0
- package/dist/domain/processCapture.js +5 -55
- package/dist/domain/processCaptureExample.js +0 -9
- package/dist/domain/processCaptureValidation.js +13 -144
- package/dist/domain/processComparison.js +3 -25
- package/dist/domain/processObservation.js +0 -29
- package/dist/domain/processScenario.js +28 -228
- package/dist/domain/processTraceDimensionProjection.js +0 -15
- package/dist/domain/processTraceEvaluation.js +0 -6
- package/dist/domain/protocolCapture.js +8 -36
- package/dist/domain/reconstructionCoverage.js +3 -2
- package/dist/domain/reconstructionObligationLedgerSchemas.js +4 -12
- package/dist/domain/reconstructionReadinessSchemas.js +4 -3
- package/dist/domain/reconstructionVerification.js +2 -1
- package/dist/domain/reconstructionVerificationSchemas.js +6 -13
- package/dist/domain/referenceSourceClassification.js +0 -110
- package/dist/domain/referenceSourceGraph.js +15 -5
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/runtimeIdentification.js +6 -5
- package/dist/domain/sourceMapContents.js +5 -0
- package/dist/domain/sourceToBundleComparison.js +3 -10
- package/dist/domain/sourceToBundleComparisonSchemas.js +7 -6
- package/dist/domain/sourceToBundleSignals.js +9 -3
- package/dist/domain/staticRuntimeCorrelation.js +5 -11
- package/dist/domain/webBundleAnalysis.js +17 -9
- package/dist/domain/webBundleAnalyzer.js +1 -1
- package/dist/domain/webCaptureDiff.js +5 -11
- package/dist/domain/webCaptureDiffSchemas.js +2 -1
- package/dist/domain/webMcpDiscovery.js +2 -1
- package/dist/dotnet/ManagedMemberInspectorCore.js +15 -7
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +57 -40
- package/dist/dotnet/ManagedMemberRows.js +2 -0
- package/dist/dotnet/ManagedMethodBodyReader.js +15 -8
- package/dist/dotnet/ManagedPeReader.js +2 -0
- package/dist/generatedMcpToolCatalog.js +1 -1
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +15 -5
- package/dist/ghidra/GhidraClient.js +38 -8
- package/dist/ghidra/GhidraFunctionValues.js +56 -20
- package/dist/ghidra/GhidraInstallation.js +7 -4
- package/dist/ghidra/GhidraInventoryValues.js +44 -9
- package/dist/ghidra/GhidraLauncher.js +18 -3
- package/dist/ghidra/GhidraProvider.js +23 -2
- package/dist/ghidra/GhidraRequestQueue.js +45 -4
- package/dist/ghidra/GhidraSessionValues.js +5 -0
- package/dist/hopper/HopperAnalysisProfile.js +2 -0
- package/dist/hopper/HopperProvider.js +29 -6
- package/dist/hopper/HopperTargetLease.js +18 -4
- package/dist/logger.js +0 -13
- package/dist/main/messages.js +0 -1
- package/dist/main/reload.js +3 -32
- package/dist/main/shutdown.js +1 -2
- package/dist/main/transport.js +0 -17
- package/dist/main.js +0 -10
- package/dist/native/AppleDispatchMetadata.js +582 -0
- package/dist/native/AppleObjcProtocols.js +88 -0
- package/dist/native/AppleSwiftVtables.js +86 -0
- package/dist/native/CommandRunner.js +1 -1
- package/dist/native/NativeHostCapabilities.js +23 -0
- package/dist/native/NativeMacOSProvider.js +61 -9
- package/dist/native/NativeMachoInspection.js +39 -6
- package/dist/native/NativeUiHelperRuntime.js +42 -0
- package/dist/native/NativeUiObservation.js +174 -0
- package/dist/native/parsers/codesign.js +4 -1
- package/dist/native/parsers/dyldInfo.js +51 -25
- package/dist/native/parsers/lipo.js +13 -4
- package/dist/native/parsers/otool.js +84 -39
- package/dist/native/parsers/plist.js +2 -1
- package/dist/process/ExecFileOutput.js +5 -1
- package/dist/process/ProcessOwnership.js +69 -33
- package/dist/process/ProcessOwnershipObservation.js +31 -12
- package/dist/process/ProviderProcess.js +4 -2
- package/dist/reference/ReferenceSourceReaderEntries.js +48 -31
- package/dist/reference/ReferenceSourceReaderErrors.js +24 -0
- package/dist/reference/ReferenceSourceReaderFile.js +11 -5
- package/dist/reference/ReferenceSourceReaderValidate.js +22 -8
- package/dist/server/createServer.js +7 -62
- package/dist/server/registerApplicationTools/helpers.js +2 -9
- package/dist/server/registerApplicationTools.js +0 -4
- package/dist/server/registerArtifactComparisonTool.js +1 -1
- package/dist/server/registerBrowserScenarioTool.js +4 -2
- package/dist/server/registerBrowserTools.js +7 -7
- package/dist/server/registerBundleComparisonTool.js +1 -1
- package/dist/server/registerCloseLifecycleTool.js +1 -1
- package/dist/server/registerElectronTools.js +10 -4
- package/dist/server/registerEnhancedTools.js +20 -12
- package/dist/server/registerEvidenceTools.js +4 -28
- package/dist/server/registerFunctionComparisonTool.js +1 -1
- package/dist/server/registerInvestigationTools.js +6 -6
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -2
- package/dist/server/registerManagedTools.js +28 -14
- package/dist/server/registerManagedWorkflowTools.js +0 -2
- package/dist/server/registerProcessComparisonTool.js +1 -3
- package/dist/server/registerSessionRecordTools.js +9 -9
- package/dist/server/registerSessionStatusTool.js +1 -1
- package/dist/server/registerSessionTools.js +28 -57
- package/dist/server/sessionAvailabilityPolicy.js +2 -3
- package/dist/server/sessionToolPolicies.js +0 -4
- package/dist/server/toolResult.js +8 -10
- package/package.json +32 -22
- package/skills/reverse-engineer-anything/SKILL.md +15 -11
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +3 -2
- package/skills/reverse-engineer-anything/references/javascript-applications.md +3 -2
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +8 -6
- package/skills/reverse-engineer-anything/references/runtime-observation.md +15 -11
- package/dist/application/CommandShimReplay.js +0 -152
- package/dist/application/ConfiguredRoots.js +0 -19
- package/dist/application/InstrumentedJavaScriptReplayHost.js +0 -36
- package/dist/application/JavaScriptReplayPermission.js +0 -16
- package/dist/application/JavaScriptReplayPlanning.js +0 -207
- package/dist/application/JavaScriptReplayService.js +0 -274
- package/dist/application/LoopbackReplay.js +0 -389
- package/dist/application/LoopbackReplayRecorder.js +0 -129
- package/dist/application/ManagedRuntimeCorrelationService.js +0 -104
- package/dist/application/NodeRuntimeCharacterizationService.js +0 -191
- package/dist/application/PermissionAuthority.js +0 -268
- package/dist/application/PermissionConfiguration.js +0 -26
- package/dist/application/PermissionFailure.js +0 -5
- package/dist/application/ProcessCaptureAuthority.js +0 -24
- package/dist/application/ProcessCapturePermission.js +0 -13
- package/dist/application/ProcessCheckpoints.js +0 -178
- package/dist/application/ProcessReactiveCoordinator.js +0 -223
- package/dist/application/ProcessReactiveEffects.js +0 -153
- package/dist/application/ProcessReactiveHarness.js +0 -106
- package/dist/application/ProcessReactiveObservations.js +0 -105
- package/dist/application/ProjectPermissionStore.js +0 -199
- package/dist/application/RuntimeExecutableDiagnostics.js +0 -198
- package/dist/application/Upgrade.js +0 -134
- package/dist/browser/SensitiveTextCapture.js +0 -8
- package/dist/cliPolicyCommands.js +0 -185
- package/dist/config/browserScenario.js +0 -77
- package/dist/config/electronAutomation.js +0 -35
- package/dist/config/javascriptReplay.js +0 -41
- package/dist/config/managedRuntime.js +0 -25
- package/dist/config/passiveObservation.js +0 -87
- package/dist/config/permissions.js +0 -23
- package/dist/config/processCapture.js +0 -47
- package/dist/contracts/replayMachineExample.js +0 -37
- package/dist/domain/javascriptExportInstrumentation.js +0 -95
- package/dist/domain/javascriptReplay.js +0 -360
- package/dist/domain/managedRuntimeCorrelation.js +0 -181
- package/dist/domain/nodeRuntimeCharacterization.js +0 -63
- package/dist/domain/permissionPolicy.js +0 -176
- package/dist/domain/processCaptureReactiveSchema.js +0 -68
- package/dist/domain/processCaptureReactiveValidation.js +0 -180
- package/dist/domain/processReactiveCheckpointDataflow.js +0 -32
- package/dist/domain/processReactiveMatching.js +0 -196
- package/dist/domain/processReactiveRuntime.js +0 -116
- package/dist/domain/processReactiveScenario.js +0 -296
- package/dist/domain/processReactiveScenarioPreflight.js +0 -95
- package/dist/domain/processReactiveTransition.js +0 -187
- package/dist/domain/replayMachine.js +0 -320
- package/dist/domain/replayMachineRun.js +0 -168
- package/dist/domain/replayMachineRuntime.js +0 -296
- package/dist/domain/replayMachineValues.js +0 -84
- package/dist/domain/runtimeCharacterization.js +0 -84
- package/dist/replay/JavaScriptReplayWorker.js +0 -382
- package/dist/replay/JavaScriptReplayWorkerTypes.js +0 -1
- package/dist/replay/LinuxJavaScriptReplayRunner.js +0 -216
- package/dist/replay/LinuxJavaScriptReplaySandbox.js +0 -121
- package/dist/replay/LinuxRuntimeClosure.js +0 -44
- package/dist/replay/LinuxSeccompPolicy.js +0 -40
- package/dist/replay/ReplayOutcome.js +0 -104
- package/dist/replay/ReplayProcessLifecycle.js +0 -96
- package/dist/replay/ReplaySeccompFile.js +0 -29
- package/dist/replay/ReplayWorkerProtocol.js +0 -58
- package/dist/replay/SystemJavaScriptReplayHost.js +0 -153
- package/dist/server/ProcessCaptureElicitation.js +0 -153
- package/dist/server/registerApplicationTools/characterization.js +0 -46
- package/dist/server/registerApplicationTools/controlledReplay.js +0 -31
- package/dist/server/registerManagedWorkflowTools/planManagedRuntimeCorrelation.js +0 -29
- package/dist/server/registerReplayMachineTool.js +0 -14
- package/skills/reverse-engineer-anything/references/controlled-replay.md +0 -12
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/** Decode non-generic, non-resilient Swift class vtable descriptors without instantiating metadata. */
|
|
2
|
+
export const decodeSwiftClassVtables = (input) => {
|
|
3
|
+
const { readers: read, result } = input;
|
|
4
|
+
const failures = [];
|
|
5
|
+
let examined = 0;
|
|
6
|
+
for (const field of input.entries) {
|
|
7
|
+
if (!read.admit()) {
|
|
8
|
+
failures.push("max_records_reached");
|
|
9
|
+
break;
|
|
10
|
+
}
|
|
11
|
+
examined++;
|
|
12
|
+
try {
|
|
13
|
+
const descriptor = read.relative(field);
|
|
14
|
+
const flags = read.u32(descriptor);
|
|
15
|
+
if ((flags & 31) !== 16)
|
|
16
|
+
continue;
|
|
17
|
+
const specific = flags >>> 16;
|
|
18
|
+
if ((flags & 0x80) !== 0 || (specific & 0x2000) !== 0)
|
|
19
|
+
throw new TypeError("Generic class or resilient superclass metadata is unsupported");
|
|
20
|
+
if ((specific & 0x8000) === 0)
|
|
21
|
+
continue;
|
|
22
|
+
const initialization = specific & 3;
|
|
23
|
+
if (initialization === 3)
|
|
24
|
+
throw new TypeError("Unknown metadata initialization kind");
|
|
25
|
+
const header = descriptor +
|
|
26
|
+
44n +
|
|
27
|
+
BigInt(initialization === 1 ? 12 : initialization === 2 ? 4 : 0);
|
|
28
|
+
const tableOffset = read.u32(header);
|
|
29
|
+
const count = read.u32(header + 4n);
|
|
30
|
+
const positiveWords = read.u32(descriptor + 28n);
|
|
31
|
+
if (count > 20000 || tableOffset + count > positiveWords)
|
|
32
|
+
throw new RangeError("Swift vtable count or offset exceeds declared metadata bounds");
|
|
33
|
+
const owner = read.string(read.relative(descriptor + 8n));
|
|
34
|
+
for (let index = 0; index < count; index++) {
|
|
35
|
+
if (!read.admit()) {
|
|
36
|
+
failures.push("max_records_reached");
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
const entry = header + 8n + BigInt(index * 8);
|
|
40
|
+
const methodFlags = read.u32(entry);
|
|
41
|
+
// Async slots reference async descriptors; coroutine and future kinds need separate decoders.
|
|
42
|
+
const synchronous = (methodFlags & 0x40) === 0 && (methodFlags & 15) <= 3;
|
|
43
|
+
const implementation = read.relative(entry + 4n);
|
|
44
|
+
const resolved = synchronous && read.executable(implementation);
|
|
45
|
+
result.swift_dispatch_slots.push({
|
|
46
|
+
owner,
|
|
47
|
+
table_kind: "class_vtable",
|
|
48
|
+
slot_index: tableOffset + index,
|
|
49
|
+
requirement: null,
|
|
50
|
+
implementation: null,
|
|
51
|
+
implementation_address: resolved
|
|
52
|
+
? `0x${implementation.toString(16)}`
|
|
53
|
+
: null,
|
|
54
|
+
thunk_address: null,
|
|
55
|
+
location: read.location(entry),
|
|
56
|
+
decode: resolved
|
|
57
|
+
? { status: "decoded", reason: null }
|
|
58
|
+
: {
|
|
59
|
+
status: "partial",
|
|
60
|
+
reason: "Async, coroutine, external or unmapped vtable implementation is unresolved",
|
|
61
|
+
},
|
|
62
|
+
evidence: read.evidence(entry, "Swift class vtable method descriptor; slot index is a metadata word offset, not a source method ordinal"),
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
if ((specific & 0x4000) !== 0)
|
|
66
|
+
failures.push(`${owner}: inherited override descriptors are unsupported`);
|
|
67
|
+
}
|
|
68
|
+
catch (cause) {
|
|
69
|
+
failures.push(`0x${field.toString(16)}: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const slots = result.swift_dispatch_slots.filter((slot) => slot.table_kind === "class_vtable");
|
|
73
|
+
result.coverage.push({
|
|
74
|
+
facet: "swift_class_vtable_descriptors",
|
|
75
|
+
examined,
|
|
76
|
+
decoded: slots.filter((slot) => slot.decode.status === "decoded").length,
|
|
77
|
+
status: failures.length > 0 ||
|
|
78
|
+
slots.some((slot) => slot.decode.status !== "decoded")
|
|
79
|
+
? "partial"
|
|
80
|
+
: "complete",
|
|
81
|
+
reason: failures.join("; ") ||
|
|
82
|
+
(slots.some((slot) => slot.decode.status !== "decoded")
|
|
83
|
+
? "vtable_implementations_unresolved"
|
|
84
|
+
: null),
|
|
85
|
+
});
|
|
86
|
+
};
|
|
@@ -133,7 +133,7 @@ const captureProcess = (executable, arguments_, tool, options) => new Promise((r
|
|
|
133
133
|
finish(err(new NativeCommandFailure(tool, reason, code)));
|
|
134
134
|
return;
|
|
135
135
|
}
|
|
136
|
-
if (code !== 0 && options.acceptNonZero !== true) {
|
|
136
|
+
if (signal !== null || (code !== 0 && options.acceptNonZero !== true)) {
|
|
137
137
|
finish(err(new NativeCommandFailure(tool, "nonzero-exit", code)));
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Apply native host restrictions to portable provider discovery metadata. */
|
|
2
|
+
export const nativeHostCapabilities = (capabilities, platform = process.platform) => {
|
|
3
|
+
if (platform === "darwin")
|
|
4
|
+
return capabilities;
|
|
5
|
+
return capabilities.map((capability) => {
|
|
6
|
+
if (capability.provider.id === "native-macos")
|
|
7
|
+
return {
|
|
8
|
+
...capability,
|
|
9
|
+
available: false,
|
|
10
|
+
availabilityCode: "unsupported_host",
|
|
11
|
+
reason: "Native macOS utilities require macOS.",
|
|
12
|
+
};
|
|
13
|
+
if (capability.provider.id === "rea-artifact-graph" &&
|
|
14
|
+
capability.operation === "inspect_asset_catalog")
|
|
15
|
+
return {
|
|
16
|
+
...capability,
|
|
17
|
+
available: false,
|
|
18
|
+
availabilityCode: "unsupported_host",
|
|
19
|
+
reason: "Apple asset catalogs require macOS assetutil.",
|
|
20
|
+
};
|
|
21
|
+
return capability;
|
|
22
|
+
});
|
|
23
|
+
};
|
|
@@ -1,10 +1,12 @@
|
|
|
1
|
+
import { inspectAppleDispatchMetadata } from "./AppleDispatchMetadata.js";
|
|
2
|
+
import { observeNativeUi } from "./NativeUiObservation.js";
|
|
1
3
|
import { dirname, isAbsolute, resolve } from "node:path";
|
|
2
4
|
import { stat } from "node:fs/promises";
|
|
3
5
|
import { parse as parseXmlPlist } from "plist";
|
|
4
6
|
import { z } from "zod";
|
|
5
7
|
import { createAnalysisExecution, } from "../application/AnalysisProvider.js";
|
|
6
8
|
import { NATIVE_TOOL_CONTRACTS, } from "../contracts/nativeToolContracts.js";
|
|
7
|
-
import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisOutputError, ProviderAdapterError, } from "../domain/errors.js";
|
|
9
|
+
import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisOutputError, ProviderAdapterError, AnalysisError, } from "../domain/errors.js";
|
|
8
10
|
import { jsonValueSchema } from "../domain/jsonValue.js";
|
|
9
11
|
import { demangleSwiftSchema, inspectPlistSchema, inspectSignatureSchema, listArchitecturesSchema, } from "../domain/nativeInspection.js";
|
|
10
12
|
import { err, ok } from "../domain/result.js";
|
|
@@ -28,7 +30,10 @@ export class NativeMacOSProvider {
|
|
|
28
30
|
constructor(runner = new XcrunCommandRunner(), platform = process.platform) {
|
|
29
31
|
this.runner = runner;
|
|
30
32
|
const available = platform === "darwin";
|
|
31
|
-
this.#capabilities = Object.freeze(
|
|
33
|
+
this.#capabilities = Object.freeze([
|
|
34
|
+
...NATIVE_TOOL_CONTRACTS,
|
|
35
|
+
{ name: "inspect_native_dispatch_metadata" },
|
|
36
|
+
].map((contract) => {
|
|
32
37
|
const availability = available
|
|
33
38
|
? { available: true, reason: null }
|
|
34
39
|
: {
|
|
@@ -42,10 +47,11 @@ export class NativeMacOSProvider {
|
|
|
42
47
|
...availability,
|
|
43
48
|
effects: Object.freeze({
|
|
44
49
|
mutatesArtifact: false,
|
|
45
|
-
launchesProcess:
|
|
46
|
-
mayShowUi:
|
|
47
|
-
mayAccessNetwork:
|
|
48
|
-
mayWriteFilesystem:
|
|
50
|
+
launchesProcess: contract.name !== "inspect_native_dispatch_metadata",
|
|
51
|
+
mayShowUi: contract.name === "capture_native_ui_scenario",
|
|
52
|
+
mayAccessNetwork: contract.name === "capture_native_ui_scenario",
|
|
53
|
+
mayWriteFilesystem: contract.name === "capture_native_ui_scenario" ||
|
|
54
|
+
contract.name === "observe_native_ui",
|
|
49
55
|
changesPermissions: false,
|
|
50
56
|
requiresRoot: false,
|
|
51
57
|
}),
|
|
@@ -77,8 +83,49 @@ class NativeMacOSClient {
|
|
|
77
83
|
return err(new AnalysisCancelledError(operation));
|
|
78
84
|
if (operation === "health")
|
|
79
85
|
return ok(createAnalysisExecution(null, IDENTITY));
|
|
86
|
+
if (operation === "inspect_native_dispatch_metadata") {
|
|
87
|
+
if (this.target.kind !== "executable" || this.target.format !== "mach-o")
|
|
88
|
+
return err(new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, "Binary Apple metadata requires Mach-O; other providers can report symbol-only metadata"));
|
|
89
|
+
try {
|
|
90
|
+
const maxRecords = z
|
|
91
|
+
.number()
|
|
92
|
+
.int()
|
|
93
|
+
.min(1)
|
|
94
|
+
.max(20000)
|
|
95
|
+
.parse(parameters.max_records ?? 5000);
|
|
96
|
+
const result = await inspectAppleDispatchMetadata(this.target, maxRecords, options?.signal);
|
|
97
|
+
return ok(createAnalysisExecution(result, result.provider, {
|
|
98
|
+
locations: [{ kind: "artifact-path", path: this.target.path }],
|
|
99
|
+
limitations: result.result.coverage.flatMap(({ reason }) => reason === null ? [] : [reason]),
|
|
100
|
+
}));
|
|
101
|
+
}
|
|
102
|
+
catch (cause) {
|
|
103
|
+
if (cause instanceof AnalysisError)
|
|
104
|
+
return err(cause);
|
|
105
|
+
return err(options?.signal?.aborted
|
|
106
|
+
? new AnalysisCancelledError(operation)
|
|
107
|
+
: new ProviderAdapterError(IDENTITY.id, operation, {
|
|
108
|
+
cause,
|
|
109
|
+
diagnostics: {
|
|
110
|
+
target_path: this.target.path,
|
|
111
|
+
reason: cause instanceof Error ? cause.message : String(cause),
|
|
112
|
+
},
|
|
113
|
+
}));
|
|
114
|
+
}
|
|
115
|
+
}
|
|
80
116
|
if (!isNativeOperation(operation))
|
|
81
117
|
return err(new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, "Operation is not implemented by native macOS tools."));
|
|
118
|
+
if (operation === "observe_native_ui" ||
|
|
119
|
+
operation === "capture_native_ui_scenario") {
|
|
120
|
+
const result = await observeNativeUi(this.target, operation, parameters, {
|
|
121
|
+
signal: options?.signal,
|
|
122
|
+
});
|
|
123
|
+
return result.ok
|
|
124
|
+
? ok(createAnalysisExecution(result.value, IDENTITY, {
|
|
125
|
+
limitations: result.value.limitations,
|
|
126
|
+
}))
|
|
127
|
+
: result;
|
|
128
|
+
}
|
|
82
129
|
try {
|
|
83
130
|
const observation = await this.#dispatch(operation, parameters, options?.signal);
|
|
84
131
|
return observation.ok
|
|
@@ -100,6 +147,9 @@ class NativeMacOSClient {
|
|
|
100
147
|
}
|
|
101
148
|
#dispatch(operation, parameters, signal) {
|
|
102
149
|
switch (operation) {
|
|
150
|
+
case "observe_native_ui":
|
|
151
|
+
case "capture_native_ui_scenario":
|
|
152
|
+
return Promise.resolve(err(new AnalysisCapabilityUnavailableError(IDENTITY.id, operation, "UI observation uses its explicit authority boundary")));
|
|
103
153
|
case "inspect_macho":
|
|
104
154
|
return this.#inspectMacho(signal);
|
|
105
155
|
case "inspect_signature":
|
|
@@ -159,13 +209,15 @@ class NativeMacOSClient {
|
|
|
159
209
|
const display = await this.#run("inspect_signature", "codesign", ["-d", "--verbose=4", this.target.path], { signal, acceptNonZero: true });
|
|
160
210
|
if (!display.ok)
|
|
161
211
|
return display;
|
|
162
|
-
const
|
|
212
|
+
const unsigned = /not signed at all|code object is not signed/iu.test(`${display.value.stdout}\n${display.value.stderr}`);
|
|
213
|
+
if (!unsigned && display.value.exitCode !== 0)
|
|
214
|
+
return err(translateCommandFailure("inspect_signature", new NativeCommandFailure("codesign", "nonzero-exit", display.value.exitCode)));
|
|
215
|
+
const requirements = await this.#run("inspect_signature", "codesign", ["-d", "-r-", this.target.path], { signal, acceptNonZero: unsigned });
|
|
163
216
|
if (!requirements.ok)
|
|
164
217
|
return requirements;
|
|
165
|
-
const entitlements = await this.#run("inspect_signature", "codesign", ["-d", "--entitlements", ":-", this.target.path], { signal, acceptNonZero:
|
|
218
|
+
const entitlements = await this.#run("inspect_signature", "codesign", ["-d", "--entitlements", ":-", this.target.path], { signal, acceptNonZero: unsigned });
|
|
166
219
|
if (!entitlements.ok)
|
|
167
220
|
return entitlements;
|
|
168
|
-
const unsigned = /not signed at all|code object is not signed/iu.test(`${display.value.stdout}\n${display.value.stderr}`);
|
|
169
221
|
const parsed = parseCodeSignature(`${display.value.stdout}\n${display.value.stderr}`, unsigned);
|
|
170
222
|
const requirementText = /designated\s*=>\s*(.+)$/mu.exec(`${requirements.value.stdout}\n${requirements.value.stderr}`)?.[1] ?? null;
|
|
171
223
|
const entitlementValue = parseEntitlements(`${entitlements.value.stdout}\n${entitlements.value.stderr}`);
|
|
@@ -7,7 +7,7 @@ import { parseOtoolLoadCommands } from "./parsers/otool.js";
|
|
|
7
7
|
const REQUIRED_COMMANDS = [
|
|
8
8
|
["file", ["-b"]],
|
|
9
9
|
["lipo", ["-detailed_info"]],
|
|
10
|
-
["otool", ["-l"]],
|
|
10
|
+
["otool", ["-h", "-l"]],
|
|
11
11
|
["nm", ["-gjU"]],
|
|
12
12
|
["dyld_info", ["-imports"]],
|
|
13
13
|
["dyld_info", ["-exports"]],
|
|
@@ -19,14 +19,22 @@ const VTOOL_UNAVAILABLE_LIMITATION = "vtool is unavailable; build metadata is no
|
|
|
19
19
|
export const inspectNativeMacho = async (context) => {
|
|
20
20
|
const captures = [];
|
|
21
21
|
for (const [tool, prefix] of REQUIRED_COMMANDS) {
|
|
22
|
-
const captured = await context.run(tool, [
|
|
22
|
+
const captured = await context.run(tool, [
|
|
23
|
+
...prefix,
|
|
24
|
+
...selectedArchitectureArguments(tool, context.target),
|
|
25
|
+
context.target.path,
|
|
26
|
+
], context.signal);
|
|
23
27
|
if (!captured.ok)
|
|
24
28
|
return err(captured.error);
|
|
25
29
|
captures.push(captured.value);
|
|
26
30
|
}
|
|
27
31
|
const limitations = [];
|
|
28
32
|
const [tool, prefix] = OPTIONAL_VTOOL_COMMAND;
|
|
29
|
-
const optional = await context.run(tool, [
|
|
33
|
+
const optional = await context.run(tool, [
|
|
34
|
+
...prefix,
|
|
35
|
+
...selectedArchitectureArguments(tool, context.target),
|
|
36
|
+
context.target.path,
|
|
37
|
+
], context.signal);
|
|
30
38
|
if (optional.ok)
|
|
31
39
|
captures.push(optional.value);
|
|
32
40
|
else if (optional.error._tag === "AnalysisCapabilityUnavailableError")
|
|
@@ -46,7 +54,8 @@ const normalizeMacho = (captures, toInvocation, additionalLimitations) => {
|
|
|
46
54
|
const architectures = parseLipoArchitectures(byTool("lipo").stdout);
|
|
47
55
|
const load = parseOtoolLoadCommands(byTool("otool").stdout);
|
|
48
56
|
const imports = parseDyldSymbols(byTool("dyld_info", 0).stdout, "imports");
|
|
49
|
-
const
|
|
57
|
+
const imageBase = load.segments.find((segment) => segment.file_offset === 0 && (segment.file_size ?? 0) > 0)?.vm_address ?? null;
|
|
58
|
+
const dyldExports = parseDyldSymbols(byTool("dyld_info", 1).stdout, "exports", imageBase);
|
|
50
59
|
const exports = uniqueSymbols([
|
|
51
60
|
...dyldExports,
|
|
52
61
|
...parseNmExports(byTool("nm").stdout),
|
|
@@ -54,6 +63,11 @@ const normalizeMacho = (captures, toInvocation, additionalLimitations) => {
|
|
|
54
63
|
const uuid = /UUID:\s*([A-Fa-f0-9-]+)/u.exec(byTool("dwarfdump").stdout)?.[1] ??
|
|
55
64
|
load.uuid;
|
|
56
65
|
const provenance = captures.map(toInvocation);
|
|
66
|
+
// A thread-state command carries the entrypoint in architecture-specific
|
|
67
|
+
// register state, so an absent decoded offset means unknown, not absent.
|
|
68
|
+
const threadEntrypoint = load.entrypoints.length === 0 &&
|
|
69
|
+
load.commands.some((command) => command.kind === "LC_UNIXTHREAD" || command.kind === "LC_THREAD");
|
|
70
|
+
const threadEntrypointLimitation = "Thread-state entrypoints (LC_UNIXTHREAD/LC_THREAD) are retained as raw load commands; file offsets are not derived.";
|
|
57
71
|
const limitations = [
|
|
58
72
|
"Imports and exports combine dyld_info and nm; stripped or toolchain-hidden symbols may be absent.",
|
|
59
73
|
...(captures.some(({ tool }) => tool === "vtool")
|
|
@@ -62,6 +76,13 @@ const normalizeMacho = (captures, toInvocation, additionalLimitations) => {
|
|
|
62
76
|
]
|
|
63
77
|
: []),
|
|
64
78
|
...additionalLimitations,
|
|
79
|
+
...(threadEntrypoint ? [threadEntrypointLimitation] : []),
|
|
80
|
+
...(imageBase === null &&
|
|
81
|
+
/^\s*offset\s+symbol\s*$/mu.test(byTool("dyld_info", 1).stdout)
|
|
82
|
+
? [
|
|
83
|
+
"Export virtual addresses are unavailable because no file-backed image base was observed.",
|
|
84
|
+
]
|
|
85
|
+
: []),
|
|
65
86
|
];
|
|
66
87
|
return inspectMachoSchema.parse({
|
|
67
88
|
format: "mach-o",
|
|
@@ -70,7 +91,7 @@ const normalizeMacho = (captures, toInvocation, additionalLimitations) => {
|
|
|
70
91
|
file_type: load.fileType,
|
|
71
92
|
flags: load.flags,
|
|
72
93
|
uuid: uuid ?? null,
|
|
73
|
-
entrypoints: covered(load.entrypoints,
|
|
94
|
+
entrypoints: covered(load.entrypoints, !threadEntrypoint, threadEntrypoint ? [threadEntrypointLimitation] : []),
|
|
74
95
|
architectures: covered(architectures, true),
|
|
75
96
|
build_metadata: covered(load.builds, true),
|
|
76
97
|
load_commands: covered(load.commands, true),
|
|
@@ -120,7 +141,8 @@ const covered = (items, exhaustive, limitations = []) => ({
|
|
|
120
141
|
const uniqueSymbols = (items) => {
|
|
121
142
|
const unique = new Map();
|
|
122
143
|
for (const item of items)
|
|
123
|
-
unique.
|
|
144
|
+
if (!unique.has(item.name))
|
|
145
|
+
unique.set(item.name, item);
|
|
124
146
|
return [...unique.values()].sort((left, right) => left.name.localeCompare(right.name));
|
|
125
147
|
};
|
|
126
148
|
const fileOffsetLocations = (macho) => {
|
|
@@ -148,3 +170,14 @@ export const architectureLocations = (architectures) => {
|
|
|
148
170
|
}
|
|
149
171
|
return locations;
|
|
150
172
|
};
|
|
173
|
+
const selectedArchitectureArguments = (tool, target) => {
|
|
174
|
+
if (target.kind !== "executable" ||
|
|
175
|
+
target.availableArchitectures.length < 2 ||
|
|
176
|
+
tool === "file" ||
|
|
177
|
+
tool === "lipo")
|
|
178
|
+
return [];
|
|
179
|
+
const architecture = target.architecture === "x86" ? "i386" : target.architecture;
|
|
180
|
+
return tool === "dwarfdump"
|
|
181
|
+
? [`--arch=${architecture}`]
|
|
182
|
+
: ["-arch", architecture];
|
|
183
|
+
};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { mkdtemp, rm } from "node:fs/promises";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { execFileOutput } from "../process/ExecFileOutput.js";
|
|
6
|
+
/** Lazily compile one owned helper per observation/scenario and remove its compiler cache. */
|
|
7
|
+
export const createNativeUiHelperRuntime = () => {
|
|
8
|
+
let root;
|
|
9
|
+
let executable;
|
|
10
|
+
const invoke = async (parameters, signal) => {
|
|
11
|
+
if (executable === undefined) {
|
|
12
|
+
root = await mkdtemp(join(tmpdir(), "rea-native-ui-"));
|
|
13
|
+
const output = join(root, "observer");
|
|
14
|
+
await execFileOutput("/usr/bin/xcrun", [
|
|
15
|
+
"swiftc",
|
|
16
|
+
"-module-cache-path",
|
|
17
|
+
join(root, "modules"),
|
|
18
|
+
fileURLToPath(new URL("../../bridge/native/ReaNativeUI.swift", import.meta.url)),
|
|
19
|
+
"-o",
|
|
20
|
+
output,
|
|
21
|
+
], {
|
|
22
|
+
timeout: 60_000,
|
|
23
|
+
maxBuffer: 1024 * 1024,
|
|
24
|
+
...(signal === undefined ? {} : { signal }),
|
|
25
|
+
});
|
|
26
|
+
executable = output;
|
|
27
|
+
}
|
|
28
|
+
const output = await execFileOutput(executable, [JSON.stringify(parameters)], {
|
|
29
|
+
timeout: 30_000,
|
|
30
|
+
maxBuffer: 16 * 1024 * 1024,
|
|
31
|
+
...(signal === undefined ? {} : { signal }),
|
|
32
|
+
});
|
|
33
|
+
return JSON.parse(output.stdout);
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
invoke,
|
|
37
|
+
close: async () => {
|
|
38
|
+
if (root !== undefined)
|
|
39
|
+
await rm(root, { recursive: true, force: true });
|
|
40
|
+
},
|
|
41
|
+
};
|
|
42
|
+
};
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { fileURLToPath } from "node:url";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { nativeUiObservationInputSchema, nativeUiScenarioInputSchema, nativeUiSnapshotSchema, nativeUiResultSchema, } from "../domain/nativeUiObservation.js";
|
|
4
|
+
import { AnalysisCancelledError, AnalysisCapabilityUnavailableError, AnalysisInputError, ProviderAdapterError, } from "../domain/errors.js";
|
|
5
|
+
import { err, ok } from "../domain/result.js";
|
|
6
|
+
import { createNativeUiHelperRuntime } from "./NativeUiHelperRuntime.js";
|
|
7
|
+
const helper = fileURLToPath(new URL("../../bridge/native/ReaNativeUI.swift", import.meta.url));
|
|
8
|
+
const responseSchema = z.discriminatedUnion("ok", [
|
|
9
|
+
z.strictObject({ ok: z.literal(true), result: nativeUiSnapshotSchema }),
|
|
10
|
+
z.strictObject({
|
|
11
|
+
ok: z.literal(false),
|
|
12
|
+
code: z.string(),
|
|
13
|
+
message: z.string(),
|
|
14
|
+
}),
|
|
15
|
+
]);
|
|
16
|
+
/** Capture a selected existing app window and run explicitly selected scenarios. */
|
|
17
|
+
export const observeNativeUi = async (target, operation, parameters, options = {}) => {
|
|
18
|
+
const runtime = createNativeUiHelperRuntime();
|
|
19
|
+
try {
|
|
20
|
+
return await observeWithHelper(target, operation, parameters, {
|
|
21
|
+
...options,
|
|
22
|
+
invoke: options.invoke ?? runtime.invoke,
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
finally {
|
|
26
|
+
await runtime.close();
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
const observeWithHelper = async (target, operation, parameters, options) => {
|
|
30
|
+
const parsed = (operation === "observe_native_ui"
|
|
31
|
+
? nativeUiObservationInputSchema
|
|
32
|
+
: nativeUiScenarioInputSchema).safeParse(parameters);
|
|
33
|
+
if (!parsed.success)
|
|
34
|
+
return err(new AnalysisInputError(operation, { cause: parsed.error }));
|
|
35
|
+
if (target.kind !== "executable" || target.format !== "mach-o")
|
|
36
|
+
return err(new AnalysisCapabilityUnavailableError("native-macos", operation, "Native UI observation requires an active Mach-O executable or app target"));
|
|
37
|
+
const input = parsed.data;
|
|
38
|
+
if (!input.screenshot && !input.accessibility)
|
|
39
|
+
return err(new AnalysisInputError(operation, {
|
|
40
|
+
cause: new Error("Enable screenshot or accessibility capture"),
|
|
41
|
+
}));
|
|
42
|
+
const steps = operation === "capture_native_ui_scenario"
|
|
43
|
+
? nativeUiScenarioInputSchema.parse(parameters).steps
|
|
44
|
+
: [];
|
|
45
|
+
const signal = options.signal === undefined
|
|
46
|
+
? AbortSignal.timeout(180_000)
|
|
47
|
+
: AbortSignal.any([options.signal, AbortSignal.timeout(180_000)]);
|
|
48
|
+
const invoke = options.invoke;
|
|
49
|
+
let launchTime;
|
|
50
|
+
let outputBytes = 0;
|
|
51
|
+
const take = async (action) => {
|
|
52
|
+
if (signal.aborted)
|
|
53
|
+
return err(new AnalysisCancelledError(operation));
|
|
54
|
+
try {
|
|
55
|
+
const response = responseSchema.parse(await invoke({
|
|
56
|
+
pid: input.pid,
|
|
57
|
+
window_id: input.window_id,
|
|
58
|
+
executable: target.path,
|
|
59
|
+
sha256: target.sha256,
|
|
60
|
+
...(launchTime === undefined ? {} : { launch_time: launchTime }),
|
|
61
|
+
screenshot: input.screenshot,
|
|
62
|
+
accessibility: input.accessibility,
|
|
63
|
+
max_nodes: input.max_nodes,
|
|
64
|
+
...(action === undefined ? {} : { action }),
|
|
65
|
+
}, signal));
|
|
66
|
+
if (!response.ok)
|
|
67
|
+
return err(new AnalysisCapabilityUnavailableError("native-macos", operation, `${response.code}: ${response.message}`));
|
|
68
|
+
if (response.result.window.pid !== input.pid ||
|
|
69
|
+
response.result.window.window_id !== input.window_id ||
|
|
70
|
+
response.result.window.executable !== target.path ||
|
|
71
|
+
(launchTime !== undefined &&
|
|
72
|
+
response.result.window.launch_time !== launchTime))
|
|
73
|
+
return err(new AnalysisCapabilityUnavailableError("native-macos", operation, "Native helper returned a different target process or window"));
|
|
74
|
+
launchTime = response.result.window.launch_time;
|
|
75
|
+
outputBytes += 2 * Buffer.byteLength(JSON.stringify(response.result));
|
|
76
|
+
if (outputBytes > 64 * 1024 * 1024)
|
|
77
|
+
return err(new AnalysisCapabilityUnavailableError("native-macos", operation, "Scenario captures exceeded the 64 MiB output budget"));
|
|
78
|
+
return ok(response.result);
|
|
79
|
+
}
|
|
80
|
+
catch (cause) {
|
|
81
|
+
return err(signal.aborted
|
|
82
|
+
? new AnalysisCancelledError(operation)
|
|
83
|
+
: new ProviderAdapterError("native-macos", operation, {
|
|
84
|
+
cause,
|
|
85
|
+
diagnostics: {
|
|
86
|
+
helper_path: helper,
|
|
87
|
+
reason: "Native helper failed, timed out, or returned malformed capture data; install compatible Xcode command-line tools and inspect local OS permissions",
|
|
88
|
+
},
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const initial = await take();
|
|
93
|
+
if (!initial.ok)
|
|
94
|
+
return initial;
|
|
95
|
+
const results = [];
|
|
96
|
+
let before = initial.value;
|
|
97
|
+
for (const [index, step] of steps.entries()) {
|
|
98
|
+
if (signal.aborted) {
|
|
99
|
+
results.push({
|
|
100
|
+
index,
|
|
101
|
+
kind: step.kind,
|
|
102
|
+
before,
|
|
103
|
+
after: null,
|
|
104
|
+
outcome: "cancelled",
|
|
105
|
+
reason: "Scenario cancelled before action",
|
|
106
|
+
});
|
|
107
|
+
break;
|
|
108
|
+
}
|
|
109
|
+
if (step.kind === "wait") {
|
|
110
|
+
try {
|
|
111
|
+
await new Promise((resolve, reject) => {
|
|
112
|
+
const abort = () => {
|
|
113
|
+
clearTimeout(timer);
|
|
114
|
+
reject(new Error("cancelled"));
|
|
115
|
+
};
|
|
116
|
+
const timer = setTimeout(() => {
|
|
117
|
+
signal.removeEventListener("abort", abort);
|
|
118
|
+
resolve();
|
|
119
|
+
}, step.milliseconds);
|
|
120
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
121
|
+
if (signal.aborted)
|
|
122
|
+
abort();
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
catch {
|
|
126
|
+
results.push({
|
|
127
|
+
index,
|
|
128
|
+
kind: step.kind,
|
|
129
|
+
before,
|
|
130
|
+
after: null,
|
|
131
|
+
outcome: "cancelled",
|
|
132
|
+
reason: "Scenario cancelled during wait",
|
|
133
|
+
});
|
|
134
|
+
break;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const after = await take(step.kind === "wait" ? undefined : step);
|
|
138
|
+
if (!after.ok) {
|
|
139
|
+
results.push({
|
|
140
|
+
index,
|
|
141
|
+
kind: step.kind,
|
|
142
|
+
before,
|
|
143
|
+
after: null,
|
|
144
|
+
outcome: after.error._tag === "AnalysisCancelledError"
|
|
145
|
+
? "cancelled"
|
|
146
|
+
: "failed",
|
|
147
|
+
reason: after.error.message,
|
|
148
|
+
});
|
|
149
|
+
break;
|
|
150
|
+
}
|
|
151
|
+
results.push({
|
|
152
|
+
index,
|
|
153
|
+
kind: step.kind,
|
|
154
|
+
before,
|
|
155
|
+
after: after.value,
|
|
156
|
+
outcome: "completed",
|
|
157
|
+
reason: null,
|
|
158
|
+
});
|
|
159
|
+
before = after.value;
|
|
160
|
+
}
|
|
161
|
+
return ok(nativeUiResultSchema.parse({
|
|
162
|
+
target_sha256: target.sha256,
|
|
163
|
+
initial: initial.value,
|
|
164
|
+
steps: results,
|
|
165
|
+
restore: "leave-as-is",
|
|
166
|
+
limitations: [
|
|
167
|
+
"Only the explicitly selected already-running process/window is admitted. REA starts no target process and does not change permissions, foreground applications, or restore application data.",
|
|
168
|
+
"Click uses AXPress; scroll uses AXIncrement/AXDecrement; key-entry sets the selected element's AXValue. Unsupported elements fail without global event fallback.",
|
|
169
|
+
"Each completed action is followed immediately by capture; delayed UI changes require explicit wait steps. A failed after-capture can follow a completed action, so failure does not prove absence of application effects.",
|
|
170
|
+
"Scenarios can change app data, cause app network activity and persist changes. The caller explicitly chooses leave-as-is; automatic restoration is unsupported.",
|
|
171
|
+
"Window matching uses exact PID and window ID for screenshots and unique accessibility geometry. Accessibility paths can change as the UI changes; stale or ambiguous paths fail. Screenshots are scaled to at most 2048 pixels; scenario output is budgeted at 64 MiB and execution is cancelled after 180 seconds.",
|
|
172
|
+
],
|
|
173
|
+
}));
|
|
174
|
+
};
|
|
@@ -51,5 +51,8 @@ const splitAlgorithms = (value) => value === undefined
|
|
|
51
51
|
const parseRuntime = (value) => {
|
|
52
52
|
if (value === undefined)
|
|
53
53
|
return null;
|
|
54
|
-
|
|
54
|
+
const flags = /(?:^|\s)flags=[^(]*\(([^)]*)\)/u.exec(value)?.[1];
|
|
55
|
+
if (flags === undefined)
|
|
56
|
+
return null;
|
|
57
|
+
return flags.split(",").some((flag) => flag.trim() === "runtime");
|
|
55
58
|
};
|
|
@@ -1,25 +1,51 @@
|
|
|
1
|
-
/**
|
|
2
|
-
export const parseDyldSymbols = (output, mode
|
|
3
|
-
const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
1
|
+
/** Decode Apple dyld inventory rows, projecting export offsets to VM addresses. */
|
|
2
|
+
export const parseDyldSymbols = (output, mode, imageBase = null) => {
|
|
3
|
+
const offsets = /^\s*offset\s+symbol\s*$/mu.test(output);
|
|
4
|
+
return output.split(/\r?\n/u).flatMap((rawLine) => {
|
|
5
|
+
const line = rawLine.trim();
|
|
6
|
+
if (mode === "imports") {
|
|
7
|
+
const imported = /^(?:0x[\da-f]+\s+)?(\S+)(?:\s+\[([^\]]+)\])?\s+\(from (.+)\)$/iu.exec(line);
|
|
8
|
+
if (imported?.[1] !== undefined)
|
|
9
|
+
return [
|
|
10
|
+
{
|
|
11
|
+
name: imported[1],
|
|
12
|
+
address: null,
|
|
13
|
+
weak: /\bweak-import\b/u.test(imported[2] ?? "") ? true : null,
|
|
14
|
+
reexport: null,
|
|
15
|
+
source: imported[3] ?? null,
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
return [];
|
|
19
|
+
}
|
|
20
|
+
const reexport = /^\[re-export\]\s+(\S+)(?:\s+\(from (.+)\))?$/u.exec(line);
|
|
21
|
+
if (reexport?.[1] !== undefined)
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
name: reexport[1],
|
|
25
|
+
address: null,
|
|
26
|
+
weak: null,
|
|
27
|
+
reexport: true,
|
|
28
|
+
source: reexport[2] ?? null,
|
|
29
|
+
},
|
|
30
|
+
];
|
|
31
|
+
const exported = /^(0x[\da-f]+)\s+(\S+)(?:\s+\[([^\]]+)\])?$/iu.exec(line);
|
|
32
|
+
if (exported?.[1] === undefined || exported[2] === undefined)
|
|
33
|
+
return [];
|
|
34
|
+
const absolute = /\babsolute\b/u.test(exported[3] ?? "");
|
|
35
|
+
const address = offsets && !absolute
|
|
36
|
+
? imageBase === null
|
|
37
|
+
? null
|
|
38
|
+
: `0x${(BigInt(imageBase) + BigInt(exported[1])).toString(16)}`
|
|
39
|
+
: canonicalHex(exported[1]);
|
|
40
|
+
return [
|
|
41
|
+
{
|
|
42
|
+
name: exported[2],
|
|
43
|
+
address,
|
|
44
|
+
weak: /\bweak-def\b/u.test(exported[3] ?? "") ? true : null,
|
|
45
|
+
reexport: false,
|
|
46
|
+
source: null,
|
|
47
|
+
},
|
|
48
|
+
];
|
|
49
|
+
});
|
|
50
|
+
};
|
|
51
|
+
const canonicalHex = (value) => value === undefined ? null : `0x${BigInt(value).toString(16)}`;
|