reverseport 0.0.0-stage → 1.2.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/DISCLAIMER.md +136 -0
- package/LICENSE +22 -0
- package/README.md +289 -2
- package/RESPONSIBLE-USE.md +22 -0
- package/THIRD_PARTY_NOTICES.md +130 -0
- package/bin/reverseport.mjs +136 -0
- package/bridge/android/ReaJadxBridge.java +270 -0
- package/bridge/ghidra/ReaGhidraAnalysisOptions.java +38 -0
- package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
- package/bridge/ghidra/ReaGhidraBridge.java +3858 -0
- package/bridge/ghidra/ReaGhidraBundleActivator.java +14 -0
- package/bridge/ghidra/ReaGhidraExtensions.java +113 -0
- package/bridge/ghidra/ReaGhidraMipsSoftFloat.java +176 -0
- package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
- package/bridge/ghidra/ReaGhidraPrepareCom.java +32 -0
- package/bridge/ghidra/ReaGhidraPrepareRaw.java +36 -0
- package/bridge/hopper_bridge.py +1162 -0
- package/bridge/mitmproxy/capture.py +208 -0
- package/bridge/native/NativeUIChildren.swift +27 -0
- package/bridge/native/ReaNativeUI.swift +171 -0
- package/bridge/native/rea_lldb_tracer.py +839 -0
- package/bridge/process/ProcessRunTokenReader.swift +339 -0
- package/bridge/process/ProcessRunTokenReaderMain.swift +35 -0
- package/bridge/pwndbg/core_context.py +101 -0
- package/bridge/pwndbg/launch.py +39 -0
- package/bridge/pwndbg/launch_impl.py +34 -0
- package/bridge/pwntools/decoder_runtime.py +59 -0
- package/bridge/pwntools/layout.py +39 -0
- package/bridge/pwntools/layout_impl.py +314 -0
- package/bridge/pwntools/recorded_crash.py +39 -0
- package/bridge/pwntools/recorded_crash_impl.py +147 -0
- package/dist/adb/AdbConfiguration.js +88 -0
- package/dist/adb/AdbDeviceOutput.js +191 -0
- package/dist/adb/AdbDirectoryListing.js +80 -0
- package/dist/adb/AdbHostFileName.js +34 -0
- package/dist/adb/AdbProvider.js +1227 -0
- package/dist/adb/AdbShellOutput.js +267 -0
- package/dist/android/AndroidTargetSnapshot.js +118 -0
- package/dist/android/JadxAnalysis.js +201 -0
- package/dist/android/JadxConfiguration.js +320 -0
- package/dist/android/JadxMcpTransport.js +188 -0
- package/dist/android/JadxProtocol.js +115 -0
- package/dist/android/JadxProvider.js +337 -0
- package/dist/android/JadxRelease.js +27 -0
- package/dist/android/JadxSession.js +172 -0
- package/dist/apktool/ApktoolConfiguration.js +120 -0
- package/dist/apktool/ApktoolDecodeOutput.js +142 -0
- package/dist/apktool/ApktoolProvider.js +522 -0
- package/dist/application/AnalysisContextQueries.js +128 -0
- package/dist/application/AnalysisDocument.js +32 -0
- package/dist/application/AnalysisProvider.js +27 -0
- package/dist/application/AppBundleExecutable.js +192 -0
- package/dist/application/BinaryTargetResolver.js +356 -0
- package/dist/application/BrowserEvidence.js +127 -0
- package/dist/application/BrowserObservationPort.js +1 -0
- package/dist/application/BrowserObservationService.js +86 -0
- package/dist/application/BrowserScenarioCapturePort.js +1 -0
- package/dist/application/BrowserScenarioCaptureService.js +17 -0
- package/dist/application/BrowserScenarioEvidence.js +28 -0
- package/dist/application/CallPathTracing.js +182 -0
- package/dist/application/CapabilityClientRequirements.js +17 -0
- package/dist/application/CapabilityInventory.js +525 -0
- package/dist/application/ClientConfigPath.js +35 -0
- package/dist/application/ClientConfigurationDocument.js +1196 -0
- package/dist/application/ClientConfigurationFiles.js +91 -0
- package/dist/application/ClientRegistrationEnvironment.js +39 -0
- package/dist/application/ClientRegistrationIdentity.js +80 -0
- package/dist/application/ClientRegistrationStatus.js +233 -0
- package/dist/application/DirectAnalysis.js +371 -0
- package/dist/application/DirectAnalysisCleanup.js +71 -0
- package/dist/application/DirectAnalysisDependencies.js +1 -0
- package/dist/application/DirectAnalysisStatus.js +22 -0
- package/dist/application/Doctor.js +349 -0
- package/dist/application/DoctorDiagnostics.js +169 -0
- package/dist/application/DoctorProviderIds.js +2 -0
- package/dist/application/DoctorScope.js +113 -0
- package/dist/application/DshCordisPatch.js +342 -0
- package/dist/application/DshCordisYaml.js +155 -0
- package/dist/application/EnhancedLiteralTracing.js +88 -0
- package/dist/application/EnhancedToolTypes.js +4 -0
- package/dist/application/EnhancedTools.js +428 -0
- package/dist/application/EvidenceBundleCommands.js +70 -0
- package/dist/application/EvidenceBundleFiles.js +79 -0
- package/dist/application/EvidenceInputResolver.js +30 -0
- package/dist/application/FunctionAnalysisEvidence.js +34 -0
- package/dist/application/GeminiClientSettings.js +139 -0
- package/dist/application/HermesClientHome.js +115 -0
- package/dist/application/HopperDownload.js +39 -0
- package/dist/application/InventoryProjectionEvidence.js +44 -0
- package/dist/application/InvestigationProviders.js +130 -0
- package/dist/application/JsonFiles.js +225 -0
- package/dist/application/JsonInputFile.js +410 -0
- package/dist/application/LinuxHopper.js +232 -0
- package/dist/application/MacHopper.js +235 -0
- package/dist/application/MipsElfMetadata.js +175 -0
- package/dist/application/MipsElfSharedLoad.js +164 -0
- package/dist/application/OptionalObservationProviders.js +3 -0
- package/dist/application/ProcedureAddressResolution.js +11 -0
- package/dist/application/ProgressReporter.js +30 -0
- package/dist/application/ProviderOperationExecution.js +31 -0
- package/dist/application/RealHopperAssertions.js +135 -0
- package/dist/application/ReconstructionCoverageService.js +22 -0
- package/dist/application/ReconstructionObligationAuthority.js +72 -0
- package/dist/application/ReconstructionObligationCandidates.js +286 -0
- package/dist/application/ReconstructionObligationLedgerDiagnostics.js +47 -0
- package/dist/application/ReconstructionObligationLedgerEvaluation.js +238 -0
- package/dist/application/ReconstructionObligationLedgerProjection.js +15 -0
- package/dist/application/ReconstructionObligationLedgerService.js +54 -0
- package/dist/application/ReconstructionObligationOriginalCases.js +34 -0
- package/dist/application/ReconstructionObligationPolicies.js +132 -0
- package/dist/application/ReferenceSourceImport.js +200 -0
- package/dist/application/ReferenceSourceImportEntries.js +151 -0
- package/dist/application/ReferenceSourceImportPolicy.js +125 -0
- package/dist/application/ReferenceSourceImportTypes.js +47 -0
- package/dist/application/ReferenceSourceVcsAdapter.js +180 -0
- package/dist/application/RegularFileRead.js +120 -0
- package/dist/application/Setup.js +408 -0
- package/dist/application/SetupClientConfiguration.js +314 -0
- package/dist/application/SetupClients.js +44 -0
- package/dist/application/SetupHost.js +203 -0
- package/dist/application/SetupInstallFailure.js +77 -0
- package/dist/application/SetupPlan.js +210 -0
- package/dist/application/SetupRegistrationEnvironment.js +5 -0
- package/dist/application/SetupSkill.js +248 -0
- package/dist/application/SetupTypes.js +17 -0
- package/dist/application/SupportedClients.js +469 -0
- package/dist/application/TypeScriptEmittedSourceCandidates.js +23 -0
- package/dist/application/Uninstall.js +452 -0
- package/dist/application/UninstallFailure.js +14 -0
- package/dist/application/Update.js +137 -0
- package/dist/application/UpdateFailure.js +17 -0
- package/dist/application/UpdateMaintenance.js +111 -0
- package/dist/application/UpdateRuntime.js +264 -0
- package/dist/application/Utf8JsonInput.js +71 -0
- package/dist/application/ValidateSelectedWebScript.js +27 -0
- package/dist/application/WebModulePorts.js +1 -0
- package/dist/application/WebModuleTraceService.js +214 -0
- package/dist/application/WebNetworkCapturePort.js +1 -0
- package/dist/application/WebNetworkCaptureService.js +134 -0
- package/dist/application/WebRuntimePort.js +1 -0
- package/dist/application/WebRuntimeService.js +75 -0
- package/dist/application/WebScriptArtifactPort.js +1 -0
- package/dist/application/WebScriptExportService.js +214 -0
- package/dist/application/WebSourceLocationPorts.js +1 -0
- package/dist/application/WebSourceLocationService.js +177 -0
- package/dist/application/WindowsCapabilities.js +87 -0
- package/dist/application/WorkflowEvidence.js +105 -0
- package/dist/application/XrefsAddressResolution.js +45 -0
- package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
- package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
- package/dist/application/analysisView/AnalysisViewService.js +133 -0
- package/dist/application/android/AndroidAnalysisPort.js +1 -0
- package/dist/application/android/AndroidAnalysisService.js +37 -0
- package/dist/application/android/AndroidApplicationService.js +17 -0
- package/dist/application/android/AndroidSearchEvidenceSummary.js +100 -0
- package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
- package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
- package/dist/application/apple/AppleApplicationService.js +17 -0
- package/dist/application/artifacts/ArtifactExtractionDestination.js +5 -0
- package/dist/application/binary/AbortablePromise.js +28 -0
- package/dist/application/binary/AnalysisClientCleanup.js +15 -0
- package/dist/application/binary/AnalysisProviderEvaluation.js +77 -0
- package/dist/application/binary/AnalysisProviderRegistry.js +235 -0
- package/dist/application/binary/AnalysisSnapshotCache.js +232 -0
- package/dist/application/binary/AnalysisSnapshotFiles.js +96 -0
- package/dist/application/binary/BinarySession.js +605 -0
- package/dist/application/binary/BinarySessionComposition.js +9 -0
- package/dist/application/binary/BinarySessionExecution.js +66 -0
- package/dist/application/binary/BinarySessionOpen.js +66 -0
- package/dist/application/binary/BinarySessionPort.js +1 -0
- package/dist/application/binary/BinarySessionRecords.js +216 -0
- package/dist/application/binary/BinarySessionStatus.js +219 -0
- package/dist/application/binary/BinaryTargetSummary.js +9 -0
- package/dist/application/binary/CompositeProvider.js +103 -0
- package/dist/application/binary/LazyAnalysisProvider.js +105 -0
- package/dist/application/binary/SessionProviderRouter.js +118 -0
- package/dist/application/binaryDiagnostics/BinaryLayoutPort.js +1 -0
- package/dist/application/binaryDiagnostics/BinaryLayoutService.js +60 -0
- package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
- package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
- package/dist/application/binaryDiagnostics/RecordedCrashPort.js +1 -0
- package/dist/application/binaryDiagnostics/RecordedCrashService.js +63 -0
- package/dist/application/evm/EvmInterfacePort.js +1 -0
- package/dist/application/evm/EvmInterfaceService.js +67 -0
- package/dist/application/firmware/FirmwareAnalysisPort.js +1 -0
- package/dist/application/firmware/FirmwareAnalysisService.js +38 -0
- package/dist/application/go/GoBinaryPort.js +1 -0
- package/dist/application/go/GoBinaryService.js +77 -0
- package/dist/application/harmony/HarmonyApplicationService.js +17 -0
- package/dist/application/homebrew.js +67 -0
- package/dist/application/investigation/EvidenceLedger.js +338 -0
- package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
- package/dist/application/investigation/InvestigationRecordPort.js +1 -0
- package/dist/application/investigation/InvestigationRecords.js +65 -0
- package/dist/application/investigation/UnknownEvidence.js +37 -0
- package/dist/application/javascript/ElectronActiveEvidence.js +29 -0
- package/dist/application/javascript/ElectronActiveObservationPort.js +1 -0
- package/dist/application/javascript/ElectronActiveObservationService.js +51 -0
- package/dist/application/javascript/ElectronBoundaryAnalysis.js +118 -0
- package/dist/application/javascript/ElectronBoundaryGraph.js +11 -0
- package/dist/application/javascript/ElectronBoundaryGraphCallPaths.js +134 -0
- package/dist/application/javascript/ElectronBoundaryGraphContext.js +63 -0
- package/dist/application/javascript/ElectronBoundaryGraphIpc.js +261 -0
- package/dist/application/javascript/ElectronBoundaryGraphNative.js +102 -0
- package/dist/application/javascript/ElectronBoundaryGraphWindows.js +224 -0
- package/dist/application/javascript/ElectronEvidence.js +37 -0
- package/dist/application/javascript/ElectronObservationPort.js +1 -0
- package/dist/application/javascript/ElectronObservationService.js +26 -0
- package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +49 -0
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +173 -0
- package/dist/application/javascript/JavaScriptApplicationService.js +170 -0
- package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +67 -0
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +194 -0
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +431 -0
- package/dist/application/javascript/JavaScriptArtifactAnalysisTypes.js +1 -0
- package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +89 -0
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +193 -0
- package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +229 -0
- package/dist/application/javascript/JavaScriptArtifactGraphContext.js +194 -0
- package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +160 -0
- package/dist/application/javascript/JavaScriptArtifactGraphEvidence.js +85 -0
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +349 -0
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +424 -0
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +836 -0
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +245 -0
- package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +12 -0
- package/dist/application/javascript/JavaScriptJsonModules.js +40 -0
- package/dist/application/javascript/JavaScriptModuleRelationships.js +304 -0
- package/dist/application/javascript/JavaScriptRecoveryPort.js +1 -0
- package/dist/application/javascript/JavaScriptRecoveryService.js +77 -0
- package/dist/application/javascript/JavaScriptRuntimeObservationEvidence.js +36 -0
- package/dist/application/javascript/JavaScriptRuntimeObservationPort.js +1 -0
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +28 -0
- package/dist/application/javascript/JavaScriptRuntimeReconciliationEvidence.js +24 -0
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +52 -0
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +163 -0
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +527 -0
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +165 -0
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +156 -0
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +216 -0
- package/dist/application/javascript/JavaScriptSemanticGraphElectronProjection.js +61 -0
- package/dist/application/javascript/JavaScriptSemanticGraphEvidence.js +86 -0
- package/dist/application/javascript/JavaScriptSemanticGraphFingerprintProjection.js +25 -0
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +183 -0
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +112 -0
- package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +144 -0
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +58 -0
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +136 -0
- package/dist/application/javascript/JavaScriptSemanticTraceService.js +41 -0
- package/dist/application/jeb/JebAnalysisPort.js +1 -0
- package/dist/application/jeb/JebAnalysisService.js +13 -0
- package/dist/application/managed/ManagedApplicationGraphService.js +55 -0
- package/dist/application/managed/ManagedMemberComparisonService.js +125 -0
- package/dist/application/managed/ManagedNativeVerificationService.js +40 -0
- package/dist/application/managed/ManagedReconstructionService.js +59 -0
- package/dist/application/native/NativeApiInspection.js +77 -0
- package/dist/application/native/NativeCallRoutes.js +73 -0
- package/dist/application/native/NativeDispatchMetadataInspection.js +33 -0
- package/dist/application/native/NativeUiActionTrace.js +427 -0
- package/dist/application/native/NativeValueTrace.js +340 -0
- package/dist/application/process/ProcessCli.js +190 -0
- package/dist/application/process/ProcessEvidence.js +30 -0
- package/dist/application/wasm/WasmArtifactPort.js +1 -0
- package/dist/application/wasm/WasmArtifactService.js +72 -0
- package/dist/application/workflowInputError.js +18 -0
- package/dist/artifacts/ArtifactHash.js +29 -0
- package/dist/artifacts/ArtifactPaths.js +167 -0
- package/dist/artifacts/ArtifactProvider.js +280 -0
- package/dist/artifacts/ArtifactProviderMetadata.js +34 -0
- package/dist/artifacts/ArtifactReader.js +77 -0
- package/dist/artifacts/ArtifactResourceScope.js +103 -0
- package/dist/artifacts/AsarArtifactReader.js +518 -0
- package/dist/artifacts/AsarEntryStream.js +76 -0
- package/dist/artifacts/AsarHeader.js +24 -0
- package/dist/artifacts/DirectoryArtifactReader.js +292 -0
- package/dist/artifacts/MachOSliceArtifactReader.js +342 -0
- package/dist/artifacts/NativeDmgArtifactReader.js +508 -0
- package/dist/artifacts/NativeDmgOwnership.js +109 -0
- package/dist/artifacts/SafeOutputTree.js +394 -0
- package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
- package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
- package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
- package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
- package/dist/artifacts/StreamBytes.js +10 -0
- package/dist/artifacts/ZipArtifactReader.js +222 -0
- package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +190 -0
- package/dist/artifacts/apple/DylibResolutionReader.js +269 -0
- package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +500 -0
- package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +233 -0
- package/dist/artifacts/apple/KeyedArchiveReader.js +163 -0
- package/dist/artifacts/apple/MachoLoadCommandReader.js +393 -0
- package/dist/artifacts/apple/NibArchive.js +338 -0
- package/dist/artifacts/apple/NibViewHierarchy.js +157 -0
- package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
- package/dist/artifacts/extraction/ArtifactExtraction.js +253 -0
- package/dist/artifacts/hostExecutableMarking.js +16 -0
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +343 -0
- package/dist/artifacts/inventory/ArtifactInventory.js +16 -0
- package/dist/artifacts/inventory/classify.js +94 -0
- package/dist/artifacts/inventory/hashStableRootArtifact.js +70 -0
- package/dist/artifacts/inventory/reader.js +40 -0
- package/dist/artifacts/inventory/scanCanonical.js +213 -0
- package/dist/artifacts/inventory/scanReader.js +169 -0
- package/dist/artifacts/inventory/types.js +3 -0
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +317 -0
- package/dist/artifacts/javascript/JavaScriptArtifactReader.js +6 -0
- package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
- package/dist/artifacts/readStableArtifact.js +68 -0
- package/dist/browser/BrowserProcessStartup.js +89 -0
- package/dist/browser/BrowserScenarioPartialObservation.js +127 -0
- package/dist/browser/BrowserScenarioSecrets.js +137 -0
- package/dist/browser/BrowserScenarioSessionPort.js +1 -0
- package/dist/browser/CdpAuthorizedMainFrame.js +16 -0
- package/dist/browser/CdpAuthorizedTarget.js +22 -0
- package/dist/browser/CdpBrowserProvider.js +276 -0
- package/dist/browser/CdpCaptureCompleteness.js +92 -0
- package/dist/browser/CdpCaptureDocuments.js +375 -0
- package/dist/browser/CdpCaptureDomSvg.js +210 -0
- package/dist/browser/CdpCaptureEventBodyShapes.js +55 -0
- package/dist/browser/CdpCaptureEventHandlers.js +463 -0
- package/dist/browser/CdpCaptureEventHelpers.js +84 -0
- package/dist/browser/CdpCaptureEventState.js +1 -0
- package/dist/browser/CdpCaptureEventTypes.js +5 -0
- package/dist/browser/CdpCaptureEvents.js +199 -0
- package/dist/browser/CdpCaptureStorage.js +86 -0
- package/dist/browser/CdpCaptureStorageFingerprints.js +320 -0
- package/dist/browser/CdpCaptureValues.js +91 -0
- package/dist/browser/CdpCommandRejection.js +17 -0
- package/dist/browser/CdpConnection.js +303 -0
- package/dist/browser/CdpElectronInspection.js +253 -0
- package/dist/browser/CdpElectronProvider.js +115 -0
- package/dist/browser/CdpElectronScriptEvents.js +55 -0
- package/dist/browser/CdpElectronScripts.js +65 -0
- package/dist/browser/CdpElectronWorkers.js +57 -0
- package/dist/browser/CdpEndpoint.js +217 -0
- package/dist/browser/CdpObservationSession.js +332 -0
- package/dist/browser/CdpOptionalCommand.js +14 -0
- package/dist/browser/CdpPageCapture.js +278 -0
- package/dist/browser/CdpPageCaptureScripts.js +79 -0
- package/dist/browser/CdpPageCaptureWorkers.js +46 -0
- package/dist/browser/CdpSafeMetadata.js +284 -0
- package/dist/browser/CdpScreenshot.js +110 -0
- package/dist/browser/CdpTargetEvents.js +8 -0
- package/dist/browser/CdpTargetSession.js +65 -0
- package/dist/browser/CdpWebMcpDiscovery.js +361 -0
- package/dist/browser/ElectronFileScope.js +135 -0
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +301 -0
- package/dist/browser/PlaywrightElectronActiveActions.js +257 -0
- package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
- package/dist/browser/PlaywrightElectronActiveProvider.js +293 -0
- package/dist/browser/PlaywrightExecutionBoundary.js +53 -0
- package/dist/browser/PlaywrightScenarioActions.js +58 -0
- package/dist/browser/PlaywrightScenarioArtifacts.js +162 -0
- package/dist/browser/PlaywrightScenarioBrowser.js +412 -0
- package/dist/browser/PlaywrightScenarioEvents.js +253 -0
- package/dist/browser/PlaywrightScenarioSession.js +279 -0
- package/dist/browser/PlaywrightScenarioStorage.js +507 -0
- package/dist/browser/PngVisualDiff.js +380 -0
- package/dist/browser/WebSourceMapFetcher.js +718 -0
- package/dist/browser/assets/LocalWebScriptArtifacts.js +89 -0
- package/dist/browser/assets/PageScriptCapture.js +32 -0
- package/dist/browser/assets/PublishWebScripts.js +140 -0
- package/dist/browser/assets/ScenarioScriptCapture.js +73 -0
- package/dist/browser/assets/ScriptCaptureAdapters.js +57 -0
- package/dist/browser/assets/WebArtifactReads.js +78 -0
- package/dist/browser/assets/WebSourceLocationArtifacts.js +41 -0
- package/dist/browser/execution/CdpEventListeners.js +79 -0
- package/dist/browser/execution/CdpExecutionCapture.js +135 -0
- package/dist/browser/execution/CdpExecutionCollection.js +57 -0
- package/dist/browser/execution/CdpExecutionWindow.js +100 -0
- package/dist/browser/execution/CdpListenerSelector.js +22 -0
- package/dist/browser/execution/CdpPreciseCoverage.js +45 -0
- package/dist/browser/execution/CdpRuntimeInitiator.js +18 -0
- package/dist/browser/execution/CdpRuntimeProtocol.js +106 -0
- package/dist/browser/execution/CdpRuntimeRequests.js +81 -0
- package/dist/browser/execution/CdpRuntimeSession.js +163 -0
- package/dist/browser/execution/CdpRuntimeSources.js +223 -0
- package/dist/browser/execution/CdpWebRuntimeProvider.js +51 -0
- package/dist/browser/history/CaptureFailures.js +153 -0
- package/dist/browser/history/CaptureFormatError.js +10 -0
- package/dist/browser/history/CaptureRedaction.js +68 -0
- package/dist/browser/history/CaptureRelease.js +23 -0
- package/dist/browser/history/HarCapture.js +179 -0
- package/dist/browser/history/HarCaptureAdapter.js +23 -0
- package/dist/browser/history/HarCaptureProcess.js +49 -0
- package/dist/browser/history/HarJson.js +92 -0
- package/dist/browser/history/HarSchema.js +72 -0
- package/dist/browser/history/HistoricalCaptureDecoder.js +198 -0
- package/dist/browser/history/HistoricalCaptureFormatAdapter.js +1 -0
- package/dist/browser/history/MitmproxyCaptureAdapter.js +46 -0
- package/dist/browser/modules/NativeModuleResolver.js +277 -0
- package/dist/browser/modules/WebModuleArtifacts.js +41 -0
- package/dist/browser/network/PlaywrightNetworkContent.js +71 -0
- package/dist/browser/network/PlaywrightScenarioNetwork.js +180 -0
- package/dist/browser/providerIdentities.js +24 -0
- package/dist/catalogIdentity.js +65 -0
- package/dist/cli/adbCommands.js +337 -0
- package/dist/cli/analysisSelector.js +23 -0
- package/dist/cli/analysisViewCommands.js +74 -0
- package/dist/cli/androidCommands.js +91 -0
- package/dist/cli/apktoolCommands.js +53 -0
- package/dist/cli/applicationCommands.js +173 -0
- package/dist/cli/artifactCommands.js +160 -0
- package/dist/cli/binaryDiagnosticsCommands.js +57 -0
- package/dist/cli/browserAdvancedCommands.js +189 -0
- package/dist/cli/browserCommands.js +125 -0
- package/dist/cli/commandCancellation.js +24 -0
- package/dist/cli/coreAnalysisCommands.js +7 -0
- package/dist/cli/coreBinaryCommands.js +283 -0
- package/dist/cli/coreNativeCommands.js +269 -0
- package/dist/cli/electronCommands.js +150 -0
- package/dist/cli/evmCommands.js +33 -0
- package/dist/cli/firmwareCommands.js +61 -0
- package/dist/cli/goCommands.js +21 -0
- package/dist/cli/interactiveSetup.js +236 -0
- package/dist/cli/javascriptApplicationAnalysis.js +34 -0
- package/dist/cli/javascriptRecoveryCommands.js +59 -0
- package/dist/cli/jebCommands.js +99 -0
- package/dist/cli/jsonOutput.js +46 -0
- package/dist/cli/managedCommands.js +129 -0
- package/dist/cli/managedProjectGraphCommand.js +24 -0
- package/dist/cli/nativeCallCommands.js +33 -0
- package/dist/cli/omittableDefaults.js +50 -0
- package/dist/cli/options.js +33 -0
- package/dist/cli/processCommands.js +25 -0
- package/dist/cli/referenceSourceImportStatus.js +22 -0
- package/dist/cli/setupCommands.js +189 -0
- package/dist/cli/streamedJsonOutput.js +134 -0
- package/dist/cli/types.js +1 -0
- package/dist/cli/utilityCommands.js +226 -0
- package/dist/cli/wasmCommands.js +44 -0
- package/dist/cli/webModuleCommands.js +60 -0
- package/dist/cli/webNetworkCaptureCommands.js +40 -0
- package/dist/cli/webRuntimeCommands.js +60 -0
- package/dist/cli/webScriptCommands.js +50 -0
- package/dist/cli/webSourceLocationCommands.js +54 -0
- package/dist/cli-runtime/AnalysisProvider-CeyX2u-b.js +25 -0
- package/dist/cli-runtime/AnalysisSnapshotFiles-BuK_ymw5.js +523 -0
- package/dist/cli-runtime/ArtifactReader-BXkffc1D.js +55 -0
- package/dist/cli-runtime/ArtifactResourceScope-CZqLEfbb.js +108 -0
- package/dist/cli-runtime/AsarHeader-CnzOzYEH.js +31 -0
- package/dist/cli-runtime/BinaryTargetResolver-CKRfFhLj.js +965 -0
- package/dist/cli-runtime/BoundedFileBytes-BU30odTm.js +39 -0
- package/dist/cli-runtime/ClientConfigPath-c6jr6INc.js +36 -0
- package/dist/cli-runtime/ClientConfigurationDocument-D0ZqgTCv.js +1522 -0
- package/dist/cli-runtime/ClientRegistrationStatus-DGpwJ4ry.js +422 -0
- package/dist/cli-runtime/DirectAnalysis-DW3MvxW0.js +500 -0
- package/dist/cli-runtime/Doctor-CzwYS9nB.js +862 -0
- package/dist/cli-runtime/ElectronFileScope-C1hUEp36.js +1419 -0
- package/dist/cli-runtime/ExecFileOutput-Czbj-HpV.js +106 -0
- package/dist/cli-runtime/IdaConfiguration-rEjpuRQ1.js +854 -0
- package/dist/cli-runtime/InterfaceBuilderDecodeBudget-DT74BY9z.js +225 -0
- package/dist/cli-runtime/InventoryProjectionEvidence-Dt4Og45O.js +49 -0
- package/dist/cli-runtime/InvestigationProviders-D-QCy-4c.js +117 -0
- package/dist/cli-runtime/JavaScriptApplicationEvidenceGraph-CODAjVru.js +160 -0
- package/dist/cli-runtime/JavaScriptApplicationWorkflowEvidence-CCtwSg8r.js +75 -0
- package/dist/cli-runtime/JavaScriptWorkerMemoryLimit-CJeBSMPx.js +83 -0
- package/dist/cli-runtime/JsonFiles-Ce_O5NcH.js +708 -0
- package/dist/cli-runtime/ManagedSnapshot-DthWfmy9.js +3622 -0
- package/dist/cli-runtime/OwnedCommand-CnK8-h3N.js +106 -0
- package/dist/cli-runtime/PrivateRuntimeRoot-KNg6qLwo.js +237 -0
- package/dist/cli-runtime/ProcessOwnership-AOJaszxt.js +1310 -0
- package/dist/cli-runtime/ProviderDeadline-BSbNOmuW.js +89 -0
- package/dist/cli-runtime/RegularFile-CL6meBxi.js +114 -0
- package/dist/cli-runtime/RegularFileRead-BMh5FMXd.js +115 -0
- package/dist/cli-runtime/SafeOutputTree-D8z2Zrnu.js +512 -0
- package/dist/cli-runtime/SetupHost-CzzRF89z.js +842 -0
- package/dist/cli-runtime/SupportedClients-BrZ2qZVg.js +671 -0
- package/dist/cli-runtime/UninstallFailure-1blyKXHE.js +22 -0
- package/dist/cli-runtime/Update-DF55X_N2.js +143 -0
- package/dist/cli-runtime/UpdateFailure-BcFNxEZZ.js +24 -0
- package/dist/cli-runtime/WindowsBatchCommand-5gT-d7O4.js +45 -0
- package/dist/cli-runtime/ZipArtifactReader-Db65WuM_.js +380 -0
- package/dist/cli-runtime/analysisErrorCleanup-DaUQNiQd.js +32 -0
- package/dist/cli-runtime/analysisErrorPresentation-DZrKL8kS.js +331 -0
- package/dist/cli-runtime/application__DirectAnalysisStatus-OZFIFjZr.js +93 -0
- package/dist/cli-runtime/application__EnhancedTools-C__HAdqG.js +1728 -0
- package/dist/cli-runtime/application__FunctionAnalysisEvidence-fWSgvV74.js +41 -0
- package/dist/cli-runtime/application__ReconstructionCoverageService-DlNt-4TY.js +32 -0
- package/dist/cli-runtime/application__ReconstructionObligationLedgerService-CEpbUv-7.js +813 -0
- package/dist/cli-runtime/application__Setup-BExVGpqG.js +540 -0
- package/dist/cli-runtime/application__Uninstall-BVgWDCPN.js +349 -0
- package/dist/cli-runtime/application__UpdateRuntime-Dj6UIhHQ.js +358 -0
- package/dist/cli-runtime/application__android__AndroidApplicationService-CyynwW6Z.js +31 -0
- package/dist/cli-runtime/application__apple__AppleApplicationService-BNPcWeL8.js +31 -0
- package/dist/cli-runtime/application__harmony__HarmonyApplicationService-W66PwMvx.js +31 -0
- package/dist/cli-runtime/application__javascript__ElectronActiveObservationService-D8VbeCxz.js +85 -0
- package/dist/cli-runtime/application__javascript__ElectronObservationService-FmXFG4f2.js +63 -0
- package/dist/cli-runtime/application__javascript__JavaScriptApplicationService-D-dVrmAY.js +10467 -0
- package/dist/cli-runtime/application__javascript__JavaScriptApplicationWorkflowService-Cb0jmh8J.js +2284 -0
- package/dist/cli-runtime/application__javascript__JavaScriptRuntimeReconciliationService-D55gO7Gq.js +88 -0
- package/dist/cli-runtime/application__javascript__JavaScriptSemanticTraceService-DivM-Ym-.js +298 -0
- package/dist/cli-runtime/artifactOperationError-Wd0PRLIZ.js +27 -0
- package/dist/cli-runtime/artifacts__ArtifactProvider-B_4h3RAw.js +2091 -0
- package/dist/cli-runtime/binary-9Gt3vJ1P.js +12990 -0
- package/dist/cli-runtime/browserObservationError-D73SM55P.js +40 -0
- package/dist/cli-runtime/browserScenario-CTNr5ISp.js +5543 -0
- package/dist/cli-runtime/catalogIdentity-EYVhBUYJ.js +339 -0
- package/dist/cli-runtime/cli.js +28528 -0
- package/dist/cli-runtime/cliOutput-CoDmWVu5.js +98 -0
- package/dist/cli-runtime/cliOutput.js +5 -0
- package/dist/cli-runtime/composition__browserScenario-DNr3A_BM.js +2318 -0
- package/dist/cli-runtime/composition__electronObservation-DNw1f38M.js +550 -0
- package/dist/cli-runtime/composition__electronScenario-Cu7PX270.js +586 -0
- package/dist/cli-runtime/configurationErrors-ByuF6gMR.js +49 -0
- package/dist/cli-runtime/doctorRuntime-D5y43lEp.js +162 -0
- package/dist/cli-runtime/dosMz-pwwUuxyC.js +65 -0
- package/dist/cli-runtime/dotnet__ManagedStaticProvider-BSnWggeb.js +5 -0
- package/dist/cli-runtime/enhancedInputs-K8C_o3b4.js +56 -0
- package/dist/cli-runtime/javascriptApplicationGraph-DUWeec4O.js +940 -0
- package/dist/cli-runtime/javascriptExportReturnShapeProjection-BVbnAdOd.js +78 -0
- package/dist/cli-runtime/javascriptExportShapeComparisonSchemas-BzSil7ft.js +1153 -0
- package/dist/cli-runtime/javascriptRuntimeObservation-9xTNoKY2.js +1215 -0
- package/dist/cli-runtime/javascriptRuntimeReconciliation-CneBtMvx.js +1437 -0
- package/dist/cli-runtime/javascriptRuntimeReconciliationSchemas-D1Mrb_Y0.js +245 -0
- package/dist/cli-runtime/javascriptSemanticTraceSchemas-BHItrqIA.js +126 -0
- package/dist/cli-runtime/lipo-BCA3wVyN.js +365 -0
- package/dist/cli-runtime/logger-CKq3JfbZ.js +34 -0
- package/dist/cli-runtime/machoContainer-DxxkB2b0.js +52 -0
- package/dist/cli-runtime/managedApplicationGraph-BqOr01E6.js +1116 -0
- package/dist/cli-runtime/managedToolContracts-BSy4TRaK.js +80 -0
- package/dist/cli-runtime/mcpDoctor.js +342 -0
- package/dist/cli-runtime/mcpStartupPolicy-Bb7TMLzn.js +18 -0
- package/dist/cli-runtime/native__NativeMacOSProvider-BIG9iCcj.js +4415 -0
- package/dist/cli-runtime/plistValue-KM-SqiXe.js +47 -0
- package/dist/cli-runtime/propertyListKeys-DejfMb-U.js +86 -0
- package/dist/cli-runtime/providerAdapterError-SRSE_gzN.js +27 -0
- package/dist/cli-runtime/providerCleanupError-Do66qCEp.js +27 -0
- package/dist/cli-runtime/providerIdentities-Ao1XTvwx.js +31 -0
- package/dist/cli-runtime/providerOperationHealth-DSTcYPJe.js +577 -0
- package/dist/cli-runtime/providerStartupTimeout-Be8B1Ro8.js +16 -0
- package/dist/cli-runtime/readFileHandleChunks-dp60iZ6v.js +38 -0
- package/dist/cli-runtime/reconstructionObligationLedgerSchemas-dvp6PEnZ.js +15839 -0
- package/dist/cli-runtime/rolldown-runtime-DXoylpqc.js +121 -0
- package/dist/cli-runtime/runtimeVersion-CMGd0bDu.js +23 -0
- package/dist/cli-runtime/safeJson-DKKACtdy.js +25 -0
- package/dist/cli-runtime/scanCanonical-Bi6si9nb.js +2773 -0
- package/dist/cli-runtime/snapshotEnvironment-B5Ai0mha.js +678 -0
- package/dist/cli-runtime/streamedJsonOutput-VYlQZsM7.js +654 -0
- package/dist/cli-runtime/streamedJsonOutput.js +5 -0
- package/dist/cli-runtime/toolContracts-C7pvYKxF.js +4516 -0
- package/dist/cli-runtime/toolEffects-DW31yTSx.js +7004 -0
- package/dist/cli-runtime/workflowInputError-26EGiDpx.js +26 -0
- package/dist/cli.js +91 -0
- package/dist/cliBrowserContext.js +11 -0
- package/dist/cliBrowserScenarioCommands.js +73 -0
- package/dist/cliCommandNames.js +205 -0
- package/dist/cliEvidenceCommands.js +51 -0
- package/dist/cliJavaScriptRuntimeCommands.js +69 -0
- package/dist/cliJsonInput.js +129 -0
- package/dist/cliLogging.js +48 -0
- package/dist/cliObservationOptions.js +73 -0
- package/dist/cliOutput.js +97 -0
- package/dist/composition/adb.js +3 -0
- package/dist/composition/android.js +3 -0
- package/dist/composition/apktool.js +3 -0
- package/dist/composition/auxiliaryAnalysisProviders.js +35 -0
- package/dist/composition/binary.js +25 -0
- package/dist/composition/binaryDiagnostics.js +12 -0
- package/dist/composition/browserObservation.js +3 -0
- package/dist/composition/browserScenario.js +4 -0
- package/dist/composition/directAnalysis.js +44 -0
- package/dist/composition/electronObservation.js +3 -0
- package/dist/composition/electronScenario.js +3 -0
- package/dist/composition/evm.js +4 -0
- package/dist/composition/firmware.js +3 -0
- package/dist/composition/go.js +4 -0
- package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
- package/dist/composition/javascriptRecovery.js +3 -0
- package/dist/composition/javascriptRuntimeObservation.js +3 -0
- package/dist/composition/jeb.js +6 -0
- package/dist/composition/optionalObservationProviders.js +54 -0
- package/dist/composition/wasm.js +4 -0
- package/dist/composition/webModules.js +5 -0
- package/dist/composition/webNetworkCaptures.js +6 -0
- package/dist/composition/webRuntime.js +4 -0
- package/dist/composition/webSourceLocations.js +5 -0
- package/dist/config/environment.js +73 -0
- package/dist/config/ghidraDisabledAnalyzers.js +25 -0
- package/dist/config/ghidraLanguageOverride.js +9 -0
- package/dist/config/homeDirectory.js +12 -0
- package/dist/config/mcpInputSchemaProfile.js +27 -0
- package/dist/config/mcpResponseBudget.js +30 -0
- package/dist/config/parseConfig.js +93 -0
- package/dist/config/parsers.js +30 -0
- package/dist/config/providerStartupTimeout.js +13 -0
- package/dist/config/types.js +1 -0
- package/dist/contracts/adb/adbToolContracts.js +353 -0
- package/dist/contracts/advertisedInputExamples.js +48 -0
- package/dist/contracts/analysisDetail.js +13 -0
- package/dist/contracts/analysisSearchContract.js +14 -0
- package/dist/contracts/analysisViewApiSurfaceExample.js +68 -0
- package/dist/contracts/analysisViewToolContracts.js +76 -0
- package/dist/contracts/android/androidToolContracts.js +77 -0
- package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
- package/dist/contracts/applicationToolContracts.js +261 -0
- package/dist/contracts/artifactComparisonExample.js +86 -0
- package/dist/contracts/artifactToolContracts.js +68 -0
- package/dist/contracts/browserProviderToolContracts.js +7 -0
- package/dist/contracts/browserScenarioToolContracts.js +32 -0
- package/dist/contracts/browserToolContracts.js +256 -0
- package/dist/contracts/compactInputSchema.js +256 -0
- package/dist/contracts/enhancedInputs.js +74 -0
- package/dist/contracts/enhancedToolContracts.js +32 -0
- package/dist/contracts/errorSchemas.js +87 -0
- package/dist/contracts/evidenceInputContracts.js +13 -0
- package/dist/contracts/evm/evmToolContracts.js +20 -0
- package/dist/contracts/firmware/firmwareToolContracts.js +38 -0
- package/dist/contracts/functionComparisonExample.js +51 -0
- package/dist/contracts/functionInstructionContract.js +6 -0
- package/dist/contracts/functionWorkflowToolContracts.js +29 -0
- package/dist/contracts/go/goToolContracts.js +20 -0
- package/dist/contracts/hopperMemoryContracts.js +19 -0
- package/dist/contracts/inputSchemaPresentation.js +181 -0
- package/dist/contracts/investigationExamples.js +116 -0
- package/dist/contracts/javascript/applicationWorkflowInputContracts.js +52 -0
- package/dist/contracts/javascript/electronToolContracts.js +118 -0
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +85 -0
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +248 -0
- package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +35 -0
- package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +40 -0
- package/dist/contracts/javascript/javascriptRuntimeReconciliationExample.js +242 -0
- package/dist/contracts/jeb/jebToolContracts.js +64 -0
- package/dist/contracts/managed/managedToolContracts.js +87 -0
- package/dist/contracts/managed/managedWorkflowExamples.js +281 -0
- package/dist/contracts/managed/managedWorkflowToolContracts.js +165 -0
- package/dist/contracts/mobileApplicationGraphExamples.js +117 -0
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +65 -0
- package/dist/contracts/native/nativeToolContracts.js +77 -0
- package/dist/contracts/officialToolContracts.js +69 -0
- package/dist/contracts/promptContracts.js +253 -0
- package/dist/contracts/providerSelection.js +29 -0
- package/dist/contracts/reconstructionReadinessExample.js +438 -0
- package/dist/contracts/sessionLifecycleInputs.js +63 -0
- package/dist/contracts/sessionStatusContract.js +17 -0
- package/dist/contracts/sessionToolContracts.js +61 -0
- package/dist/contracts/sessionToolSchemas.js +51 -0
- package/dist/contracts/toolContractExamples.js +77 -0
- package/dist/contracts/toolContractHelpers.js +22 -0
- package/dist/contracts/toolContractTypes.js +18 -0
- package/dist/contracts/toolContracts.js +60 -0
- package/dist/contracts/toolEffects.js +544 -0
- package/dist/contracts/toolOutputSchemaGroups.js +411 -0
- package/dist/contracts/toolOutputSchemaPrimitives.js +532 -0
- package/dist/contracts/toolSchemaMetadata.js +197 -0
- package/dist/contracts/unknownContractExamples.js +31 -0
- package/dist/contracts/wasm/wasmToolContracts.js +24 -0
- package/dist/contracts/webNetworkCaptureToolContracts.js +24 -0
- package/dist/contracts/webRuntimeToolContracts.js +43 -0
- package/dist/contracts/webScriptToolContracts.js +68 -0
- package/dist/doctorRuntime.js +53 -0
- package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
- package/dist/domain/analysisErrorBase.js +58 -0
- package/dist/domain/analysisErrorCleanup.js +29 -0
- package/dist/domain/analysisErrorCore.js +123 -0
- package/dist/domain/analysisErrorPresentation.js +372 -0
- package/dist/domain/analysisErrorProjection.js +454 -0
- package/dist/domain/analysisProfile.js +50 -0
- package/dist/domain/analysisSnapshot.js +538 -0
- package/dist/domain/analysisView/WebNetworkApiSurfaceAccumulator.js +362 -0
- package/dist/domain/analysisView/analysisView.js +340 -0
- package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
- package/dist/domain/analysisView/binaryLayoutView.js +161 -0
- package/dist/domain/analysisView/javascriptApplicationView.js +245 -0
- package/dist/domain/analysisView/nativeFunctionView.js +155 -0
- package/dist/domain/analysisView/webNetworkApiSurfaceView.js +108 -0
- package/dist/domain/android/androidAnalysis.js +143 -0
- package/dist/domain/android/androidApplication.js +144 -0
- package/dist/domain/android/androidPartialObservation.js +36 -0
- package/dist/domain/apktool/apktoolResourceAnalysis.js +75 -0
- package/dist/domain/apple/appleApplication.js +315 -0
- package/dist/domain/apple/appleAssetCatalog.js +127 -0
- package/dist/domain/apple/appleBundleAnatomy.js +303 -0
- package/dist/domain/apple/dyldEnvironment.js +73 -0
- package/dist/domain/apple/dyldPaths.js +89 -0
- package/dist/domain/apple/dylibResolution.js +485 -0
- package/dist/domain/apple/dylibResolutionFindings.js +77 -0
- package/dist/domain/apple/interfaceBuilderGraph.js +403 -0
- package/dist/domain/apple/interfaceBuilderKeyedArchive.js +430 -0
- package/dist/domain/apple/keyedArchive.js +214 -0
- package/dist/domain/apple/machoContainer.js +54 -0
- package/dist/domain/apple/plistNumbers.js +76 -0
- package/dist/domain/apple/plistValue.js +35 -0
- package/dist/domain/artifactComparison.js +348 -0
- package/dist/domain/artifactGraph.js +213 -0
- package/dist/domain/artifactIdentity.js +57 -0
- package/dist/domain/artifactInspection.js +279 -0
- package/dist/domain/artifactIntegrityPolicy.js +10 -0
- package/dist/domain/artifactInventoryEvidence.js +166 -0
- package/dist/domain/artifactInventorySnapshot.js +1 -0
- package/dist/domain/artifactOperationError.js +20 -0
- package/dist/domain/artifactPartialObservation.js +1 -0
- package/dist/domain/artifactPathSyntax.js +75 -0
- package/dist/domain/binaryTarget.js +233 -0
- package/dist/domain/binaryTargetTypes.js +10 -0
- package/dist/domain/bridgeCandidateProjection.js +71 -0
- package/dist/domain/browserCaptureComparison.js +21 -0
- package/dist/domain/browserCompleteness.js +103 -0
- package/dist/domain/browserNetworkEvidence.js +92 -0
- package/dist/domain/browserObservation.js +187 -0
- package/dist/domain/browserObservationError.js +44 -0
- package/dist/domain/browserObservationErrors.js +1 -0
- package/dist/domain/browserObservationSchemas.js +327 -0
- package/dist/domain/browserScenario.js +61 -0
- package/dist/domain/browserScenarioCapture.js +76 -0
- package/dist/domain/browserScenarioCaptureValues.js +292 -0
- package/dist/domain/browserScenarioDiff.js +266 -0
- package/dist/domain/browserScenarioDiffEvidence.js +73 -0
- package/dist/domain/browserScenarioDiffValues.js +140 -0
- package/dist/domain/browserScenarioNormalization.js +40 -0
- package/dist/domain/browserScenarioValues.js +268 -0
- package/dist/domain/browserSession.js +55 -0
- package/dist/domain/bundleComparison.js +243 -0
- package/dist/domain/callPath.js +301 -0
- package/dist/domain/callPathSchemas.js +89 -0
- package/dist/domain/canonicalDigest.js +83 -0
- package/dist/domain/canonicalJsonDigestSteps.js +155 -0
- package/dist/domain/canonicalOrdering.js +3 -0
- package/dist/domain/changedBehavior.js +282 -0
- package/dist/domain/compactStringIdentity.js +9 -0
- package/dist/domain/comparisonSemantics.js +12 -0
- package/dist/domain/comparisonSourceEvidence.js +40 -0
- package/dist/domain/comparisonStatus.js +11 -0
- package/dist/domain/completionLedgerGeneration.js +186 -0
- package/dist/domain/configurationErrors.js +37 -0
- package/dist/domain/conformancePackage.js +200 -0
- package/dist/domain/conformanceReplay.js +132 -0
- package/dist/domain/conformanceTrustGate.js +319 -0
- package/dist/domain/digests.js +27 -0
- package/dist/domain/dosCom.js +8 -0
- package/dist/domain/dosMz.js +83 -0
- package/dist/domain/emptyArraySchema.js +3 -0
- package/dist/domain/evidence.js +305 -0
- package/dist/domain/evidenceBundle.js +413 -0
- package/dist/domain/evidenceCompletionLedger.js +113 -0
- package/dist/domain/evidenceErrors.js +46 -0
- package/dist/domain/evidenceRecordSummary.js +144 -0
- package/dist/domain/evm/evmInterface.js +61 -0
- package/dist/domain/explicitSensitiveFailure.js +108 -0
- package/dist/domain/explicitSensitiveValues.js +10 -0
- package/dist/domain/firmware/firmwareAnalysis.js +128 -0
- package/dist/domain/functionComparison.js +38 -0
- package/dist/domain/functionComparisonDimensions.js +199 -0
- package/dist/domain/functionComparisonNormalization.js +150 -0
- package/dist/domain/functionComparisonResults.js +54 -0
- package/dist/domain/functionComparisonSchemas.js +88 -0
- package/dist/domain/functionDossierEvidence.js +20 -0
- package/dist/domain/go/goBinary.js +96 -0
- package/dist/domain/harmony/harmonyApplication.js +169 -0
- package/dist/domain/hopperErrors.js +98 -0
- package/dist/domain/hopperStartupFailure.js +64 -0
- package/dist/domain/hopperValues.js +368 -0
- package/dist/domain/immutableJson.js +114 -0
- package/dist/domain/inputIssueProjection.js +94 -0
- package/dist/domain/javascript/electronActiveObservation.js +237 -0
- package/dist/domain/javascript/electronObservation.js +122 -0
- package/dist/domain/javascript/electronStaticAnalysis.js +9 -0
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +187 -0
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +197 -0
- package/dist/domain/javascript/electronStaticAnalysisNative.js +199 -0
- package/dist/domain/javascript/electronStaticAnalysisTypes.js +1 -0
- package/dist/domain/javascript/electronStaticAnalysisValues.js +134 -0
- package/dist/domain/javascript/electronWrappedCallPaths.js +399 -0
- package/dist/domain/javascript/htmlArtifactReferences.js +40 -0
- package/dist/domain/javascript/javascriptAnalysisResourceControls.js +65 -0
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +146 -0
- package/dist/domain/javascript/javascriptApplicationChangeGraph.js +175 -0
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +400 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +378 -0
- package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +126 -0
- package/dist/domain/javascript/javascriptApplicationProjectionResources.js +43 -0
- package/dist/domain/javascript/javascriptApplicationVersionComparison.js +104 -0
- package/dist/domain/javascript/javascriptApplicationVersionComparisonSchemas.js +211 -0
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +324 -0
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +199 -0
- package/dist/domain/javascript/javascriptArtifactFiles.js +1 -0
- package/dist/domain/javascript/javascriptAstFingerprint.js +153 -0
- package/dist/domain/javascript/javascriptAstValues.js +99 -0
- package/dist/domain/javascript/javascriptBootstrap.js +94 -0
- package/dist/domain/javascript/javascriptElectronMemberWrites.js +119 -0
- package/dist/domain/javascript/javascriptExportReturnShapeProjection.js +81 -0
- package/dist/domain/javascript/javascriptExportShapeComparison.js +161 -0
- package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +16 -0
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +302 -0
- package/dist/domain/javascript/javascriptExportShapeSelection.js +130 -0
- package/dist/domain/javascript/javascriptExportShapeVariants.js +333 -0
- package/dist/domain/javascript/javascriptFeatureSeed.js +193 -0
- package/dist/domain/javascript/javascriptFeatureTrace.js +177 -0
- package/dist/domain/javascript/javascriptFeatureTraceSchemas.js +131 -0
- package/dist/domain/javascript/javascriptFeatureTraversal.js +61 -0
- package/dist/domain/javascript/javascriptIntrinsicInvocation.js +93 -0
- package/dist/domain/javascript/javascriptModuleInterop.js +617 -0
- package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
- package/dist/domain/javascript/javascriptNativeHandoff.js +90 -0
- package/dist/domain/javascript/javascriptPackageImportAliases.js +58 -0
- package/dist/domain/javascript/javascriptRecovery.js +90 -0
- package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +98 -0
- package/dist/domain/javascript/javascriptRuntimeObservation.js +136 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliation.js +46 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationActive.js +74 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationCaptureParsing.js +212 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +163 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationInputValidation.js +28 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +270 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +39 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationResult.js +126 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationRuntime.js +334 -0
- package/dist/domain/javascript/javascriptRuntimeReconciliationSchemas.js +234 -0
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +206 -0
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +910 -0
- package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +246 -0
- package/dist/domain/javascript/javascriptSemanticCallResolution.js +127 -0
- package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
- package/dist/domain/javascript/javascriptSemanticCalls.js +272 -0
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +224 -0
- package/dist/domain/javascript/javascriptSemanticCoverage.js +32 -0
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +182 -0
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +299 -0
- package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +52 -0
- package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
- package/dist/domain/javascript/javascriptSemanticFingerprints.js +187 -0
- package/dist/domain/javascript/javascriptSemanticGraph.js +575 -0
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +316 -0
- package/dist/domain/javascript/javascriptSemanticGraphSerialization.js +12 -0
- package/dist/domain/javascript/javascriptSemanticIr.js +31 -0
- package/dist/domain/javascript/javascriptSemanticIterationSources.js +139 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +865 -0
- package/dist/domain/javascript/javascriptSemanticMutationInitializers.js +190 -0
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +104 -0
- package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
- package/dist/domain/javascript/javascriptSemanticObjects.js +164 -0
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +38 -0
- package/dist/domain/javascript/javascriptSemanticProjection.js +571 -0
- package/dist/domain/javascript/javascriptSemanticPromises.js +321 -0
- package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +100 -0
- package/dist/domain/javascript/javascriptSemanticProvenance.js +29 -0
- package/dist/domain/javascript/javascriptSemanticQuery.js +175 -0
- package/dist/domain/javascript/javascriptSemanticQueryAssessment.js +45 -0
- package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +63 -0
- package/dist/domain/javascript/javascriptSemanticQueryRelations.js +15 -0
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +95 -0
- package/dist/domain/javascript/javascriptSemanticRequireOrigin.js +34 -0
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
- package/dist/domain/javascript/javascriptSemanticResources.js +129 -0
- package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
- package/dist/domain/javascript/javascriptSemanticReturns.js +159 -0
- package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
- package/dist/domain/javascript/javascriptSemanticState.js +116 -0
- package/dist/domain/javascript/javascriptSemanticTraceSchemas.js +15 -0
- package/dist/domain/javascript/javascriptSemanticTraversal.js +80 -0
- package/dist/domain/javascript/javascriptSemanticValueTypes.js +1 -0
- package/dist/domain/javascript/javascriptSemanticValues.js +581 -0
- package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
- package/dist/domain/javascript/javascriptSourceMapPaths.js +114 -0
- package/dist/domain/javascript/javascriptSourceParser.js +50 -0
- package/dist/domain/javascript/javascriptSourceSelection.js +11 -0
- package/dist/domain/javascript/javascriptStaticAnalysis.js +142 -0
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +239 -0
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +271 -0
- package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +86 -0
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +561 -0
- package/dist/domain/javascript/javascriptStaticAnalysisState.js +21 -0
- package/dist/domain/javascript/javascriptStaticAnalysisTypes.js +2 -0
- package/dist/domain/javascript/javascriptSymbolicBindings.js +795 -0
- package/dist/domain/javascript/javascriptSymbolicControlFlow.js +40 -0
- package/dist/domain/javascript/javascriptSymbolicValues.js +34 -0
- package/dist/domain/javascript/sourceToBundleComparison.js +261 -0
- package/dist/domain/javascript/sourceToBundleComparisonSchemas.js +109 -0
- package/dist/domain/javascript/sourceToBundleSignals.js +231 -0
- package/dist/domain/jeb/jebAnalysis.js +114 -0
- package/dist/domain/jsonSerialization.js +163 -0
- package/dist/domain/jsonShape.js +141 -0
- package/dist/domain/jsonValue.js +96 -0
- package/dist/domain/localPath.js +24 -0
- package/dist/domain/managed/managedApplicationGraph.js +221 -0
- package/dist/domain/managed/managedApplicationGraphCoverage.js +48 -0
- package/dist/domain/managed/managedApplicationGraphNodes.js +367 -0
- package/dist/domain/managed/managedArtifact.js +465 -0
- package/dist/domain/managed/managedInspectionEvidence.js +28 -0
- package/dist/domain/managed/managedMemberComparison.js +211 -0
- package/dist/domain/managed/managedMemberComparisonCoverage.js +71 -0
- package/dist/domain/managed/managedMemberComparisonItems.js +304 -0
- package/dist/domain/managed/managedMemberComparisonMatch.js +204 -0
- package/dist/domain/managed/managedNativeVerification.js +35 -0
- package/dist/domain/managed/managedNativeVerificationMatch.js +276 -0
- package/dist/domain/managed/managedNativeVerificationSchemas.js +180 -0
- package/dist/domain/managed/managedReconstruction.js +190 -0
- package/dist/domain/mobileApplicationGraphProjection.js +61 -0
- package/dist/domain/native/binaryLayout.js +354 -0
- package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
- package/dist/domain/native/nativeAotPe.js +1408 -0
- package/dist/domain/native/nativeApiBoundary.js +140 -0
- package/dist/domain/native/nativeCallObservation.js +186 -0
- package/dist/domain/native/nativeCallPartialObservation.js +33 -0
- package/dist/domain/native/nativeDataType.js +53 -0
- package/dist/domain/native/nativeFunctionAnnotations.js +43 -0
- package/dist/domain/native/nativeInspection.js +174 -0
- package/dist/domain/native/nativeInstruction.js +125 -0
- package/dist/domain/native/nativeInvestigationGraph.js +364 -0
- package/dist/domain/native/nativeLoadImage.js +112 -0
- package/dist/domain/native/nativeMetadataRecovery.js +128 -0
- package/dist/domain/native/nativeUiObservation.js +137 -0
- package/dist/domain/native/nativeValueFlow.js +72 -0
- package/dist/domain/native/nativeValueTrace.js +64 -0
- package/dist/domain/native/objcSwiftMetadata.js +419 -0
- package/dist/domain/native/peResources.js +100 -0
- package/dist/domain/native/recordedCrash.js +263 -0
- package/dist/domain/native/recordedCrashNoteCoverage.js +73 -0
- package/dist/domain/nativeConvention.js +33 -0
- package/dist/domain/offsetDateTime.js +17 -0
- package/dist/domain/peMachine.js +36 -0
- package/dist/domain/process/processCapture.js +412 -0
- package/dist/domain/process/processCaptureCoverage.js +70 -0
- package/dist/domain/process/processCaptureExample.js +132 -0
- package/dist/domain/process/processCaptureParsing.js +21 -0
- package/dist/domain/process/processCaptureValidation.js +246 -0
- package/dist/domain/process/processComparison.js +315 -0
- package/dist/domain/process/processEvidenceProvider.js +11 -0
- package/dist/domain/process/processObservation.js +140 -0
- package/dist/domain/process/processScenario.js +247 -0
- package/dist/domain/process/processTraceComparison.js +34 -0
- package/dist/domain/process/processTraceDimensionProjection.js +35 -0
- package/dist/domain/process/processTraceEvaluation.js +320 -0
- package/dist/domain/process/processTraceSpecification.js +382 -0
- package/dist/domain/propertyListKeys.js +107 -0
- package/dist/domain/propertyListXmlText.js +19 -0
- package/dist/domain/providerAdapterError.js +19 -0
- package/dist/domain/providerCleanupError.js +18 -0
- package/dist/domain/providerConfigurationRefusal.js +12 -0
- package/dist/domain/providerOperationHealth.js +54 -0
- package/dist/domain/providerSelectionError.js +46 -0
- package/dist/domain/rawBinary.js +93 -0
- package/dist/domain/reconstructionCoverage.js +325 -0
- package/dist/domain/reconstructionCoverageEvaluation.js +234 -0
- package/dist/domain/reconstructionCoverageInput.js +7 -0
- package/dist/domain/reconstructionObligationLedgerIntegrity.js +114 -0
- package/dist/domain/reconstructionObligationLedgerSchemas.js +347 -0
- package/dist/domain/reconstructionReadiness.js +116 -0
- package/dist/domain/reconstructionReadinessFindingHelpers.js +17 -0
- package/dist/domain/reconstructionReadinessIntegrityFindings.js +118 -0
- package/dist/domain/reconstructionReadinessJourneyFindings.js +193 -0
- package/dist/domain/reconstructionReadinessSchemas.js +268 -0
- package/dist/domain/reconstructionUnknowns.js +91 -0
- package/dist/domain/reconstructionVerification.js +218 -0
- package/dist/domain/reconstructionVerificationSchemas.js +141 -0
- package/dist/domain/recordedTransportUrl.js +51 -0
- package/dist/domain/referenceSourceClassification.js +385 -0
- package/dist/domain/referenceSourceGraph.js +380 -0
- package/dist/domain/referenceSourceImportParsing.js +238 -0
- package/dist/domain/referenceSourcePathIdentity.js +22 -0
- package/dist/domain/referenceSourcePolicy.js +1 -0
- package/dist/domain/referenceSourceRequireBindings.js +137 -0
- package/dist/domain/relationshipCoverage.js +20 -0
- package/dist/domain/residualUnknown.js +252 -0
- package/dist/domain/result.js +4 -0
- package/dist/domain/runtimeVersion.js +15 -0
- package/dist/domain/safeJson.js +13 -0
- package/dist/domain/sourceMapContents.js +6 -0
- package/dist/domain/sourceMapEnvelope.js +44 -0
- package/dist/domain/staticRuntimeCorrelation.js +334 -0
- package/dist/domain/stringPatterns.js +6 -0
- package/dist/domain/swiftSymbolClassification.js +66 -0
- package/dist/domain/symbolAnalysis.js +122 -0
- package/dist/domain/unicodeCodePointOrder.js +23 -0
- package/dist/domain/unknownRegistryError.js +10 -0
- package/dist/domain/wasm/wasmArtifact.js +105 -0
- package/dist/domain/webBundleAnalysis.js +192 -0
- package/dist/domain/webBundleAnalyzer.js +15 -0
- package/dist/domain/webBundleAnalyzerAst.js +49 -0
- package/dist/domain/webBundleAnalyzerInspection.js +315 -0
- package/dist/domain/webBundleAnalyzerResult.js +142 -0
- package/dist/domain/webCaptureDiff.js +423 -0
- package/dist/domain/webCaptureDiffSchemas.js +84 -0
- package/dist/domain/webContentArtifact.js +38 -0
- package/dist/domain/webEventListeners.js +29 -0
- package/dist/domain/webExecution.js +75 -0
- package/dist/domain/webInventory.js +62 -0
- package/dist/domain/webMcpDiscovery.js +53 -0
- package/dist/domain/webModuleImports.js +99 -0
- package/dist/domain/webModuleTrace.js +101 -0
- package/dist/domain/webNetworkCapture.js +142 -0
- package/dist/domain/webNetworkCaptureCoordinates.js +58 -0
- package/dist/domain/webRuntime.js +80 -0
- package/dist/domain/webScreenshot.js +132 -0
- package/dist/domain/webScriptArtifacts.js +37 -0
- package/dist/domain/webScriptExport.js +84 -0
- package/dist/domain/webScriptExportError.js +19 -0
- package/dist/domain/webScriptExportPlan.js +104 -0
- package/dist/domain/webSourceLocation.js +118 -0
- package/dist/domain/webSourcePosition.js +21 -0
- package/dist/domain/zipPackageFormat.js +52 -0
- package/dist/domain/zodCollectionSteps.js +24 -0
- package/dist/dotnet/ManagedArtifactInspector.js +308 -0
- package/dist/dotnet/ManagedDecodeBudget.js +138 -0
- package/dist/dotnet/ManagedExceptionRegionValidation.js +41 -0
- package/dist/dotnet/ManagedMemberInspector.js +173 -0
- package/dist/dotnet/ManagedMemberInspectorCore.js +446 -0
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +468 -0
- package/dist/dotnet/ManagedMemberOwnership.js +71 -0
- package/dist/dotnet/ManagedMemberPointers.js +62 -0
- package/dist/dotnet/ManagedMemberRows.js +227 -0
- package/dist/dotnet/ManagedMetadataHeaps.js +179 -0
- package/dist/dotnet/ManagedMetadataInventory.js +99 -0
- package/dist/dotnet/ManagedMetadataInventoryRows.js +295 -0
- package/dist/dotnet/ManagedMetadataLayout.js +270 -0
- package/dist/dotnet/ManagedMetadataRowSizes.js +54 -0
- package/dist/dotnet/ManagedMethodBodyReader.js +155 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +314 -0
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +128 -0
- package/dist/dotnet/ManagedPeReader.js +233 -0
- package/dist/dotnet/ManagedReaderFailure.js +27 -0
- package/dist/dotnet/ManagedSnapshot.js +88 -0
- package/dist/dotnet/ManagedStaticProvider.js +158 -0
- package/dist/dotnet/ManagedStaticProviderMetadata.js +33 -0
- package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
- package/dist/evaluation/AgentEvaluationReport.js +32 -0
- package/dist/evaluation/CodexAgentEval.js +188 -0
- package/dist/evaluation/KnownAnswerEvaluation.js +323 -0
- package/dist/evm/EvmBytecodeCarrier.js +21 -0
- package/dist/evm/EvmWorkerLimits.js +40 -0
- package/dist/evm/EvmoleFailures.js +124 -0
- package/dist/evm/EvmoleInterfaceAdapter.js +53 -0
- package/dist/evm/EvmoleInterfaceProvider.js +339 -0
- package/dist/evm/EvmoleInterfaceWorker.js +87 -0
- package/dist/evm/EvmoleRelease.js +16 -0
- package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
- package/dist/filesystem/OwnedFileHandle.js +36 -0
- package/dist/filesystem/OwnedStagedOutput.js +138 -0
- package/dist/filesystem/RegularFile.js +73 -0
- package/dist/filesystem/StableFileHash.js +46 -0
- package/dist/filesystem/readFileHandleChunks.js +35 -0
- package/dist/firmware/FirmwareCommand.js +190 -0
- package/dist/firmware/FirmwareFiles.js +206 -0
- package/dist/firmware/FirmwareProvider.js +388 -0
- package/dist/firmware/FirmwarePublication.js +105 -0
- package/dist/firmware/FirmwareRelease.js +33 -0
- package/dist/firmware/FirmwareReports.js +287 -0
- package/dist/firmware/FirmwareVersion.js +80 -0
- package/dist/generatedPackageMetadata.js +9 -0
- package/dist/ghidra/GhidraAnalysisProfile.js +219 -0
- package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
- package/dist/ghidra/GhidraClient.js +725 -0
- package/dist/ghidra/GhidraClientStartup.js +27 -0
- package/dist/ghidra/GhidraClientTypes.js +1 -0
- package/dist/ghidra/GhidraClientWire.js +38 -0
- package/dist/ghidra/GhidraDiagnostics.js +53 -0
- package/dist/ghidra/GhidraDoctor.js +88 -0
- package/dist/ghidra/GhidraFunctionValues.js +328 -0
- package/dist/ghidra/GhidraInstallation.js +443 -0
- package/dist/ghidra/GhidraInstallationPolicy.js +140 -0
- package/dist/ghidra/GhidraInventoryValues.js +262 -0
- package/dist/ghidra/GhidraJavaLaunch.js +66 -0
- package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
- package/dist/ghidra/GhidraLauncher.js +490 -0
- package/dist/ghidra/GhidraLoadImageAttest.js +103 -0
- package/dist/ghidra/GhidraLoadImageValues.js +260 -0
- package/dist/ghidra/GhidraMipsProfile.js +187 -0
- package/dist/ghidra/GhidraProvider.js +250 -0
- package/dist/ghidra/GhidraProviderCapabilities.js +208 -0
- package/dist/ghidra/GhidraProviderClient.js +613 -0
- package/dist/ghidra/GhidraPspExtension.js +144 -0
- package/dist/ghidra/GhidraPspProfile.js +50 -0
- package/dist/ghidra/GhidraRawBinaryLanguage.js +18 -0
- package/dist/ghidra/GhidraRequestQueue.js +115 -0
- package/dist/ghidra/GhidraResponseBuffer.js +31 -0
- package/dist/ghidra/GhidraResponseRouter.js +24 -0
- package/dist/ghidra/GhidraSessionError.js +180 -0
- package/dist/ghidra/GhidraSessionRoot.js +39 -0
- package/dist/ghidra/GhidraSessionValues.js +86 -0
- package/dist/ghidra/GhidraSocketConnection.js +83 -0
- package/dist/ghidra/GhidraTargetSnapshot.js +79 -0
- package/dist/ghidra/GhidraTransport.js +101 -0
- package/dist/ghidra/extensions/GhidraExtensionFailures.js +20 -0
- package/dist/ghidra/extensions/GhidraExtensions.js +177 -0
- package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +27 -0
- package/dist/ghidra/extensions/nativeaot/NativeAotReport.js +100 -0
- package/dist/ghidra/protocol.js +46 -0
- package/dist/go/GoBinaryContainer.js +125 -0
- package/dist/go/GoBinaryImage.js +172 -0
- package/dist/go/GoBinaryProvider.js +137 -0
- package/dist/go/GoElfImage.js +149 -0
- package/dist/go/GoMachoImage.js +113 -0
- package/dist/go/GoModuleText.js +217 -0
- package/dist/go/GoPeImage.js +102 -0
- package/dist/hopper/BridgeLauncher.js +305 -0
- package/dist/hopper/HopperAnalysisProfile.js +168 -0
- package/dist/hopper/HopperCleanup.js +245 -0
- package/dist/hopper/HopperClient.js +767 -0
- package/dist/hopper/HopperDiagnostics.js +14 -0
- package/dist/hopper/HopperFileOffset.js +237 -0
- package/dist/hopper/HopperMachOImage.js +200 -0
- package/dist/hopper/HopperOperationStage.js +6 -0
- package/dist/hopper/HopperProcessDiagnostic.js +26 -0
- package/dist/hopper/HopperProvider.js +269 -0
- package/dist/hopper/HopperProviderCapabilities.js +91 -0
- package/dist/hopper/HopperRegexSearch.js +134 -0
- package/dist/hopper/HopperRegexWorker.js +27 -0
- package/dist/hopper/HopperRequestQueue.js +261 -0
- package/dist/hopper/HopperResponseStream.js +44 -0
- package/dist/hopper/HopperSessionValues.js +30 -0
- package/dist/hopper/HopperSocketConnection.js +31 -0
- package/dist/hopper/HopperTargetLease.js +233 -0
- package/dist/hopper/LinuxPrivateDisplayDiagnostic.js +64 -0
- package/dist/hopper/LinuxPrivateDisplayProbe.js +224 -0
- package/dist/hopper/protocol.js +88 -0
- package/dist/ida/IdaBusyHealth.js +44 -0
- package/dist/ida/IdaCallGraph.js +134 -0
- package/dist/ida/IdaConfiguration.js +61 -0
- package/dist/ida/IdaDoctor.js +53 -0
- package/dist/ida/IdaInput.js +56 -0
- package/dist/ida/IdaMcpConnection.js +115 -0
- package/dist/ida/IdaOperationRunner.js +376 -0
- package/dist/ida/IdaProtocolValues.js +208 -0
- package/dist/ida/IdaProvider.js +136 -0
- package/dist/ida/IdaProviderCapabilities.js +64 -0
- package/dist/ida/IdaSessionClient.js +444 -0
- package/dist/ida/IdaWorkspace.js +55 -0
- package/dist/identity.js +25 -0
- package/dist/inspector/JavaScriptRuntimeScope.js +89 -0
- package/dist/inspector/V8InspectorCaptureProjection.js +197 -0
- package/dist/inspector/V8InspectorEndpoint.js +70 -0
- package/dist/inspector/V8InspectorProvider.js +378 -0
- package/dist/inspector/providerIdentity.js +6 -0
- package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +337 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +574 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +64 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +558 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +121 -0
- package/dist/javascript/recovery/RecoveryFiles.js +175 -0
- package/dist/javascript/recovery/WakaruCommand.js +137 -0
- package/dist/javascript/recovery/WakaruExecution.js +115 -0
- package/dist/javascript/recovery/WakaruProvider.js +218 -0
- package/dist/javascript/recovery/WakaruPublication.js +126 -0
- package/dist/javascript/recovery/WakaruRelease.js +36 -0
- package/dist/javascript/recovery/WakaruReport.js +140 -0
- package/dist/javascript/recovery/WakaruVersion.js +24 -0
- package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
- package/dist/javascript/sourceMaps/SourceMapCodecProcess.js +37 -0
- package/dist/javascript/sourceMaps/SourceMapCodecProtocol.js +20 -0
- package/dist/javascript/sourceMaps/SourceMapCommand.js +223 -0
- package/dist/javascript/sourceMaps/SourceMapDecoder.js +135 -0
- package/dist/javascript/sourceMaps/SourceMapFormat.js +238 -0
- package/dist/javascript/sourceMaps/TraceSourceMap.js +152 -0
- package/dist/jeb/JebMcpConnection.js +186 -0
- package/dist/jeb/JebMcpEndpoint.js +40 -0
- package/dist/jeb/JebProvider.js +297 -0
- package/dist/logger.js +14 -0
- package/dist/main/messages.js +4 -0
- package/dist/main/shutdown.js +102 -0
- package/dist/main/startup.js +21 -0
- package/dist/main/transport.js +72 -0
- package/dist/main/types.js +1 -0
- package/dist/main.js +92 -0
- package/dist/mcp/AnalysisSnapshotFiles-DbgHi36O.js +1225 -0
- package/dist/mcp/ArtifactProvider-BNxKlaKX.js +2090 -0
- package/dist/mcp/ArtifactProviderMetadata--hy-wyJK.js +76 -0
- package/dist/mcp/ArtifactReader-OyM03Gjn.js +55 -0
- package/dist/mcp/ArtifactResourceScope-CBR5q4aK.js +108 -0
- package/dist/mcp/AsarHeader-WsPgoooH.js +31 -0
- package/dist/mcp/BinaryTargetResolver-DbiUzRLh.js +1073 -0
- package/dist/mcp/BoundedFileBytes-CJPW_TzE.js +68 -0
- package/dist/mcp/CdpConnection-CM0tkVfW.js +557 -0
- package/dist/mcp/CdpOptionalCommand-H8_fL7Q_.js +120 -0
- package/dist/mcp/CdpTargetSession-OYD1d6XM.js +647 -0
- package/dist/mcp/DirectAnalysis-BWAu8Ro5.js +395 -0
- package/dist/mcp/DirectAnalysisStatus-DofNPhKd.js +33 -0
- package/dist/mcp/ElectronFileScope-DEayib6K.js +110 -0
- package/dist/mcp/InterfaceBuilderDecodeBudget-CUrOtfNo.js +401 -0
- package/dist/mcp/ManagedStaticProvider-CXE93Bow.js +4460 -0
- package/dist/mcp/NativeMacOSProvider-BbITFLHW.js +4408 -0
- package/dist/mcp/NativeMacOSProviderMetadata-mxDhaNJf.js +281 -0
- package/dist/mcp/ProcedureAddressResolution-Gnjf9Hya.js +19 -0
- package/dist/mcp/ProcessOwnership-nOFZsmD3.js +1411 -0
- package/dist/mcp/WorkflowEvidence-DJyEy3K0.js +94 -0
- package/dist/mcp/analysisErrorCore-BqyeMw3_.js +201 -0
- package/dist/mcp/analysisErrorProjection-B7pHef2y.js +724 -0
- package/dist/mcp/artifactOperationError-B_jxO8at.js +27 -0
- package/dist/mcp/artifactToolContracts-TXegBBr1.js +159 -0
- package/dist/mcp/browserObservation-BCgaDRyQ.js +4398 -0
- package/dist/mcp/browserObservationError-BKBEX85K.js +40 -0
- package/dist/mcp/browserObservationSchemas-yzRJ90-E.js +573 -0
- package/dist/mcp/browserScenario-z7jveI9P.js +2319 -0
- package/dist/mcp/browserScenarioCapture-BvnKTmtZ.js +460 -0
- package/dist/mcp/canonicalDigest-Bi_0_zGi.js +71 -0
- package/dist/mcp/digests-Dugt3H71.js +199 -0
- package/dist/mcp/electronActiveObservation-lDvQTMR0.js +226 -0
- package/dist/mcp/electronObservation-DjQQYGw4.js +556 -0
- package/dist/mcp/electronObservation-DuhMHCmQ.js +112 -0
- package/dist/mcp/electronScenario-9mLG6h-g.js +586 -0
- package/dist/mcp/emptyArraySchema-DEEefG2V.js +140 -0
- package/dist/mcp/enhancedInputs-CLdEXv88.js +56 -0
- package/dist/mcp/interfaceBuilderGraph-BOKqQzjK.js +2613 -0
- package/dist/mcp/javascriptRuntimeObservation-C_wglsz_.js +661 -0
- package/dist/mcp/javascriptRuntimeObservation-CxQ1UT_y.js +121 -0
- package/dist/mcp/lipo-Do-2eBrl.js +465 -0
- package/dist/mcp/localPath-AxvW9aPe.js +19 -0
- package/dist/mcp/logger-CZ4Hlc6u.js +34 -0
- package/dist/mcp/machoContainer-9En6pSkd.js +813 -0
- package/dist/mcp/main-WQSCuTNt.js +52791 -0
- package/dist/mcp/main.js +6 -0
- package/dist/mcp/managedToolContracts-o5LHFwHc.js +81 -0
- package/dist/mcp/plistValue-DsU7z4yF.js +47 -0
- package/dist/mcp/propertyListKeys-cX-BUv2y.js +197 -0
- package/dist/mcp/providerAdapterError-CdPaQ6-Z.js +27 -0
- package/dist/mcp/providerCleanupError-DvE79aUX.js +49 -0
- package/dist/mcp/providerIdentities--ptAh481.js +31 -0
- package/dist/mcp/providerIdentity-BCQ5n5tw.js +16 -0
- package/dist/mcp/providerOperationHealth-CUeCJZiP.js +212 -0
- package/dist/mcp/rolldown-runtime-BjeaiXFo.js +121 -0
- package/dist/mcp/safeJson-NeGfpkrI.js +25 -0
- package/dist/mcp/scanCanonical-2GN0h-BE.js +3647 -0
- package/dist/mcp/serverIdentity-rOY69sxc.js +633 -0
- package/dist/mcp/sourceMapEnvelope-D8Zezqyi.js +252 -0
- package/dist/mcp/toolContracts-CrfYDTUz.js +14561 -0
- package/dist/mcp/toolOutputSchemaGroups-ChxVLGoy.js +11114 -0
- package/dist/mcp/unicodeCodePointOrder-BezCbTpg.js +26 -0
- package/dist/mcp/webContentArtifact-DUBgMzVO.js +185 -0
- package/dist/mcp/webRuntime-C2Tx-fgS.js +74 -0
- package/dist/mcp/webSourceLocation-Dnkpf0R2.js +8532 -0
- package/dist/mcpDoctor.js +360 -0
- package/dist/mcpStartupPolicy.js +14 -0
- package/dist/native/AppleDispatchCoverage.js +112 -0
- package/dist/native/AppleDispatchDecodeFacts.js +6 -0
- package/dist/native/AppleDispatchMetadata.js +176 -0
- package/dist/native/AppleMachoFixups.js +372 -0
- package/dist/native/AppleMachoSelection.js +234 -0
- package/dist/native/AppleObjcCategories.js +63 -0
- package/dist/native/AppleObjcDispatchFacets.js +260 -0
- package/dist/native/AppleObjcProperties.js +79 -0
- package/dist/native/AppleObjcProtocols.js +89 -0
- package/dist/native/AppleSwiftDispatchFacets.js +156 -0
- package/dist/native/AppleSwiftVtables.js +92 -0
- package/dist/native/CommandRunner.js +240 -0
- package/dist/native/LldbCallTracer.js +713 -0
- package/dist/native/LldbRetainedObservations.js +178 -0
- package/dist/native/NativeCallObservation.js +195 -0
- package/dist/native/NativeMacOSProvider.js +701 -0
- package/dist/native/NativeMacOSProviderMetadata.js +46 -0
- package/dist/native/NativeMachoInspection.js +273 -0
- package/dist/native/NativeUiHelperRuntime.js +66 -0
- package/dist/native/NativeUiObservation.js +183 -0
- package/dist/native/NativeUiOutputBudget.js +8 -0
- package/dist/native/SignatureTargetBinding.js +155 -0
- package/dist/native/parsers/codesign.js +93 -0
- package/dist/native/parsers/demangle.js +30 -0
- package/dist/native/parsers/dyldInfo.js +60 -0
- package/dist/native/parsers/echoedPath.js +14 -0
- package/dist/native/parsers/lipo.js +177 -0
- package/dist/native/parsers/machoUuid.js +150 -0
- package/dist/native/parsers/otool.js +379 -0
- package/dist/native/parsers/plist.js +187 -0
- package/dist/native/pe/PeResourceLayout.js +120 -0
- package/dist/native/pe/PeResourceParser.js +286 -0
- package/dist/native/pe/PeResourcesProvider.js +63 -0
- package/dist/native/pwndbg/PwndbgCoreContext.js +180 -0
- package/dist/native/pwntools/PwntoolsDecoder.js +206 -0
- package/dist/native/pwntools/PwntoolsFailures.js +180 -0
- package/dist/native/pwntools/PwntoolsLayoutProvider.js +36 -0
- package/dist/native/pwntools/PwntoolsRecordedCrashProvider.js +75 -0
- package/dist/native/pwntools/PwntoolsRelease.js +19 -0
- package/dist/native/pwntools/PwntoolsResourceLimits.js +76 -0
- package/dist/native/pwntools/RecordedCrashSourceBindings.js +46 -0
- package/dist/native/pwntools/RecordedCrashStructureBindings.js +103 -0
- package/dist/process/BoundedFileBytes.js +40 -0
- package/dist/process/DarwinProcessRunTokenReader.js +376 -0
- package/dist/process/ExecFileOutput.js +124 -0
- package/dist/process/JavaScriptWorkerMemoryLimit.js +25 -0
- package/dist/process/OwnedCommand.js +131 -0
- package/dist/process/PendingOperations.js +61 -0
- package/dist/process/PrivateRuntimeRoot.js +61 -0
- package/dist/process/ProcessCommandIdentity.js +19 -0
- package/dist/process/ProcessOwnership.js +636 -0
- package/dist/process/ProcessOwnershipIdentity.js +13 -0
- package/dist/process/ProcessOwnershipObservation.js +407 -0
- package/dist/process/ProcessOwnershipProcessTree.js +35 -0
- package/dist/process/ProcessRunTokenObservations.js +48 -0
- package/dist/process/ProviderDeadline.js +91 -0
- package/dist/process/ProviderDiagnosticRedaction.js +17 -0
- package/dist/process/ProviderProcess.js +381 -0
- package/dist/process/ProviderRunLineage.js +21 -0
- package/dist/process/WindowsAuthority.js +51 -0
- package/dist/process/WindowsBatchCommand.js +46 -0
- package/dist/process/boundedUtf8Text.js +13 -0
- package/dist/process/capture/FilesystemSnapshot.js +268 -0
- package/dist/process/capture/ProcessCaptureCapability.js +65 -0
- package/dist/process/capture/ProcessCaptureEnvironment.js +9 -0
- package/dist/process/capture/ProcessCaptureError.js +74 -0
- package/dist/process/capture/ProcessCaptureJournal.js +61 -0
- package/dist/process/capture/ProcessCaptureLifecycle.js +1050 -0
- package/dist/process/capture/ProcessCaptureProgress.js +62 -0
- package/dist/process/capture/ProcessFilesystemEffects.js +81 -0
- package/dist/process/capture/ProcessHarness.js +602 -0
- package/dist/process/capture/ProcessNormalization.js +88 -0
- package/dist/process/capture/ProcessSampling.js +415 -0
- package/dist/process/capture/ProcessScenarioRuntimeValidation.js +79 -0
- package/dist/process/capture/ProcessTimer.js +39 -0
- package/dist/process/capture/TerminalRenderer.js +124 -0
- package/dist/process/snapshotEnvironment.js +14 -0
- package/dist/reference/ReferenceSourceReader.js +73 -0
- package/dist/reference/ReferenceSourceReaderEntries.js +273 -0
- package/dist/reference/ReferenceSourceReaderErrors.js +54 -0
- package/dist/reference/ReferenceSourceReaderFile.js +147 -0
- package/dist/reference/ReferenceSourceReaderPaths.js +8 -0
- package/dist/reference/ReferenceSourceReaderTypes.js +1 -0
- package/dist/reference/ReferenceSourceReaderValidate.js +81 -0
- package/dist/server/EvidenceMcpServer.js +216 -0
- package/dist/server/admittedToolOperation.js +9 -0
- package/dist/server/analysisAdmission.js +8 -0
- package/dist/server/contractToolHandler.js +21 -0
- package/dist/server/createServer.js +344 -0
- package/dist/server/lifecycleProgress.js +10 -0
- package/dist/server/mcpClientMetadata.js +42 -0
- package/dist/server/mcpProgress.js +26 -0
- package/dist/server/promptCompletion.js +141 -0
- package/dist/server/recordDerivedEvidence.js +10 -0
- package/dist/server/registerAdbTools.js +36 -0
- package/dist/server/registerAnalysisViewTool.js +10 -0
- package/dist/server/registerAndroidTools.js +31 -0
- package/dist/server/registerApktoolTools.js +14 -0
- package/dist/server/registerApplicationTools/compareExportShapes.js +29 -0
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +29 -0
- package/dist/server/registerApplicationTools/compareVersions.js +34 -0
- package/dist/server/registerApplicationTools/coverage.js +13 -0
- package/dist/server/registerApplicationTools/helpers.js +37 -0
- package/dist/server/registerApplicationTools/obligationLedger.js +23 -0
- package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +50 -0
- package/dist/server/registerApplicationTools/traceFeature.js +26 -0
- package/dist/server/registerApplicationTools/traceSemantics.js +25 -0
- package/dist/server/registerApplicationTools/types.js +1 -0
- package/dist/server/registerApplicationTools.js +19 -0
- package/dist/server/registerArtifactComparisonTool.js +71 -0
- package/dist/server/registerArtifactTools.js +14 -0
- package/dist/server/registerBinaryDiagnosticsTools.js +26 -0
- package/dist/server/registerBrowserScenarioTool.js +26 -0
- package/dist/server/registerBrowserTools.js +58 -0
- package/dist/server/registerBundleComparisonTool.js +54 -0
- package/dist/server/registerCloseLifecycleTool.js +55 -0
- package/dist/server/registerElectronTools.js +70 -0
- package/dist/server/registerEnhancedTools.js +169 -0
- package/dist/server/registerEvidenceTools.js +68 -0
- package/dist/server/registerEvmTools.js +9 -0
- package/dist/server/registerFirmwareTools.js +11 -0
- package/dist/server/registerFunctionComparisonTool.js +86 -0
- package/dist/server/registerGoTools.js +9 -0
- package/dist/server/registerInvestigationTools/helpers.js +46 -0
- package/dist/server/registerInvestigationTools/types.js +1 -0
- package/dist/server/registerInvestigationTools.js +168 -0
- package/dist/server/registerJavaScriptRecoveryTool.js +9 -0
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +27 -0
- package/dist/server/registerJebTools.js +16 -0
- package/dist/server/registerManagedTools.js +40 -0
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +53 -0
- package/dist/server/registerManagedWorkflowTools/contract.js +7 -0
- package/dist/server/registerManagedWorkflowTools/evidence.js +27 -0
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +27 -0
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +41 -0
- package/dist/server/registerManagedWorkflowTools/types.js +1 -0
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +62 -0
- package/dist/server/registerManagedWorkflowTools.js +11 -0
- package/dist/server/registerOfficialTools.js +74 -0
- package/dist/server/registerPeResourcesTool.js +9 -0
- package/dist/server/registerProcessComparisonTool.js +156 -0
- package/dist/server/registerPrompts.js +73 -0
- package/dist/server/registerRecordedCrashTools.js +9 -0
- package/dist/server/registerSessionRecordTools.js +90 -0
- package/dist/server/registerSessionStatusTool.js +61 -0
- package/dist/server/registerSessionTools.js +217 -0
- package/dist/server/registerWasmTools.js +9 -0
- package/dist/server/registerWebModuleTool.js +9 -0
- package/dist/server/registerWebNetworkCaptureTool.js +20 -0
- package/dist/server/registerWebRuntimeTools.js +27 -0
- package/dist/server/registerWebScriptTool.js +18 -0
- package/dist/server/registerWebSourceLocationTool.js +9 -0
- package/dist/server/runDerivedOperation.js +55 -0
- package/dist/server/sessionAvailabilityPolicy.js +29 -0
- package/dist/server/sessionEvidence.js +11 -0
- package/dist/server/toolLogging.js +11 -0
- package/dist/server/toolRegistrationOptions.js +9 -0
- package/dist/server/toolResult.js +119 -0
- package/dist/server/toolResultEncoding.js +34 -0
- package/dist/serverIdentity.js +69 -0
- package/dist/wasm/WabtArtifactProvider.js +313 -0
- package/dist/wasm/WabtFailures.js +62 -0
- package/dist/wasm/WabtOutput.js +60 -0
- package/dist/wasm/WabtRelease.js +12 -0
- package/dist/wasm/WabtWat.js +184 -0
- package/dist/wasm/WasmGlueAdapter.js +51 -0
- package/dist/windows/WindowsNativeLoader.js +124 -0
- package/dist/windows/WindowsOwnedProcess.js +265 -0
- package/dist/windows/WindowsPrivateRuntime.js +143 -0
- package/hooks/hooks.json +17 -0
- package/install.sh +172 -0
- package/licenses/Apache-2.0.txt +202 -0
- package/licenses/GCC-Runtime-Library-Exception-3.1.txt +73 -0
- package/licenses/GPL-3.0.txt +674 -0
- package/licenses/MIT-template.txt +18 -0
- package/licenses/MinGW-w64-runtime.txt +240 -0
- package/licenses/Node-22.19.0-LICENSE.txt +2666 -0
- package/licenses/README.md +54 -0
- package/licenses/cfworker-MIT.txt +21 -0
- package/licenses/digfox-MIT.txt +21 -0
- package/licenses/dotnet-runtime-MIT.txt +23 -0
- package/licenses/ghidra-12.1.4-DISCLAIMER.txt +13 -0
- package/licenses/ghidra-12.1.4-LICENSE.txt +201 -0
- package/licenses/ghidra-12.1.4-NOTICE.txt +49 -0
- package/licenses/nativeaot-parser-MIT.txt +28 -0
- package/licenses/npm-dependencies.txt +2812 -0
- package/licenses/npm-runtime-notices.txt +6632 -0
- package/licenses/rea-jev-MIT.txt +21 -0
- package/licenses/rea-lab-MIT.txt +21 -0
- package/licenses/upstream-sources.json +62 -0
- package/licenses/xterm-MIT.txt +21 -0
- package/native/windows/README.md +156 -0
- package/native/windows/build/manifest.json +9 -0
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +371 -4
- package/port/cli.mjs +210 -0
- package/port/hooks/guard.mjs +140 -0
- package/port/knowledge/engines.json +67 -0
- package/port/knowledge/footprints.json +189 -0
- package/port/knowledge/maps/godot-godot-csharp.json +38 -0
- package/port/knowledge/maps/godot-threejs.json +42 -0
- package/port/knowledge/maps/godot-unity.json +62 -0
- package/port/knowledge/maps/godot-unreal.json +48 -0
- package/port/knowledge/maps/unity-godot.json +52 -0
- package/port/knowledge/maps/unity-unreal.json +33 -0
- package/port/knowledge/systems.json +1554 -0
- package/port/mcp.mjs +62 -0
- package/port/plugin/mcp-launch.mjs +19 -0
- package/port/server.mjs +129 -0
- package/port/src/agent.mjs +257 -0
- package/port/src/archive.mjs +324 -0
- package/port/src/binary.mjs +606 -0
- package/port/src/blueprint.mjs +225 -0
- package/port/src/compare.mjs +165 -0
- package/port/src/connect.mjs +58 -0
- package/port/src/convert.mjs +134 -0
- package/port/src/formats.mjs +229 -0
- package/port/src/graph.mjs +275 -0
- package/port/src/knowledge.mjs +90 -0
- package/port/src/lookup.mjs +615 -0
- package/port/src/main-module.mjs +10 -0
- package/port/src/plan.mjs +606 -0
- package/port/src/porters.mjs +360 -0
- package/port/src/proofcase.mjs +343 -0
- package/port/src/relay.mjs +493 -0
- package/port/src/scan.mjs +189 -0
- package/port/src/scene.mjs +338 -0
- package/port/src/stashpad.mjs +114 -0
- package/port/src/symbols.mjs +201 -0
- package/port/src/tools.mjs +198 -0
- package/port/src/util.mjs +162 -0
- package/port/src/workspace.mjs +39 -0
- package/port/templates/unity/ReversePortSceneBuilder.cs +258 -0
- package/scripts/electron-active-hook-boundaries.cjs +392 -0
- package/scripts/electron-active-hook.cjs +673 -0
- package/scripts/hopper-demo-x11.py +787 -0
- package/scripts/prepack.mjs +60 -0
- package/scripts/prepare.mjs +28 -0
- package/scripts/rea.mjs +110 -0
- package/scripts/verify-windows-native-artifact.mjs +39 -0
- package/skills/build-inspector/SKILL.md +44 -0
- package/skills/godot-port/SKILL.md +42 -0
- package/skills/port-project/SKILL.md +59 -0
- package/skills/port-verify/SKILL.md +35 -0
- package/skills/proof-case/SKILL.md +52 -0
- package/skills/rebuild/SKILL.md +66 -0
- package/skills/reverse-engineer/SKILL.md +67 -0
- package/skills/reverse-engineer-anything/SKILL.md +204 -0
- package/skills/reverse-engineer-anything/references/android-applications.md +34 -0
- package/skills/reverse-engineer-anything/references/connection-and-recovery.md +130 -0
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +54 -0
- package/skills/reverse-engineer-anything/references/godot-source.md +37 -0
- package/skills/reverse-engineer-anything/references/javascript-applications.md +175 -0
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +252 -0
- package/skills/reverse-engineer-anything/references/porting-and-rebuilds.md +92 -0
- package/skills/reverse-engineer-anything/references/runtime-observation.md +28 -0
- package/skills/reverse-engineer-anything/references/unity-source.md +32 -0
- package/skills/troubleshoot/SKILL.md +27 -0
- package/skills/unity-to-godot/SKILL.md +37 -0
- package/third_party/README.md +60 -0
- package/third_party/evmole/LICENSE +21 -0
- package/third_party/evmole/README.md +22 -0
- package/third_party/pwndbg/LICENSE.md +21 -0
- package/third_party/pwndbg/README.md +23 -0
- package/third_party/pwntools/README.md +40 -0
- package/third_party/wabt/README.md +24 -0
|
@@ -0,0 +1,4408 @@
|
|
|
1
|
+
import { t as __esmMin } from "./rolldown-runtime-BjeaiXFo.js";
|
|
2
|
+
import { a as init_ProviderDeadline, c as init_ProviderProcess, g as snapshotEnvironment, h as init_snapshotEnvironment, i as ProviderStartupDeadline, l as spawnOwnedProviderProcess, n as readFatSliceDeclarations, o as waitForAbortableDelay, r as validateFatSlice, s as ProviderProcessSupervisor, t as init_machoContainer } from "./machoContainer-9En6pSkd.js";
|
|
3
|
+
import { a as AnalysisInputError, c as AnalysisResourceConstraintError, d as init_analysisErrorCore, f as err, g as init_analysisErrorBase, h as AnalysisError, i as AnalysisCapabilityUnavailableError, l as AnalysisTimeoutError, m as ok, n as AnalysisArtifactChangedError, o as AnalysisOutputError, p as init_result, r as AnalysisCancelledError, t as AnalysisAccessDeniedError } from "./analysisErrorCore-BqyeMw3_.js";
|
|
4
|
+
import { d as init_evidenceErrors, f as BinaryTargetError, h as init_configurationErrors, l as EvidenceIntegrityError, n as projectAnalysisError, t as init_analysisErrorProjection } from "./analysisErrorProjection-B7pHef2y.js";
|
|
5
|
+
import { $t as inspectPlistSchema, Bn as nativeCallEventSchema, Fn as nativeUiObservationInputSchema, Hn as nativeCallObservationResultSchema, In as nativeUiResultSchema, Ln as nativeUiScenarioInputSchema, Pn as init_nativeUiObservation, Qt as inspectMachoSchema, Rn as nativeUiSnapshotSchema, Un as nativeCodeLocationSchema, Vn as nativeCallObservationInputSchema, Xt as demangleSwiftSchema, Zt as init_nativeInspection, en as inspectSignatureSchema, tn as listArchitecturesSchema, zn as init_nativeCallObservation } from "./toolOutputSchemaGroups-ChxVLGoy.js";
|
|
6
|
+
import { n as safeParseJson, t as init_safeJson } from "./safeJson-NeGfpkrI.js";
|
|
7
|
+
import { c as jsonValueSchema, o as init_jsonValue } from "./digests-Dugt3H71.js";
|
|
8
|
+
import { dt as init_binaryTargetTypes, f as nativeDispatchMetadataResultSchema, ft as isMachOFormat, p as objcSwiftMetadataSchema, u as init_objcSwiftMetadata } from "./interfaceBuilderGraph-BOKqQzjK.js";
|
|
9
|
+
import { i as init_AnalysisProvider, n as init_providerCleanupError, r as createAnalysisExecution, t as ProviderCleanupError } from "./providerCleanupError-DvE79aUX.js";
|
|
10
|
+
import { d as signalProcessWithStartIdentity, h as init_DarwinProcessRunTokenReader, l as observeProcessStartIdentity, m as SWIFTC_INTERRUPT, o as init_ProcessOwnershipObservation, r as init_ProcessOwnership, t as cleanupOwnedProcessGroup, x as init_ExecFileOutput, y as execFileOutput } from "./ProcessOwnership-nOFZsmD3.js";
|
|
11
|
+
import { r as init_unicodeCodePointOrder, t as compareUnicodeCodePoints } from "./unicodeCodePointOrder-BezCbTpg.js";
|
|
12
|
+
import { n as init_providerAdapterError, t as ProviderAdapterError } from "./providerAdapterError-CdPaQ6-Z.js";
|
|
13
|
+
import { Xt as NATIVE_TOOL_CONTRACTS, Zt as init_nativeToolContracts, n as init_toolContracts, r as toolContract } from "./toolContracts-CrfYDTUz.js";
|
|
14
|
+
import { i as init_analysisErrorCleanup, n as readBoundedFileBytes, r as analysisErrorWithCleanupFailure, t as init_BoundedFileBytes } from "./BoundedFileBytes-CJPW_TzE.js";
|
|
15
|
+
import { i as PrivateRuntimeRoot, n as init_NativeMacOSProviderMetadata, o as init_PrivateRuntimeRoot, r as nativeMacOSCapabilities, t as NATIVE_MACOS_PROVIDER_IDENTITY } from "./NativeMacOSProviderMetadata-mxDhaNJf.js";
|
|
16
|
+
import { a as parseXmlPropertyList, i as omittedPrototypeKeysLimitation, l as init_RegularFile, n as init_propertyListKeys, r as omitPrototypeKeys, u as openRegularFile } from "./propertyListKeys-cX-BUv2y.js";
|
|
17
|
+
import { c as analysisInputErrorFromIssues, l as init_inputIssueProjection } from "./artifactToolContracts-TXegBBr1.js";
|
|
18
|
+
import { a as NATIVE_COMMAND_TIMEOUT_MS, c as init_CommandRunner, i as NATIVE_COMMAND_OUTPUT_BUDGET_BYTES, l as resolveXcrunTool, o as NativeCommandFailure, r as parseLipoArchitectures, s as XcrunCommandRunner, t as init_lipo } from "./lipo-Do-2eBrl.js";
|
|
19
|
+
import { n as projectPlistValue, t as init_plistValue } from "./plistValue-DsU7z4yF.js";
|
|
20
|
+
import { fileURLToPath } from "node:url";
|
|
21
|
+
import { constants } from "node:fs";
|
|
22
|
+
import { basename, dirname, isAbsolute, join, resolve } from "node:path";
|
|
23
|
+
import { z } from "zod";
|
|
24
|
+
import { tmpdir } from "node:os";
|
|
25
|
+
import { lstat, mkdir, mkdtemp, open, readFile, realpath, rm, stat, symlink, writeFile } from "node:fs/promises";
|
|
26
|
+
import { createHash, randomUUID } from "node:crypto";
|
|
27
|
+
|
|
28
|
+
//#region dist/native/AppleDispatchCoverage.js
|
|
29
|
+
var describeFixups, pushDispatchCoverage, formatIssue;
|
|
30
|
+
function init_AppleDispatchCoverage() {
|
|
31
|
+
return (init_AppleDispatchCoverage = __esmMin((() => {
|
|
32
|
+
describeFixups = (fixups) => {
|
|
33
|
+
const unread = fixups.unreadRebaseBytes > 0 ? `LC_DYLD_INFO rebase opcodes were not decoded (${fixups.unreadRebaseBytes} bytes)` : undefined;
|
|
34
|
+
const kind = fixups.kind === "chained" ? `chained fixups: ${fixups.formats.join(", ") || "no fixup segments"}` : fixups.kind === "dyld-info" ? "LC_DYLD_INFO bind opcodes" : unread === undefined ? "no fixup load commands" : undefined;
|
|
35
|
+
return [unread, kind].filter((line) => line !== undefined).join("; ");
|
|
36
|
+
};
|
|
37
|
+
pushDispatchCoverage = (input) => {
|
|
38
|
+
const { result, failures, categoryIssues, examined, categoriesExamined, truncated, fixups, vtables, swift } = input;
|
|
39
|
+
result.coverage.push({
|
|
40
|
+
facet: "objc_class_method_ivar_metadata",
|
|
41
|
+
status: failures.length > 0 || truncated ? "partial" : "complete",
|
|
42
|
+
reason: [...failures, ...truncated ? ["max_records_reached"] : []].join("; ") || null,
|
|
43
|
+
examined,
|
|
44
|
+
decoded: result.objc_classes.length
|
|
45
|
+
});
|
|
46
|
+
result.coverage.push({
|
|
47
|
+
facet: "binary_relative_pointers",
|
|
48
|
+
status: truncated || result.relative_pointers.some((item) => item.decode.status !== "decoded") ? "partial" : "complete",
|
|
49
|
+
reason: truncated ? "max_records_reached" : result.relative_pointers.some((item) => item.decode.status !== "decoded") ? "relative_pointer_targets_unresolved" : null,
|
|
50
|
+
examined: result.relative_pointers.length,
|
|
51
|
+
decoded: result.relative_pointers.filter((item) => item.decode.status === "decoded").length
|
|
52
|
+
});
|
|
53
|
+
const categoryFailures = categoryIssues.map(({ code, location, message }) => `${code}${location === undefined ? "" : ` at ${location}`}: ${message}`);
|
|
54
|
+
result.coverage.push({
|
|
55
|
+
facet: "objc_properties_categories",
|
|
56
|
+
status: truncated || categoryFailures.length > 0 || result.objc_categories.some(({ decode }) => decode.status !== "decoded") ? "partial" : "complete",
|
|
57
|
+
reason: [...categoryFailures, ...truncated ? ["max_records_reached"] : []].join("; ") || null,
|
|
58
|
+
examined: categoriesExamined,
|
|
59
|
+
decoded: result.objc_categories.filter(({ decode }) => decode.status === "decoded").length
|
|
60
|
+
});
|
|
61
|
+
const fixupReason = [describeFixups(fixups), ...fixups.issues.map(({ code, location, message }) => `${code}${location === undefined ? "" : ` at ${location}`}: ${message}`)].filter((line) => line.length > 0).join("; ");
|
|
62
|
+
result.coverage.push({
|
|
63
|
+
facet: "pointer_fixups",
|
|
64
|
+
status: fixups.issues.length > 0 || fixups.unreadRebaseBytes > 0 ? "partial" : fixups.examined === 0 ? "unsupported" : "complete",
|
|
65
|
+
reason: fixupReason.length > 0 ? fixupReason : null,
|
|
66
|
+
examined: fixups.examined,
|
|
67
|
+
decoded: fixups.issues.length > 0 ? 0 : fixups.examined
|
|
68
|
+
});
|
|
69
|
+
result.coverage.push({
|
|
70
|
+
facet: "swift_generic_resilient_witnesses_overrides_async_coroutines",
|
|
71
|
+
status: "unsupported",
|
|
72
|
+
reason: "This reader admits simple Swift conformance/static witness records and non-generic, non-resilient class vtables; generic/resilient tables and other Swift metadata families are not decoded",
|
|
73
|
+
examined: 0,
|
|
74
|
+
decoded: 0
|
|
75
|
+
});
|
|
76
|
+
result.coverage.push({
|
|
77
|
+
facet: "swift_conformances_static_witness_slots",
|
|
78
|
+
status: swift.exhaustive && !truncated && !result.swift_conformances.some(({ decode }) => decode.status !== "decoded") && !result.swift_dispatch_slots.some(({ table_kind, decode }) => table_kind === "witness_table" && decode.status !== "decoded") ? "complete" : "partial",
|
|
79
|
+
reason: [
|
|
80
|
+
...swift.issues.map(formatIssue),
|
|
81
|
+
...truncated ? ["max_records_reached"] : [],
|
|
82
|
+
...result.swift_conformances.some(({ decode }) => decode.status !== "decoded") || result.swift_dispatch_slots.some(({ table_kind, decode }) => table_kind === "witness_table" && decode.status !== "decoded") ? ["swift_records_unresolved"] : []
|
|
83
|
+
].join("; ") || null,
|
|
84
|
+
examined: swift.examined,
|
|
85
|
+
decoded: swift.decoded
|
|
86
|
+
});
|
|
87
|
+
result.coverage.push({
|
|
88
|
+
facet: "swift_class_vtable_descriptors",
|
|
89
|
+
status: vtables.exhaustive && !truncated && !result.swift_dispatch_slots.some(({ table_kind, decode }) => table_kind === "class_vtable" && decode.status !== "decoded") ? "complete" : "partial",
|
|
90
|
+
reason: [
|
|
91
|
+
...vtables.issues.map(formatIssue),
|
|
92
|
+
...truncated ? ["max_records_reached"] : [],
|
|
93
|
+
...result.swift_dispatch_slots.some(({ table_kind, decode }) => table_kind === "class_vtable" && decode.status !== "decoded") ? ["vtable_implementations_unresolved"] : []
|
|
94
|
+
].join("; ") || null,
|
|
95
|
+
examined: vtables.examined,
|
|
96
|
+
decoded: vtables.decoded
|
|
97
|
+
});
|
|
98
|
+
};
|
|
99
|
+
formatIssue = ({ code, location, message }) => `${code}${location === undefined ? "" : ` at ${location}`}: ${message}`;
|
|
100
|
+
})))();
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region dist/native/AppleDispatchDecodeFacts.js
|
|
105
|
+
var issue;
|
|
106
|
+
function init_AppleDispatchDecodeFacts() {
|
|
107
|
+
return (init_AppleDispatchDecodeFacts = __esmMin((() => {
|
|
108
|
+
issue = (facet, code, message, location) => ({
|
|
109
|
+
facet,
|
|
110
|
+
code,
|
|
111
|
+
message,
|
|
112
|
+
...location === undefined ? {} : { location }
|
|
113
|
+
});
|
|
114
|
+
})))();
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region dist/native/AppleMachoFixups.js
|
|
119
|
+
var POINTER_FORMATS, bits, signed, libraryName, cString, readImport, decodeChainedPointer, chainedFixups, uleb, sleb, setBindRegister, readBindStream, parsePointerFixups;
|
|
120
|
+
function init_AppleMachoFixups() {
|
|
121
|
+
return (init_AppleMachoFixups = __esmMin((() => {
|
|
122
|
+
init_AppleDispatchDecodeFacts();
|
|
123
|
+
POINTER_FORMATS = {
|
|
124
|
+
1: "DYLD_CHAINED_PTR_ARM64E",
|
|
125
|
+
2: "DYLD_CHAINED_PTR_64",
|
|
126
|
+
6: "DYLD_CHAINED_PTR_64_OFFSET",
|
|
127
|
+
9: "DYLD_CHAINED_PTR_ARM64E_USERLAND",
|
|
128
|
+
12: "DYLD_CHAINED_PTR_ARM64E_USERLAND24"
|
|
129
|
+
};
|
|
130
|
+
bits = (value, from, width) => value >> BigInt(from) & (1n << BigInt(width)) - 1n;
|
|
131
|
+
signed = (value, width) => value >= 1n << BigInt(width - 1) ? value - (1n << BigInt(width)) : value;
|
|
132
|
+
libraryName = (ordinal, dylibs) => {
|
|
133
|
+
if (ordinal > 0) return dylibs[ordinal - 1] ?? null;
|
|
134
|
+
return null;
|
|
135
|
+
};
|
|
136
|
+
cString = (bytes, offset, end) => {
|
|
137
|
+
const stop = bytes.indexOf(0, offset);
|
|
138
|
+
if (offset < 0 || offset >= end || stop < 0 || stop >= end) throw new RangeError("Fixup symbol name is outside the symbol pool");
|
|
139
|
+
return bytes.toString("utf8", offset, stop);
|
|
140
|
+
};
|
|
141
|
+
readImport = (data, header, index) => {
|
|
142
|
+
const { bytes, base, end, dylibs } = data;
|
|
143
|
+
const size = header.format === 3 ? 16 : header.format === 2 ? 8 : 4;
|
|
144
|
+
if (header.format < 1 || header.format > 3) throw new RangeError(`Unsupported chained import format ${header.format}`);
|
|
145
|
+
if (!Number.isSafeInteger(header.count) || base + header.offset + header.count * size > end) throw new RangeError("Chained import table exceeds the fixup data");
|
|
146
|
+
if (index < 0 || index >= header.count) throw new RangeError("Chained import index is outside the table");
|
|
147
|
+
const at = base + header.offset + index * size;
|
|
148
|
+
if (header.format === 3) {
|
|
149
|
+
const word = bytes.readBigUInt64LE(at);
|
|
150
|
+
const ordinal = Number(signed(bits(word, 0, 16), 16));
|
|
151
|
+
return {
|
|
152
|
+
symbol: cString(bytes, base + header.symbols + Number(bits(word, 32, 32)), end),
|
|
153
|
+
library: libraryName(ordinal, dylibs),
|
|
154
|
+
weak: bits(word, 16, 1) === 1n,
|
|
155
|
+
addend: bytes.readBigInt64LE(at + 8)
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
const word = bytes.readUInt32LE(at);
|
|
159
|
+
const ordinal = Number(signed(BigInt(word & 255), 8));
|
|
160
|
+
return {
|
|
161
|
+
symbol: cString(bytes, base + header.symbols + (word >>> 9), end),
|
|
162
|
+
library: libraryName(ordinal, dylibs),
|
|
163
|
+
weak: (word >>> 8 & 1) === 1,
|
|
164
|
+
addend: header.format === 2 ? BigInt(bytes.readInt32LE(at + 4)) : 0n
|
|
165
|
+
};
|
|
166
|
+
};
|
|
167
|
+
decodeChainedPointer = (raw, format, baseAddress, imports) => {
|
|
168
|
+
const bind = (ordinal, addend) => {
|
|
169
|
+
const target = typeof imports === "function" ? imports(Number(ordinal)) : imports[Number(ordinal)];
|
|
170
|
+
if (target === undefined) throw new RangeError(`Chained bind ordinal ${ordinal} has no import`);
|
|
171
|
+
return {
|
|
172
|
+
kind: "bind",
|
|
173
|
+
...target,
|
|
174
|
+
addend: target.addend + addend
|
|
175
|
+
};
|
|
176
|
+
};
|
|
177
|
+
if (format === 2 || format === 6) {
|
|
178
|
+
if (bits(raw, 63, 1) === 1n) return bind(bits(raw, 0, 24), bits(raw, 24, 8));
|
|
179
|
+
const target = bits(raw, 0, 36) | bits(raw, 36, 8) << 56n;
|
|
180
|
+
return {
|
|
181
|
+
kind: "rebase",
|
|
182
|
+
target: format === 6 ? target + baseAddress : target
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
if (format === 1 || format === 9 || format === 12) {
|
|
186
|
+
const auth = bits(raw, 63, 1) === 1n;
|
|
187
|
+
if (bits(raw, 62, 1) === 1n) return bind(bits(raw, 0, format === 12 ? 24 : 16), auth ? 0n : signed(bits(raw, 32, 19), 19));
|
|
188
|
+
if (auth) return {
|
|
189
|
+
kind: "rebase",
|
|
190
|
+
target: bits(raw, 0, 32) + baseAddress
|
|
191
|
+
};
|
|
192
|
+
const target = bits(raw, 0, 43) | bits(raw, 43, 8) << 56n;
|
|
193
|
+
return {
|
|
194
|
+
kind: "rebase",
|
|
195
|
+
target: format === 1 ? target : target + baseAddress
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
throw new RangeError(`Unsupported chained pointer format ${format}`);
|
|
199
|
+
};
|
|
200
|
+
chainedFixups = (image, range) => {
|
|
201
|
+
const { bytes, segments, dylibs, baseAddress } = image;
|
|
202
|
+
const base = range.offset;
|
|
203
|
+
const end = range.offset + range.size;
|
|
204
|
+
if (range.size < 28 || end > bytes.length) throw new RangeError("Chained fixup header exceeds the target");
|
|
205
|
+
const startsOffset = bytes.readUInt32LE(base + 4);
|
|
206
|
+
const importHeader = {
|
|
207
|
+
offset: bytes.readUInt32LE(base + 8),
|
|
208
|
+
symbols: bytes.readUInt32LE(base + 12),
|
|
209
|
+
count: bytes.readUInt32LE(base + 16),
|
|
210
|
+
format: bytes.readUInt32LE(base + 20)
|
|
211
|
+
};
|
|
212
|
+
const importSize = importHeader.format === 3 ? 16 : importHeader.format === 2 ? 8 : 4;
|
|
213
|
+
const importTableEnd = base + importHeader.offset + importHeader.count * importSize;
|
|
214
|
+
if (importHeader.format < 1 || importHeader.format > 3) throw new RangeError(`Unsupported chained import format ${importHeader.format}`);
|
|
215
|
+
if (!Number.isSafeInteger(importHeader.count) || importTableEnd > end) throw new RangeError("Chained import table exceeds the fixup data");
|
|
216
|
+
const imports = (index) => readImport({
|
|
217
|
+
bytes,
|
|
218
|
+
base,
|
|
219
|
+
end,
|
|
220
|
+
dylibs
|
|
221
|
+
}, importHeader, index);
|
|
222
|
+
if (bytes.readUInt32LE(base + 24) !== 0) throw new RangeError("Compressed chained-fixup symbol names are not supported");
|
|
223
|
+
const starts = base + startsOffset;
|
|
224
|
+
const segmentCount = bytes.readUInt32LE(starts);
|
|
225
|
+
const ranges = [];
|
|
226
|
+
for (let index = 0; index < segmentCount; index++) {
|
|
227
|
+
const infoOffset = bytes.readUInt32LE(starts + 4 + index * 4);
|
|
228
|
+
if (infoOffset === 0) continue;
|
|
229
|
+
const segment = segments[index];
|
|
230
|
+
if (segment === undefined || starts + infoOffset + 22 > end) throw new RangeError("Chained fixup segment table is out of range");
|
|
231
|
+
ranges.push({
|
|
232
|
+
from: segment.address,
|
|
233
|
+
to: segment.address + segment.size,
|
|
234
|
+
format: bytes.readUInt16LE(starts + infoOffset + 6)
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
const formats = [...new Set(ranges.map(({ format }) => POINTER_FORMATS[format] ?? `format-${format}`))];
|
|
238
|
+
const issues = ranges.flatMap(({ format, from }) => POINTER_FORMATS[format] === undefined ? [issue("pointer_fixups", "unsupported_pointer_format", `Unsupported chained pointer format ${format}`, `0x${from.toString(16)}`)] : []);
|
|
239
|
+
return {
|
|
240
|
+
kind: "chained",
|
|
241
|
+
formats,
|
|
242
|
+
failures: issues.map(({ message }) => message),
|
|
243
|
+
issues,
|
|
244
|
+
examined: Math.max(ranges.length, 1),
|
|
245
|
+
unreadRebaseBytes: 0,
|
|
246
|
+
decode(address, raw) {
|
|
247
|
+
const segment = ranges.find(({ from, to }) => address >= from && address < to);
|
|
248
|
+
if (segment === undefined) return {
|
|
249
|
+
kind: "rebase",
|
|
250
|
+
target: raw
|
|
251
|
+
};
|
|
252
|
+
if (raw === 0n) return {
|
|
253
|
+
kind: "rebase",
|
|
254
|
+
target: 0n
|
|
255
|
+
};
|
|
256
|
+
if (POINTER_FORMATS[segment.format] === undefined) return {
|
|
257
|
+
kind: "unsupported",
|
|
258
|
+
reason: `Unsupported chained pointer format ${segment.format}`
|
|
259
|
+
};
|
|
260
|
+
return decodeChainedPointer(raw, segment.format, baseAddress, imports);
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
};
|
|
264
|
+
uleb = (bytes, cursor, end) => {
|
|
265
|
+
let value = 0n;
|
|
266
|
+
let shift = 0n;
|
|
267
|
+
for (;;) {
|
|
268
|
+
if (cursor.at >= end) throw new RangeError("Truncated bind opcode operand");
|
|
269
|
+
const byte = bytes[cursor.at++] ?? 0;
|
|
270
|
+
value |= BigInt(byte & 127) << shift;
|
|
271
|
+
shift += 7n;
|
|
272
|
+
if ((byte & 128) === 0) return value;
|
|
273
|
+
if (shift > 63n) throw new RangeError("Oversized bind opcode operand");
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
sleb = (bytes, cursor, end) => {
|
|
277
|
+
let value = 0n;
|
|
278
|
+
let shift = 0n;
|
|
279
|
+
let byte = 0;
|
|
280
|
+
do {
|
|
281
|
+
if (cursor.at >= end) throw new RangeError("Truncated bind opcode operand");
|
|
282
|
+
byte = bytes[cursor.at++] ?? 0;
|
|
283
|
+
value |= BigInt(byte & 127) << shift;
|
|
284
|
+
shift += 7n;
|
|
285
|
+
} while ((byte & 128) !== 0 && shift <= 63n);
|
|
286
|
+
return (byte & 64) !== 0 ? value - (1n << shift) : value;
|
|
287
|
+
};
|
|
288
|
+
setBindRegister = (image, stream, state, byte) => {
|
|
289
|
+
const { bytes } = image;
|
|
290
|
+
const { cursor, end } = stream;
|
|
291
|
+
const immediate = byte & 15;
|
|
292
|
+
switch (byte & 240) {
|
|
293
|
+
case 16:
|
|
294
|
+
state.ordinal = immediate;
|
|
295
|
+
return true;
|
|
296
|
+
case 32:
|
|
297
|
+
state.ordinal = Number(uleb(bytes, cursor, end));
|
|
298
|
+
return true;
|
|
299
|
+
case 48:
|
|
300
|
+
state.ordinal = immediate === 0 ? 0 : immediate - 16;
|
|
301
|
+
return true;
|
|
302
|
+
case 64: {
|
|
303
|
+
const stop = bytes.indexOf(0, cursor.at);
|
|
304
|
+
if (stop < 0 || stop >= end) throw new RangeError("Unterminated bind symbol");
|
|
305
|
+
state.symbol = bytes.toString("utf8", cursor.at, stop);
|
|
306
|
+
state.weak = (immediate & 1) !== 0;
|
|
307
|
+
cursor.at = stop + 1;
|
|
308
|
+
return true;
|
|
309
|
+
}
|
|
310
|
+
case 80: return true;
|
|
311
|
+
case 96:
|
|
312
|
+
state.addend = sleb(bytes, cursor, end);
|
|
313
|
+
return true;
|
|
314
|
+
case 112: {
|
|
315
|
+
const segment = image.segments[immediate];
|
|
316
|
+
if (segment === undefined) throw new RangeError("Bind segment index is out of range");
|
|
317
|
+
state.segmentIndex = immediate;
|
|
318
|
+
state.address = segment.address + uleb(bytes, cursor, end);
|
|
319
|
+
return true;
|
|
320
|
+
}
|
|
321
|
+
case 128:
|
|
322
|
+
state.address = state.address + uleb(bytes, cursor, end) & 18446744073709551615n;
|
|
323
|
+
return true;
|
|
324
|
+
default: return false;
|
|
325
|
+
}
|
|
326
|
+
};
|
|
327
|
+
readBindStream = (image, range, binds) => {
|
|
328
|
+
const { bytes } = image;
|
|
329
|
+
const end = range.offset + range.size;
|
|
330
|
+
if (end > bytes.length) throw new RangeError("Bind opcodes exceed the target");
|
|
331
|
+
const cursor = { at: range.offset };
|
|
332
|
+
const state = {
|
|
333
|
+
ordinal: 0,
|
|
334
|
+
segmentIndex: -1,
|
|
335
|
+
symbol: "",
|
|
336
|
+
weak: false,
|
|
337
|
+
addend: 0n,
|
|
338
|
+
address: 0n
|
|
339
|
+
};
|
|
340
|
+
const preflightRun = (count, skip) => {
|
|
341
|
+
if (count === 0n) return;
|
|
342
|
+
const segment = image.segments[state.segmentIndex];
|
|
343
|
+
if (segment === undefined) throw new RangeError("Bind location has no selected segment");
|
|
344
|
+
const stride = 8n + skip;
|
|
345
|
+
const end = state.address + (count - 1n) * stride + 8n;
|
|
346
|
+
if (state.address < segment.address || end > segment.address + segment.size) throw new RangeError("Bind expansion leaves its file-backed segment");
|
|
347
|
+
};
|
|
348
|
+
const bind = (count, skip) => {
|
|
349
|
+
if (count === 0n) return;
|
|
350
|
+
preflightRun(count, skip);
|
|
351
|
+
const stride = 8n + skip;
|
|
352
|
+
const binding = {
|
|
353
|
+
symbol: state.symbol,
|
|
354
|
+
library: range.stream === "weak" ? null : libraryName(state.ordinal, image.dylibs),
|
|
355
|
+
weak: state.weak,
|
|
356
|
+
addend: state.addend
|
|
357
|
+
};
|
|
358
|
+
const previous = binds.at(-1);
|
|
359
|
+
if (previous !== undefined && previous.stride === stride && previous.start + previous.count * stride === state.address && previous.binding.symbol === binding.symbol && previous.binding.library === binding.library && previous.binding.weak === binding.weak && previous.binding.addend === binding.addend) {
|
|
360
|
+
previous.count += count;
|
|
361
|
+
} else {
|
|
362
|
+
binds.push({
|
|
363
|
+
start: state.address,
|
|
364
|
+
count,
|
|
365
|
+
stride,
|
|
366
|
+
binding
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
state.address += count * stride;
|
|
370
|
+
};
|
|
371
|
+
while (cursor.at < end) {
|
|
372
|
+
const byte = bytes[cursor.at++] ?? 0;
|
|
373
|
+
if (setBindRegister(image, {
|
|
374
|
+
cursor,
|
|
375
|
+
end
|
|
376
|
+
}, state, byte)) continue;
|
|
377
|
+
switch (byte & 240) {
|
|
378
|
+
case 0:
|
|
379
|
+
if (range.stream !== "lazy") return;
|
|
380
|
+
break;
|
|
381
|
+
case 144:
|
|
382
|
+
bind(1n, 0n);
|
|
383
|
+
break;
|
|
384
|
+
case 160:
|
|
385
|
+
bind(1n, uleb(bytes, cursor, end));
|
|
386
|
+
break;
|
|
387
|
+
case 176:
|
|
388
|
+
bind(1n, BigInt(byte & 15) * 8n);
|
|
389
|
+
break;
|
|
390
|
+
case 192: {
|
|
391
|
+
if (range.stream === "lazy") throw new RangeError("Lazy bind streams do not support repeated bind opcodes");
|
|
392
|
+
const count = uleb(bytes, cursor, end);
|
|
393
|
+
const skip = uleb(bytes, cursor, end);
|
|
394
|
+
bind(count, skip);
|
|
395
|
+
break;
|
|
396
|
+
}
|
|
397
|
+
default: throw new RangeError(`Unsupported bind opcode 0x${byte.toString(16)}`);
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
};
|
|
401
|
+
parsePointerFixups = (bytes, commands, segments, baseAddress) => {
|
|
402
|
+
const image = {
|
|
403
|
+
bytes,
|
|
404
|
+
segments,
|
|
405
|
+
dylibs: commands.dylibs,
|
|
406
|
+
baseAddress
|
|
407
|
+
};
|
|
408
|
+
const unreadRebaseBytes = commands.rebases.reduce((total, rebase) => total + rebase.size, 0);
|
|
409
|
+
if (commands.chained !== null) {
|
|
410
|
+
const chained = chainedFixups(image, commands.chained);
|
|
411
|
+
return unreadRebaseBytes === 0 ? chained : {
|
|
412
|
+
...chained,
|
|
413
|
+
unreadRebaseBytes
|
|
414
|
+
};
|
|
415
|
+
}
|
|
416
|
+
if (commands.binds.length === 0) return {
|
|
417
|
+
kind: "none",
|
|
418
|
+
formats: [],
|
|
419
|
+
failures: [],
|
|
420
|
+
issues: [],
|
|
421
|
+
examined: 0,
|
|
422
|
+
unreadRebaseBytes,
|
|
423
|
+
decode: (_address, raw) => ({
|
|
424
|
+
kind: "rebase",
|
|
425
|
+
target: raw
|
|
426
|
+
})
|
|
427
|
+
};
|
|
428
|
+
const binds = [];
|
|
429
|
+
const failures = [];
|
|
430
|
+
for (const stream of commands.binds) try {
|
|
431
|
+
readBindStream(image, stream, binds);
|
|
432
|
+
} catch (cause) {
|
|
433
|
+
failures.push(`${stream.stream} bind opcodes: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
434
|
+
}
|
|
435
|
+
return {
|
|
436
|
+
kind: "dyld-info",
|
|
437
|
+
formats: [],
|
|
438
|
+
failures,
|
|
439
|
+
issues: failures.map((message) => issue("pointer_fixups", "bind_stream_decode_failed", message)),
|
|
440
|
+
examined: commands.binds.length,
|
|
441
|
+
unreadRebaseBytes,
|
|
442
|
+
decode(address, raw) {
|
|
443
|
+
let match;
|
|
444
|
+
for (const run of binds) {
|
|
445
|
+
const { start, count, stride } = run;
|
|
446
|
+
const distance = address - start;
|
|
447
|
+
if (distance >= 0n && distance % stride === 0n && distance / stride < count) {
|
|
448
|
+
if (match !== undefined) return {
|
|
449
|
+
kind: "unsupported",
|
|
450
|
+
reason: `Ambiguous bind records target pointer location 0x${address.toString(16)}`
|
|
451
|
+
};
|
|
452
|
+
match = run;
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
return match === undefined ? {
|
|
456
|
+
kind: "rebase",
|
|
457
|
+
target: raw
|
|
458
|
+
} : {
|
|
459
|
+
kind: "bind",
|
|
460
|
+
...match.binding
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
};
|
|
464
|
+
};
|
|
465
|
+
})))();
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
//#endregion
|
|
469
|
+
//#region dist/native/AppleMachoSelection.js
|
|
470
|
+
var hex$2, fatHeaderFormat, selectMachoSlice, MACHO_CPU_TYPE, MH_MAGIC, MH_CIGAM, parseMachoLayout, collectSegment$1, LC_DYLD_INFO, LC_DYLD_INFO_ONLY, LC_DYLD_CHAINED_FIXUPS, DYLIB_COMMANDS$1, collectFixupCommand;
|
|
471
|
+
function init_AppleMachoSelection() {
|
|
472
|
+
return (init_AppleMachoSelection = __esmMin((() => {
|
|
473
|
+
init_machoContainer();
|
|
474
|
+
hex$2 = (value) => `0x${value.toString(16)}`;
|
|
475
|
+
fatHeaderFormat = (magic) => {
|
|
476
|
+
switch (magic) {
|
|
477
|
+
case 3405691582: return {
|
|
478
|
+
littleEndian: false,
|
|
479
|
+
fat64: false
|
|
480
|
+
};
|
|
481
|
+
case 3405691583: return {
|
|
482
|
+
littleEndian: false,
|
|
483
|
+
fat64: true
|
|
484
|
+
};
|
|
485
|
+
case 3199925962: return {
|
|
486
|
+
littleEndian: true,
|
|
487
|
+
fat64: false
|
|
488
|
+
};
|
|
489
|
+
case 3216703178: return {
|
|
490
|
+
littleEndian: true,
|
|
491
|
+
fat64: true
|
|
492
|
+
};
|
|
493
|
+
default: return null;
|
|
494
|
+
}
|
|
495
|
+
};
|
|
496
|
+
selectMachoSlice = (bytes, architecture) => {
|
|
497
|
+
const magic = bytes.readUInt32BE(0);
|
|
498
|
+
const header = fatHeaderFormat(magic);
|
|
499
|
+
if (header === null) return {
|
|
500
|
+
slice: 0,
|
|
501
|
+
sliceEnd: bytes.length
|
|
502
|
+
};
|
|
503
|
+
const { littleEndian, fat64 } = header;
|
|
504
|
+
const stride = fat64 ? 32 : 20;
|
|
505
|
+
const readUInt32 = littleEndian ? (offset) => bytes.readUInt32LE(offset) : (offset) => bytes.readUInt32BE(offset);
|
|
506
|
+
const byteOrder = littleEndian ? "little-endian" : "big-endian";
|
|
507
|
+
const malformed = (reason) => new RangeError(`${reason} (FAT header byte order: ${byteOrder})`);
|
|
508
|
+
const invalid = (reason) => new TypeError(`${reason} (FAT header byte order: ${byteOrder})`);
|
|
509
|
+
if (bytes.length < 8) throw malformed("Malformed FAT architecture table");
|
|
510
|
+
const count = readUInt32(4);
|
|
511
|
+
const headerEnd = 8 + count * stride;
|
|
512
|
+
if (count > 128 || headerEnd > bytes.length) throw malformed("Malformed FAT architecture table");
|
|
513
|
+
const cpu = MACHO_CPU_TYPE[architecture];
|
|
514
|
+
if (cpu === undefined) throw invalid("Requested FAT architecture is absent");
|
|
515
|
+
const declarations = readFatSliceDeclarations(bytes.subarray(8, headerEnd), {
|
|
516
|
+
count,
|
|
517
|
+
wide: fat64,
|
|
518
|
+
littleEndian
|
|
519
|
+
});
|
|
520
|
+
if (declarations.status !== "parsed") throw malformed(declarations.reason);
|
|
521
|
+
let selected;
|
|
522
|
+
for (const declaration of declarations.slices) {
|
|
523
|
+
const issue = validateFatSlice(declaration, bytes.length, headerEnd);
|
|
524
|
+
if (issue !== null) throw malformed(issue);
|
|
525
|
+
if (declaration.cpuType !== cpu) continue;
|
|
526
|
+
if (selected !== undefined) throw invalid("Ambiguous FAT architecture slice");
|
|
527
|
+
selected = {
|
|
528
|
+
slice: declaration.offset,
|
|
529
|
+
sliceEnd: declaration.offset + declaration.size,
|
|
530
|
+
fatDeclaration: {
|
|
531
|
+
...declaration,
|
|
532
|
+
tableEnd: headerEnd
|
|
533
|
+
}
|
|
534
|
+
};
|
|
535
|
+
}
|
|
536
|
+
if (selected === undefined) throw invalid("Requested FAT architecture is absent");
|
|
537
|
+
if (selected.slice + 4 > bytes.length) throw malformed("Truncated Mach-O header");
|
|
538
|
+
const sliceMagic = bytes.readUInt32LE(selected.slice);
|
|
539
|
+
if (sliceMagic === MH_MAGIC || sliceMagic === MH_CIGAM) throw invalid(`Unsupported 32-bit Mach-O metadata for requested CPU type ${architecture}`);
|
|
540
|
+
return selected;
|
|
541
|
+
};
|
|
542
|
+
MACHO_CPU_TYPE = {
|
|
543
|
+
x86: 7,
|
|
544
|
+
x86_64: 16777223,
|
|
545
|
+
arm: 12,
|
|
546
|
+
arm64: 16777228
|
|
547
|
+
};
|
|
548
|
+
MH_MAGIC = 4277009102;
|
|
549
|
+
MH_CIGAM = 3472551422;
|
|
550
|
+
parseMachoLayout = (bytes, architecture) => {
|
|
551
|
+
if (bytes.length < 4) throw new RangeError("Truncated Mach-O header");
|
|
552
|
+
const selection = selectMachoSlice(bytes, architecture);
|
|
553
|
+
const { slice, sliceEnd } = selection;
|
|
554
|
+
if (slice === 0 && sliceEnd === bytes.length && bytes.length < 32) throw new RangeError("Truncated Mach-O header");
|
|
555
|
+
if (slice + 32 > sliceEnd || bytes.readUInt32LE(slice) !== 4277009103) throw new TypeError("Only little-endian 64-bit Mach-O metadata is supported");
|
|
556
|
+
const fat = selection.fatDeclaration;
|
|
557
|
+
if (fat !== undefined) {
|
|
558
|
+
const issue = validateFatSlice(fat, bytes.length, fat.tableEnd, {
|
|
559
|
+
cpuType: bytes.readUInt32LE(slice + 4),
|
|
560
|
+
cpuSubtype: bytes.readUInt32LE(slice + 8)
|
|
561
|
+
});
|
|
562
|
+
if (issue !== null) throw new TypeError(issue);
|
|
563
|
+
}
|
|
564
|
+
const commands = bytes.readUInt32LE(slice + 16);
|
|
565
|
+
const commandEnd = slice + 32 + bytes.readUInt32LE(slice + 20);
|
|
566
|
+
if (commands > 4096 || commandEnd > sliceEnd) throw new RangeError("Malformed Mach-O command bounds");
|
|
567
|
+
const state = {
|
|
568
|
+
slice,
|
|
569
|
+
sliceEnd,
|
|
570
|
+
segments: [],
|
|
571
|
+
sections: [],
|
|
572
|
+
dylibs: [],
|
|
573
|
+
binds: [],
|
|
574
|
+
rebases: [],
|
|
575
|
+
chained: null,
|
|
576
|
+
baseAddress: undefined
|
|
577
|
+
};
|
|
578
|
+
let cursor = slice + 32;
|
|
579
|
+
for (let index = 0; index < commands; index++) {
|
|
580
|
+
if (cursor + 8 > commandEnd) throw new RangeError("Truncated load command");
|
|
581
|
+
const command = {
|
|
582
|
+
cursor,
|
|
583
|
+
kind: bytes.readUInt32LE(cursor),
|
|
584
|
+
size: bytes.readUInt32LE(cursor + 4)
|
|
585
|
+
};
|
|
586
|
+
if (command.size < 8 || cursor + command.size > commandEnd) throw new RangeError("Invalid load command size");
|
|
587
|
+
if (command.kind === 25) collectSegment$1(bytes, command, state);
|
|
588
|
+
else collectFixupCommand(bytes, command, state);
|
|
589
|
+
cursor += command.size;
|
|
590
|
+
}
|
|
591
|
+
const { segments, sections, chained, binds, rebases, dylibs } = state;
|
|
592
|
+
const offset = (address, size = 1) => {
|
|
593
|
+
const matches = segments.filter((segment) => address >= segment.address && address + BigInt(size) <= segment.address + segment.size);
|
|
594
|
+
if (matches.length !== 1) throw new RangeError(`Unmapped or ambiguous metadata pointer ${hex$2(address)}`);
|
|
595
|
+
const segment = matches[0];
|
|
596
|
+
if (segment === undefined) throw new RangeError("Missing metadata segment");
|
|
597
|
+
return segment.offset + Number(address - segment.address);
|
|
598
|
+
};
|
|
599
|
+
return {
|
|
600
|
+
segments,
|
|
601
|
+
sections,
|
|
602
|
+
offset,
|
|
603
|
+
fixups: {
|
|
604
|
+
chained,
|
|
605
|
+
binds,
|
|
606
|
+
rebases,
|
|
607
|
+
dylibs
|
|
608
|
+
},
|
|
609
|
+
baseAddress: state.baseAddress ?? 0n
|
|
610
|
+
};
|
|
611
|
+
};
|
|
612
|
+
collectSegment$1 = (bytes, { cursor, size }, state) => {
|
|
613
|
+
if (size < 72) throw new RangeError("Truncated segment command");
|
|
614
|
+
const address = bytes.readBigUInt64LE(cursor + 24), fileSize = bytes.readBigUInt64LE(cursor + 48), fileOffset = bytes.readBigUInt64LE(cursor + 40);
|
|
615
|
+
if (fileOffset + fileSize > BigInt(state.sliceEnd - state.slice)) throw new RangeError("Segment file range exceeds target bytes");
|
|
616
|
+
state.segments.push({
|
|
617
|
+
address,
|
|
618
|
+
size: fileSize,
|
|
619
|
+
offset: state.slice + Number(fileOffset),
|
|
620
|
+
executable: (bytes.readUInt32LE(cursor + 60) & 4) !== 0
|
|
621
|
+
});
|
|
622
|
+
if (fileOffset === 0n && fileSize > 0n) state.baseAddress ??= address;
|
|
623
|
+
const count = bytes.readUInt32LE(cursor + 64);
|
|
624
|
+
if (72 + count * 80 > size) throw new RangeError("Truncated section table");
|
|
625
|
+
for (let section = 0; section < count; section++) {
|
|
626
|
+
const position = cursor + 72 + section * 80;
|
|
627
|
+
const sectionSize = bytes.readBigUInt64LE(position + 40);
|
|
628
|
+
if (sectionSize > BigInt(Number.MAX_SAFE_INTEGER)) throw new RangeError("Section size exceeds exact numeric range");
|
|
629
|
+
state.sections.push({
|
|
630
|
+
name: bytes.subarray(position, position + 16).toString("ascii").replace(/\0.*$/u, ""),
|
|
631
|
+
address: bytes.readBigUInt64LE(position + 32),
|
|
632
|
+
size: Number(sectionSize)
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
};
|
|
636
|
+
LC_DYLD_INFO = 34;
|
|
637
|
+
LC_DYLD_INFO_ONLY = 2147483682;
|
|
638
|
+
LC_DYLD_CHAINED_FIXUPS = 2147483700;
|
|
639
|
+
DYLIB_COMMANDS$1 = [
|
|
640
|
+
12,
|
|
641
|
+
2147483672,
|
|
642
|
+
2147483679,
|
|
643
|
+
32,
|
|
644
|
+
2147483683
|
|
645
|
+
];
|
|
646
|
+
collectFixupCommand = (bytes, { cursor, kind, size }, state) => {
|
|
647
|
+
const range = (at) => {
|
|
648
|
+
const offset = state.slice + bytes.readUInt32LE(at);
|
|
649
|
+
const length = bytes.readUInt32LE(at + 4);
|
|
650
|
+
if (offset + length > state.sliceEnd) throw new RangeError("Fixup data exceeds the Mach-O slice");
|
|
651
|
+
return {
|
|
652
|
+
offset,
|
|
653
|
+
size: length
|
|
654
|
+
};
|
|
655
|
+
};
|
|
656
|
+
if (kind === LC_DYLD_CHAINED_FIXUPS) {
|
|
657
|
+
if (size < 16) throw new RangeError("Truncated chained-fixups command");
|
|
658
|
+
state.chained = range(cursor + 8);
|
|
659
|
+
} else if (kind === LC_DYLD_INFO || kind === LC_DYLD_INFO_ONLY) {
|
|
660
|
+
if (size < 48) throw new RangeError("Truncated dyld-info command");
|
|
661
|
+
const rebase = range(cursor + 8);
|
|
662
|
+
if (rebase.size > 0) state.rebases.push(rebase);
|
|
663
|
+
for (const [at, stream] of [
|
|
664
|
+
[cursor + 16, "bind"],
|
|
665
|
+
[cursor + 24, "weak"],
|
|
666
|
+
[cursor + 32, "lazy"]
|
|
667
|
+
]) {
|
|
668
|
+
const bound = range(at);
|
|
669
|
+
if (bound.size > 0) state.binds.push({
|
|
670
|
+
...bound,
|
|
671
|
+
stream
|
|
672
|
+
});
|
|
673
|
+
}
|
|
674
|
+
} else if (DYLIB_COMMANDS$1.includes(kind)) {
|
|
675
|
+
if (size < 24) throw new RangeError("Truncated dylib command");
|
|
676
|
+
const nameOffset = bytes.readUInt32LE(cursor + 8);
|
|
677
|
+
if (nameOffset < 24 || nameOffset >= size) throw new RangeError("Dylib install name is outside its load command");
|
|
678
|
+
const end = bytes.indexOf(0, cursor + nameOffset);
|
|
679
|
+
if (end < 0 || end >= cursor + size) throw new RangeError("Unterminated dylib install name");
|
|
680
|
+
state.dylibs.push(bytes.toString("utf8", cursor + nameOffset, end));
|
|
681
|
+
}
|
|
682
|
+
};
|
|
683
|
+
})))();
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
//#endregion
|
|
687
|
+
//#region dist/native/AppleObjcProperties.js
|
|
688
|
+
var parsePropertyAttributes, splitAttributes, readObjcPropertyList, readObjcPropertiesOf;
|
|
689
|
+
function init_AppleObjcProperties() {
|
|
690
|
+
return (init_AppleObjcProperties = __esmMin((() => {
|
|
691
|
+
init_AppleDispatchDecodeFacts();
|
|
692
|
+
parsePropertyAttributes = (name, attributes) => {
|
|
693
|
+
const tokens = attributes.length === 0 ? [] : splitAttributes(attributes);
|
|
694
|
+
const typeAttributes = tokens.filter((token) => token[0] === "T");
|
|
695
|
+
const typeAttribute = typeAttributes.length === 1 ? typeAttributes[0] : undefined;
|
|
696
|
+
const typeEncoding = typeAttribute !== undefined && typeAttribute.length > 1 ? typeAttribute.slice(1) : null;
|
|
697
|
+
const value = (code) => tokens.find((token) => token[0] === code)?.slice(1) ?? null;
|
|
698
|
+
return {
|
|
699
|
+
name,
|
|
700
|
+
type_encoding: typeEncoding,
|
|
701
|
+
attributes: tokens.map((token) => ({
|
|
702
|
+
name: token.slice(0, 1),
|
|
703
|
+
value: token.slice(1)
|
|
704
|
+
})),
|
|
705
|
+
atomicity: tokens.includes("N") ? "nonatomic" : typeEncoding === null ? null : "atomic",
|
|
706
|
+
is_readonly: tokens.includes("R") ? true : typeEncoding === null ? null : false,
|
|
707
|
+
getter: value("G"),
|
|
708
|
+
setter: value("S")
|
|
709
|
+
};
|
|
710
|
+
};
|
|
711
|
+
splitAttributes = (attributes) => {
|
|
712
|
+
const tokens = [];
|
|
713
|
+
let current = "";
|
|
714
|
+
let quoted = false;
|
|
715
|
+
for (const character of attributes) {
|
|
716
|
+
if (character === "\"") quoted = !quoted;
|
|
717
|
+
if (character === "," && !quoted) {
|
|
718
|
+
tokens.push(current);
|
|
719
|
+
current = "";
|
|
720
|
+
} else current += character;
|
|
721
|
+
}
|
|
722
|
+
tokens.push(current);
|
|
723
|
+
return tokens.filter((token) => token.length > 0);
|
|
724
|
+
};
|
|
725
|
+
readObjcPropertyList = (read, list, admit) => {
|
|
726
|
+
if (list === 0n) return [];
|
|
727
|
+
const entrySize = read.u32(list) & ~3;
|
|
728
|
+
const count = read.u32(list + 4n);
|
|
729
|
+
if (entrySize !== 16) throw new TypeError(`Unsupported Objective-C property entry size ${entrySize}`);
|
|
730
|
+
const properties = [];
|
|
731
|
+
for (let index = 0; index < count; index++) {
|
|
732
|
+
if (!admit()) break;
|
|
733
|
+
const entry = list + 8n + BigInt(index * entrySize);
|
|
734
|
+
properties.push(parsePropertyAttributes(read.string(read.pointer(entry)), read.string(read.pointer(entry + 8n))));
|
|
735
|
+
}
|
|
736
|
+
return properties;
|
|
737
|
+
};
|
|
738
|
+
readObjcPropertiesOf = (read, list, context) => {
|
|
739
|
+
try {
|
|
740
|
+
return readObjcPropertyList(read, list, context.admit);
|
|
741
|
+
} catch (cause) {
|
|
742
|
+
context.issues.push(issue("objc_properties_categories", "property_decode_failed", `${context.owner}: ${cause instanceof Error ? cause.message : String(cause)}`, context.location));
|
|
743
|
+
return [];
|
|
744
|
+
}
|
|
745
|
+
};
|
|
746
|
+
})))();
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
//#endregion
|
|
750
|
+
//#region dist/native/AppleObjcCategories.js
|
|
751
|
+
var CLASS_SYMBOL, boundClassName, decodeObjcCategories;
|
|
752
|
+
function init_AppleObjcCategories() {
|
|
753
|
+
return (init_AppleObjcCategories = __esmMin((() => {
|
|
754
|
+
init_AppleObjcProperties();
|
|
755
|
+
init_AppleDispatchDecodeFacts();
|
|
756
|
+
CLASS_SYMBOL = /^_OBJC_(?:META)?CLASS_\$_(.+)$/u;
|
|
757
|
+
boundClassName = (read, field) => {
|
|
758
|
+
const bound = read.bound(field);
|
|
759
|
+
return bound === undefined ? undefined : CLASS_SYMBOL.exec(bound.symbol)?.[1];
|
|
760
|
+
};
|
|
761
|
+
decodeObjcCategories = (input) => {
|
|
762
|
+
const { read, result, failures } = input;
|
|
763
|
+
let examined = 0;
|
|
764
|
+
for (const section of input.sections.filter(({ name }) => name === "__objc_catlist")) {
|
|
765
|
+
if (section.size % 8 !== 0) throw new RangeError("Misaligned Objective-C category list");
|
|
766
|
+
for (let index = 0; index < section.size / 8; index++) {
|
|
767
|
+
if (!input.admit()) break;
|
|
768
|
+
examined++;
|
|
769
|
+
const field = section.address + BigInt(index * 8);
|
|
770
|
+
try {
|
|
771
|
+
const category = read.pointer(field);
|
|
772
|
+
const name = read.string(read.pointer(category));
|
|
773
|
+
const external = boundClassName(read, category + 8n);
|
|
774
|
+
const local = read.pointer(category + 8n);
|
|
775
|
+
const className = external ?? (local === 0n ? null : input.localClassName(local));
|
|
776
|
+
const owner = className ?? `(${name})`;
|
|
777
|
+
result.objc_categories.push({
|
|
778
|
+
name,
|
|
779
|
+
class_name: className,
|
|
780
|
+
class_source: external !== undefined ? "external" : className === null ? "unresolved" : "local",
|
|
781
|
+
instance_methods: input.methods(read.pointer(category + 16n), owner, "instance", name),
|
|
782
|
+
class_methods: input.methods(read.pointer(category + 24n), owner, "class", name),
|
|
783
|
+
protocols: input.protocols(read.pointer(category + 32n)),
|
|
784
|
+
properties: readObjcPropertiesOf(read, read.pointer(category + 40n), {
|
|
785
|
+
owner: `category ${name}`,
|
|
786
|
+
admit: input.admit,
|
|
787
|
+
issues: input.issues,
|
|
788
|
+
location: `0x${read.pointer(category + 40n).toString(16)}`
|
|
789
|
+
}),
|
|
790
|
+
location: read.location(category),
|
|
791
|
+
decode: className === null ? {
|
|
792
|
+
status: "partial",
|
|
793
|
+
reason: "category_class_unresolved"
|
|
794
|
+
} : {
|
|
795
|
+
status: "decoded",
|
|
796
|
+
reason: null
|
|
797
|
+
},
|
|
798
|
+
evidence: read.evidence(category, "Objective-C category_t record")
|
|
799
|
+
});
|
|
800
|
+
} catch (cause) {
|
|
801
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
802
|
+
failures.push(`Category at 0x${field.toString(16)}: ${message}`);
|
|
803
|
+
input.issues.push(issue("objc_properties_categories", "category_decode_failed", message, `0x${field.toString(16)}`));
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
}
|
|
807
|
+
return examined;
|
|
808
|
+
};
|
|
809
|
+
})))();
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
//#endregion
|
|
813
|
+
//#region dist/native/AppleObjcProtocols.js
|
|
814
|
+
var createObjcProtocolReader;
|
|
815
|
+
function init_AppleObjcProtocols() {
|
|
816
|
+
return (init_AppleObjcProtocols = __esmMin((() => {
|
|
817
|
+
createObjcProtocolReader = (input) => {
|
|
818
|
+
const { readers: read, result, failures } = input;
|
|
819
|
+
const visited = new Set();
|
|
820
|
+
const name = (address) => read.string(read.pointer(address + 8n));
|
|
821
|
+
const list = (address) => {
|
|
822
|
+
if (address === 0n) return [];
|
|
823
|
+
const count = read.u64(address);
|
|
824
|
+
if (count > 20000n) throw new RangeError("Protocol list exceeds 20000 entries");
|
|
825
|
+
const names = [];
|
|
826
|
+
for (let index = 0n; index < count; index++) {
|
|
827
|
+
if (!read.admit()) break;
|
|
828
|
+
const protocol = read.pointer(address + 8n + index * 8n);
|
|
829
|
+
names.push(name(protocol));
|
|
830
|
+
record(protocol);
|
|
831
|
+
}
|
|
832
|
+
return names;
|
|
833
|
+
};
|
|
834
|
+
const methods = (address, required, instance) => {
|
|
835
|
+
const output = [];
|
|
836
|
+
if (address === 0n) return output;
|
|
837
|
+
const flags = read.u32(address), count = read.u32(address + 4n);
|
|
838
|
+
const relative = (flags & 2147483648) !== 0;
|
|
839
|
+
const stride = flags & 65532;
|
|
840
|
+
if (stride !== (relative ? 12 : 24)) throw new TypeError("Unsupported Objective-C protocol method entry size");
|
|
841
|
+
for (let index = 0; index < count; index++) {
|
|
842
|
+
if (!read.admit()) break;
|
|
843
|
+
const entry = address + 8n + BigInt(index * stride);
|
|
844
|
+
let selector = relative ? entry + BigInt(read.i32(entry)) : read.pointer(entry);
|
|
845
|
+
if (relative && (flags & 1073741824) === 0) selector = read.pointer(selector);
|
|
846
|
+
output.push({
|
|
847
|
+
selector: read.string(selector),
|
|
848
|
+
method_type: instance ? "instance" : "class",
|
|
849
|
+
address: null,
|
|
850
|
+
is_required: required,
|
|
851
|
+
is_optional: !required
|
|
852
|
+
});
|
|
853
|
+
}
|
|
854
|
+
return output;
|
|
855
|
+
};
|
|
856
|
+
const record = (address) => {
|
|
857
|
+
if (address === 0n || visited.has(address) || !read.admit()) return;
|
|
858
|
+
visited.add(address);
|
|
859
|
+
try {
|
|
860
|
+
if (read.u32(address + 64n) < 72) throw new RangeError("Truncated Objective-C protocol declaration");
|
|
861
|
+
const protocolName = name(address);
|
|
862
|
+
const adopted = list(read.pointer(address + 16n));
|
|
863
|
+
const required = [...methods(read.pointer(address + 24n), true, true), ...methods(read.pointer(address + 32n), true, false)];
|
|
864
|
+
const optional = [...methods(read.pointer(address + 40n), false, true), ...methods(read.pointer(address + 48n), false, false)];
|
|
865
|
+
result.objc_protocols.push({
|
|
866
|
+
name: protocolName,
|
|
867
|
+
methods: required,
|
|
868
|
+
optional_methods: optional,
|
|
869
|
+
properties: []
|
|
870
|
+
});
|
|
871
|
+
result.objc_protocol_records.push({
|
|
872
|
+
name: protocolName,
|
|
873
|
+
adopted_protocols: adopted,
|
|
874
|
+
methods: required,
|
|
875
|
+
optional_methods: optional,
|
|
876
|
+
location: read.location(address),
|
|
877
|
+
decode: {
|
|
878
|
+
status: "decoded",
|
|
879
|
+
reason: null
|
|
880
|
+
},
|
|
881
|
+
evidence: read.evidence(address, "Objective-C protocol declaration and encoded method lists; IMP fields are not handler targets")
|
|
882
|
+
});
|
|
883
|
+
} catch (cause) {
|
|
884
|
+
failures.push(`Protocol 0x${address.toString(16)}: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
885
|
+
}
|
|
886
|
+
};
|
|
887
|
+
return {
|
|
888
|
+
list,
|
|
889
|
+
record
|
|
890
|
+
};
|
|
891
|
+
};
|
|
892
|
+
})))();
|
|
893
|
+
}
|
|
894
|
+
|
|
895
|
+
//#endregion
|
|
896
|
+
//#region dist/native/AppleObjcDispatchFacets.js
|
|
897
|
+
var hex$1, decoded$1, localClassName, resolveSuperclass, decodeObjcDispatchFacets;
|
|
898
|
+
function init_AppleObjcDispatchFacets() {
|
|
899
|
+
return (init_AppleObjcDispatchFacets = __esmMin((() => {
|
|
900
|
+
init_AppleObjcCategories();
|
|
901
|
+
init_AppleObjcProperties();
|
|
902
|
+
init_AppleObjcProtocols();
|
|
903
|
+
hex$1 = (value) => `0x${value.toString(16)}`;
|
|
904
|
+
decoded$1 = {
|
|
905
|
+
status: "decoded",
|
|
906
|
+
reason: null
|
|
907
|
+
};
|
|
908
|
+
localClassName = (read, address) => read.string(read.pointer((read.pointer(address + 32n) & ~7n) + 24n));
|
|
909
|
+
resolveSuperclass = (read, address, className, failures) => {
|
|
910
|
+
const external = boundClassName(read, address + 8n);
|
|
911
|
+
if (external !== undefined) return {
|
|
912
|
+
name: external,
|
|
913
|
+
address: null
|
|
914
|
+
};
|
|
915
|
+
const superclass = read.pointer(address + 8n);
|
|
916
|
+
if (superclass === 0n) return {
|
|
917
|
+
name: null,
|
|
918
|
+
address: null
|
|
919
|
+
};
|
|
920
|
+
try {
|
|
921
|
+
return {
|
|
922
|
+
name: localClassName(read, superclass),
|
|
923
|
+
address: hex$1(superclass)
|
|
924
|
+
};
|
|
925
|
+
} catch (cause) {
|
|
926
|
+
void cause;
|
|
927
|
+
failures.push(`Superclass pointer ${hex$1(superclass)} of ${className} requires unsupported binding/fixup resolution`);
|
|
928
|
+
return {
|
|
929
|
+
name: null,
|
|
930
|
+
address: hex$1(superclass)
|
|
931
|
+
};
|
|
932
|
+
}
|
|
933
|
+
};
|
|
934
|
+
decodeObjcDispatchFacets = (input) => {
|
|
935
|
+
const { bytes, sections, segments, readers: read, budget, result } = input;
|
|
936
|
+
const failures = [];
|
|
937
|
+
const categoryIssues = [];
|
|
938
|
+
let examined = 0;
|
|
939
|
+
const methods = (list, className, methodType, category) => {
|
|
940
|
+
const selectors = [];
|
|
941
|
+
if (list === 0n) return selectors;
|
|
942
|
+
const flags = read.u32(list), count = read.u32(list + 4n), relative = (flags & 2147483648) !== 0;
|
|
943
|
+
const stride = flags & 65532;
|
|
944
|
+
if (stride !== (relative ? 12 : 24)) throw new TypeError(`Unsupported method stride/flags at ${hex$1(list)}`);
|
|
945
|
+
for (let index = 0; index < count; index++) {
|
|
946
|
+
if (!budget.admit()) break;
|
|
947
|
+
const entry = list + 8n + BigInt(index * stride);
|
|
948
|
+
const rel = (field) => {
|
|
949
|
+
const displacement = bytes.readInt32LE(read.offset(field, 4));
|
|
950
|
+
const target = field + BigInt(displacement);
|
|
951
|
+
let fileOffset = null;
|
|
952
|
+
try {
|
|
953
|
+
fileOffset = read.offset(target);
|
|
954
|
+
} catch (cause) {
|
|
955
|
+
void cause;
|
|
956
|
+
}
|
|
957
|
+
if (budget.admit()) result.relative_pointers.push({
|
|
958
|
+
field: read.location(field),
|
|
959
|
+
target: {
|
|
960
|
+
address: hex$1(target),
|
|
961
|
+
file_offset: fileOffset
|
|
962
|
+
},
|
|
963
|
+
displacement,
|
|
964
|
+
indirectable: false,
|
|
965
|
+
indirect: false,
|
|
966
|
+
decode: fileOffset === null ? {
|
|
967
|
+
status: "partial",
|
|
968
|
+
reason: "relative_target_unmapped"
|
|
969
|
+
} : decoded$1,
|
|
970
|
+
evidence: read.evidence(field, "Signed-relative Objective-C method-list pointer")
|
|
971
|
+
});
|
|
972
|
+
return target;
|
|
973
|
+
};
|
|
974
|
+
let selectorAddress = relative ? rel(entry) : read.pointer(entry);
|
|
975
|
+
if (relative && (flags & 1073741824) === 0) selectorAddress = read.pointer(selectorAddress);
|
|
976
|
+
const implementation = relative ? rel(entry + 8n) : read.pointer(entry + 16n);
|
|
977
|
+
let implementationLocation = null;
|
|
978
|
+
try {
|
|
979
|
+
if (!segments.some((segment) => segment.executable && implementation >= segment.address && implementation < segment.address + segment.size)) throw new RangeError("Method implementation is not in an executable segment");
|
|
980
|
+
implementationLocation = read.location(implementation);
|
|
981
|
+
} catch (cause) {
|
|
982
|
+
void cause;
|
|
983
|
+
}
|
|
984
|
+
const selector = read.string(selectorAddress);
|
|
985
|
+
selectors.push(selector);
|
|
986
|
+
result.objc_dispatch_implementations.push({
|
|
987
|
+
class_name: className,
|
|
988
|
+
selector,
|
|
989
|
+
method_type: methodType,
|
|
990
|
+
...category === undefined ? {} : { category },
|
|
991
|
+
implementation_address: implementationLocation?.address ?? null,
|
|
992
|
+
location: read.location(entry),
|
|
993
|
+
decode: implementationLocation === null ? {
|
|
994
|
+
status: "partial",
|
|
995
|
+
reason: "implementation_pointer_unmapped_or_encoded"
|
|
996
|
+
} : decoded$1,
|
|
997
|
+
evidence: read.evidence(entry, relative ? "Encoded relative Objective-C method entry" : "Encoded absolute Objective-C method entry")
|
|
998
|
+
});
|
|
999
|
+
}
|
|
1000
|
+
return selectors;
|
|
1001
|
+
};
|
|
1002
|
+
const protocolReader = createObjcProtocolReader({
|
|
1003
|
+
readers: {
|
|
1004
|
+
u32: read.u32,
|
|
1005
|
+
pointer: read.pointer,
|
|
1006
|
+
string: read.string,
|
|
1007
|
+
location: read.location,
|
|
1008
|
+
evidence: read.evidence,
|
|
1009
|
+
admit: () => budget.admit(),
|
|
1010
|
+
i32: read.i32,
|
|
1011
|
+
u64: read.u64
|
|
1012
|
+
},
|
|
1013
|
+
result,
|
|
1014
|
+
failures
|
|
1015
|
+
});
|
|
1016
|
+
for (const section of sections.filter(({ name }) => name === "__objc_protolist")) {
|
|
1017
|
+
if (section.size % 8 !== 0) throw new RangeError("Misaligned Objective-C protocol list");
|
|
1018
|
+
for (let index = 0; index < section.size / 8; index++) {
|
|
1019
|
+
if (budget.isFull()) {
|
|
1020
|
+
budget.markTruncated();
|
|
1021
|
+
break;
|
|
1022
|
+
}
|
|
1023
|
+
protocolReader.record(read.pointer(section.address + BigInt(index * 8)));
|
|
1024
|
+
}
|
|
1025
|
+
}
|
|
1026
|
+
const visited = new Set();
|
|
1027
|
+
const readClass = (address, meta = false) => {
|
|
1028
|
+
if (address === 0n || visited.has(hex$1(address)) || !budget.admit()) return;
|
|
1029
|
+
visited.add(hex$1(address));
|
|
1030
|
+
const ro = read.pointer(address + 32n) & ~7n;
|
|
1031
|
+
const name = read.string(read.pointer(ro + 24n));
|
|
1032
|
+
const root = (read.u32(ro) & 2) !== 0;
|
|
1033
|
+
const superclass = resolveSuperclass(read, address, name, failures);
|
|
1034
|
+
if (superclass.name === null && superclass.address === null && !root) failures.push(`Superclass of ${name} requires external binding resolution`);
|
|
1035
|
+
const ivarList = read.pointer(ro + 48n);
|
|
1036
|
+
let ivarCount = meta ? null : 0;
|
|
1037
|
+
if (ivarList !== 0n && !meta) {
|
|
1038
|
+
const stride = read.u32(ivarList), count = read.u32(ivarList + 4n);
|
|
1039
|
+
if (stride !== 32) throw new TypeError("Unsupported Objective-C ivar entry size");
|
|
1040
|
+
ivarCount = count;
|
|
1041
|
+
for (let index = 0; index < count; index++) {
|
|
1042
|
+
if (!budget.admit()) break;
|
|
1043
|
+
const entry = ivarList + 8n + BigInt(index * stride);
|
|
1044
|
+
const encodedOffset = read.pointer(entry);
|
|
1045
|
+
let value = null;
|
|
1046
|
+
try {
|
|
1047
|
+
value = read.u32(encodedOffset);
|
|
1048
|
+
} catch (cause) {
|
|
1049
|
+
void cause;
|
|
1050
|
+
failures.push(`Unresolved ivar offset pointer ${hex$1(encodedOffset)}`);
|
|
1051
|
+
}
|
|
1052
|
+
result.objc_ivars.push({
|
|
1053
|
+
class_name: name,
|
|
1054
|
+
name: read.string(read.pointer(entry + 8n)),
|
|
1055
|
+
type_encoding: read.string(read.pointer(entry + 16n)),
|
|
1056
|
+
offset: value,
|
|
1057
|
+
size: read.u32(entry + 28n),
|
|
1058
|
+
alignment: read.u32(entry + 24n) < 31 ? 2 ** read.u32(entry + 24n) : null,
|
|
1059
|
+
location: read.location(entry),
|
|
1060
|
+
decode: value === null ? {
|
|
1061
|
+
status: "partial",
|
|
1062
|
+
reason: "ivar_offset_pointer_unresolved"
|
|
1063
|
+
} : decoded$1,
|
|
1064
|
+
evidence: read.evidence(entry, "Objective-C ivar entry and encoded offset storage")
|
|
1065
|
+
});
|
|
1066
|
+
}
|
|
1067
|
+
}
|
|
1068
|
+
methods(read.pointer(ro + 32n), name, meta ? "class" : "instance");
|
|
1069
|
+
result.objc_classes.push({
|
|
1070
|
+
name,
|
|
1071
|
+
super_class: superclass.name,
|
|
1072
|
+
is_meta_class: meta,
|
|
1073
|
+
is_root_class: root,
|
|
1074
|
+
methods: result.objc_dispatch_implementations.filter((item) => item.class_name === name && item.method_type === (meta ? "class" : "instance")).map((item) => ({
|
|
1075
|
+
selector: item.selector,
|
|
1076
|
+
method_type: item.method_type,
|
|
1077
|
+
address: item.implementation_address !== null && BigInt(item.implementation_address) <= BigInt(Number.MAX_SAFE_INTEGER) ? Number(BigInt(item.implementation_address)) : null,
|
|
1078
|
+
is_required: null,
|
|
1079
|
+
is_optional: null
|
|
1080
|
+
})),
|
|
1081
|
+
properties: readObjcPropertiesOf(read, read.pointer(ro + 64n), {
|
|
1082
|
+
owner: name,
|
|
1083
|
+
admit: () => budget.admit(),
|
|
1084
|
+
issues: categoryIssues,
|
|
1085
|
+
location: hex$1(read.pointer(ro + 64n))
|
|
1086
|
+
}),
|
|
1087
|
+
protocols: protocolReader.list(read.pointer(ro + 40n)),
|
|
1088
|
+
ivar_count: ivarCount,
|
|
1089
|
+
instance_size: read.u32(ro + 8n),
|
|
1090
|
+
location: read.location(address),
|
|
1091
|
+
superclass_address: superclass.address,
|
|
1092
|
+
metaclass_address: meta ? null : hex$1(read.pointer(address)),
|
|
1093
|
+
decode: superclass.name === null && !root ? {
|
|
1094
|
+
status: "partial",
|
|
1095
|
+
reason: "superclass_binding_unresolved"
|
|
1096
|
+
} : decoded$1,
|
|
1097
|
+
evidence: read.evidence(address, "Objective-C class and class_ro_t records")
|
|
1098
|
+
});
|
|
1099
|
+
if (!meta) {
|
|
1100
|
+
try {
|
|
1101
|
+
readClass(read.pointer(address), true);
|
|
1102
|
+
} catch (cause) {
|
|
1103
|
+
failures.push(`Metaclass of ${name}: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
1104
|
+
}
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
1107
|
+
for (const section of sections.filter(({ name }) => name === "__objc_classlist")) {
|
|
1108
|
+
if (section.size % 8 !== 0) throw new RangeError("Misaligned Objective-C class-list size");
|
|
1109
|
+
for (let index = 0; index < section.size / 8; index++) {
|
|
1110
|
+
if (budget.isFull()) {
|
|
1111
|
+
budget.markTruncated();
|
|
1112
|
+
break;
|
|
1113
|
+
}
|
|
1114
|
+
examined++;
|
|
1115
|
+
const field = section.address + BigInt(index * 8);
|
|
1116
|
+
try {
|
|
1117
|
+
readClass(read.pointer(field));
|
|
1118
|
+
} catch (cause) {
|
|
1119
|
+
failures.push(`${hex$1(field)}: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
1120
|
+
}
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
const categoriesExamined = decodeObjcCategories({
|
|
1124
|
+
sections,
|
|
1125
|
+
read,
|
|
1126
|
+
result,
|
|
1127
|
+
failures,
|
|
1128
|
+
issues: categoryIssues,
|
|
1129
|
+
admit: () => budget.admit(),
|
|
1130
|
+
methods,
|
|
1131
|
+
protocols: (list) => protocolReader.list(list),
|
|
1132
|
+
localClassName: (address) => localClassName(read, address)
|
|
1133
|
+
});
|
|
1134
|
+
return {
|
|
1135
|
+
failures,
|
|
1136
|
+
categoryIssues,
|
|
1137
|
+
examined,
|
|
1138
|
+
categoriesExamined
|
|
1139
|
+
};
|
|
1140
|
+
};
|
|
1141
|
+
})))();
|
|
1142
|
+
}
|
|
1143
|
+
|
|
1144
|
+
//#endregion
|
|
1145
|
+
//#region dist/native/AppleSwiftDispatchFacets.js
|
|
1146
|
+
var hex, decoded, createSwiftRelativeReader, decodeSwiftDispatchFacets;
|
|
1147
|
+
function init_AppleSwiftDispatchFacets() {
|
|
1148
|
+
return (init_AppleSwiftDispatchFacets = __esmMin((() => {
|
|
1149
|
+
init_AppleDispatchDecodeFacts();
|
|
1150
|
+
hex = (value) => `0x${value.toString(16)}`;
|
|
1151
|
+
decoded = {
|
|
1152
|
+
status: "decoded",
|
|
1153
|
+
reason: null
|
|
1154
|
+
};
|
|
1155
|
+
createSwiftRelativeReader = (input) => {
|
|
1156
|
+
const { bytes, readers: read, budget, result } = input;
|
|
1157
|
+
return (field, indirectable = false) => {
|
|
1158
|
+
const displacement = bytes.readInt32LE(read.offset(field, 4));
|
|
1159
|
+
const indirect = indirectable && (displacement & 1) !== 0;
|
|
1160
|
+
let target = displacement === 0 ? 0n : field + BigInt(indirectable ? displacement & ~1 : displacement);
|
|
1161
|
+
let fileOffset = null;
|
|
1162
|
+
let reason = null;
|
|
1163
|
+
try {
|
|
1164
|
+
if (indirect && target !== 0n) target = read.pointer(target);
|
|
1165
|
+
if (target !== 0n) fileOffset = read.offset(target);
|
|
1166
|
+
} catch (cause) {
|
|
1167
|
+
reason = cause instanceof Error ? cause.message : String(cause);
|
|
1168
|
+
}
|
|
1169
|
+
if (budget.admit()) result.relative_pointers.push({
|
|
1170
|
+
field: read.location(field),
|
|
1171
|
+
target: {
|
|
1172
|
+
address: target === 0n ? null : hex(target),
|
|
1173
|
+
file_offset: fileOffset
|
|
1174
|
+
},
|
|
1175
|
+
displacement,
|
|
1176
|
+
indirectable,
|
|
1177
|
+
indirect,
|
|
1178
|
+
decode: reason === null ? decoded : {
|
|
1179
|
+
status: "partial",
|
|
1180
|
+
reason
|
|
1181
|
+
},
|
|
1182
|
+
evidence: read.evidence(field, "Swift ABI signed-relative metadata pointer")
|
|
1183
|
+
});
|
|
1184
|
+
if (reason !== null) throw new RangeError(reason);
|
|
1185
|
+
return target;
|
|
1186
|
+
};
|
|
1187
|
+
};
|
|
1188
|
+
decodeSwiftDispatchFacets = (input) => {
|
|
1189
|
+
const { sections, segments, readers: read, relative, budget, result } = input;
|
|
1190
|
+
const swiftFailures = [];
|
|
1191
|
+
const issues = [];
|
|
1192
|
+
let swiftExamined = 0;
|
|
1193
|
+
let decodedRecords = 0;
|
|
1194
|
+
for (const section of sections.filter(({ name }) => name === "__swift5_proto")) {
|
|
1195
|
+
if (section.size % 4 !== 0) throw new RangeError("Misaligned Swift conformance section");
|
|
1196
|
+
for (let index = 0; index < section.size / 4; index++) {
|
|
1197
|
+
if (!budget.admit()) break;
|
|
1198
|
+
swiftExamined++;
|
|
1199
|
+
const field = section.address + BigInt(index * 4);
|
|
1200
|
+
try {
|
|
1201
|
+
const descriptor = relative(field);
|
|
1202
|
+
const flags = read.u32(descriptor + 12n);
|
|
1203
|
+
const protocol = relative(descriptor, true);
|
|
1204
|
+
if ((read.u32(protocol) & 31) !== 3) throw new TypeError("Unsupported Swift protocol descriptor kind");
|
|
1205
|
+
const protocolName = read.string(relative(protocol + 8n));
|
|
1206
|
+
const typeKind = flags >>> 3 & 7;
|
|
1207
|
+
if (typeKind !== 0 && typeKind !== 1) throw new TypeError("Unsupported Swift conformance type-reference kind");
|
|
1208
|
+
let type = relative(descriptor + 4n);
|
|
1209
|
+
if (typeKind === 1) type = read.pointer(type);
|
|
1210
|
+
if (![
|
|
1211
|
+
16,
|
|
1212
|
+
17,
|
|
1213
|
+
18
|
|
1214
|
+
].includes(read.u32(type) & 31)) throw new TypeError("Unsupported Swift type descriptor kind");
|
|
1215
|
+
const typeName = read.string(relative(type + 8n));
|
|
1216
|
+
const witness = relative(descriptor + 8n);
|
|
1217
|
+
const staticWitness = witness !== 0n && (flags & ~56) === 0 && (read.u32(type) & 128) === 0;
|
|
1218
|
+
let witnessReason = staticWitness ? null : "Conditional, generic, resilient or missing static witness table is not decoded";
|
|
1219
|
+
if (staticWitness && read.pointer(witness) !== descriptor) witnessReason = "Witness-table conformance header is unresolved or encoded";
|
|
1220
|
+
const conformanceDecode = witnessReason === null ? {
|
|
1221
|
+
status: "decoded",
|
|
1222
|
+
reason: null
|
|
1223
|
+
} : {
|
|
1224
|
+
status: "partial",
|
|
1225
|
+
reason: witnessReason
|
|
1226
|
+
};
|
|
1227
|
+
result.swift_conformances.push({
|
|
1228
|
+
type_name: typeName,
|
|
1229
|
+
protocol_name: protocolName,
|
|
1230
|
+
module: null,
|
|
1231
|
+
witness_table: witness === 0n ? {
|
|
1232
|
+
address: null,
|
|
1233
|
+
file_offset: null
|
|
1234
|
+
} : read.location(witness),
|
|
1235
|
+
location: read.location(descriptor),
|
|
1236
|
+
decode: conformanceDecode,
|
|
1237
|
+
evidence: read.evidence(descriptor, "Swift protocol conformance descriptor and directly encoded type/protocol names")
|
|
1238
|
+
});
|
|
1239
|
+
if (conformanceDecode.status === "decoded") decodedRecords++;
|
|
1240
|
+
if (witnessReason !== null) {
|
|
1241
|
+
swiftFailures.push(`${typeName}: ${witnessReason}`);
|
|
1242
|
+
issues.push(issue("swift_conformances_static_witness_slots", "conformance_decode_partial", witnessReason, hex(descriptor)));
|
|
1243
|
+
continue;
|
|
1244
|
+
}
|
|
1245
|
+
const count = read.u32(protocol + 16n);
|
|
1246
|
+
const signatureCount = read.u32(protocol + 12n);
|
|
1247
|
+
if (count > 2e4 || signatureCount > 2e4) throw new RangeError("Swift witness requirement count exceeds 20000");
|
|
1248
|
+
for (let slot = 0; slot < count; slot++) {
|
|
1249
|
+
if (!budget.admit()) break;
|
|
1250
|
+
const entry = witness + BigInt((slot + 1) * 8);
|
|
1251
|
+
const implementation = read.pointer(entry);
|
|
1252
|
+
const requirementFlags = read.u32(protocol + 24n + BigInt(signatureCount * 12 + slot * 8));
|
|
1253
|
+
const kind = requirementFlags & 15;
|
|
1254
|
+
const synchronousFunction = kind >= 1 && kind <= 4 && (requirementFlags & 32) === 0;
|
|
1255
|
+
const executable = synchronousFunction && segments.some((segment) => segment.executable && implementation >= segment.address && implementation < segment.address + segment.size);
|
|
1256
|
+
const slotDecode = executable ? {
|
|
1257
|
+
status: "decoded",
|
|
1258
|
+
reason: null
|
|
1259
|
+
} : {
|
|
1260
|
+
status: "partial",
|
|
1261
|
+
reason: "Witness slot is non-function, async, nil, external, authenticated or encoded; implementation target is unresolved"
|
|
1262
|
+
};
|
|
1263
|
+
result.swift_dispatch_slots.push({
|
|
1264
|
+
owner: `${typeName}: ${protocolName}`,
|
|
1265
|
+
table_kind: "witness_table",
|
|
1266
|
+
slot_index: slot + 1,
|
|
1267
|
+
requirement: null,
|
|
1268
|
+
implementation: null,
|
|
1269
|
+
implementation_address: executable ? hex(implementation) : null,
|
|
1270
|
+
thunk_address: null,
|
|
1271
|
+
location: read.location(entry),
|
|
1272
|
+
decode: slotDecode,
|
|
1273
|
+
evidence: read.evidence(entry, "Static Swift witness slot, indexed after the conformance-descriptor header")
|
|
1274
|
+
});
|
|
1275
|
+
if (slotDecode.status !== "decoded") issues.push(issue("swift_conformances_static_witness_slots", "witness_slot_unresolved", slotDecode.reason, hex(entry)));
|
|
1276
|
+
}
|
|
1277
|
+
} catch (cause) {
|
|
1278
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
1279
|
+
swiftFailures.push(`${hex(field)}: ${message}`);
|
|
1280
|
+
issues.push(issue("swift_conformances_static_witness_slots", "conformance_decode_failed", message, hex(field)));
|
|
1281
|
+
}
|
|
1282
|
+
}
|
|
1283
|
+
}
|
|
1284
|
+
return {
|
|
1285
|
+
facet: "swift_conformances_static_witness_slots",
|
|
1286
|
+
examined: swiftExamined,
|
|
1287
|
+
decoded: decodedRecords,
|
|
1288
|
+
exhaustive: !budget.truncated && issues.length === 0,
|
|
1289
|
+
issues
|
|
1290
|
+
};
|
|
1291
|
+
};
|
|
1292
|
+
})))();
|
|
1293
|
+
}
|
|
1294
|
+
|
|
1295
|
+
//#endregion
|
|
1296
|
+
//#region dist/native/AppleSwiftVtables.js
|
|
1297
|
+
var decodeSwiftClassVtables;
|
|
1298
|
+
function init_AppleSwiftVtables() {
|
|
1299
|
+
return (init_AppleSwiftVtables = __esmMin((() => {
|
|
1300
|
+
init_AppleDispatchDecodeFacts();
|
|
1301
|
+
decodeSwiftClassVtables = (input) => {
|
|
1302
|
+
const { readers: read, result } = input;
|
|
1303
|
+
const failures = [];
|
|
1304
|
+
const issues = [];
|
|
1305
|
+
let examined = 0;
|
|
1306
|
+
let decoded = 0;
|
|
1307
|
+
for (const field of input.entries) {
|
|
1308
|
+
if (!read.admit()) {
|
|
1309
|
+
failures.push("max_records_reached");
|
|
1310
|
+
issues.push(issue("swift_class_vtable_descriptors", "record_budget_exhausted", "max_records_reached", `0x${field.toString(16)}`));
|
|
1311
|
+
break;
|
|
1312
|
+
}
|
|
1313
|
+
examined++;
|
|
1314
|
+
try {
|
|
1315
|
+
const descriptor = read.relative(field);
|
|
1316
|
+
const flags = read.u32(descriptor);
|
|
1317
|
+
if ((flags & 31) !== 16) continue;
|
|
1318
|
+
const specific = flags >>> 16;
|
|
1319
|
+
if ((flags & 128) !== 0 || (specific & 8192) !== 0) throw new TypeError("Generic class or resilient superclass metadata is unsupported");
|
|
1320
|
+
if ((specific & 32768) === 0) continue;
|
|
1321
|
+
const initialization = specific & 3;
|
|
1322
|
+
if (initialization === 3) throw new TypeError("Unknown metadata initialization kind");
|
|
1323
|
+
const header = descriptor + 44n + BigInt(initialization === 1 ? 12 : initialization === 2 ? 4 : 0);
|
|
1324
|
+
const tableOffset = read.u32(header);
|
|
1325
|
+
const count = read.u32(header + 4n);
|
|
1326
|
+
const positiveWords = read.u32(descriptor + 28n);
|
|
1327
|
+
if (count > 2e4 || tableOffset + count > positiveWords) throw new RangeError("Swift vtable count or offset exceeds declared metadata bounds");
|
|
1328
|
+
const owner = read.string(read.relative(descriptor + 8n));
|
|
1329
|
+
for (let index = 0; index < count; index++) {
|
|
1330
|
+
const entry = header + 8n + BigInt(index * 8);
|
|
1331
|
+
if (!read.admit()) {
|
|
1332
|
+
failures.push("max_records_reached");
|
|
1333
|
+
issues.push(issue("swift_class_vtable_descriptors", "record_budget_exhausted", "max_records_reached", `0x${entry.toString(16)}`));
|
|
1334
|
+
break;
|
|
1335
|
+
}
|
|
1336
|
+
const methodFlags = read.u32(entry);
|
|
1337
|
+
const synchronous = (methodFlags & 64) === 0 && (methodFlags & 15) <= 3;
|
|
1338
|
+
const implementation = read.relative(entry + 4n);
|
|
1339
|
+
const resolved = synchronous && read.executable(implementation);
|
|
1340
|
+
result.swift_dispatch_slots.push({
|
|
1341
|
+
owner,
|
|
1342
|
+
table_kind: "class_vtable",
|
|
1343
|
+
slot_index: tableOffset + index,
|
|
1344
|
+
requirement: null,
|
|
1345
|
+
implementation: null,
|
|
1346
|
+
implementation_address: resolved ? `0x${implementation.toString(16)}` : null,
|
|
1347
|
+
thunk_address: null,
|
|
1348
|
+
location: read.location(entry),
|
|
1349
|
+
decode: resolved ? {
|
|
1350
|
+
status: "decoded",
|
|
1351
|
+
reason: null
|
|
1352
|
+
} : {
|
|
1353
|
+
status: "partial",
|
|
1354
|
+
reason: "Async, coroutine, external or unmapped vtable implementation is unresolved"
|
|
1355
|
+
},
|
|
1356
|
+
evidence: read.evidence(entry, "Swift class vtable method descriptor; slot index is a metadata word offset, not a source method ordinal")
|
|
1357
|
+
});
|
|
1358
|
+
if (resolved) decoded++;
|
|
1359
|
+
else issues.push(issue("swift_class_vtable_descriptors", "vtable_implementation_unresolved", "Async, coroutine, external or unmapped vtable implementation is unresolved", `0x${entry.toString(16)}`));
|
|
1360
|
+
}
|
|
1361
|
+
if ((specific & 16384) !== 0) {
|
|
1362
|
+
failures.push(`${owner}: inherited override descriptors are unsupported`);
|
|
1363
|
+
issues.push(issue("swift_class_vtable_descriptors", "inherited_override_descriptors_unsupported", "Inherited override descriptors are unsupported", `0x${descriptor.toString(16)}`));
|
|
1364
|
+
}
|
|
1365
|
+
} catch (cause) {
|
|
1366
|
+
const message = cause instanceof Error ? cause.message : String(cause);
|
|
1367
|
+
failures.push(`0x${field.toString(16)}: ${message}`);
|
|
1368
|
+
issues.push(issue("swift_class_vtable_descriptors", "vtable_decode_failed", message, `0x${field.toString(16)}`));
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
return {
|
|
1372
|
+
facet: "swift_class_vtable_descriptors",
|
|
1373
|
+
examined,
|
|
1374
|
+
decoded,
|
|
1375
|
+
exhaustive: issues.length === 0,
|
|
1376
|
+
issues
|
|
1377
|
+
};
|
|
1378
|
+
};
|
|
1379
|
+
})))();
|
|
1380
|
+
}
|
|
1381
|
+
|
|
1382
|
+
//#endregion
|
|
1383
|
+
//#region dist/native/AppleDispatchMetadata.js
|
|
1384
|
+
var decodeAppleDispatchMetadata, inspectAppleDispatchMetadata;
|
|
1385
|
+
function init_AppleDispatchMetadata() {
|
|
1386
|
+
return (init_AppleDispatchMetadata = __esmMin((() => {
|
|
1387
|
+
init_objcSwiftMetadata();
|
|
1388
|
+
init_binaryTargetTypes();
|
|
1389
|
+
init_analysisErrorCore();
|
|
1390
|
+
init_RegularFile();
|
|
1391
|
+
init_BoundedFileBytes();
|
|
1392
|
+
init_evidenceErrors();
|
|
1393
|
+
init_AppleDispatchCoverage();
|
|
1394
|
+
init_AppleMachoFixups();
|
|
1395
|
+
init_AppleMachoSelection();
|
|
1396
|
+
init_AppleObjcDispatchFacets();
|
|
1397
|
+
init_AppleSwiftDispatchFacets();
|
|
1398
|
+
init_AppleSwiftVtables();
|
|
1399
|
+
decodeAppleDispatchMetadata = (bytes, maxRecords, provenance, architecture = "arm64") => {
|
|
1400
|
+
const layout = parseMachoLayout(bytes, architecture);
|
|
1401
|
+
const { segments, sections, offset } = layout;
|
|
1402
|
+
const fixups = parsePointerFixups(bytes, layout.fixups, segments, layout.baseAddress);
|
|
1403
|
+
const u32 = (address) => bytes.readUInt32LE(offset(address, 4));
|
|
1404
|
+
const decodePointer = (address) => fixups.decode(address, bytes.readBigUInt64LE(offset(address, 8)));
|
|
1405
|
+
/** Rebased target of a pointer; a bind to another image reads as 0. */
|
|
1406
|
+
const pointer = (address) => {
|
|
1407
|
+
const decodedPointer = decodePointer(address);
|
|
1408
|
+
return decodedPointer.kind === "rebase" ? decodedPointer.target : 0n;
|
|
1409
|
+
};
|
|
1410
|
+
const bound = (address) => {
|
|
1411
|
+
const decodedPointer = decodePointer(address);
|
|
1412
|
+
return decodedPointer.kind === "bind" ? decodedPointer : undefined;
|
|
1413
|
+
};
|
|
1414
|
+
const location = (address) => ({
|
|
1415
|
+
address: `0x${address.toString(16)}`,
|
|
1416
|
+
file_offset: offset(address)
|
|
1417
|
+
});
|
|
1418
|
+
const evidence = (address, description) => [{
|
|
1419
|
+
kind: "binary_metadata",
|
|
1420
|
+
description,
|
|
1421
|
+
location: location(address),
|
|
1422
|
+
artifact_path: provenance.path,
|
|
1423
|
+
artifact_sha256: provenance.sha256
|
|
1424
|
+
}];
|
|
1425
|
+
const string = (address) => {
|
|
1426
|
+
const start = offset(address);
|
|
1427
|
+
let end = start;
|
|
1428
|
+
while (end < bytes.length && end - start < 4096 && bytes[end] !== 0) end++;
|
|
1429
|
+
if (end === bytes.length || end - start >= 4096) throw new RangeError("Unterminated or oversized metadata string");
|
|
1430
|
+
offset(address, end - start + 1);
|
|
1431
|
+
return new TextDecoder("utf-8", { fatal: true }).decode(bytes.subarray(start, end));
|
|
1432
|
+
};
|
|
1433
|
+
const result = objcSwiftMetadataSchema.parse({ db_save_result: null });
|
|
1434
|
+
let records = 0;
|
|
1435
|
+
const budget = {
|
|
1436
|
+
truncated: false,
|
|
1437
|
+
isFull: () => records >= maxRecords,
|
|
1438
|
+
markTruncated: () => {
|
|
1439
|
+
budget.truncated = true;
|
|
1440
|
+
},
|
|
1441
|
+
admit: () => {
|
|
1442
|
+
if (records >= maxRecords) {
|
|
1443
|
+
budget.truncated = true;
|
|
1444
|
+
return false;
|
|
1445
|
+
}
|
|
1446
|
+
records++;
|
|
1447
|
+
return true;
|
|
1448
|
+
}
|
|
1449
|
+
};
|
|
1450
|
+
const readers = {
|
|
1451
|
+
u32,
|
|
1452
|
+
i32: (address) => bytes.readInt32LE(offset(address, 4)),
|
|
1453
|
+
u64: (address) => bytes.readBigUInt64LE(offset(address, 8)),
|
|
1454
|
+
pointer,
|
|
1455
|
+
bound,
|
|
1456
|
+
string,
|
|
1457
|
+
location,
|
|
1458
|
+
evidence,
|
|
1459
|
+
offset
|
|
1460
|
+
};
|
|
1461
|
+
const { failures, categoryIssues, examined, categoriesExamined } = decodeObjcDispatchFacets({
|
|
1462
|
+
bytes,
|
|
1463
|
+
sections,
|
|
1464
|
+
segments,
|
|
1465
|
+
readers,
|
|
1466
|
+
budget,
|
|
1467
|
+
result
|
|
1468
|
+
});
|
|
1469
|
+
const swiftRelative = createSwiftRelativeReader({
|
|
1470
|
+
bytes,
|
|
1471
|
+
readers,
|
|
1472
|
+
budget,
|
|
1473
|
+
result
|
|
1474
|
+
});
|
|
1475
|
+
const swift = decodeSwiftDispatchFacets({
|
|
1476
|
+
sections,
|
|
1477
|
+
segments,
|
|
1478
|
+
readers,
|
|
1479
|
+
relative: swiftRelative,
|
|
1480
|
+
budget,
|
|
1481
|
+
result
|
|
1482
|
+
});
|
|
1483
|
+
const typeEntries = [];
|
|
1484
|
+
for (const section of sections.filter(({ name }) => name === "__swift5_types")) {
|
|
1485
|
+
if (section.size % 4 !== 0) throw new RangeError("Misaligned Swift type section");
|
|
1486
|
+
for (let index = 0; index < section.size / 4 && index < maxRecords; index++) typeEntries.push(section.address + BigInt(index * 4));
|
|
1487
|
+
if (section.size / 4 > maxRecords) budget.truncated = true;
|
|
1488
|
+
}
|
|
1489
|
+
const vtables = decodeSwiftClassVtables({
|
|
1490
|
+
entries: typeEntries,
|
|
1491
|
+
result,
|
|
1492
|
+
readers: {
|
|
1493
|
+
u32,
|
|
1494
|
+
relative: swiftRelative,
|
|
1495
|
+
string,
|
|
1496
|
+
location,
|
|
1497
|
+
evidence,
|
|
1498
|
+
admit: () => budget.admit(),
|
|
1499
|
+
executable: (address) => segments.some((segment) => segment.executable && address >= segment.address && address < segment.address + segment.size)
|
|
1500
|
+
}
|
|
1501
|
+
});
|
|
1502
|
+
pushDispatchCoverage({
|
|
1503
|
+
result,
|
|
1504
|
+
failures,
|
|
1505
|
+
categoryIssues,
|
|
1506
|
+
examined,
|
|
1507
|
+
categoriesExamined,
|
|
1508
|
+
truncated: budget.truncated,
|
|
1509
|
+
fixups,
|
|
1510
|
+
vtables,
|
|
1511
|
+
swift
|
|
1512
|
+
});
|
|
1513
|
+
return objcSwiftMetadataSchema.parse(result);
|
|
1514
|
+
};
|
|
1515
|
+
inspectAppleDispatchMetadata = async (target, maxRecords, signal) => {
|
|
1516
|
+
if (target.kind !== "executable" || !isMachOFormat(target.format)) throw new TypeError("Apple dispatch metadata requires a Mach-O target");
|
|
1517
|
+
const maximumBytes = 64 * 1024 * 1024;
|
|
1518
|
+
const capacityError = () => new AnalysisResourceConstraintError("inspect_native_dispatch_metadata", "memory", "Apple static metadata input exceeds its 64 MiB snapshot budget", { input_bytes: maximumBytes });
|
|
1519
|
+
const handle = await openRegularFile(target.path, {
|
|
1520
|
+
symlinks: "reject",
|
|
1521
|
+
signal
|
|
1522
|
+
});
|
|
1523
|
+
try {
|
|
1524
|
+
const before = await handle.stat();
|
|
1525
|
+
if (before.size > maximumBytes) throw capacityError();
|
|
1526
|
+
if (signal?.aborted) throw new AnalysisCancelledError("inspect_native_dispatch_metadata");
|
|
1527
|
+
const bytes = await readBoundedFileBytes(handle, maximumBytes, signal);
|
|
1528
|
+
if (bytes === undefined) throw capacityError();
|
|
1529
|
+
const digest = createHash("sha256").update(bytes).digest("hex");
|
|
1530
|
+
if (digest !== target.sha256) throw new EvidenceIntegrityError("Apple metadata target digest changed after session binding");
|
|
1531
|
+
return nativeDispatchMetadataResultSchema.parse({
|
|
1532
|
+
target_sha256: target.sha256,
|
|
1533
|
+
provider: {
|
|
1534
|
+
id: "native-macos",
|
|
1535
|
+
name: "macOS native inspection utilities",
|
|
1536
|
+
version: "apple-metadata-reader-1"
|
|
1537
|
+
},
|
|
1538
|
+
analysis_profile_digest: null,
|
|
1539
|
+
result: decodeAppleDispatchMetadata(bytes, maxRecords, {
|
|
1540
|
+
path: target.path,
|
|
1541
|
+
sha256: digest
|
|
1542
|
+
}, target.architecture)
|
|
1543
|
+
});
|
|
1544
|
+
} finally {
|
|
1545
|
+
await handle.close();
|
|
1546
|
+
}
|
|
1547
|
+
};
|
|
1548
|
+
})))();
|
|
1549
|
+
}
|
|
1550
|
+
|
|
1551
|
+
//#endregion
|
|
1552
|
+
//#region dist/native/NativeUiOutputBudget.js
|
|
1553
|
+
var HELPER_SUCCESS_WRAPPER, NATIVE_UI_OUTPUT_BUDGET_BYTES, NATIVE_UI_OUTPUT_WEIGHT, NATIVE_UI_HELPER_ENVELOPE_BYTES, NATIVE_UI_HELPER_MAX_BUFFER;
|
|
1554
|
+
function init_NativeUiOutputBudget() {
|
|
1555
|
+
return (init_NativeUiOutputBudget = __esmMin((() => {
|
|
1556
|
+
HELPER_SUCCESS_WRAPPER = Buffer.from(JSON.stringify({
|
|
1557
|
+
ok: true,
|
|
1558
|
+
result: {}
|
|
1559
|
+
}));
|
|
1560
|
+
NATIVE_UI_OUTPUT_BUDGET_BYTES = 64 * 1024 * 1024;
|
|
1561
|
+
NATIVE_UI_OUTPUT_WEIGHT = 2;
|
|
1562
|
+
NATIVE_UI_HELPER_ENVELOPE_BYTES = HELPER_SUCCESS_WRAPPER.byteLength - Buffer.byteLength("{}");
|
|
1563
|
+
NATIVE_UI_HELPER_MAX_BUFFER = NATIVE_UI_OUTPUT_BUDGET_BYTES + NATIVE_UI_HELPER_ENVELOPE_BYTES;
|
|
1564
|
+
})))();
|
|
1565
|
+
}
|
|
1566
|
+
|
|
1567
|
+
//#endregion
|
|
1568
|
+
//#region dist/native/NativeUiHelperRuntime.js
|
|
1569
|
+
var createNativeUiHelperRuntime;
|
|
1570
|
+
function init_NativeUiHelperRuntime() {
|
|
1571
|
+
return (init_NativeUiHelperRuntime = __esmMin((() => {
|
|
1572
|
+
init_snapshotEnvironment();
|
|
1573
|
+
init_DarwinProcessRunTokenReader();
|
|
1574
|
+
init_ExecFileOutput();
|
|
1575
|
+
init_safeJson();
|
|
1576
|
+
init_NativeUiOutputBudget();
|
|
1577
|
+
createNativeUiHelperRuntime = (environment) => {
|
|
1578
|
+
const selectedEnvironment = snapshotEnvironment(environment);
|
|
1579
|
+
let root;
|
|
1580
|
+
let executable;
|
|
1581
|
+
const invoke = async (parameters, signal) => {
|
|
1582
|
+
if (executable === undefined) {
|
|
1583
|
+
root = await mkdtemp(join(tmpdir(), "rea-native-ui-"));
|
|
1584
|
+
const output = join(root, "observer");
|
|
1585
|
+
const main = join(root, "main.swift");
|
|
1586
|
+
await symlink(fileURLToPath(new URL("../../bridge/native/ReaNativeUI.swift", new URL("../native/NativeUiHelperRuntime.js", import.meta.url).href)), main);
|
|
1587
|
+
const compilerTemporary = join(root, "tmp");
|
|
1588
|
+
await mkdir(compilerTemporary);
|
|
1589
|
+
await execFileOutput("/usr/bin/xcrun", [
|
|
1590
|
+
"swiftc",
|
|
1591
|
+
"-module-cache-path",
|
|
1592
|
+
join(root, "modules"),
|
|
1593
|
+
fileURLToPath(new URL("../../bridge/native/NativeUIChildren.swift", new URL("../native/NativeUiHelperRuntime.js", import.meta.url).href)),
|
|
1594
|
+
main,
|
|
1595
|
+
"-o",
|
|
1596
|
+
output
|
|
1597
|
+
], {
|
|
1598
|
+
timeout: 6e4,
|
|
1599
|
+
maxBuffer: 1024 * 1024,
|
|
1600
|
+
stopSignal: SWIFTC_INTERRUPT,
|
|
1601
|
+
env: {
|
|
1602
|
+
...selectedEnvironment,
|
|
1603
|
+
TMPDIR: compilerTemporary
|
|
1604
|
+
},
|
|
1605
|
+
...signal === undefined ? {} : { signal }
|
|
1606
|
+
});
|
|
1607
|
+
executable = output;
|
|
1608
|
+
}
|
|
1609
|
+
const output = await execFileOutput(executable, [JSON.stringify(parameters)], {
|
|
1610
|
+
timeout: 3e4,
|
|
1611
|
+
maxBuffer: NATIVE_UI_HELPER_MAX_BUFFER,
|
|
1612
|
+
stopSignal: "SIGTERM",
|
|
1613
|
+
env: selectedEnvironment,
|
|
1614
|
+
...signal === undefined ? {} : { signal }
|
|
1615
|
+
});
|
|
1616
|
+
const parsed = safeParseJson(output.stdout);
|
|
1617
|
+
if (!parsed.ok) throw new Error(`Native helper returned invalid JSON: ${parsed.error}`, { cause: parsed.cause });
|
|
1618
|
+
return parsed.value;
|
|
1619
|
+
};
|
|
1620
|
+
return {
|
|
1621
|
+
invoke,
|
|
1622
|
+
close: async () => {
|
|
1623
|
+
if (root !== undefined) {
|
|
1624
|
+
await rm(root, {
|
|
1625
|
+
recursive: true,
|
|
1626
|
+
force: true
|
|
1627
|
+
});
|
|
1628
|
+
root = undefined;
|
|
1629
|
+
executable = undefined;
|
|
1630
|
+
}
|
|
1631
|
+
},
|
|
1632
|
+
resources: () => root === undefined ? [] : [root]
|
|
1633
|
+
};
|
|
1634
|
+
};
|
|
1635
|
+
})))();
|
|
1636
|
+
}
|
|
1637
|
+
|
|
1638
|
+
//#endregion
|
|
1639
|
+
//#region dist/native/NativeUiObservation.js
|
|
1640
|
+
var helper, responseSchema, observeNativeUi, observeWithHelper;
|
|
1641
|
+
function init_NativeUiObservation() {
|
|
1642
|
+
return (init_NativeUiObservation = __esmMin((() => {
|
|
1643
|
+
init_binaryTargetTypes();
|
|
1644
|
+
init_nativeUiObservation();
|
|
1645
|
+
init_analysisErrorCore();
|
|
1646
|
+
init_providerAdapterError();
|
|
1647
|
+
init_result();
|
|
1648
|
+
init_NativeUiHelperRuntime();
|
|
1649
|
+
init_NativeUiOutputBudget();
|
|
1650
|
+
helper = fileURLToPath(new URL("../../bridge/native/ReaNativeUI.swift", new URL("../native/NativeUiObservation.js", import.meta.url).href));
|
|
1651
|
+
responseSchema = z.discriminatedUnion("ok", [z.strictObject({
|
|
1652
|
+
ok: z.literal(true),
|
|
1653
|
+
result: nativeUiSnapshotSchema
|
|
1654
|
+
}), z.strictObject({
|
|
1655
|
+
ok: z.literal(false),
|
|
1656
|
+
code: z.string(),
|
|
1657
|
+
message: z.string()
|
|
1658
|
+
})]);
|
|
1659
|
+
observeNativeUi = async (target, operation, parameters, options) => {
|
|
1660
|
+
const runtime = options.runtime ?? createNativeUiHelperRuntime(options.environment);
|
|
1661
|
+
try {
|
|
1662
|
+
return await observeWithHelper(target, operation, parameters, {
|
|
1663
|
+
...options,
|
|
1664
|
+
invoke: options.invoke ?? runtime.invoke
|
|
1665
|
+
});
|
|
1666
|
+
} finally {
|
|
1667
|
+
if (options.runtime === undefined) await runtime.close();
|
|
1668
|
+
}
|
|
1669
|
+
};
|
|
1670
|
+
observeWithHelper = async (target, operation, parameters, options) => {
|
|
1671
|
+
const parsed = (operation === "observe_native_ui" ? nativeUiObservationInputSchema : nativeUiScenarioInputSchema).safeParse(parameters);
|
|
1672
|
+
if (!parsed.success) return err(new AnalysisInputError(operation, { cause: parsed.error }));
|
|
1673
|
+
if (target.kind !== "executable" || !isMachOFormat(target.format)) return err(new AnalysisCapabilityUnavailableError("native-macos", operation, "Native UI observation requires an active Mach-O executable or app target"));
|
|
1674
|
+
const input = parsed.data;
|
|
1675
|
+
if (!input.screenshot && !input.accessibility) return err(new AnalysisInputError(operation, { cause: new Error("Enable screenshot or accessibility capture") }));
|
|
1676
|
+
const steps = operation === "capture_native_ui_scenario" ? nativeUiScenarioInputSchema.parse(parameters).steps : [];
|
|
1677
|
+
const signal = options.signal === undefined ? AbortSignal.timeout(18e4) : AbortSignal.any([options.signal, AbortSignal.timeout(18e4)]);
|
|
1678
|
+
const invoke = options.invoke;
|
|
1679
|
+
let launchTime;
|
|
1680
|
+
let outputBytes = 0;
|
|
1681
|
+
const take = async (action) => {
|
|
1682
|
+
if (signal.aborted) return err(new AnalysisCancelledError(operation));
|
|
1683
|
+
try {
|
|
1684
|
+
const response = responseSchema.parse(await invoke({
|
|
1685
|
+
pid: input.pid,
|
|
1686
|
+
window_id: input.window_id,
|
|
1687
|
+
executable: target.path,
|
|
1688
|
+
sha256: target.sha256,
|
|
1689
|
+
...launchTime === undefined ? {} : { launch_time: launchTime },
|
|
1690
|
+
screenshot: input.screenshot,
|
|
1691
|
+
accessibility: input.accessibility,
|
|
1692
|
+
max_nodes: input.max_nodes,
|
|
1693
|
+
...action === undefined ? {} : { action }
|
|
1694
|
+
}, signal));
|
|
1695
|
+
if (!response.ok) return err(new AnalysisCapabilityUnavailableError("native-macos", operation, `${response.code}: ${response.message}`));
|
|
1696
|
+
if (response.result.window.pid !== input.pid || response.result.window.window_id !== input.window_id || response.result.window.executable !== target.path || launchTime !== undefined && response.result.window.launch_time !== launchTime) return err(new AnalysisCapabilityUnavailableError("native-macos", operation, "Native helper returned a different target process or window"));
|
|
1697
|
+
launchTime = response.result.window.launch_time;
|
|
1698
|
+
outputBytes += 2 * Buffer.byteLength(JSON.stringify(response.result));
|
|
1699
|
+
if (outputBytes > 67108864) return err(new AnalysisCapabilityUnavailableError("native-macos", operation, "Scenario captures exceeded the 64 MiB output budget"));
|
|
1700
|
+
return ok(response.result);
|
|
1701
|
+
} catch (cause) {
|
|
1702
|
+
return err(signal.aborted ? new AnalysisCancelledError(operation) : new ProviderAdapterError("native-macos", operation, {
|
|
1703
|
+
cause,
|
|
1704
|
+
diagnostics: {
|
|
1705
|
+
helper_path: helper,
|
|
1706
|
+
reason: cause instanceof Error ? cause.message : String(cause),
|
|
1707
|
+
remediation: "Native helper failed, timed out, or returned malformed capture data; install compatible Xcode command-line tools and inspect local OS permissions"
|
|
1708
|
+
}
|
|
1709
|
+
}));
|
|
1710
|
+
}
|
|
1711
|
+
};
|
|
1712
|
+
const initial = await take();
|
|
1713
|
+
if (!initial.ok) return initial;
|
|
1714
|
+
const results = [];
|
|
1715
|
+
let before = initial.value;
|
|
1716
|
+
for (const [index, step] of steps.entries()) {
|
|
1717
|
+
if (signal.aborted) {
|
|
1718
|
+
results.push({
|
|
1719
|
+
index,
|
|
1720
|
+
kind: step.kind,
|
|
1721
|
+
before,
|
|
1722
|
+
after: null,
|
|
1723
|
+
outcome: "cancelled",
|
|
1724
|
+
reason: "Scenario cancelled before action"
|
|
1725
|
+
});
|
|
1726
|
+
break;
|
|
1727
|
+
}
|
|
1728
|
+
if (step.kind === "wait") {
|
|
1729
|
+
try {
|
|
1730
|
+
await new Promise((resolve, reject) => {
|
|
1731
|
+
const abort = () => {
|
|
1732
|
+
clearTimeout(timer);
|
|
1733
|
+
reject(new Error("cancelled"));
|
|
1734
|
+
};
|
|
1735
|
+
const timer = setTimeout(() => {
|
|
1736
|
+
signal.removeEventListener("abort", abort);
|
|
1737
|
+
resolve();
|
|
1738
|
+
}, step.milliseconds);
|
|
1739
|
+
signal.addEventListener("abort", abort, { once: true });
|
|
1740
|
+
if (signal.aborted) abort();
|
|
1741
|
+
});
|
|
1742
|
+
} catch (cause) {
|
|
1743
|
+
void cause;
|
|
1744
|
+
results.push({
|
|
1745
|
+
index,
|
|
1746
|
+
kind: step.kind,
|
|
1747
|
+
before,
|
|
1748
|
+
after: null,
|
|
1749
|
+
outcome: "cancelled",
|
|
1750
|
+
reason: "Scenario cancelled during wait"
|
|
1751
|
+
});
|
|
1752
|
+
break;
|
|
1753
|
+
}
|
|
1754
|
+
}
|
|
1755
|
+
const after = await take(step.kind === "wait" ? undefined : step);
|
|
1756
|
+
if (!after.ok) {
|
|
1757
|
+
results.push({
|
|
1758
|
+
index,
|
|
1759
|
+
kind: step.kind,
|
|
1760
|
+
before,
|
|
1761
|
+
after: null,
|
|
1762
|
+
outcome: after.error._tag === "AnalysisCancelledError" ? "cancelled" : "failed",
|
|
1763
|
+
reason: after.error.message
|
|
1764
|
+
});
|
|
1765
|
+
break;
|
|
1766
|
+
}
|
|
1767
|
+
results.push({
|
|
1768
|
+
index,
|
|
1769
|
+
kind: step.kind,
|
|
1770
|
+
before,
|
|
1771
|
+
after: after.value,
|
|
1772
|
+
outcome: "completed",
|
|
1773
|
+
reason: null
|
|
1774
|
+
});
|
|
1775
|
+
before = after.value;
|
|
1776
|
+
}
|
|
1777
|
+
return ok(nativeUiResultSchema.parse({
|
|
1778
|
+
target_sha256: target.sha256,
|
|
1779
|
+
initial: initial.value,
|
|
1780
|
+
steps: results,
|
|
1781
|
+
restore: "leave-as-is",
|
|
1782
|
+
limitations: [
|
|
1783
|
+
"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.",
|
|
1784
|
+
"Click uses AXPress; scroll uses AXIncrement/AXDecrement; key-entry sets the selected element's AXValue. Unsupported elements fail without global event fallback.",
|
|
1785
|
+
"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.",
|
|
1786
|
+
"Scenarios can change app data, cause app network activity and persist changes. The caller explicitly chooses leave-as-is; automatic restoration is unsupported.",
|
|
1787
|
+
"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."
|
|
1788
|
+
]
|
|
1789
|
+
}));
|
|
1790
|
+
};
|
|
1791
|
+
})))();
|
|
1792
|
+
}
|
|
1793
|
+
|
|
1794
|
+
//#endregion
|
|
1795
|
+
//#region dist/native/LldbRetainedObservations.js
|
|
1796
|
+
var LLDB_OBSERVATION_JOURNAL_MAX_BYTES, MAX_CAPTURE_BYTES, projectLldbPartialObservation, parseLldbObservationJournal, readBoundedPrefix, readPrefix, readLldbObservationJournal, readPartialCapture;
|
|
1797
|
+
function init_LldbRetainedObservations() {
|
|
1798
|
+
return (init_LldbRetainedObservations = __esmMin((() => {
|
|
1799
|
+
init_nativeCallObservation();
|
|
1800
|
+
LLDB_OBSERVATION_JOURNAL_MAX_BYTES = 8 * 1024 * 1024;
|
|
1801
|
+
MAX_CAPTURE_BYTES = 1024 * 1024;
|
|
1802
|
+
projectLldbPartialObservation = (input) => ({
|
|
1803
|
+
kind: "native-call-observation",
|
|
1804
|
+
target: input.target,
|
|
1805
|
+
process: {
|
|
1806
|
+
pid: input.pid ?? null,
|
|
1807
|
+
stdout: input.stdout,
|
|
1808
|
+
stderr: input.stderr,
|
|
1809
|
+
other_stops: input.journal.otherStops
|
|
1810
|
+
},
|
|
1811
|
+
debugger: { version: input.version },
|
|
1812
|
+
events: input.journal.events,
|
|
1813
|
+
coverage: {
|
|
1814
|
+
status: "partial",
|
|
1815
|
+
reason: input.reason
|
|
1816
|
+
},
|
|
1817
|
+
limitations: [
|
|
1818
|
+
"The LLDB run did not produce a complete native call observation result.",
|
|
1819
|
+
"The target SHA-256 identifies the selected artifact; LLDB did not verify the bytes loaded into the process.",
|
|
1820
|
+
"Captured output byte counts are observed lower bounds because LLDB did not report final stream counters.",
|
|
1821
|
+
...input.journal.limitations,
|
|
1822
|
+
...input.journalLimitations ?? [],
|
|
1823
|
+
...input.limitations ?? [],
|
|
1824
|
+
...input.pid === undefined ? ["The target PID was unavailable."] : [],
|
|
1825
|
+
...input.stdout === null ? ["The target stdout capture was unavailable."] : [],
|
|
1826
|
+
...input.stderr === null ? ["The target stderr capture was unavailable."] : []
|
|
1827
|
+
]
|
|
1828
|
+
});
|
|
1829
|
+
parseLldbObservationJournal = (bytes) => {
|
|
1830
|
+
const completeText = Buffer.from(bytes).toString("utf8");
|
|
1831
|
+
const newline = completeText.lastIndexOf("\n");
|
|
1832
|
+
const hasTornTail = newline !== completeText.length - 1;
|
|
1833
|
+
const events = [];
|
|
1834
|
+
const otherStops = [];
|
|
1835
|
+
const limitations = [];
|
|
1836
|
+
let malformedCount = 0;
|
|
1837
|
+
let firstMalformedRow;
|
|
1838
|
+
let start = 0;
|
|
1839
|
+
let rowNumber = 0;
|
|
1840
|
+
while (start <= newline && newline >= 0) {
|
|
1841
|
+
const end = completeText.indexOf("\n", start);
|
|
1842
|
+
if (end < 0 || end > newline) break;
|
|
1843
|
+
const line = completeText.slice(start, end);
|
|
1844
|
+
start = end + 1;
|
|
1845
|
+
if (line.length === 0) continue;
|
|
1846
|
+
rowNumber += 1;
|
|
1847
|
+
const markMalformed = () => {
|
|
1848
|
+
malformedCount += 1;
|
|
1849
|
+
firstMalformedRow ??= rowNumber;
|
|
1850
|
+
};
|
|
1851
|
+
let row;
|
|
1852
|
+
try {
|
|
1853
|
+
row = JSON.parse(line);
|
|
1854
|
+
} catch {
|
|
1855
|
+
markMalformed();
|
|
1856
|
+
continue;
|
|
1857
|
+
}
|
|
1858
|
+
if (typeof row !== "object" || row === null || !("kind" in row) || typeof row.kind !== "string") {
|
|
1859
|
+
markMalformed();
|
|
1860
|
+
continue;
|
|
1861
|
+
}
|
|
1862
|
+
if (row.kind === "event" && "event" in row) {
|
|
1863
|
+
const event = nativeCallEventSchema.safeParse(row.event);
|
|
1864
|
+
if (event.success) events.push(event.data);
|
|
1865
|
+
else markMalformed();
|
|
1866
|
+
} else if (row.kind === "other-stop" && "reason" in row && typeof row.reason === "string") {
|
|
1867
|
+
otherStops.push(row.reason);
|
|
1868
|
+
} else {
|
|
1869
|
+
markMalformed();
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
if (malformedCount > 0) limitations.push(`${malformedCount} observation journal row(s) were malformed or invalid and ignored (first at row ${String(firstMalformedRow)}).`);
|
|
1873
|
+
if (hasTornTail) limitations.push("The final observation journal record was incomplete and was ignored.");
|
|
1874
|
+
return {
|
|
1875
|
+
events,
|
|
1876
|
+
otherStops,
|
|
1877
|
+
limitations
|
|
1878
|
+
};
|
|
1879
|
+
};
|
|
1880
|
+
readBoundedPrefix = async (requestedBytes, readChunk) => {
|
|
1881
|
+
const buffer = Buffer.alloc(requestedBytes);
|
|
1882
|
+
let bytesRead = 0;
|
|
1883
|
+
while (bytesRead < requestedBytes) {
|
|
1884
|
+
const count = await readChunk(buffer, bytesRead, requestedBytes - bytesRead, bytesRead);
|
|
1885
|
+
if (count === 0) break;
|
|
1886
|
+
if (count > requestedBytes - bytesRead) throw new Error("The bounded read returned more bytes than requested");
|
|
1887
|
+
bytesRead += count;
|
|
1888
|
+
}
|
|
1889
|
+
return {
|
|
1890
|
+
buffer,
|
|
1891
|
+
bytesRead
|
|
1892
|
+
};
|
|
1893
|
+
};
|
|
1894
|
+
readPrefix = (handle, requestedBytes) => readBoundedPrefix(requestedBytes, async (buffer, offset, length, position) => (await handle.read(buffer, offset, length, position)).bytesRead);
|
|
1895
|
+
readLldbObservationJournal = async (path) => {
|
|
1896
|
+
let handle;
|
|
1897
|
+
try {
|
|
1898
|
+
handle = await open(path, "r");
|
|
1899
|
+
const { size } = await handle.stat();
|
|
1900
|
+
const length = Math.min(size, LLDB_OBSERVATION_JOURNAL_MAX_BYTES);
|
|
1901
|
+
const { buffer, bytesRead } = await readPrefix(handle, length);
|
|
1902
|
+
const parsed = parseLldbObservationJournal(buffer.subarray(0, bytesRead));
|
|
1903
|
+
const limitations = [...size > 8388608 ? ["The observation journal exceeded 8 MiB; only its bounded prefix was read."] : [], ...bytesRead < length ? ["The observation journal became shorter while being read; the available prefix was parsed."] : []];
|
|
1904
|
+
return {
|
|
1905
|
+
parsed,
|
|
1906
|
+
limitations
|
|
1907
|
+
};
|
|
1908
|
+
} catch (cause) {
|
|
1909
|
+
return {
|
|
1910
|
+
parsed: {
|
|
1911
|
+
events: [],
|
|
1912
|
+
otherStops: [],
|
|
1913
|
+
limitations: []
|
|
1914
|
+
},
|
|
1915
|
+
limitations: [`The observation journal could not be read: ${cause instanceof Error ? cause.message : String(cause)}`]
|
|
1916
|
+
};
|
|
1917
|
+
} finally {
|
|
1918
|
+
await handle?.close().catch(() => undefined);
|
|
1919
|
+
}
|
|
1920
|
+
};
|
|
1921
|
+
readPartialCapture = async (path) => {
|
|
1922
|
+
let handle;
|
|
1923
|
+
try {
|
|
1924
|
+
handle = await open(path, "r");
|
|
1925
|
+
const { size } = await handle.stat();
|
|
1926
|
+
const length = Math.min(size, MAX_CAPTURE_BYTES);
|
|
1927
|
+
const { buffer, bytesRead } = await readPrefix(handle, length);
|
|
1928
|
+
return {
|
|
1929
|
+
capture: {
|
|
1930
|
+
text: buffer.subarray(0, bytesRead).toString("utf8"),
|
|
1931
|
+
bytes: Math.max(size, bytesRead),
|
|
1932
|
+
truncated: true,
|
|
1933
|
+
complete: false
|
|
1934
|
+
},
|
|
1935
|
+
limitations: bytesRead < length ? ["A target output capture became shorter while being read; its retained prefix may be incomplete."] : []
|
|
1936
|
+
};
|
|
1937
|
+
} catch {
|
|
1938
|
+
return null;
|
|
1939
|
+
} finally {
|
|
1940
|
+
await handle?.close().catch(() => undefined);
|
|
1941
|
+
}
|
|
1942
|
+
};
|
|
1943
|
+
})))();
|
|
1944
|
+
}
|
|
1945
|
+
|
|
1946
|
+
//#endregion
|
|
1947
|
+
//#region dist/native/LldbCallTracer.js
|
|
1948
|
+
var OPERATION$1, PROVIDER, LLDB_REQUIREMENT, MAX_OUTPUT_BYTES, DEADLINE_GRACE_MS, DIAGNOSTIC_BYTES, BRIDGE, tracedSchema, tracerOutputSchema, ATTACH_REMEDIATION, LldbCallTracer, quote, tracerFailure, partialNativeObservation, partialObservationFromTrace, lldbRuntimePaths, readTracerOutput, capturedOutput, lldbCleanupResources, runLldb, readTargetPid, ensureTerminated, targetTerminationReason, alive;
|
|
1949
|
+
function init_LldbCallTracer() {
|
|
1950
|
+
return (init_LldbCallTracer = __esmMin((() => {
|
|
1951
|
+
init_snapshotEnvironment();
|
|
1952
|
+
init_analysisErrorCore();
|
|
1953
|
+
init_evidenceErrors();
|
|
1954
|
+
init_analysisErrorProjection();
|
|
1955
|
+
init_nativeCallObservation();
|
|
1956
|
+
init_providerAdapterError();
|
|
1957
|
+
init_providerCleanupError();
|
|
1958
|
+
init_result();
|
|
1959
|
+
init_safeJson();
|
|
1960
|
+
init_ProviderProcess();
|
|
1961
|
+
init_ProcessOwnership();
|
|
1962
|
+
init_ProcessOwnershipObservation();
|
|
1963
|
+
init_ProviderDeadline();
|
|
1964
|
+
init_PrivateRuntimeRoot();
|
|
1965
|
+
init_CommandRunner();
|
|
1966
|
+
init_LldbRetainedObservations();
|
|
1967
|
+
OPERATION$1 = "observe_native_calls";
|
|
1968
|
+
PROVIDER = "native-macos";
|
|
1969
|
+
LLDB_REQUIREMENT = "LLDB from Xcode or the Command Line Tools is not available";
|
|
1970
|
+
MAX_OUTPUT_BYTES = 1024 * 1024;
|
|
1971
|
+
DEADLINE_GRACE_MS = 6e4;
|
|
1972
|
+
DIAGNOSTIC_BYTES = 16 * 1024;
|
|
1973
|
+
BRIDGE = fileURLToPath(new URL("../../bridge/native/rea_lldb_tracer.py", new URL("../native/LldbCallTracer.js", import.meta.url).href));
|
|
1974
|
+
tracedSchema = z.strictObject({
|
|
1975
|
+
status: z.literal("traced"),
|
|
1976
|
+
version: z.string(),
|
|
1977
|
+
pid: z.number().int().positive(),
|
|
1978
|
+
outcome: z.enum([
|
|
1979
|
+
"exited",
|
|
1980
|
+
"duration-elapsed",
|
|
1981
|
+
"event-limit",
|
|
1982
|
+
"stop-limit",
|
|
1983
|
+
"resource-limit"
|
|
1984
|
+
]),
|
|
1985
|
+
exit_status: z.number().int().nullable(),
|
|
1986
|
+
exit_description: z.string().nullable(),
|
|
1987
|
+
killed: z.boolean(),
|
|
1988
|
+
terminated: z.boolean(),
|
|
1989
|
+
target_identity: z.strictObject({
|
|
1990
|
+
loaded_image_sha256: z.null(),
|
|
1991
|
+
selected_file_sha256: z.string().regex(/^[0-9a-f]{64}$/u).nullable(),
|
|
1992
|
+
file_device: z.string().nullable(),
|
|
1993
|
+
file_inode: z.string().nullable(),
|
|
1994
|
+
module_path: z.string().nullable(),
|
|
1995
|
+
module_uuid: z.string().nullable(),
|
|
1996
|
+
stable: z.boolean()
|
|
1997
|
+
}),
|
|
1998
|
+
resource_limit_reached: z.boolean(),
|
|
1999
|
+
breakpoint_locations_truncated: z.boolean().optional(),
|
|
2000
|
+
target_output: z.strictObject({
|
|
2001
|
+
stdout_bytes: z.number().int().nonnegative(),
|
|
2002
|
+
stderr_bytes: z.number().int().nonnegative(),
|
|
2003
|
+
stdout_truncated: z.boolean(),
|
|
2004
|
+
stderr_truncated: z.boolean(),
|
|
2005
|
+
stdout_complete: z.boolean(),
|
|
2006
|
+
stderr_complete: z.boolean()
|
|
2007
|
+
}),
|
|
2008
|
+
elapsed_ms: z.number().nonnegative(),
|
|
2009
|
+
breakpoints: z.array(z.strictObject({
|
|
2010
|
+
index: z.number().int().nonnegative(),
|
|
2011
|
+
location_count: z.number().int().nonnegative(),
|
|
2012
|
+
locations: z.array(nativeCodeLocationSchema)
|
|
2013
|
+
})),
|
|
2014
|
+
events: z.array(nativeCallEventSchema),
|
|
2015
|
+
other_stops: z.array(z.string())
|
|
2016
|
+
});
|
|
2017
|
+
tracerOutputSchema = z.discriminatedUnion("status", [tracedSchema, z.strictObject({
|
|
2018
|
+
status: z.enum([
|
|
2019
|
+
"target-error",
|
|
2020
|
+
"target-integrity-error",
|
|
2021
|
+
"target-identity-unavailable",
|
|
2022
|
+
"launch-error",
|
|
2023
|
+
"tracer-error"
|
|
2024
|
+
]),
|
|
2025
|
+
error: z.string().nullable()
|
|
2026
|
+
})]);
|
|
2027
|
+
ATTACH_REMEDIATION = "Allow debugging for this user (Developer Tools access: `DevToolsSecurity -enable`, or membership in the _developer group). A hardened-runtime target is debuggable only with the com.apple.security.get-task-allow entitlement; see inspect_signature's debugger-attach facet.";
|
|
2028
|
+
LldbCallTracer = class {
|
|
2029
|
+
launch;
|
|
2030
|
+
resolveTool;
|
|
2031
|
+
environment;
|
|
2032
|
+
#tail = Promise.resolve();
|
|
2033
|
+
#pendingCleanup;
|
|
2034
|
+
constructor(environment, launch = runLldb, resolveTool = (tool, signal) => resolveXcrunTool(tool, this.environment, signal)) {
|
|
2035
|
+
this.launch = launch;
|
|
2036
|
+
this.resolveTool = resolveTool;
|
|
2037
|
+
this.environment = snapshotEnvironment(environment);
|
|
2038
|
+
}
|
|
2039
|
+
async trace(request, signal) {
|
|
2040
|
+
return this.#serialize(() => this.#trace(request, signal));
|
|
2041
|
+
}
|
|
2042
|
+
async #trace(request, signal) {
|
|
2043
|
+
const pendingCleanup = await this.#retryPendingCleanup();
|
|
2044
|
+
if (pendingCleanup !== undefined) return err(pendingCleanup);
|
|
2045
|
+
const lldb = await this.resolveTool("lldb", signal);
|
|
2046
|
+
if (!lldb.ok) return err(lldb.error.reason === "cancelled" ? new AnalysisCancelledError(OPERATION$1) : new AnalysisCapabilityUnavailableError(PROVIDER, OPERATION$1, LLDB_REQUIREMENT, { userMessage: LLDB_REQUIREMENT }));
|
|
2047
|
+
const root = await PrivateRuntimeRoot.create({ prefix: "rea-lldb-" });
|
|
2048
|
+
const paths = lldbRuntimePaths(root.path);
|
|
2049
|
+
let result;
|
|
2050
|
+
try {
|
|
2051
|
+
result = await this.#run(lldb.value, root, request, signal);
|
|
2052
|
+
} catch (cause) {
|
|
2053
|
+
const partialObservation = await partialNativeObservation({
|
|
2054
|
+
request,
|
|
2055
|
+
pidPath: paths.pid,
|
|
2056
|
+
stdoutPath: paths.stdoutCapture,
|
|
2057
|
+
stderrPath: paths.stderrCapture,
|
|
2058
|
+
observationPath: paths.observations,
|
|
2059
|
+
version: null,
|
|
2060
|
+
reason: "tracer-failure"
|
|
2061
|
+
});
|
|
2062
|
+
const retained = this.#pendingCleanup;
|
|
2063
|
+
const resources = retained === undefined ? [] : await lldbCleanupResources(retained);
|
|
2064
|
+
result = err(new ProviderAdapterError(PROVIDER, OPERATION$1, {
|
|
2065
|
+
cause,
|
|
2066
|
+
diagnostics: { reason: cause instanceof Error ? cause.message : String(cause) },
|
|
2067
|
+
partialObservation,
|
|
2068
|
+
...retained === undefined ? {} : { cleanup: {
|
|
2069
|
+
reason: "LLDB trace failed while owned resources remain",
|
|
2070
|
+
resources
|
|
2071
|
+
} }
|
|
2072
|
+
}));
|
|
2073
|
+
}
|
|
2074
|
+
if (this.#pendingCleanup?.root === root) return result;
|
|
2075
|
+
try {
|
|
2076
|
+
await root.close();
|
|
2077
|
+
} catch (cause) {
|
|
2078
|
+
this.#pendingCleanup = {
|
|
2079
|
+
root,
|
|
2080
|
+
supervisor: undefined,
|
|
2081
|
+
pidPath: paths.pid,
|
|
2082
|
+
targetIdentity: undefined,
|
|
2083
|
+
processStopped: true,
|
|
2084
|
+
targetStopped: true
|
|
2085
|
+
};
|
|
2086
|
+
const partialObservation = result.ok ? partialObservationFromTrace(request, result.value) : result.error.partialObservation;
|
|
2087
|
+
return err(new ProviderCleanupError(PROVIDER, [root.path], {
|
|
2088
|
+
reason: cause instanceof Error ? cause.message : String(cause),
|
|
2089
|
+
...result.ok ? {} : {
|
|
2090
|
+
execution_failure: projectAnalysisError(result.error).code,
|
|
2091
|
+
primary_failure: result.error.message
|
|
2092
|
+
}
|
|
2093
|
+
}, {
|
|
2094
|
+
operation: OPERATION$1,
|
|
2095
|
+
cause: result.ok ? cause : new AggregateError([result.error, cause], "LLDB trace and runtime cleanup both failed"),
|
|
2096
|
+
...partialObservation === undefined ? {} : { partialObservation }
|
|
2097
|
+
}));
|
|
2098
|
+
}
|
|
2099
|
+
return result;
|
|
2100
|
+
}
|
|
2101
|
+
/** Retry retained LLDB cleanup without abandoning its process or runtime owner. */
|
|
2102
|
+
async close() {
|
|
2103
|
+
return this.#serialize(() => this.#close());
|
|
2104
|
+
}
|
|
2105
|
+
async #close() {
|
|
2106
|
+
const failure = await this.#retryPendingCleanup();
|
|
2107
|
+
return failure === undefined ? ok(null) : err(failure);
|
|
2108
|
+
}
|
|
2109
|
+
#serialize(operation) {
|
|
2110
|
+
const call = this.#tail.then(operation, operation);
|
|
2111
|
+
this.#tail = call.then(() => undefined, () => undefined);
|
|
2112
|
+
return call;
|
|
2113
|
+
}
|
|
2114
|
+
async #retryPendingCleanup() {
|
|
2115
|
+
const owner = this.#pendingCleanup;
|
|
2116
|
+
if (owner === undefined) return undefined;
|
|
2117
|
+
let firstFailure;
|
|
2118
|
+
if (!owner.processStopped) {
|
|
2119
|
+
const stopped = await owner.supervisor?.stop();
|
|
2120
|
+
if (stopped?.status === "incomplete") firstFailure = stopped.reason;
|
|
2121
|
+
else {
|
|
2122
|
+
owner.supervisor?.dispose();
|
|
2123
|
+
owner.processStopped = true;
|
|
2124
|
+
}
|
|
2125
|
+
}
|
|
2126
|
+
if (firstFailure === undefined && !owner.targetStopped) {
|
|
2127
|
+
const targetTermination = await ensureTerminated(owner.pidPath, owner.targetIdentity, true);
|
|
2128
|
+
if (targetTermination !== "terminated") firstFailure = targetTerminationReason(targetTermination);
|
|
2129
|
+
else owner.targetStopped = true;
|
|
2130
|
+
}
|
|
2131
|
+
if (firstFailure === undefined) {
|
|
2132
|
+
try {
|
|
2133
|
+
await owner.root.close();
|
|
2134
|
+
this.#pendingCleanup = undefined;
|
|
2135
|
+
return undefined;
|
|
2136
|
+
} catch (cause) {
|
|
2137
|
+
firstFailure = cause instanceof Error ? cause.message : String(cause);
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
const resources = await lldbCleanupResources(owner);
|
|
2141
|
+
return new ProviderCleanupError(PROVIDER, resources, {
|
|
2142
|
+
reason: firstFailure ?? "LLDB cleanup remains incomplete",
|
|
2143
|
+
resources
|
|
2144
|
+
}, { operation: OPERATION$1 });
|
|
2145
|
+
}
|
|
2146
|
+
async #run(lldb, root, request, signal) {
|
|
2147
|
+
const directory = root.path;
|
|
2148
|
+
const paths = lldbRuntimePaths(directory);
|
|
2149
|
+
const { input } = request;
|
|
2150
|
+
await writeFile(paths.config, JSON.stringify({
|
|
2151
|
+
executable: request.executable,
|
|
2152
|
+
architecture: request.architecture,
|
|
2153
|
+
expected_sha256: request.expectedSha256,
|
|
2154
|
+
arguments: input.arguments,
|
|
2155
|
+
environment: input.environment,
|
|
2156
|
+
working_directory: input.working_directory ?? null,
|
|
2157
|
+
breakpoints: input.breakpoints.map((breakpoint) => breakpoint.kind === "function" ? {
|
|
2158
|
+
...breakpoint,
|
|
2159
|
+
module: breakpoint.module ?? null
|
|
2160
|
+
} : {
|
|
2161
|
+
...breakpoint,
|
|
2162
|
+
class_name: breakpoint.class_name ?? null
|
|
2163
|
+
}),
|
|
2164
|
+
duration_ms: input.duration_ms,
|
|
2165
|
+
max_events: input.max_events,
|
|
2166
|
+
argument_registers: input.argument_registers,
|
|
2167
|
+
backtrace_frames: input.backtrace_frames,
|
|
2168
|
+
max_output_bytes: MAX_OUTPUT_BYTES,
|
|
2169
|
+
stdout_path: paths.stdout,
|
|
2170
|
+
stderr_path: paths.stderr,
|
|
2171
|
+
stdout_capture_path: paths.stdoutCapture,
|
|
2172
|
+
stderr_capture_path: paths.stderrCapture,
|
|
2173
|
+
result_path: paths.result,
|
|
2174
|
+
pid_path: paths.pid,
|
|
2175
|
+
identity_ack_path: paths.identityAck,
|
|
2176
|
+
observation_path: paths.observations
|
|
2177
|
+
}), { mode: 384 });
|
|
2178
|
+
const exited = await this.launch(lldb.path, [
|
|
2179
|
+
"--batch",
|
|
2180
|
+
"--no-lldbinit",
|
|
2181
|
+
"--no-use-colors",
|
|
2182
|
+
"-o",
|
|
2183
|
+
`command script import ${quote(BRIDGE)}`,
|
|
2184
|
+
"-o",
|
|
2185
|
+
`rea_trace ${paths.config}`
|
|
2186
|
+
], {
|
|
2187
|
+
deadlineMs: input.duration_ms + DEADLINE_GRACE_MS,
|
|
2188
|
+
pidPath: paths.pid,
|
|
2189
|
+
identityAckPath: paths.identityAck,
|
|
2190
|
+
environment: this.environment,
|
|
2191
|
+
...signal === undefined ? {} : { signal }
|
|
2192
|
+
});
|
|
2193
|
+
const retained = {
|
|
2194
|
+
root,
|
|
2195
|
+
supervisor: exited.cleanupOwner,
|
|
2196
|
+
pidPath: paths.pid,
|
|
2197
|
+
targetIdentity: exited.targetIdentity,
|
|
2198
|
+
processStopped: exited.cleanupOwner === undefined,
|
|
2199
|
+
targetStopped: !exited.targetLaunched
|
|
2200
|
+
};
|
|
2201
|
+
this.#pendingCleanup = retained;
|
|
2202
|
+
const output = exited.kind === "exited" ? await readTracerOutput(paths.result) : undefined;
|
|
2203
|
+
let targetTermination = exited.targetLaunched ? await ensureTerminated(paths.pid, exited.targetIdentity, true) : "terminated";
|
|
2204
|
+
if (output !== undefined && (output.status === "target-error" || output.status === "launch-error") && await readTargetPid(paths.pid) === undefined) targetTermination = "terminated";
|
|
2205
|
+
retained.targetStopped = targetTermination === "terminated";
|
|
2206
|
+
if (retained.processStopped && retained.targetStopped) this.#pendingCleanup = undefined;
|
|
2207
|
+
const terminated = targetTermination === "terminated";
|
|
2208
|
+
const cleanupDetails = [exited.cleanupFailure, ...terminated ? [] : [targetTerminationReason(targetTermination)]].filter((detail) => detail !== undefined);
|
|
2209
|
+
const lifecycleCleanup = cleanupDetails.length === 0 ? undefined : {
|
|
2210
|
+
reason: cleanupDetails.join("; "),
|
|
2211
|
+
resources: await lldbCleanupResources(retained)
|
|
2212
|
+
};
|
|
2213
|
+
const partialReason = exited.kind === "cancelled" ? "cancelled" : exited.kind === "timeout" ? "timeout" : exited.cleanupFailure !== undefined ? "cleanup-failure" : "tracer-failure";
|
|
2214
|
+
const getPartialObservation = (reason = partialReason) => partialNativeObservation({
|
|
2215
|
+
request,
|
|
2216
|
+
pidPath: paths.pid,
|
|
2217
|
+
stdoutPath: paths.stdoutCapture,
|
|
2218
|
+
stderrPath: paths.stderrCapture,
|
|
2219
|
+
observationPath: paths.observations,
|
|
2220
|
+
version: output?.status === "traced" ? output.version : null,
|
|
2221
|
+
reason
|
|
2222
|
+
});
|
|
2223
|
+
if (exited.kind === "cancelled") return err(new AnalysisCancelledError(OPERATION$1, {
|
|
2224
|
+
...lifecycleCleanup === undefined ? {} : { cleanup: lifecycleCleanup },
|
|
2225
|
+
partialObservation: await getPartialObservation()
|
|
2226
|
+
}));
|
|
2227
|
+
if (exited.kind === "timeout") return err(new AnalysisTimeoutError(OPERATION$1, input.duration_ms + DEADLINE_GRACE_MS, {
|
|
2228
|
+
...lifecycleCleanup === undefined ? {} : { cleanup: lifecycleCleanup },
|
|
2229
|
+
partialObservation: await getPartialObservation()
|
|
2230
|
+
}));
|
|
2231
|
+
if (output !== undefined && output.status !== "traced") return err(tracerFailure(output, lifecycleCleanup, await getPartialObservation()));
|
|
2232
|
+
if (exited.cleanupFailure !== undefined) return err(new ProviderCleanupError(PROVIDER, await lldbCleanupResources(retained), {
|
|
2233
|
+
reason: "LLDB process-group cleanup could not be verified",
|
|
2234
|
+
cleanup_failure: exited.cleanupFailure,
|
|
2235
|
+
...lifecycleCleanup === undefined ? {} : { target_cleanup: lifecycleCleanup }
|
|
2236
|
+
}, {
|
|
2237
|
+
operation: OPERATION$1,
|
|
2238
|
+
partialObservation: await getPartialObservation()
|
|
2239
|
+
}));
|
|
2240
|
+
if (!terminated) return err(new ProviderCleanupError(PROVIDER, await lldbCleanupResources(retained), {
|
|
2241
|
+
reason: "LLDB target process termination could not be verified",
|
|
2242
|
+
...lifecycleCleanup === undefined ? {} : { target_cleanup: lifecycleCleanup }
|
|
2243
|
+
}, {
|
|
2244
|
+
operation: OPERATION$1,
|
|
2245
|
+
partialObservation: await getPartialObservation()
|
|
2246
|
+
}));
|
|
2247
|
+
if (output === undefined) return err(new ProviderAdapterError(PROVIDER, OPERATION$1, {
|
|
2248
|
+
diagnostics: {
|
|
2249
|
+
reason: "LLDB exited without a tracer result",
|
|
2250
|
+
exit_code: exited.exitCode,
|
|
2251
|
+
lldb_output: exited.output,
|
|
2252
|
+
...lifecycleCleanup === undefined ? {} : { target_cleanup: lifecycleCleanup }
|
|
2253
|
+
},
|
|
2254
|
+
partialObservation: await getPartialObservation(),
|
|
2255
|
+
...lifecycleCleanup === undefined ? {} : { cleanup: lifecycleCleanup }
|
|
2256
|
+
}));
|
|
2257
|
+
const stdout = await capturedOutput(paths.stdoutCapture, output.target_output.stdout_bytes, output.target_output.stdout_truncated, output.target_output.stdout_complete);
|
|
2258
|
+
const stderr = await capturedOutput(paths.stderrCapture, output.target_output.stderr_bytes, output.target_output.stderr_truncated, output.target_output.stderr_complete);
|
|
2259
|
+
if (!stdout.ok || !stderr.ok) {
|
|
2260
|
+
const partial = await getPartialObservation("capture-failure");
|
|
2261
|
+
return err(new ProviderAdapterError(PROVIDER, OPERATION$1, {
|
|
2262
|
+
partialObservation: partial,
|
|
2263
|
+
diagnostics: {
|
|
2264
|
+
reason: "LLDB target output capture could not be read",
|
|
2265
|
+
...stdout.ok ? {} : { stdout_capture_error: stdout.error },
|
|
2266
|
+
...stderr.ok ? {} : { stderr_capture_error: stderr.error },
|
|
2267
|
+
...lifecycleCleanup === undefined ? {} : { target_cleanup: lifecycleCleanup }
|
|
2268
|
+
},
|
|
2269
|
+
...lifecycleCleanup === undefined ? {} : { cleanup: lifecycleCleanup }
|
|
2270
|
+
}));
|
|
2271
|
+
}
|
|
2272
|
+
return ok({
|
|
2273
|
+
debugger: {
|
|
2274
|
+
...lldb,
|
|
2275
|
+
version: output.version
|
|
2276
|
+
},
|
|
2277
|
+
run: output,
|
|
2278
|
+
stdout: stdout.value,
|
|
2279
|
+
stderr: stderr.value,
|
|
2280
|
+
terminated
|
|
2281
|
+
});
|
|
2282
|
+
}
|
|
2283
|
+
};
|
|
2284
|
+
quote = (value) => `"${value.replaceAll("\\", "\\\\").replaceAll("\"", "\\\"")}"`;
|
|
2285
|
+
tracerFailure = (output, cleanup, partialObservation) => {
|
|
2286
|
+
const options = {
|
|
2287
|
+
...cleanup === undefined ? {} : { cleanup },
|
|
2288
|
+
...partialObservation === undefined ? {} : { partialObservation }
|
|
2289
|
+
};
|
|
2290
|
+
const message = output.error ?? "no LLDB error text";
|
|
2291
|
+
if (output.status === "target-integrity-error") return new EvidenceIntegrityError(message || "The launched native target did not match its session digest", options);
|
|
2292
|
+
if (output.status === "target-identity-unavailable") return new ProviderAdapterError(PROVIDER, OPERATION$1, {
|
|
2293
|
+
...options,
|
|
2294
|
+
diagnostics: {
|
|
2295
|
+
reason: message,
|
|
2296
|
+
constraint: "target process start identity could not be verified"
|
|
2297
|
+
}
|
|
2298
|
+
});
|
|
2299
|
+
if (output.status === "tracer-error") return new ProviderAdapterError(PROVIDER, OPERATION$1, {
|
|
2300
|
+
...options,
|
|
2301
|
+
diagnostics: { reason: `LLDB bridge failed: ${message}` }
|
|
2302
|
+
});
|
|
2303
|
+
if (output.status === "target-error") return new AnalysisCapabilityUnavailableError(PROVIDER, OPERATION$1, `lldb-target-unloadable: ${message}`, options);
|
|
2304
|
+
return /attach|not allowed|permission|denied|debugserver/iu.test(message) ? new AnalysisCapabilityUnavailableError(PROVIDER, OPERATION$1, `debugger-attach-denied: ${message}`, {
|
|
2305
|
+
userMessage: ATTACH_REMEDIATION,
|
|
2306
|
+
...options
|
|
2307
|
+
}) : new AnalysisCapabilityUnavailableError(PROVIDER, OPERATION$1, `launch-failed: ${message}`, options);
|
|
2308
|
+
};
|
|
2309
|
+
partialNativeObservation = async (options) => {
|
|
2310
|
+
const [journal, pid, stdout, stderr] = await Promise.all([
|
|
2311
|
+
readLldbObservationJournal(options.observationPath),
|
|
2312
|
+
readTargetPid(options.pidPath),
|
|
2313
|
+
readPartialCapture(options.stdoutPath),
|
|
2314
|
+
readPartialCapture(options.stderrPath)
|
|
2315
|
+
]);
|
|
2316
|
+
return projectLldbPartialObservation({
|
|
2317
|
+
target: {
|
|
2318
|
+
path: options.request.executable,
|
|
2319
|
+
sha256: options.request.expectedSha256,
|
|
2320
|
+
architecture: options.request.architecture,
|
|
2321
|
+
arguments: options.request.input.arguments,
|
|
2322
|
+
environment: options.request.input.environment,
|
|
2323
|
+
working_directory: options.request.input.working_directory ?? null
|
|
2324
|
+
},
|
|
2325
|
+
pid,
|
|
2326
|
+
stdout: stdout?.capture ?? null,
|
|
2327
|
+
stderr: stderr?.capture ?? null,
|
|
2328
|
+
version: options.version,
|
|
2329
|
+
journal: journal.parsed,
|
|
2330
|
+
journalLimitations: journal.limitations,
|
|
2331
|
+
limitations: [...stdout?.limitations ?? [], ...stderr?.limitations ?? []],
|
|
2332
|
+
reason: options.reason
|
|
2333
|
+
});
|
|
2334
|
+
};
|
|
2335
|
+
partialObservationFromTrace = (request, trace) => projectLldbPartialObservation({
|
|
2336
|
+
target: {
|
|
2337
|
+
path: request.executable,
|
|
2338
|
+
sha256: request.expectedSha256,
|
|
2339
|
+
architecture: request.architecture,
|
|
2340
|
+
arguments: request.input.arguments,
|
|
2341
|
+
environment: request.input.environment,
|
|
2342
|
+
working_directory: request.input.working_directory ?? null
|
|
2343
|
+
},
|
|
2344
|
+
pid: trace.run.pid,
|
|
2345
|
+
stdout: trace.stdout,
|
|
2346
|
+
stderr: trace.stderr,
|
|
2347
|
+
version: trace.run.version,
|
|
2348
|
+
journal: {
|
|
2349
|
+
events: trace.run.events,
|
|
2350
|
+
otherStops: trace.run.other_stops,
|
|
2351
|
+
limitations: []
|
|
2352
|
+
},
|
|
2353
|
+
reason: "cleanup-failure"
|
|
2354
|
+
});
|
|
2355
|
+
lldbRuntimePaths = (directory) => ({
|
|
2356
|
+
config: join(directory, "config.json"),
|
|
2357
|
+
result: join(directory, "result.json"),
|
|
2358
|
+
pid: join(directory, "pid"),
|
|
2359
|
+
identityAck: join(directory, "identity.ack"),
|
|
2360
|
+
stdout: join(directory, "stdout"),
|
|
2361
|
+
stderr: join(directory, "stderr"),
|
|
2362
|
+
stdoutCapture: join(directory, "stdout.capture"),
|
|
2363
|
+
stderrCapture: join(directory, "stderr.capture"),
|
|
2364
|
+
observations: join(directory, "observations.jsonl")
|
|
2365
|
+
});
|
|
2366
|
+
readTracerOutput = async (path) => {
|
|
2367
|
+
let text;
|
|
2368
|
+
try {
|
|
2369
|
+
text = await readFile(path, "utf8");
|
|
2370
|
+
} catch {
|
|
2371
|
+
return undefined;
|
|
2372
|
+
}
|
|
2373
|
+
const parsed = safeParseJson(text);
|
|
2374
|
+
if (!parsed.ok) return undefined;
|
|
2375
|
+
const output = tracerOutputSchema.safeParse(parsed.value);
|
|
2376
|
+
return output.success ? output.data : undefined;
|
|
2377
|
+
};
|
|
2378
|
+
capturedOutput = async (path, observedBytes, truncated, complete) => {
|
|
2379
|
+
let handle;
|
|
2380
|
+
try {
|
|
2381
|
+
handle = await open(path, "r");
|
|
2382
|
+
const { size } = await handle.stat();
|
|
2383
|
+
const captureHandle = handle;
|
|
2384
|
+
const { buffer, bytesRead } = await readBoundedPrefix(Math.min(size, MAX_OUTPUT_BYTES), async (target, offset, length, position) => (await captureHandle.read(target, offset, length, position)).bytesRead);
|
|
2385
|
+
const captured = {
|
|
2386
|
+
text: buffer.subarray(0, bytesRead).toString("utf8"),
|
|
2387
|
+
bytes: observedBytes,
|
|
2388
|
+
truncated: truncated || size > MAX_OUTPUT_BYTES,
|
|
2389
|
+
complete: complete && bytesRead >= Math.min(observedBytes, MAX_OUTPUT_BYTES)
|
|
2390
|
+
};
|
|
2391
|
+
await handle.close();
|
|
2392
|
+
handle = undefined;
|
|
2393
|
+
return ok(captured);
|
|
2394
|
+
} catch (cause) {
|
|
2395
|
+
const failure = cause instanceof Error ? cause.message : String(cause);
|
|
2396
|
+
if (handle !== undefined) {
|
|
2397
|
+
try {
|
|
2398
|
+
await handle.close();
|
|
2399
|
+
} catch (closeCause) {
|
|
2400
|
+
return err(`${failure}; closing capture file failed: ${closeCause instanceof Error ? closeCause.message : String(closeCause)}`);
|
|
2401
|
+
}
|
|
2402
|
+
}
|
|
2403
|
+
return err(failure);
|
|
2404
|
+
}
|
|
2405
|
+
};
|
|
2406
|
+
lldbCleanupResources = async (owner) => [
|
|
2407
|
+
...owner.processStopped ? [] : ["lldb-process-group"],
|
|
2408
|
+
...owner.targetStopped ? [] : [`native-target:${String(await readTargetPid(owner.pidPath) ?? "unknown")}`],
|
|
2409
|
+
owner.root.path
|
|
2410
|
+
];
|
|
2411
|
+
runLldb = async (executable, arguments_, options) => {
|
|
2412
|
+
if (options.signal?.aborted === true) return {
|
|
2413
|
+
kind: "cancelled",
|
|
2414
|
+
targetLaunched: false,
|
|
2415
|
+
targetIdentity: undefined,
|
|
2416
|
+
cleanupFailure: undefined
|
|
2417
|
+
};
|
|
2418
|
+
const deadline = new ProviderStartupDeadline(options.deadlineMs, options.signal);
|
|
2419
|
+
let targetIdentity;
|
|
2420
|
+
let supervisor;
|
|
2421
|
+
let retained = false;
|
|
2422
|
+
const finish = async (outcome) => {
|
|
2423
|
+
const stopped = await supervisor?.stop();
|
|
2424
|
+
retained = stopped?.status === "incomplete";
|
|
2425
|
+
return {
|
|
2426
|
+
...deadline.interruption === undefined ? outcome : { kind: deadline.interruption },
|
|
2427
|
+
targetLaunched: supervisor !== undefined,
|
|
2428
|
+
targetIdentity,
|
|
2429
|
+
cleanupFailure: stopped?.status === "incomplete" ? stopped.reason : undefined,
|
|
2430
|
+
...retained && supervisor !== undefined ? { cleanupOwner: supervisor } : {}
|
|
2431
|
+
};
|
|
2432
|
+
};
|
|
2433
|
+
try {
|
|
2434
|
+
const launched = await spawnOwnedProviderProcess({
|
|
2435
|
+
command: executable,
|
|
2436
|
+
arguments: arguments_,
|
|
2437
|
+
runId: randomUUID(),
|
|
2438
|
+
expectedCommand: executable,
|
|
2439
|
+
signal: deadline.signal,
|
|
2440
|
+
hostEnvironment: options.environment
|
|
2441
|
+
});
|
|
2442
|
+
supervisor = new ProviderProcessSupervisor({
|
|
2443
|
+
...launched,
|
|
2444
|
+
ownsProcessLifetime: true,
|
|
2445
|
+
cleanup: () => cleanupOwnedProcessGroup(launched.ownership)
|
|
2446
|
+
}, { maxDiagnosticBytes: DIAGNOSTIC_BYTES });
|
|
2447
|
+
let identityAckWritten = false;
|
|
2448
|
+
while (!await supervisor.waitForOutputClose(20)) {
|
|
2449
|
+
const pid = await readTargetPid(options.pidPath);
|
|
2450
|
+
if (pid !== undefined && !identityAckWritten) {
|
|
2451
|
+
let observation;
|
|
2452
|
+
try {
|
|
2453
|
+
observation = await observeProcessStartIdentity(pid);
|
|
2454
|
+
} catch {
|
|
2455
|
+
observation = undefined;
|
|
2456
|
+
}
|
|
2457
|
+
if (observation?.state === "readable") targetIdentity = observation.identity;
|
|
2458
|
+
await writeFile(options.identityAckPath, observation?.state === "readable" ? "readable" : "unavailable", { mode: 384 });
|
|
2459
|
+
identityAckWritten = true;
|
|
2460
|
+
}
|
|
2461
|
+
const interruption = deadline.interruption;
|
|
2462
|
+
if (interruption !== undefined) return await finish({ kind: interruption });
|
|
2463
|
+
await waitForAbortableDelay(20, deadline.signal);
|
|
2464
|
+
}
|
|
2465
|
+
const snapshot = supervisor.snapshot();
|
|
2466
|
+
const interruption = deadline.interruption;
|
|
2467
|
+
return await finish(interruption === undefined ? {
|
|
2468
|
+
kind: "exited",
|
|
2469
|
+
exitCode: snapshot.exitCode ?? null,
|
|
2470
|
+
output: `${snapshot.stdout.text}${snapshot.stderr.text}`.slice(-DIAGNOSTIC_BYTES)
|
|
2471
|
+
} : { kind: interruption });
|
|
2472
|
+
} catch (cause) {
|
|
2473
|
+
const interruption = deadline.interruption;
|
|
2474
|
+
return await finish(interruption === undefined ? {
|
|
2475
|
+
kind: "exited",
|
|
2476
|
+
exitCode: null,
|
|
2477
|
+
output: cause instanceof Error ? cause.message : String(cause)
|
|
2478
|
+
} : { kind: interruption });
|
|
2479
|
+
} finally {
|
|
2480
|
+
if (!retained) supervisor?.dispose();
|
|
2481
|
+
deadline.dispose();
|
|
2482
|
+
}
|
|
2483
|
+
};
|
|
2484
|
+
readTargetPid = async (pidPath) => {
|
|
2485
|
+
try {
|
|
2486
|
+
const contents = (await readFile(pidPath, "utf8")).trim();
|
|
2487
|
+
if (!/^[1-9]\d*$/u.test(contents)) return undefined;
|
|
2488
|
+
const pid = Number(contents);
|
|
2489
|
+
return Number.isSafeInteger(pid) ? pid : undefined;
|
|
2490
|
+
} catch {
|
|
2491
|
+
return undefined;
|
|
2492
|
+
}
|
|
2493
|
+
};
|
|
2494
|
+
ensureTerminated = async (pidPath, identity, missingPidIsUnknown) => {
|
|
2495
|
+
const pid = await readTargetPid(pidPath);
|
|
2496
|
+
if (pid === undefined) return missingPidIsUnknown ? "identity-unavailable" : "terminated";
|
|
2497
|
+
if (!Number.isSafeInteger(pid) || pid <= 0) return "identity-unavailable";
|
|
2498
|
+
let signalDisposition;
|
|
2499
|
+
for (let attempt = 0; attempt < 20; attempt++) {
|
|
2500
|
+
if (!alive(pid)) return "terminated";
|
|
2501
|
+
if (attempt === 10) {
|
|
2502
|
+
if (identity === undefined) signalDisposition = "identity-unavailable";
|
|
2503
|
+
else {
|
|
2504
|
+
const result = await signalProcessWithStartIdentity(pid, identity, "SIGKILL");
|
|
2505
|
+
if (result === "gone") return "terminated";
|
|
2506
|
+
if (result === "identity-changed") signalDisposition = "identity-changed";
|
|
2507
|
+
else if (result === "unverified") signalDisposition = "identity-unavailable";
|
|
2508
|
+
else if (result === "signaled") signalDisposition = "signal-did-not-stop";
|
|
2509
|
+
}
|
|
2510
|
+
}
|
|
2511
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
2512
|
+
}
|
|
2513
|
+
return !alive(pid) ? "terminated" : signalDisposition ?? "identity-unavailable";
|
|
2514
|
+
};
|
|
2515
|
+
targetTerminationReason = (termination) => {
|
|
2516
|
+
switch (termination) {
|
|
2517
|
+
case "terminated": return "target process terminated";
|
|
2518
|
+
case "identity-unavailable": return "target process start identity was unavailable; survivor was left untouched";
|
|
2519
|
+
case "identity-changed": return "target PID start identity changed; replacement process was left untouched";
|
|
2520
|
+
case "signal-did-not-stop": return "verified target did not exit after SIGKILL";
|
|
2521
|
+
}
|
|
2522
|
+
};
|
|
2523
|
+
alive = (pid) => {
|
|
2524
|
+
try {
|
|
2525
|
+
process.kill(pid, 0);
|
|
2526
|
+
return true;
|
|
2527
|
+
} catch (cause) {
|
|
2528
|
+
return !(cause instanceof Error && "code" in cause && cause.code === "ESRCH");
|
|
2529
|
+
}
|
|
2530
|
+
};
|
|
2531
|
+
})))();
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
//#endregion
|
|
2535
|
+
//#region dist/native/NativeCallObservation.js
|
|
2536
|
+
var OPERATION, NATIVE_CALL_OBSERVATION_LIMITATIONS, observeNativeCalls, isAbortError, projectNativeCalls, fileSha256;
|
|
2537
|
+
function init_NativeCallObservation() {
|
|
2538
|
+
return (init_NativeCallObservation = __esmMin((() => {
|
|
2539
|
+
init_analysisErrorCore();
|
|
2540
|
+
init_binaryTargetTypes();
|
|
2541
|
+
init_evidenceErrors();
|
|
2542
|
+
init_providerAdapterError();
|
|
2543
|
+
init_nativeCallObservation();
|
|
2544
|
+
init_result();
|
|
2545
|
+
OPERATION = "observe_native_calls";
|
|
2546
|
+
NATIVE_CALL_OBSERVATION_LIMITATIONS = [
|
|
2547
|
+
"Only entries are observed; return values, floating-point and stack-passed arguments are not captured.",
|
|
2548
|
+
"Registers are the raw integer argument registers at entry. For Objective-C methods the first two hold the receiver and the selector.",
|
|
2549
|
+
"Receiver classes come from LLDB's Objective-C runtime reader without running target code; they are null for class methods and for receivers LLDB cannot classify.",
|
|
2550
|
+
"Calls that never reach a symbol's entry, such as inlined code or objc_direct methods called directly, are not observed.",
|
|
2551
|
+
"The target is launched directly under LLDB, not through LaunchServices; LLDB disables ASLR for it, so load addresses can equal file addresses.",
|
|
2552
|
+
"The observation window is checked about once a second, and recording pauses the process at every entry, which slows it."
|
|
2553
|
+
];
|
|
2554
|
+
observeNativeCalls = async (target, parameters, tracer, signal, readTargetDigest = fileSha256) => {
|
|
2555
|
+
if (target.kind !== "executable" || !isMachOFormat(target.format)) return err(new AnalysisCapabilityUnavailableError("native-macos", OPERATION, "Native call observation launches a Mach-O executable; the active target is not one"));
|
|
2556
|
+
const parsed = nativeCallObservationInputSchema.safeParse(parameters);
|
|
2557
|
+
if (!parsed.success) return err(new AnalysisInputError(OPERATION, { cause: parsed.error }));
|
|
2558
|
+
let digest;
|
|
2559
|
+
try {
|
|
2560
|
+
digest = await readTargetDigest(target.path, signal);
|
|
2561
|
+
} catch (cause) {
|
|
2562
|
+
if (signal?.aborted === true || isAbortError(cause)) return err(new AnalysisCancelledError(OPERATION));
|
|
2563
|
+
return err(new ProviderAdapterError("native-macos", OPERATION, { diagnostics: {
|
|
2564
|
+
reason: "Unable to verify the selected target digest",
|
|
2565
|
+
detail: cause instanceof Error ? cause.message : String(cause)
|
|
2566
|
+
} }));
|
|
2567
|
+
}
|
|
2568
|
+
if (digest !== target.sha256) return err(new EvidenceIntegrityError("Native call observation target digest changed after session binding"));
|
|
2569
|
+
if (signal?.aborted === true) return err(new AnalysisCancelledError(OPERATION));
|
|
2570
|
+
const traced = await tracer.trace({
|
|
2571
|
+
executable: target.path,
|
|
2572
|
+
architecture: target.architecture,
|
|
2573
|
+
expectedSha256: target.sha256,
|
|
2574
|
+
input: parsed.data
|
|
2575
|
+
}, signal);
|
|
2576
|
+
if (!traced.ok) return traced;
|
|
2577
|
+
return ok(projectNativeCalls(target, parsed.data, traced.value));
|
|
2578
|
+
};
|
|
2579
|
+
isAbortError = (cause) => cause instanceof Error && cause.name === "AbortError";
|
|
2580
|
+
projectNativeCalls = (target, input, trace) => {
|
|
2581
|
+
const { run } = trace;
|
|
2582
|
+
const unresolved = run.breakpoints.filter(({ location_count: count }) => count === 0).map(({ index }) => index);
|
|
2583
|
+
const eventLimit = run.outcome === "event-limit";
|
|
2584
|
+
const resourceLimit = run.outcome === "resource-limit";
|
|
2585
|
+
const breakpointLocationLimit = run.breakpoint_locations_truncated === true;
|
|
2586
|
+
const partial = eventLimit || resourceLimit || breakpointLocationLimit || run.outcome === "duration-elapsed" || run.outcome === "stop-limit" || unresolved.length > 0;
|
|
2587
|
+
return nativeCallObservationResultSchema.parse({
|
|
2588
|
+
target: {
|
|
2589
|
+
path: target.path,
|
|
2590
|
+
sha256: target.sha256,
|
|
2591
|
+
architecture: target.architecture,
|
|
2592
|
+
arguments: input.arguments,
|
|
2593
|
+
environment: input.environment,
|
|
2594
|
+
working_directory: input.working_directory ?? null,
|
|
2595
|
+
launch_identity: {
|
|
2596
|
+
loaded_image_sha256: run.target_identity.loaded_image_sha256,
|
|
2597
|
+
file_device: run.target_identity.file_device,
|
|
2598
|
+
file_inode: run.target_identity.file_inode,
|
|
2599
|
+
selected_file_sha256: run.target_identity.selected_file_sha256,
|
|
2600
|
+
module_path: run.target_identity.module_path,
|
|
2601
|
+
module_uuid: run.target_identity.module_uuid,
|
|
2602
|
+
stable: run.target_identity.stable
|
|
2603
|
+
}
|
|
2604
|
+
},
|
|
2605
|
+
debugger: trace.debugger,
|
|
2606
|
+
process: {
|
|
2607
|
+
pid: run.pid,
|
|
2608
|
+
outcome: run.outcome,
|
|
2609
|
+
exit_status: run.exit_status,
|
|
2610
|
+
exit_description: run.exit_description,
|
|
2611
|
+
terminated: run.terminated && trace.terminated,
|
|
2612
|
+
elapsed_ms: run.elapsed_ms,
|
|
2613
|
+
stdout: trace.stdout,
|
|
2614
|
+
stderr: trace.stderr,
|
|
2615
|
+
other_stops: run.other_stops
|
|
2616
|
+
},
|
|
2617
|
+
breakpoints: input.breakpoints.map((request, index) => ({
|
|
2618
|
+
index,
|
|
2619
|
+
request: request.kind === "function" ? {
|
|
2620
|
+
...request,
|
|
2621
|
+
module: request.module ?? null
|
|
2622
|
+
} : {
|
|
2623
|
+
...request,
|
|
2624
|
+
class_name: request.class_name ?? null
|
|
2625
|
+
},
|
|
2626
|
+
location_count: run.breakpoints[index]?.location_count ?? 0,
|
|
2627
|
+
locations: run.breakpoints[index]?.locations ?? []
|
|
2628
|
+
})),
|
|
2629
|
+
events: run.events,
|
|
2630
|
+
coverage: {
|
|
2631
|
+
status: partial ? "partial" : "complete",
|
|
2632
|
+
event_limit_reached: eventLimit,
|
|
2633
|
+
resource_limit_reached: resourceLimit,
|
|
2634
|
+
...breakpointLocationLimit ? { breakpoint_locations_truncated: true } : {},
|
|
2635
|
+
unresolved_breakpoints: unresolved
|
|
2636
|
+
},
|
|
2637
|
+
limitations: [
|
|
2638
|
+
...NATIVE_CALL_OBSERVATION_LIMITATIONS,
|
|
2639
|
+
"The selected pathname digest and LLDB module identity are checked around launch. No immutable executable snapshot is used; concurrent in-place mutation or replacement and restoration cannot be ruled out, so the loaded-image digest remains unknown.",
|
|
2640
|
+
...eventLimit ? [`Observation stopped at max_events (${input.max_events}); later calls were not recorded and the process was killed.`] : [],
|
|
2641
|
+
...resourceLimit ? ["Observation stopped before retaining the next complete event because the estimated 8 MiB trace-payload or 65,536-frame aggregate budget was reached; the process was killed."] : [],
|
|
2642
|
+
...run.outcome === "duration-elapsed" ? [`The process was still running after duration_ms (${input.duration_ms}) and was killed.`] : [],
|
|
2643
|
+
...run.target_identity.stable ? [] : ["LLDB did not provide enough module identity evidence to confirm pathname and module continuity around launch."],
|
|
2644
|
+
...run.outcome === "stop-limit" ? ["Observation stopped after repeated signal or exception stops; the process was killed."] : [],
|
|
2645
|
+
...unresolved.length === 0 ? [] : [`Breakpoints ${unresolved.join(", ")} matched no code in any image loaded while observing; their calls could not be observed.`],
|
|
2646
|
+
...run.breakpoints.some(({ location_count: count, locations }) => locations.length < count) ? ["Breakpoints with many matching locations list only the first 64; location_count gives the total."] : [],
|
|
2647
|
+
...breakpointLocationLimit ? ["Resolved breakpoint locations exceeded the aggregate 8 MiB metadata budget; omitted locations are counted in location_count. This metadata limit does not change the process outcome."] : [],
|
|
2648
|
+
...trace.stdout.truncated || trace.stderr.truncated ? ["Target output beyond 1 MiB per stream is counted but not kept."] : [],
|
|
2649
|
+
...!trace.stdout.complete || !trace.stderr.complete ? ["Target output draining did not complete; reported byte counts are observed lower bounds, not stream totals."] : [],
|
|
2650
|
+
...run.terminated && trace.terminated ? [] : [`REA could not confirm that process ${run.pid} exited; check for it before relying on host state.`]
|
|
2651
|
+
]
|
|
2652
|
+
});
|
|
2653
|
+
};
|
|
2654
|
+
fileSha256 = async (path, signal) => {
|
|
2655
|
+
const handle = await open(path, "r");
|
|
2656
|
+
try {
|
|
2657
|
+
const hash = createHash("sha256");
|
|
2658
|
+
const buffer = new Uint8Array(1024 * 1024);
|
|
2659
|
+
for (;;) {
|
|
2660
|
+
signal?.throwIfAborted();
|
|
2661
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, null);
|
|
2662
|
+
if (bytesRead === 0) break;
|
|
2663
|
+
hash.update(buffer.subarray(0, bytesRead));
|
|
2664
|
+
}
|
|
2665
|
+
return hash.digest("hex");
|
|
2666
|
+
} finally {
|
|
2667
|
+
await handle.close();
|
|
2668
|
+
}
|
|
2669
|
+
};
|
|
2670
|
+
})))();
|
|
2671
|
+
}
|
|
2672
|
+
|
|
2673
|
+
//#endregion
|
|
2674
|
+
//#region dist/native/SignatureTargetBinding.js
|
|
2675
|
+
var identity, changedTarget, signatureReadFailure, withSignatureTarget, snapshotFailure, snapshotIO, copySignatureBytes, bindSignatureTarget, verifySignatureTarget;
|
|
2676
|
+
function init_SignatureTargetBinding() {
|
|
2677
|
+
return (init_SignatureTargetBinding = __esmMin((() => {
|
|
2678
|
+
init_analysisErrorBase();
|
|
2679
|
+
init_analysisErrorCore();
|
|
2680
|
+
init_providerAdapterError();
|
|
2681
|
+
init_result();
|
|
2682
|
+
init_NativeMacOSProviderMetadata();
|
|
2683
|
+
identity = (stat) => [
|
|
2684
|
+
stat.dev,
|
|
2685
|
+
stat.ino,
|
|
2686
|
+
stat.size,
|
|
2687
|
+
stat.mtimeNs,
|
|
2688
|
+
stat.ctimeNs
|
|
2689
|
+
].join(":");
|
|
2690
|
+
changedTarget = (target, reason) => err(new AnalysisArtifactChangedError("inspect_signature", target.path, reason));
|
|
2691
|
+
signatureReadFailure = (target, cause) => {
|
|
2692
|
+
if (cause instanceof AnalysisError) return cause;
|
|
2693
|
+
const code = cause instanceof Error && "code" in cause ? cause.code : undefined;
|
|
2694
|
+
if (code === "EACCES" || code === "EPERM") return new AnalysisAccessDeniedError("inspect_signature", target.path, code, { cause });
|
|
2695
|
+
if (code === "ENOENT" || code === "ENOTDIR" || code === "ELOOP") return new AnalysisArtifactChangedError("inspect_signature", target.path, `Registered signature target is no longer readable (${code}): ${target.path}`, { cause });
|
|
2696
|
+
return new ProviderAdapterError(NATIVE_MACOS_PROVIDER_IDENTITY.id, "inspect_signature", {
|
|
2697
|
+
cause,
|
|
2698
|
+
diagnostics: {
|
|
2699
|
+
path: target.path,
|
|
2700
|
+
phase: "target-version-binding",
|
|
2701
|
+
system_code: typeof code === "string" ? code : null,
|
|
2702
|
+
reason: cause instanceof Error ? cause.message : String(cause)
|
|
2703
|
+
}
|
|
2704
|
+
});
|
|
2705
|
+
};
|
|
2706
|
+
withSignatureTarget = async (target, inspect, signal) => {
|
|
2707
|
+
let directory;
|
|
2708
|
+
try {
|
|
2709
|
+
signal?.throwIfAborted();
|
|
2710
|
+
directory = await mkdtemp(join(tmpdir(), "rea-signature-"));
|
|
2711
|
+
} catch (cause) {
|
|
2712
|
+
return err(signal?.aborted ? new AnalysisCancelledError("inspect_signature") : snapshotFailure(target, "create", cause));
|
|
2713
|
+
}
|
|
2714
|
+
let result;
|
|
2715
|
+
let cleanup;
|
|
2716
|
+
try {
|
|
2717
|
+
const binding = await bindSignatureTarget(target, join(directory, basename(target.path)), signal);
|
|
2718
|
+
result = binding.ok ? await inspect(binding.value) : binding;
|
|
2719
|
+
} finally {
|
|
2720
|
+
try {
|
|
2721
|
+
await rm(directory, {
|
|
2722
|
+
recursive: true,
|
|
2723
|
+
force: true
|
|
2724
|
+
});
|
|
2725
|
+
cleanup = ok(undefined);
|
|
2726
|
+
} catch (cause) {
|
|
2727
|
+
cleanup = err(snapshotFailure(target, "cleanup", cause));
|
|
2728
|
+
}
|
|
2729
|
+
}
|
|
2730
|
+
return result.ok && !cleanup.ok ? cleanup : result;
|
|
2731
|
+
};
|
|
2732
|
+
snapshotFailure = (target, phase, cause) => new ProviderAdapterError(NATIVE_MACOS_PROVIDER_IDENTITY.id, "inspect_signature", {
|
|
2733
|
+
cause,
|
|
2734
|
+
diagnostics: {
|
|
2735
|
+
path: target.path,
|
|
2736
|
+
phase: `signature-snapshot-${phase}`,
|
|
2737
|
+
reason: cause instanceof Error ? cause.message : String(cause)
|
|
2738
|
+
}
|
|
2739
|
+
});
|
|
2740
|
+
snapshotIO = async (target, phase, operation) => {
|
|
2741
|
+
try {
|
|
2742
|
+
return await operation();
|
|
2743
|
+
} catch (cause) {
|
|
2744
|
+
throw snapshotFailure(target, phase, cause);
|
|
2745
|
+
}
|
|
2746
|
+
};
|
|
2747
|
+
copySignatureBytes = async (target, source, snapshot, signal) => {
|
|
2748
|
+
const size = Number(source.stat.size);
|
|
2749
|
+
if (!Number.isSafeInteger(size)) throw new AnalysisResourceConstraintError("inspect_signature", "file-size", `Signature target size is not exactly representable: ${target.path}`, null);
|
|
2750
|
+
const hash = createHash("sha256");
|
|
2751
|
+
const chunk = Buffer.alloc(64 * 1024);
|
|
2752
|
+
let position = 0;
|
|
2753
|
+
while (position < size) {
|
|
2754
|
+
signal?.throwIfAborted();
|
|
2755
|
+
const { bytesRead } = await source.file.read(chunk, 0, Math.min(chunk.length, size - position), position);
|
|
2756
|
+
signal?.throwIfAborted();
|
|
2757
|
+
if (bytesRead === 0) throw new AnalysisArtifactChangedError("inspect_signature", target.path, `Signature target was truncated while hashing: ${target.path}`);
|
|
2758
|
+
const bytes = chunk.subarray(0, bytesRead);
|
|
2759
|
+
hash.update(bytes);
|
|
2760
|
+
await snapshotIO(target, "write", () => snapshot.writeFile(bytes));
|
|
2761
|
+
position += bytesRead;
|
|
2762
|
+
}
|
|
2763
|
+
return hash.digest("hex");
|
|
2764
|
+
};
|
|
2765
|
+
bindSignatureTarget = async (target, snapshotPath, signal) => {
|
|
2766
|
+
try {
|
|
2767
|
+
signal?.throwIfAborted();
|
|
2768
|
+
const before = await lstat(target.path, { bigint: true });
|
|
2769
|
+
signal?.throwIfAborted();
|
|
2770
|
+
if (!before.isFile() || before.isSymbolicLink()) return changedTarget(target, `Signature target is no longer a regular file: ${target.path}`);
|
|
2771
|
+
const file = await open(target.path, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
2772
|
+
try {
|
|
2773
|
+
const opened = await file.stat({ bigint: true });
|
|
2774
|
+
signal?.throwIfAborted();
|
|
2775
|
+
if (identity(opened) !== identity(before)) return changedTarget(target, `Signature target changed before open: ${target.path}`);
|
|
2776
|
+
const snapshot = await snapshotIO(target, "create-file", () => open(snapshotPath, "wx", 384));
|
|
2777
|
+
try {
|
|
2778
|
+
const observed = await copySignatureBytes(target, {
|
|
2779
|
+
file,
|
|
2780
|
+
stat: opened
|
|
2781
|
+
}, snapshot, signal);
|
|
2782
|
+
if (observed !== target.sha256) return changedTarget(target, `Signature target digest changed: ${target.path}; expected ${target.sha256}, observed ${observed}`);
|
|
2783
|
+
const after = await file.stat({ bigint: true });
|
|
2784
|
+
const current = await lstat(target.path, { bigint: true });
|
|
2785
|
+
signal?.throwIfAborted();
|
|
2786
|
+
if (identity(after) !== identity(opened) || identity(current) !== identity(opened)) return changedTarget(target, `Signature target changed while establishing its version: ${target.path}`);
|
|
2787
|
+
await snapshotIO(target, "seal", () => snapshot.chmod(256));
|
|
2788
|
+
return ok({
|
|
2789
|
+
identity: identity(opened),
|
|
2790
|
+
snapshotPath
|
|
2791
|
+
});
|
|
2792
|
+
} finally {
|
|
2793
|
+
await snapshotIO(target, "close", () => snapshot.close());
|
|
2794
|
+
}
|
|
2795
|
+
} finally {
|
|
2796
|
+
await file.close();
|
|
2797
|
+
}
|
|
2798
|
+
} catch (cause) {
|
|
2799
|
+
return err(signal?.aborted ? new AnalysisCancelledError("inspect_signature") : signatureReadFailure(target, cause));
|
|
2800
|
+
}
|
|
2801
|
+
};
|
|
2802
|
+
verifySignatureTarget = async (target, binding, signal) => {
|
|
2803
|
+
try {
|
|
2804
|
+
signal?.throwIfAborted();
|
|
2805
|
+
const current = await lstat(target.path, { bigint: true });
|
|
2806
|
+
signal?.throwIfAborted();
|
|
2807
|
+
return current.isFile() && identity(current) === binding.identity ? ok(undefined) : changedTarget(target, `Signature target changed during inspection: ${target.path}`);
|
|
2808
|
+
} catch (cause) {
|
|
2809
|
+
return err(signal?.aborted ? new AnalysisCancelledError("inspect_signature") : signatureReadFailure(target, cause));
|
|
2810
|
+
}
|
|
2811
|
+
};
|
|
2812
|
+
})))();
|
|
2813
|
+
}
|
|
2814
|
+
|
|
2815
|
+
//#endregion
|
|
2816
|
+
//#region dist/native/parsers/codesign.js
|
|
2817
|
+
var parseCodeSignature, splitEchoedValues, nullableCodeSignValue, splitAlgorithms, parseRuntime;
|
|
2818
|
+
function init_codesign() {
|
|
2819
|
+
return (init_codesign = __esmMin((() => {
|
|
2820
|
+
init_nativeInspection();
|
|
2821
|
+
parseCodeSignature = (output, unsigned, executablePaths = []) => {
|
|
2822
|
+
const { identifier, fields } = splitEchoedValues(output.replaceAll("\r\n", "\n"), executablePaths);
|
|
2823
|
+
const values = new Map();
|
|
2824
|
+
const authorities = [];
|
|
2825
|
+
const cdhashes = [];
|
|
2826
|
+
for (const line of fields.split("\n")) {
|
|
2827
|
+
if (line.startsWith("CodeDirectory ")) {
|
|
2828
|
+
values.set("CodeDirectory", line.slice("CodeDirectory ".length));
|
|
2829
|
+
continue;
|
|
2830
|
+
}
|
|
2831
|
+
const separator = line.indexOf("=");
|
|
2832
|
+
if (separator < 1) continue;
|
|
2833
|
+
const key = line.slice(0, separator).trim();
|
|
2834
|
+
const value = line.slice(separator + 1).trim();
|
|
2835
|
+
if (key === "Authority") authorities.push(value);
|
|
2836
|
+
else if (key === "CDHash") cdhashes.push(value);
|
|
2837
|
+
else values.set(key, value);
|
|
2838
|
+
}
|
|
2839
|
+
const parsed = inspectSignatureSchema.omit({ provenance: true }).parse({
|
|
2840
|
+
signed: !unsigned,
|
|
2841
|
+
identifier: identifier ?? null,
|
|
2842
|
+
team_identifier: nullableCodeSignValue(values.get("TeamIdentifier")),
|
|
2843
|
+
format: values.get("Format") ?? null,
|
|
2844
|
+
cdhashes,
|
|
2845
|
+
hash_algorithms: splitAlgorithms(values.get("Hash choices")),
|
|
2846
|
+
authorities,
|
|
2847
|
+
designated_requirement: values.get("designated") ?? null,
|
|
2848
|
+
entitlements: null,
|
|
2849
|
+
timestamp: values.get("Timestamp") ?? null,
|
|
2850
|
+
hardened_runtime: parseRuntime(values.get("CodeDirectory")),
|
|
2851
|
+
limitations: unsigned ? ["Artifact is not signed."] : ["Entitlements and designated requirements require separate bounded commands."]
|
|
2852
|
+
});
|
|
2853
|
+
return parsed;
|
|
2854
|
+
};
|
|
2855
|
+
splitEchoedValues = (text, executablePaths) => {
|
|
2856
|
+
const executable = executablePaths.map((path) => `Executable=${path}\n`).find((line) => text.startsWith(line));
|
|
2857
|
+
let rest = text;
|
|
2858
|
+
if (executable !== undefined) rest = text.slice(executable.length);
|
|
2859
|
+
else if (text.startsWith("Executable=")) {
|
|
2860
|
+
const identifierLine = text.indexOf("\nIdentifier=");
|
|
2861
|
+
rest = identifierLine < 0 ? text : text.slice(identifierLine + 1);
|
|
2862
|
+
}
|
|
2863
|
+
if (!rest.startsWith("Identifier=")) return {
|
|
2864
|
+
identifier: undefined,
|
|
2865
|
+
fields: rest
|
|
2866
|
+
};
|
|
2867
|
+
const format = rest.lastIndexOf("\nFormat=");
|
|
2868
|
+
const lineEnd = rest.indexOf("\n");
|
|
2869
|
+
const end = format >= 0 ? format : lineEnd >= 0 ? lineEnd : rest.length;
|
|
2870
|
+
return {
|
|
2871
|
+
identifier: rest.slice("Identifier=".length, end),
|
|
2872
|
+
fields: rest.slice(end)
|
|
2873
|
+
};
|
|
2874
|
+
};
|
|
2875
|
+
nullableCodeSignValue = (value) => value === undefined || value === "not set" ? null : value;
|
|
2876
|
+
splitAlgorithms = (value) => value === undefined ? [] : value.split(/[,+\s]+/u).map((part) => part.trim()).filter((part) => part.length > 0);
|
|
2877
|
+
parseRuntime = (value) => {
|
|
2878
|
+
if (value === undefined) return null;
|
|
2879
|
+
const flags = /(?:^|\s)flags=[^(]*\(([^)]*)\)/u.exec(value)?.[1];
|
|
2880
|
+
if (flags === undefined) return null;
|
|
2881
|
+
return flags.split(",").some((flag) => flag.trim() === "runtime");
|
|
2882
|
+
};
|
|
2883
|
+
})))();
|
|
2884
|
+
}
|
|
2885
|
+
|
|
2886
|
+
//#endregion
|
|
2887
|
+
//#region dist/native/parsers/demangle.js
|
|
2888
|
+
var resultSchema, parseDemangledSymbols;
|
|
2889
|
+
function init_demangle() {
|
|
2890
|
+
return (init_demangle = __esmMin((() => {
|
|
2891
|
+
resultSchema = z.object({
|
|
2892
|
+
input: z.string(),
|
|
2893
|
+
output: z.string(),
|
|
2894
|
+
status: z.enum([
|
|
2895
|
+
"demangled",
|
|
2896
|
+
"unchanged",
|
|
2897
|
+
"invalid"
|
|
2898
|
+
])
|
|
2899
|
+
});
|
|
2900
|
+
parseDemangledSymbols = (inputs, output) => {
|
|
2901
|
+
const lines = output.replace(/\n$/u, "").split("\n");
|
|
2902
|
+
if (lines.length !== inputs.length) throw new TypeError("swift-demangle output count does not match input");
|
|
2903
|
+
return inputs.map((input, index) => {
|
|
2904
|
+
const value = lines[index];
|
|
2905
|
+
if (value === undefined) throw new TypeError("swift-demangle omitted an output line");
|
|
2906
|
+
return resultSchema.parse({
|
|
2907
|
+
input,
|
|
2908
|
+
output: value,
|
|
2909
|
+
status: value === input ? input.startsWith("$s") || input.startsWith("_$s") ? "invalid" : "unchanged" : "demangled"
|
|
2910
|
+
});
|
|
2911
|
+
});
|
|
2912
|
+
};
|
|
2913
|
+
})))();
|
|
2914
|
+
}
|
|
2915
|
+
|
|
2916
|
+
//#endregion
|
|
2917
|
+
//#region dist/native/parsers/plist.js
|
|
2918
|
+
var plistObject, INTEGRAL_LITERAL, decodePlistJson, plistJsonNeedsNumberTypes, parsePlistJson, parsePlistXml, xmlNumberLiterals, prototypeKeyLimitations, numberLimitations, mapJsonNumbers, projectPlistBundle;
|
|
2919
|
+
function init_plist() {
|
|
2920
|
+
return (init_plist = __esmMin((() => {
|
|
2921
|
+
init_analysisErrorCore();
|
|
2922
|
+
init_plistValue();
|
|
2923
|
+
init_propertyListKeys();
|
|
2924
|
+
init_result();
|
|
2925
|
+
plistObject = z.record(z.string(), z.unknown());
|
|
2926
|
+
INTEGRAL_LITERAL = /^-?\d+$/u;
|
|
2927
|
+
decodePlistJson = (output, unsafe) => {
|
|
2928
|
+
const text = output.replace(/^\uFEFF/u, "");
|
|
2929
|
+
return JSON.parse(text, (_key, item, context) => {
|
|
2930
|
+
const source = context?.source;
|
|
2931
|
+
return typeof item !== "number" || Number.isSafeInteger(item) || source === undefined || !INTEGRAL_LITERAL.test(source) ? item : unsafe(item, source);
|
|
2932
|
+
});
|
|
2933
|
+
};
|
|
2934
|
+
plistJsonNeedsNumberTypes = (output) => {
|
|
2935
|
+
let found = false;
|
|
2936
|
+
try {
|
|
2937
|
+
decodePlistJson(output, (item) => {
|
|
2938
|
+
found = true;
|
|
2939
|
+
return item;
|
|
2940
|
+
});
|
|
2941
|
+
} catch {}
|
|
2942
|
+
return found;
|
|
2943
|
+
};
|
|
2944
|
+
parsePlistJson = (output, xmlConversion) => {
|
|
2945
|
+
const literals = xmlConversion === undefined ? undefined : xmlNumberLiterals(xmlConversion);
|
|
2946
|
+
let exactIntegerCount = 0;
|
|
2947
|
+
let ambiguousNumberCount = 0;
|
|
2948
|
+
const classify = (item, digits) => {
|
|
2949
|
+
const exact = BigInt(digits).toString();
|
|
2950
|
+
const integer = literals?.integers.get(item)?.has(exact) === true;
|
|
2951
|
+
const real = literals?.reals.has(item) === true;
|
|
2952
|
+
if (integer && !real) {
|
|
2953
|
+
exactIntegerCount += 1;
|
|
2954
|
+
return {
|
|
2955
|
+
$plist_type: "integer",
|
|
2956
|
+
decimal: digits
|
|
2957
|
+
};
|
|
2958
|
+
}
|
|
2959
|
+
if (real && !integer) return item;
|
|
2960
|
+
ambiguousNumberCount += 1;
|
|
2961
|
+
return item;
|
|
2962
|
+
};
|
|
2963
|
+
let decoded;
|
|
2964
|
+
try {
|
|
2965
|
+
decoded = omitPrototypeKeys(decodePlistJson(output, classify));
|
|
2966
|
+
} catch (cause) {
|
|
2967
|
+
return err(new AnalysisOutputError("inspect_plist", cause instanceof Error ? cause.message : String(cause), { cause }));
|
|
2968
|
+
}
|
|
2969
|
+
const { value } = decoded;
|
|
2970
|
+
return ok({
|
|
2971
|
+
value,
|
|
2972
|
+
bundle: projectPlistBundle(value),
|
|
2973
|
+
limitations: [...numberLimitations(exactIntegerCount, ambiguousNumberCount), ...prototypeKeyLimitations(decoded.omittedPrototypeKeys)]
|
|
2974
|
+
});
|
|
2975
|
+
};
|
|
2976
|
+
parsePlistXml = (output) => {
|
|
2977
|
+
let projected;
|
|
2978
|
+
let omittedPrototypeKeys;
|
|
2979
|
+
try {
|
|
2980
|
+
const decoded = parseXmlPropertyList(output);
|
|
2981
|
+
omittedPrototypeKeys = decoded.omittedPrototypeKeys;
|
|
2982
|
+
projected = projectPlistValue(decoded.value);
|
|
2983
|
+
} catch (cause) {
|
|
2984
|
+
return err(new AnalysisOutputError("inspect_plist", "plutil XML conversion was not a readable plist", { cause }));
|
|
2985
|
+
}
|
|
2986
|
+
const literals = xmlNumberLiterals(output);
|
|
2987
|
+
let exactIntegerCount = 0;
|
|
2988
|
+
let ambiguousNumberCount = 0;
|
|
2989
|
+
const value = mapJsonNumbers(projected.value, (item) => {
|
|
2990
|
+
const decimals = literals.integers.get(item);
|
|
2991
|
+
if (decimals === undefined) return item;
|
|
2992
|
+
const [decimal] = decimals;
|
|
2993
|
+
if (decimals.size !== 1 || decimal === undefined || literals.reals.has(item)) {
|
|
2994
|
+
ambiguousNumberCount += 1;
|
|
2995
|
+
return item;
|
|
2996
|
+
}
|
|
2997
|
+
exactIntegerCount += 1;
|
|
2998
|
+
return {
|
|
2999
|
+
$plist_type: "integer",
|
|
3000
|
+
decimal
|
|
3001
|
+
};
|
|
3002
|
+
});
|
|
3003
|
+
return ok({
|
|
3004
|
+
value,
|
|
3005
|
+
bundle: projectPlistBundle(value),
|
|
3006
|
+
limitations: [
|
|
3007
|
+
"plutil cannot express this plist as JSON, so it was decoded from plutil's XML conversion; data and date values are typed objects such as { \"$plist_type\": \"data\", \"base64\": ... }.",
|
|
3008
|
+
...projected.unknownRealCount === 0 ? [] : [`${String(projected.unknownRealCount)} non-finite real value(s) are reported as { "$plist_type": "real", "value": null } because the XML decoder does not distinguish NaN from infinity.`],
|
|
3009
|
+
...numberLimitations(exactIntegerCount, ambiguousNumberCount),
|
|
3010
|
+
...prototypeKeyLimitations(omittedPrototypeKeys)
|
|
3011
|
+
]
|
|
3012
|
+
});
|
|
3013
|
+
};
|
|
3014
|
+
xmlNumberLiterals = (xml) => {
|
|
3015
|
+
const integers = new Map();
|
|
3016
|
+
for (const [, decimal = ""] of xml.matchAll(/<integer>\s*([+-]?\d+)\s*<\/integer>/gu)) {
|
|
3017
|
+
const rounded = Number(decimal);
|
|
3018
|
+
if (Number.isSafeInteger(rounded)) continue;
|
|
3019
|
+
integers.set(rounded, (integers.get(rounded) ?? new Set()).add(BigInt(decimal).toString()));
|
|
3020
|
+
}
|
|
3021
|
+
const reals = new Set([...xml.matchAll(/<real>([^<]*)<\/real>/gu)].map(([, text = ""]) => Number.parseFloat(text)));
|
|
3022
|
+
return {
|
|
3023
|
+
integers,
|
|
3024
|
+
reals
|
|
3025
|
+
};
|
|
3026
|
+
};
|
|
3027
|
+
prototypeKeyLimitations = (count) => count === 0 ? [] : [omittedPrototypeKeysLimitation(count)];
|
|
3028
|
+
numberLimitations = (exactIntegerCount, ambiguousNumberCount) => [...exactIntegerCount === 0 ? [] : [`${String(exactIntegerCount)} integer value(s) exceed the exact range of a JSON number and are reported as { "$plist_type": "integer", "decimal": "<exact digits>" }.`], ...ambiguousNumberCount === 0 ? [] : [`${String(ambiguousNumberCount)} number(s) beyond the exact range of a JSON number are reported as decoded because the XML literal they came from, a rounded <integer> or a <real>, cannot be identified.`]];
|
|
3029
|
+
mapJsonNumbers = (value, map) => {
|
|
3030
|
+
if (typeof value === "number") return map(value);
|
|
3031
|
+
if (Array.isArray(value)) return value.map((item) => mapJsonNumbers(item, map));
|
|
3032
|
+
if (value !== null && typeof value === "object") return Object.fromEntries(Object.entries(value).map(([key, item]) => [key, mapJsonNumbers(item, map)]));
|
|
3033
|
+
return value;
|
|
3034
|
+
};
|
|
3035
|
+
projectPlistBundle = (value) => {
|
|
3036
|
+
const object = plistObject.safeParse(value);
|
|
3037
|
+
const field = (name) => {
|
|
3038
|
+
if (!object.success) return null;
|
|
3039
|
+
const candidate = object.data[name];
|
|
3040
|
+
return typeof candidate === "string" ? candidate : null;
|
|
3041
|
+
};
|
|
3042
|
+
return {
|
|
3043
|
+
identifier: field("CFBundleIdentifier"),
|
|
3044
|
+
executable: field("CFBundleExecutable"),
|
|
3045
|
+
name: field("CFBundleName"),
|
|
3046
|
+
version: field("CFBundleVersion"),
|
|
3047
|
+
short_version: field("CFBundleShortVersionString")
|
|
3048
|
+
};
|
|
3049
|
+
};
|
|
3050
|
+
})))();
|
|
3051
|
+
}
|
|
3052
|
+
|
|
3053
|
+
//#endregion
|
|
3054
|
+
//#region dist/native/parsers/dyldInfo.js
|
|
3055
|
+
var parseDyldSymbols, canonicalHex;
|
|
3056
|
+
function init_dyldInfo() {
|
|
3057
|
+
return (init_dyldInfo = __esmMin((() => {
|
|
3058
|
+
parseDyldSymbols = (output, mode, imageBase = null, knownExportNames = new Set()) => {
|
|
3059
|
+
const offsets = /^\s*offset\s+symbol\s*$/mu.test(output);
|
|
3060
|
+
return output.split(/\r?\n/u).flatMap((rawLine) => {
|
|
3061
|
+
const line = rawLine.trim();
|
|
3062
|
+
if (mode === "imports") {
|
|
3063
|
+
const imported = /^(?:0x[\da-f]+\s+)?(.+?)(?:\s+\[([^\]]+)\])?\s+\(from (.+)\)$/iu.exec(line);
|
|
3064
|
+
if (imported?.[1] !== undefined) return [{
|
|
3065
|
+
name: imported[1],
|
|
3066
|
+
address: null,
|
|
3067
|
+
weak: /\bweak-import\b/u.test(imported[2] ?? "") ? true : null,
|
|
3068
|
+
reexport: null,
|
|
3069
|
+
source: imported[3] ?? null
|
|
3070
|
+
}];
|
|
3071
|
+
return [];
|
|
3072
|
+
}
|
|
3073
|
+
const reexport = /^\[re-export\]\s+(.+?)(?:\s+\(from (.+)\))?$/u.exec(line);
|
|
3074
|
+
if (reexport?.[1] !== undefined) return [{
|
|
3075
|
+
name: reexport[1],
|
|
3076
|
+
address: null,
|
|
3077
|
+
weak: null,
|
|
3078
|
+
reexport: true,
|
|
3079
|
+
source: reexport[2] ?? null
|
|
3080
|
+
}];
|
|
3081
|
+
const exported = /^(0x[\da-f]+)\s+(.+?)(?:\s+\[([^\]]+)\])?$/iu.exec(line);
|
|
3082
|
+
if (exported?.[1] === undefined || exported[2] === undefined) return [];
|
|
3083
|
+
const rawName = /^0x[\da-f]+\s+(.+)$/iu.exec(line)?.[1];
|
|
3084
|
+
const literalName = rawName !== undefined && knownExportNames.has(rawName);
|
|
3085
|
+
if (literalName && exported[3] !== undefined && knownExportNames.has(exported[2])) return [];
|
|
3086
|
+
const annotation = literalName ? undefined : exported[3];
|
|
3087
|
+
const absolute = /\babsolute\b/u.test(annotation ?? "");
|
|
3088
|
+
const address = offsets && !absolute ? imageBase === null ? null : `0x${(BigInt(imageBase) + BigInt(exported[1])).toString(16)}` : canonicalHex(exported[1]);
|
|
3089
|
+
return [{
|
|
3090
|
+
name: literalName ? rawName : exported[2],
|
|
3091
|
+
address,
|
|
3092
|
+
weak: /\bweak-def\b/u.test(annotation ?? "") ? true : null,
|
|
3093
|
+
reexport: false,
|
|
3094
|
+
source: null
|
|
3095
|
+
}];
|
|
3096
|
+
});
|
|
3097
|
+
};
|
|
3098
|
+
canonicalHex = (value) => value === undefined ? null : `0x${BigInt(value).toString(16)}`;
|
|
3099
|
+
})))();
|
|
3100
|
+
}
|
|
3101
|
+
|
|
3102
|
+
//#endregion
|
|
3103
|
+
//#region dist/native/parsers/echoedPath.js
|
|
3104
|
+
var withoutEchoedPathHeader;
|
|
3105
|
+
function init_echoedPath() {
|
|
3106
|
+
return (init_echoedPath = __esmMin((() => {
|
|
3107
|
+
withoutEchoedPathHeader = (output, path) => {
|
|
3108
|
+
if (path === undefined || !output.startsWith(path)) return output;
|
|
3109
|
+
const header = /^(?: \(architecture [^)\n]*\)| \[[^\]\n]*\])?:\r?\n/u.exec(output.slice(path.length));
|
|
3110
|
+
return header === null ? output : output.slice(path.length + header[0].length);
|
|
3111
|
+
};
|
|
3112
|
+
})))();
|
|
3113
|
+
}
|
|
3114
|
+
|
|
3115
|
+
//#endregion
|
|
3116
|
+
//#region dist/native/parsers/otool.js
|
|
3117
|
+
var DYLIB_COMMANDS, DYLIB_FIELDS, DYLIB_ENCODING_FIELDS, EMPTY_VALUE_FIELDS, normalizeLineEndings, parseOtoolLoadCommands, parseHeader, headerValue, validateLoadCommandFraming, createLoadCommandState, parseLoadCommand, validateDylibCommandLines, scalarFields, collectUuid, collectEntrypoint, collectBuild, collectDependency, collectSegment, parseFields, parseField, requireUniqueField, parseSegment, parseSections, parseBuildTools, permissions, NUMERIC_PATTERN, numeric, nonEmptyName, stringField, numberField, hexField, stripOffsetSuffix, sectionAlignment;
|
|
3118
|
+
function init_otool() {
|
|
3119
|
+
return (init_otool = __esmMin((() => {
|
|
3120
|
+
DYLIB_COMMANDS = new Set([
|
|
3121
|
+
"LC_ID_DYLIB",
|
|
3122
|
+
"LC_LOAD_DYLIB",
|
|
3123
|
+
"LC_LOAD_WEAK_DYLIB",
|
|
3124
|
+
"LC_REEXPORT_DYLIB",
|
|
3125
|
+
"LC_LAZY_LOAD_DYLIB",
|
|
3126
|
+
"LC_LOAD_UPWARD_DYLIB"
|
|
3127
|
+
]);
|
|
3128
|
+
DYLIB_FIELDS = [
|
|
3129
|
+
"cmd",
|
|
3130
|
+
"cmdsize",
|
|
3131
|
+
"name",
|
|
3132
|
+
"current version",
|
|
3133
|
+
"compatibility version"
|
|
3134
|
+
];
|
|
3135
|
+
DYLIB_ENCODING_FIELDS = ["time stamp", "options"];
|
|
3136
|
+
EMPTY_VALUE_FIELDS = new Set([
|
|
3137
|
+
"options",
|
|
3138
|
+
"segname",
|
|
3139
|
+
"sectname"
|
|
3140
|
+
]);
|
|
3141
|
+
normalizeLineEndings = (output) => output.replaceAll("\r\n", "\n");
|
|
3142
|
+
parseOtoolLoadCommands = (raw) => {
|
|
3143
|
+
const output = normalizeLineEndings(raw);
|
|
3144
|
+
const header = parseHeader(output);
|
|
3145
|
+
if (header === undefined) throw new TypeError("otool output is missing the Mach header");
|
|
3146
|
+
const state = createLoadCommandState(header.flags);
|
|
3147
|
+
for (const block of output.split(/(?=^Load command \d+$)/mu)) parseLoadCommand(block, state);
|
|
3148
|
+
validateLoadCommandFraming(header, state.commands);
|
|
3149
|
+
return {
|
|
3150
|
+
fileType: header.fileType,
|
|
3151
|
+
flags: [...state.flags].sort(),
|
|
3152
|
+
uuid: state.uuid,
|
|
3153
|
+
commands: state.commands,
|
|
3154
|
+
segments: state.segments,
|
|
3155
|
+
dependencies: state.dependencies,
|
|
3156
|
+
entrypoints: state.entrypoints,
|
|
3157
|
+
builds: state.builds
|
|
3158
|
+
};
|
|
3159
|
+
};
|
|
3160
|
+
parseHeader = (output) => {
|
|
3161
|
+
const lines = output.split(/\r?\n/u).map((line) => line.trim());
|
|
3162
|
+
const columnsLine = lines.findIndex((line) => /(?:^|\s)magic\s/u.test(line));
|
|
3163
|
+
if (columnsLine < 0) return undefined;
|
|
3164
|
+
const columns = lines[columnsLine]?.split(/\s+/u);
|
|
3165
|
+
const dataLine = lines.slice(columnsLine + 1).find((line) => line.length > 0);
|
|
3166
|
+
const values = dataLine?.split(/\s+/u);
|
|
3167
|
+
if (columns === undefined || values === undefined) return undefined;
|
|
3168
|
+
const commandCount = headerValue(columns, values, "ncmds");
|
|
3169
|
+
const commandBytes = headerValue(columns, values, "sizeofcmds");
|
|
3170
|
+
if (commandCount === null || commandBytes === null) throw new TypeError("otool Mach header is missing valid command framing");
|
|
3171
|
+
const fileTypeIndex = columns.indexOf("filetype");
|
|
3172
|
+
const flagsIndex = columns.indexOf("flags");
|
|
3173
|
+
const complete = values.length >= columns.length;
|
|
3174
|
+
const fileTypeValueIndex = flagsIndex >= 0 && fileTypeIndex > flagsIndex ? values.length - (columns.length - fileTypeIndex) : fileTypeIndex;
|
|
3175
|
+
const flagsEnd = flagsIndex >= 0 ? values.length - (columns.length - flagsIndex - 1) : 0;
|
|
3176
|
+
return {
|
|
3177
|
+
commandCount,
|
|
3178
|
+
commandBytes,
|
|
3179
|
+
fileType: complete && fileTypeValueIndex >= 0 && fileTypeValueIndex < values.length ? values[fileTypeValueIndex] ?? null : null,
|
|
3180
|
+
flags: !complete || flagsIndex < 0 || flagsIndex >= flagsEnd ? [] : values.slice(flagsIndex, flagsEnd).filter((value) => value.length > 0)
|
|
3181
|
+
};
|
|
3182
|
+
};
|
|
3183
|
+
headerValue = (columns, values, name) => {
|
|
3184
|
+
const index = columns.indexOf(name);
|
|
3185
|
+
if (index < 0) return null;
|
|
3186
|
+
const flagsIndex = columns.indexOf("flags");
|
|
3187
|
+
const valueIndex = flagsIndex >= 0 && index > flagsIndex ? values.length - (columns.length - index) : index;
|
|
3188
|
+
const value = values[valueIndex];
|
|
3189
|
+
return value === undefined ? null : numeric(value);
|
|
3190
|
+
};
|
|
3191
|
+
validateLoadCommandFraming = (header, commands) => {
|
|
3192
|
+
if (commands.length !== header.commandCount) throw new TypeError("otool load-command count does not match the Mach header");
|
|
3193
|
+
let totalBytes = 0;
|
|
3194
|
+
for (const [expectedIndex, command] of commands.entries()) {
|
|
3195
|
+
const size = numberField(command.fields, "cmdsize");
|
|
3196
|
+
if (command.index !== expectedIndex || size === null || size < 8) throw new TypeError("otool load-command sequence or size is invalid");
|
|
3197
|
+
totalBytes += size;
|
|
3198
|
+
if (!Number.isSafeInteger(totalBytes)) throw new TypeError("otool load-command byte count is unsafe");
|
|
3199
|
+
}
|
|
3200
|
+
if (totalBytes !== header.commandBytes) throw new TypeError("otool load-command sizes do not match the Mach header");
|
|
3201
|
+
};
|
|
3202
|
+
createLoadCommandState = (headerFlags) => ({
|
|
3203
|
+
commands: [],
|
|
3204
|
+
segments: [],
|
|
3205
|
+
dependencies: [],
|
|
3206
|
+
entrypoints: [],
|
|
3207
|
+
builds: [],
|
|
3208
|
+
uuid: null,
|
|
3209
|
+
flags: new Set(headerFlags ?? [])
|
|
3210
|
+
});
|
|
3211
|
+
parseLoadCommand = (block, state) => {
|
|
3212
|
+
const indexText = /^Load command (\d+)/u.exec(block)?.[1];
|
|
3213
|
+
if (indexText === undefined) return;
|
|
3214
|
+
const index = Number(indexText);
|
|
3215
|
+
if (!Number.isSafeInteger(index)) throw new TypeError("otool load-command index is unsafe");
|
|
3216
|
+
const header = block.split(/\n\s*Section\n/u)[0] ?? block;
|
|
3217
|
+
const parsed = parseFields(header);
|
|
3218
|
+
const fields = parsed.values;
|
|
3219
|
+
const kind = stringField(fields, "cmd");
|
|
3220
|
+
if (kind === null) throw new TypeError("otool load command is missing cmd");
|
|
3221
|
+
for (const key of scalarFields(kind)) requireUniqueField(parsed, key);
|
|
3222
|
+
if (DYLIB_COMMANDS.has(kind)) validateDylibCommandLines(parsed);
|
|
3223
|
+
state.commands.push({
|
|
3224
|
+
index,
|
|
3225
|
+
kind,
|
|
3226
|
+
fields
|
|
3227
|
+
});
|
|
3228
|
+
collectUuid(kind, fields, state);
|
|
3229
|
+
collectEntrypoint(kind, fields, state);
|
|
3230
|
+
collectBuild(kind, block, fields, state);
|
|
3231
|
+
collectDependency(kind, fields, state);
|
|
3232
|
+
collectSegment(kind, block, fields, state);
|
|
3233
|
+
};
|
|
3234
|
+
validateDylibCommandLines = (parsed) => {
|
|
3235
|
+
const encodingFields = DYLIB_ENCODING_FIELDS.filter((key) => Object.hasOwn(parsed.values, key));
|
|
3236
|
+
if (encodingFields.length !== 1) throw new TypeError("otool dylib command must contain timestamp or options");
|
|
3237
|
+
for (const key of encodingFields) requireUniqueField(parsed, key);
|
|
3238
|
+
const allowed = new Set([...DYLIB_FIELDS, ...DYLIB_ENCODING_FIELDS]);
|
|
3239
|
+
for (const field of parsed.rows) {
|
|
3240
|
+
const key = field?.[0];
|
|
3241
|
+
if (key === undefined || !allowed.has(key)) throw new TypeError("otool dylib command contains ambiguous multiline text");
|
|
3242
|
+
}
|
|
3243
|
+
};
|
|
3244
|
+
scalarFields = (kind) => {
|
|
3245
|
+
const common = ["cmd", "cmdsize"];
|
|
3246
|
+
if (DYLIB_COMMANDS.has(kind)) return DYLIB_FIELDS;
|
|
3247
|
+
if (kind === "LC_LOAD_DYLINKER" || kind === "LC_ID_DYLINKER") return [...common, "name"];
|
|
3248
|
+
if (kind === "LC_UUID") return [...common, "uuid"];
|
|
3249
|
+
if (kind === "LC_MAIN") return [...common, "entryoff"];
|
|
3250
|
+
if (kind === "LC_BUILD_VERSION") return [
|
|
3251
|
+
...common,
|
|
3252
|
+
"platform",
|
|
3253
|
+
"minos",
|
|
3254
|
+
"sdk",
|
|
3255
|
+
"ntools"
|
|
3256
|
+
];
|
|
3257
|
+
if (kind.startsWith("LC_VERSION_MIN_")) return [
|
|
3258
|
+
...common,
|
|
3259
|
+
"version",
|
|
3260
|
+
"sdk"
|
|
3261
|
+
];
|
|
3262
|
+
if (kind === "LC_SEGMENT" || kind === "LC_SEGMENT_64") return [
|
|
3263
|
+
...common,
|
|
3264
|
+
"segname",
|
|
3265
|
+
"vmaddr",
|
|
3266
|
+
"vmsize",
|
|
3267
|
+
"fileoff",
|
|
3268
|
+
"filesize",
|
|
3269
|
+
"maxprot",
|
|
3270
|
+
"initprot",
|
|
3271
|
+
"nsects",
|
|
3272
|
+
"flags"
|
|
3273
|
+
];
|
|
3274
|
+
return common;
|
|
3275
|
+
};
|
|
3276
|
+
collectUuid = (kind, fields, state) => {
|
|
3277
|
+
if (kind === "LC_UUID") state.uuid = stringField(fields, "uuid") ?? state.uuid;
|
|
3278
|
+
};
|
|
3279
|
+
collectEntrypoint = (kind, fields, state) => {
|
|
3280
|
+
if (kind !== "LC_MAIN") return;
|
|
3281
|
+
const entry = numberField(fields, "entryoff");
|
|
3282
|
+
if (entry !== null) state.entrypoints.push({ file_offset: entry });
|
|
3283
|
+
};
|
|
3284
|
+
collectBuild = (kind, block, fields, state) => {
|
|
3285
|
+
if (kind === "LC_BUILD_VERSION") {
|
|
3286
|
+
const tools = parseBuildTools(block);
|
|
3287
|
+
if (numberField(fields, "ntools") !== tools.length) throw new TypeError("otool build-tool count does not match ntools");
|
|
3288
|
+
state.builds.push({
|
|
3289
|
+
platform: stringField(fields, "platform"),
|
|
3290
|
+
minimum_os: stringField(fields, "minos"),
|
|
3291
|
+
sdk: stringField(fields, "sdk"),
|
|
3292
|
+
tools
|
|
3293
|
+
});
|
|
3294
|
+
return;
|
|
3295
|
+
}
|
|
3296
|
+
if (kind.startsWith("LC_VERSION_MIN_")) state.builds.push({
|
|
3297
|
+
platform: kind.slice("LC_VERSION_MIN_".length) || null,
|
|
3298
|
+
minimum_os: stringField(fields, "version"),
|
|
3299
|
+
sdk: stringField(fields, "sdk"),
|
|
3300
|
+
tools: []
|
|
3301
|
+
});
|
|
3302
|
+
};
|
|
3303
|
+
collectDependency = (kind, fields, state) => {
|
|
3304
|
+
if (!DYLIB_COMMANDS.has(kind)) return;
|
|
3305
|
+
state.dependencies.push({
|
|
3306
|
+
path: stripOffsetSuffix(stringField(fields, "name")),
|
|
3307
|
+
kind,
|
|
3308
|
+
current_version: stringField(fields, "current version"),
|
|
3309
|
+
compatibility_version: stringField(fields, "compatibility version")
|
|
3310
|
+
});
|
|
3311
|
+
};
|
|
3312
|
+
collectSegment = (kind, block, fields, state) => {
|
|
3313
|
+
if (kind !== "LC_SEGMENT" && kind !== "LC_SEGMENT_64") return;
|
|
3314
|
+
const segment = parseSegment(block, fields);
|
|
3315
|
+
if (numberField(fields, "nsects") !== segment.sections.length) throw new TypeError("otool segment section count does not match its sections");
|
|
3316
|
+
state.segments.push(segment);
|
|
3317
|
+
};
|
|
3318
|
+
parseFields = (block) => {
|
|
3319
|
+
const fields = {};
|
|
3320
|
+
const rows = [];
|
|
3321
|
+
for (const rawLine of block.split(/\r?\n/u).slice(1)) {
|
|
3322
|
+
if (rawLine.trim().length === 0) continue;
|
|
3323
|
+
const field = parseField(rawLine);
|
|
3324
|
+
rows.push(field);
|
|
3325
|
+
if (field === undefined) continue;
|
|
3326
|
+
const [key, value] = field;
|
|
3327
|
+
fields[key] = key === "segname" || key === "sectname" ? value : numeric(value) ?? value;
|
|
3328
|
+
}
|
|
3329
|
+
return {
|
|
3330
|
+
values: fields,
|
|
3331
|
+
rows
|
|
3332
|
+
};
|
|
3333
|
+
};
|
|
3334
|
+
parseField = (rawLine) => {
|
|
3335
|
+
const line = rawLine.trim();
|
|
3336
|
+
const match = /^((?:time stamp)|\S+(?:\s+version)?)(?:\s+(.+))?$/u.exec(line);
|
|
3337
|
+
return match?.[1] === undefined ? undefined : [match[1], match[2]?.trim() ?? ""];
|
|
3338
|
+
};
|
|
3339
|
+
requireUniqueField = (parsed, key) => {
|
|
3340
|
+
const matches = parsed.rows.filter((field) => field?.[0] === key);
|
|
3341
|
+
const field = matches[0];
|
|
3342
|
+
if (matches.length !== 1 || field === undefined) throw new TypeError(`otool field ${key} is missing or repeated`);
|
|
3343
|
+
if (field[1] === "" && !EMPTY_VALUE_FIELDS.has(key)) throw new TypeError(`otool field ${key} has no value`);
|
|
3344
|
+
};
|
|
3345
|
+
parseSegment = (block, fields) => ({
|
|
3346
|
+
name: nonEmptyName(stringField(fields, "segname")),
|
|
3347
|
+
vm_address: hexField(fields, "vmaddr"),
|
|
3348
|
+
vm_size: numberField(fields, "vmsize"),
|
|
3349
|
+
file_offset: numberField(fields, "fileoff"),
|
|
3350
|
+
file_size: numberField(fields, "filesize"),
|
|
3351
|
+
maximum_permissions: permissions(stringField(fields, "maxprot")),
|
|
3352
|
+
initial_permissions: permissions(stringField(fields, "initprot")),
|
|
3353
|
+
sections: parseSections(block)
|
|
3354
|
+
});
|
|
3355
|
+
parseSections = (block) => block.split(/(?=\n\s*Section\n)/u).slice(1).map((sectionBlock) => {
|
|
3356
|
+
const parsed = parseFields(`Section${sectionBlock}`);
|
|
3357
|
+
const fields = parsed.values;
|
|
3358
|
+
for (const key of [
|
|
3359
|
+
"sectname",
|
|
3360
|
+
"segname",
|
|
3361
|
+
"addr",
|
|
3362
|
+
"size",
|
|
3363
|
+
"offset",
|
|
3364
|
+
"align",
|
|
3365
|
+
"flags"
|
|
3366
|
+
]) requireUniqueField(parsed, key);
|
|
3367
|
+
return {
|
|
3368
|
+
segment: nonEmptyName(stringField(fields, "segname")),
|
|
3369
|
+
name: nonEmptyName(stringField(fields, "sectname")),
|
|
3370
|
+
address: hexField(fields, "addr"),
|
|
3371
|
+
size: numberField(fields, "size"),
|
|
3372
|
+
file_offset: numberField(fields, "offset"),
|
|
3373
|
+
alignment: sectionAlignment(stringField(fields, "align")),
|
|
3374
|
+
flags: (stringField(fields, "flags") ?? "").split(/\s+/u).filter((flag) => flag.length > 0)
|
|
3375
|
+
};
|
|
3376
|
+
});
|
|
3377
|
+
parseBuildTools = (block) => {
|
|
3378
|
+
const tools = [];
|
|
3379
|
+
const lines = block.split(/\r?\n/u).map((line) => line.trim());
|
|
3380
|
+
for (let index = 0; index < lines.length - 1; index += 1) {
|
|
3381
|
+
const tool = /^tool\s+(.+)$/u.exec(lines[index] ?? "")?.[1];
|
|
3382
|
+
const version = /^version\s+(.+)$/u.exec(lines[index + 1] ?? "")?.[1];
|
|
3383
|
+
if (tool !== undefined && version !== undefined) tools.push({
|
|
3384
|
+
name: tool,
|
|
3385
|
+
version
|
|
3386
|
+
});
|
|
3387
|
+
}
|
|
3388
|
+
return tools;
|
|
3389
|
+
};
|
|
3390
|
+
permissions = (raw) => {
|
|
3391
|
+
if (raw === null) return {
|
|
3392
|
+
read: null,
|
|
3393
|
+
write: null,
|
|
3394
|
+
execute: null,
|
|
3395
|
+
raw: null
|
|
3396
|
+
};
|
|
3397
|
+
const numericValue = numeric(raw);
|
|
3398
|
+
if (numericValue !== null) return {
|
|
3399
|
+
read: (numericValue & 1) !== 0,
|
|
3400
|
+
write: (numericValue & 2) !== 0,
|
|
3401
|
+
execute: (numericValue & 4) !== 0,
|
|
3402
|
+
raw
|
|
3403
|
+
};
|
|
3404
|
+
if (/^[r-][w-][x-]$/u.test(raw)) return {
|
|
3405
|
+
read: raw[0] === "r",
|
|
3406
|
+
write: raw[1] === "w",
|
|
3407
|
+
execute: raw[2] === "x",
|
|
3408
|
+
raw
|
|
3409
|
+
};
|
|
3410
|
+
return {
|
|
3411
|
+
read: null,
|
|
3412
|
+
write: null,
|
|
3413
|
+
execute: null,
|
|
3414
|
+
raw
|
|
3415
|
+
};
|
|
3416
|
+
};
|
|
3417
|
+
NUMERIC_PATTERN = /^(?:0x[a-fA-F0-9]+|\d+)$/u;
|
|
3418
|
+
numeric = (value) => {
|
|
3419
|
+
if (!NUMERIC_PATTERN.test(value)) return null;
|
|
3420
|
+
const parsed = Number.parseInt(value, value.startsWith("0x") ? 16 : 10);
|
|
3421
|
+
return Number.isSafeInteger(parsed) && parsed >= 0 ? parsed : null;
|
|
3422
|
+
};
|
|
3423
|
+
nonEmptyName = (name) => name === null || name.length === 0 ? "unknown" : name;
|
|
3424
|
+
stringField = (fields, name) => {
|
|
3425
|
+
const value = fields[name];
|
|
3426
|
+
return typeof value === "string" ? value : value === undefined || value === null ? null : String(value);
|
|
3427
|
+
};
|
|
3428
|
+
numberField = (fields, name) => {
|
|
3429
|
+
const value = fields[name];
|
|
3430
|
+
return typeof value === "number" ? value : typeof value === "string" ? numeric(value) : null;
|
|
3431
|
+
};
|
|
3432
|
+
hexField = (fields, name) => {
|
|
3433
|
+
const value = stringField(fields, name);
|
|
3434
|
+
if (value === null || !NUMERIC_PATTERN.test(value)) return null;
|
|
3435
|
+
return `0x${BigInt(value).toString(16)}`;
|
|
3436
|
+
};
|
|
3437
|
+
stripOffsetSuffix = (value) => value?.replace(/\s+\(offset\s+\d+\)$/u, "") ?? "unknown";
|
|
3438
|
+
sectionAlignment = (raw) => {
|
|
3439
|
+
if (raw === null) return null;
|
|
3440
|
+
const exponent = numeric(/^2\^(\d+)(?:\s+\(\d+\))?$/u.exec(raw)?.[1] ?? raw);
|
|
3441
|
+
return exponent === null || exponent > 52 ? null : 2 ** exponent;
|
|
3442
|
+
};
|
|
3443
|
+
})))();
|
|
3444
|
+
}
|
|
3445
|
+
|
|
3446
|
+
//#endregion
|
|
3447
|
+
//#region dist/native/parsers/machoUuid.js
|
|
3448
|
+
var MACHO_UUID, reconcileMachoUuid, parseDwarfdumpUuid, parseDwarfdumpRows, selectDwarfdumpRow, loadCommandUuid, reconcileObservations;
|
|
3449
|
+
function init_machoUuid() {
|
|
3450
|
+
return (init_machoUuid = __esmMin((() => {
|
|
3451
|
+
MACHO_UUID = /^[\da-f]{8}(?:-[\da-f]{4}){3}-[\da-f]{12}$/iu;
|
|
3452
|
+
reconcileMachoUuid = (commands, dwarfdumpOutput, artifactPath, selectedArchitecture) => reconcileObservations(loadCommandUuid(commands), parseDwarfdumpUuid(dwarfdumpOutput, artifactPath, selectedArchitecture));
|
|
3453
|
+
parseDwarfdumpUuid = (output, artifactPath, selectedArchitecture) => {
|
|
3454
|
+
const parsed = parseDwarfdumpRows(output, artifactPath);
|
|
3455
|
+
return parsed.kind === "invalid" ? parsed : selectDwarfdumpRow(parsed.rows, selectedArchitecture);
|
|
3456
|
+
};
|
|
3457
|
+
parseDwarfdumpRows = (output, artifactPath) => {
|
|
3458
|
+
if (output.trim().length === 0) return {
|
|
3459
|
+
kind: "rows",
|
|
3460
|
+
rows: []
|
|
3461
|
+
};
|
|
3462
|
+
const header = /UUID:[ \t]*([^\s]+)[ \t]+\(([^)\r\n]+)\) /uy;
|
|
3463
|
+
const rows = [];
|
|
3464
|
+
let offset = 0;
|
|
3465
|
+
while (offset < output.length) {
|
|
3466
|
+
if (output.startsWith("\r\n", offset)) {
|
|
3467
|
+
offset += 2;
|
|
3468
|
+
continue;
|
|
3469
|
+
}
|
|
3470
|
+
if (output[offset] === "\n") {
|
|
3471
|
+
offset += 1;
|
|
3472
|
+
continue;
|
|
3473
|
+
}
|
|
3474
|
+
header.lastIndex = offset;
|
|
3475
|
+
const match = header.exec(output);
|
|
3476
|
+
if (match === null) return {
|
|
3477
|
+
kind: "invalid",
|
|
3478
|
+
reason: "dwarfdump --uuid output contains an unrecognized row"
|
|
3479
|
+
};
|
|
3480
|
+
const value = match[1] ?? "";
|
|
3481
|
+
const architecture = match[2] ?? "";
|
|
3482
|
+
offset = header.lastIndex;
|
|
3483
|
+
if (!output.startsWith(artifactPath, offset)) return {
|
|
3484
|
+
kind: "invalid",
|
|
3485
|
+
reason: `dwarfdump --uuid row does not match the selected artifact path (UUID ${JSON.stringify(value)})`
|
|
3486
|
+
};
|
|
3487
|
+
offset += artifactPath.length;
|
|
3488
|
+
if (offset < output.length && output.startsWith("\r\n", offset)) offset += 2;
|
|
3489
|
+
else if (output[offset] === "\n") offset += 1;
|
|
3490
|
+
else if (offset !== output.length) return {
|
|
3491
|
+
kind: "invalid",
|
|
3492
|
+
reason: `dwarfdump --uuid returned malformed UUID row ${JSON.stringify(value)}`
|
|
3493
|
+
};
|
|
3494
|
+
rows.push({
|
|
3495
|
+
value,
|
|
3496
|
+
architecture
|
|
3497
|
+
});
|
|
3498
|
+
}
|
|
3499
|
+
return {
|
|
3500
|
+
kind: "rows",
|
|
3501
|
+
rows
|
|
3502
|
+
};
|
|
3503
|
+
};
|
|
3504
|
+
selectDwarfdumpRow = (rows, selectedArchitecture) => {
|
|
3505
|
+
if (rows.length === 0) return { kind: "absent" };
|
|
3506
|
+
const selectedRows = selectedArchitecture === null ? rows : rows.filter(({ architecture }) => architecture === selectedArchitecture);
|
|
3507
|
+
const validRows = selectedRows.filter(({ value }) => MACHO_UUID.test(value));
|
|
3508
|
+
const distinctValid = new Set(validRows.map(({ value }) => value.toLowerCase()));
|
|
3509
|
+
if (distinctValid.size > 1) return {
|
|
3510
|
+
kind: "conflict",
|
|
3511
|
+
reason: `dwarfdump --uuid returned conflicting UUIDs for selected architecture ${selectedArchitecture ?? "unknown"}`
|
|
3512
|
+
};
|
|
3513
|
+
if (selectedRows.length !== 1) return {
|
|
3514
|
+
kind: "invalid",
|
|
3515
|
+
reason: selectedRows.length > 1 ? `dwarfdump --uuid returned multiple rows for selected architecture ${selectedArchitecture}` : `dwarfdump --uuid returned no row for selected architecture ${selectedArchitecture}`
|
|
3516
|
+
};
|
|
3517
|
+
const [row] = selectedRows;
|
|
3518
|
+
if (row === undefined) return { kind: "absent" };
|
|
3519
|
+
if (!MACHO_UUID.test(row.value)) return {
|
|
3520
|
+
kind: "invalid",
|
|
3521
|
+
reason: `dwarfdump --uuid returned malformed UUID ${JSON.stringify(row.value)}`
|
|
3522
|
+
};
|
|
3523
|
+
return {
|
|
3524
|
+
kind: "valid",
|
|
3525
|
+
value: row.value
|
|
3526
|
+
};
|
|
3527
|
+
};
|
|
3528
|
+
loadCommandUuid = (commands) => {
|
|
3529
|
+
const loadCommands = commands.filter(({ kind }) => kind === "LC_UUID");
|
|
3530
|
+
if (loadCommands.length === 0) return { kind: "absent" };
|
|
3531
|
+
if (loadCommands.length > 1) {
|
|
3532
|
+
const observed = loadCommands.map(({ fields }) => fields.uuid).filter((value) => typeof value === "string" && MACHO_UUID.test(value));
|
|
3533
|
+
const distinct = new Set(observed.map((value) => value.toLowerCase()));
|
|
3534
|
+
return {
|
|
3535
|
+
kind: distinct.size > 1 ? "conflict" : "invalid",
|
|
3536
|
+
reason: distinct.size > 1 ? `otool returned conflicting LC_UUID values ${observed.map((value) => JSON.stringify(value)).join(" and ")}` : `otool returned ${String(loadCommands.length)} LC_UUID commands`
|
|
3537
|
+
};
|
|
3538
|
+
}
|
|
3539
|
+
const value = loadCommands[0]?.fields.uuid;
|
|
3540
|
+
return typeof value === "string" && MACHO_UUID.test(value) ? {
|
|
3541
|
+
kind: "valid",
|
|
3542
|
+
value
|
|
3543
|
+
} : {
|
|
3544
|
+
kind: "invalid",
|
|
3545
|
+
reason: `otool LC_UUID contains malformed UUID ${JSON.stringify(value ?? null)}`
|
|
3546
|
+
};
|
|
3547
|
+
};
|
|
3548
|
+
reconcileObservations = (loadUuid, dwarfdump) => {
|
|
3549
|
+
if (dwarfdump.kind === "valid" && loadUuid.kind === "valid") {
|
|
3550
|
+
if (dwarfdump.value.toLowerCase() === loadUuid.value.toLowerCase()) return {
|
|
3551
|
+
value: dwarfdump.value,
|
|
3552
|
+
limitations: []
|
|
3553
|
+
};
|
|
3554
|
+
return {
|
|
3555
|
+
value: null,
|
|
3556
|
+
limitations: [`dwarfdump --uuid (${dwarfdump.value}) conflicts with otool LC_UUID (${loadUuid.value}); the image UUID is unknown.`]
|
|
3557
|
+
};
|
|
3558
|
+
}
|
|
3559
|
+
if (dwarfdump.kind === "valid" && loadUuid.kind === "conflict") return {
|
|
3560
|
+
value: null,
|
|
3561
|
+
limitations: [loadUuid.reason]
|
|
3562
|
+
};
|
|
3563
|
+
if (loadUuid.kind === "valid" && dwarfdump.kind === "conflict") return {
|
|
3564
|
+
value: null,
|
|
3565
|
+
limitations: [dwarfdump.reason]
|
|
3566
|
+
};
|
|
3567
|
+
if (dwarfdump.kind === "valid") return {
|
|
3568
|
+
value: dwarfdump.value,
|
|
3569
|
+
limitations: loadUuid.kind === "invalid" ? [`${loadUuid.reason}; using the unambiguous dwarfdump UUID.`] : []
|
|
3570
|
+
};
|
|
3571
|
+
if (loadUuid.kind === "valid") return {
|
|
3572
|
+
value: loadUuid.value,
|
|
3573
|
+
limitations: dwarfdump.kind === "invalid" ? [`${dwarfdump.reason}; using the unambiguous otool LC_UUID.`] : []
|
|
3574
|
+
};
|
|
3575
|
+
return {
|
|
3576
|
+
value: null,
|
|
3577
|
+
limitations: [...dwarfdump.kind === "invalid" || dwarfdump.kind === "conflict" ? [dwarfdump.reason] : [], ...loadUuid.kind === "invalid" || loadUuid.kind === "conflict" ? [loadUuid.reason] : []]
|
|
3578
|
+
};
|
|
3579
|
+
};
|
|
3580
|
+
})))();
|
|
3581
|
+
}
|
|
3582
|
+
|
|
3583
|
+
//#endregion
|
|
3584
|
+
//#region dist/native/NativeMachoInspection.js
|
|
3585
|
+
var DISCOVERY_COMMANDS, REQUIRED_SLICE_COMMANDS, OPTIONAL_VTOOL_COMMAND, VTOOL_UNAVAILABLE_LIMITATION, inspectNativeMacho, normalizeMacho, sliceOutput, captureLookup, parseNmExports, parseEndian, parseWordSize, covered, uniqueSymbols, fileOffsetLocations, architectureLocations, selectedArchitectureArguments, selectArchitecture;
|
|
3586
|
+
function init_NativeMachoInspection() {
|
|
3587
|
+
return (init_NativeMachoInspection = __esmMin((() => {
|
|
3588
|
+
init_analysisErrorCore();
|
|
3589
|
+
init_nativeInspection();
|
|
3590
|
+
init_jsonValue();
|
|
3591
|
+
init_result();
|
|
3592
|
+
init_dyldInfo();
|
|
3593
|
+
init_lipo();
|
|
3594
|
+
init_echoedPath();
|
|
3595
|
+
init_otool();
|
|
3596
|
+
init_machoUuid();
|
|
3597
|
+
init_unicodeCodePointOrder();
|
|
3598
|
+
DISCOVERY_COMMANDS = [["file", ["-b"]], ["lipo", ["-detailed_info"]]];
|
|
3599
|
+
REQUIRED_SLICE_COMMANDS = [
|
|
3600
|
+
["otool", ["-h", "-l"]],
|
|
3601
|
+
["nm", ["-gjU"]],
|
|
3602
|
+
["dyld_info", ["-imports"]],
|
|
3603
|
+
["dyld_info", ["-exports"]],
|
|
3604
|
+
["dwarfdump", ["--uuid"]]
|
|
3605
|
+
];
|
|
3606
|
+
OPTIONAL_VTOOL_COMMAND = ["vtool", ["-show-build"]];
|
|
3607
|
+
VTOOL_UNAVAILABLE_LIMITATION = "vtool is unavailable; build metadata is normalized from otool only.";
|
|
3608
|
+
inspectNativeMacho = async (context) => {
|
|
3609
|
+
const captures = [];
|
|
3610
|
+
for (const [tool, prefix] of DISCOVERY_COMMANDS) {
|
|
3611
|
+
const captured = await context.run(tool, [...prefix, context.target.path], context.signal);
|
|
3612
|
+
if (!captured.ok) return err(captured.error);
|
|
3613
|
+
captures.push(captured.value);
|
|
3614
|
+
}
|
|
3615
|
+
const lipo = captures.find(({ tool }) => tool === "lipo");
|
|
3616
|
+
if (lipo === undefined) throw new TypeError("Missing lipo capture");
|
|
3617
|
+
const architectures = parseLipoArchitectures(lipo.stdout);
|
|
3618
|
+
const availableArchitectures = architectures.map(({ name }) => name);
|
|
3619
|
+
const selection = selectArchitecture(context.target, availableArchitectures);
|
|
3620
|
+
if (selection.status === "absent") return err(new AnalysisOutputError("inspect_macho", `lipo did not list ${selection.architecture}; refusing to read another slice`));
|
|
3621
|
+
const selectedArchitecture = selection.status === "selected" ? selection.architecture : null;
|
|
3622
|
+
for (const [tool, prefix] of REQUIRED_SLICE_COMMANDS) {
|
|
3623
|
+
const captured = await context.run(tool, [
|
|
3624
|
+
...prefix,
|
|
3625
|
+
...selectedArchitectureArguments(tool, selectedArchitecture),
|
|
3626
|
+
context.target.path
|
|
3627
|
+
], context.signal);
|
|
3628
|
+
if (!captured.ok) return err(captured.error);
|
|
3629
|
+
captures.push(captured.value);
|
|
3630
|
+
}
|
|
3631
|
+
const limitations = [];
|
|
3632
|
+
const [tool, prefix] = OPTIONAL_VTOOL_COMMAND;
|
|
3633
|
+
const optional = await context.run(tool, [
|
|
3634
|
+
...prefix,
|
|
3635
|
+
...selectedArchitectureArguments(tool, selectedArchitecture),
|
|
3636
|
+
context.target.path
|
|
3637
|
+
], context.signal);
|
|
3638
|
+
if (optional.ok) captures.push(optional.value);
|
|
3639
|
+
else if (optional.error._tag === "AnalysisCapabilityUnavailableError") limitations.push(VTOOL_UNAVAILABLE_LIMITATION);
|
|
3640
|
+
else return err(optional.error);
|
|
3641
|
+
const otool = captures.find(({ tool }) => tool === "otool");
|
|
3642
|
+
if (otool === undefined) throw new TypeError("Missing otool capture");
|
|
3643
|
+
let load;
|
|
3644
|
+
try {
|
|
3645
|
+
load = parseOtoolLoadCommands(sliceOutput(otool));
|
|
3646
|
+
} catch (cause) {
|
|
3647
|
+
return err(new AnalysisOutputError("inspect_macho", "Malformed otool load-command output", {
|
|
3648
|
+
cause,
|
|
3649
|
+
capturedOutput: {
|
|
3650
|
+
stdout: otool.stdout,
|
|
3651
|
+
stderr: otool.stderr,
|
|
3652
|
+
truncated: false,
|
|
3653
|
+
stdout_bytes: otool.stdoutBytes,
|
|
3654
|
+
stderr_bytes: otool.stderrBytes,
|
|
3655
|
+
exit_code: otool.exitCode,
|
|
3656
|
+
signal: otool.signal
|
|
3657
|
+
}
|
|
3658
|
+
}));
|
|
3659
|
+
}
|
|
3660
|
+
const selectedArchitectureName = selectedArchitecture ?? (architectures.length === 1 ? architectures[0]?.name ?? null : null);
|
|
3661
|
+
const containerOffset = selectedArchitectureName === null ? undefined : /^Non-fat file:/mu.test(lipo.stdout) ? 0 : architectures.find(({ name }) => name === selectedArchitectureName)?.file_offset ?? undefined;
|
|
3662
|
+
const normalized = normalizeMacho(captures, context.invocation, limitations, load, architectures, context.target.path, {
|
|
3663
|
+
name: selectedArchitectureName,
|
|
3664
|
+
container_file_offset: containerOffset ?? null
|
|
3665
|
+
});
|
|
3666
|
+
const result = containerOffset === undefined ? inspectMachoSchema.parse({
|
|
3667
|
+
...normalized,
|
|
3668
|
+
limitations: [...normalized.limitations, selectedArchitectureName === null ? "The selected Mach-O slice is unknown; slice-based evidence locations are unavailable." : "The selected Mach-O slice's container file offset was not observed; slice-based evidence locations are unavailable."]
|
|
3669
|
+
}) : normalized;
|
|
3670
|
+
return ok({
|
|
3671
|
+
result: jsonValueSchema.parse(result),
|
|
3672
|
+
limitations: result.limitations,
|
|
3673
|
+
locations: fileOffsetLocations(result, containerOffset)
|
|
3674
|
+
});
|
|
3675
|
+
};
|
|
3676
|
+
normalizeMacho = (captures, toInvocation, additionalLimitations, load, architectures, artifactPath, selectedArchitecture) => {
|
|
3677
|
+
const byTool = captureLookup(captures);
|
|
3678
|
+
const imports = parseDyldSymbols(sliceOutput(byTool("dyld_info", 0)), "imports");
|
|
3679
|
+
const imageBase = load.segments.find((segment) => segment.file_offset === 0 && (segment.file_size ?? 0) > 0)?.vm_address ?? null;
|
|
3680
|
+
const nmExports = parseNmExports(byTool("nm").stdout);
|
|
3681
|
+
const dyldExports = parseDyldSymbols(sliceOutput(byTool("dyld_info", 1)), "exports", imageBase, new Set(nmExports.map(({ name }) => name)));
|
|
3682
|
+
const exports = uniqueSymbols([...dyldExports, ...nmExports]);
|
|
3683
|
+
const dwarfdump = byTool("dwarfdump");
|
|
3684
|
+
const uuid = reconcileMachoUuid(load.commands, dwarfdump.stdout, artifactPath, selectedArchitecture.name);
|
|
3685
|
+
const provenance = captures.map(toInvocation);
|
|
3686
|
+
const threadEntrypoint = load.entrypoints.length === 0 && load.commands.some((command) => command.kind === "LC_UNIXTHREAD" || command.kind === "LC_THREAD");
|
|
3687
|
+
const threadEntrypointLimitation = "Thread-state entrypoints (LC_UNIXTHREAD/LC_THREAD) are retained as raw load commands; file offsets are not derived.";
|
|
3688
|
+
const limitations = [
|
|
3689
|
+
"Imports and exports combine dyld_info and nm; stripped or toolchain-hidden symbols may be absent.",
|
|
3690
|
+
...captures.some(({ tool }) => tool === "vtool") ? ["vtool output is retained as provenance but only otool build metadata is normalized."] : [],
|
|
3691
|
+
...additionalLimitations,
|
|
3692
|
+
...uuid.limitations,
|
|
3693
|
+
...threadEntrypoint ? [threadEntrypointLimitation] : [],
|
|
3694
|
+
...imageBase === null && /^\s*offset\s+symbol\s*$/mu.test(sliceOutput(byTool("dyld_info", 1))) ? ["Export virtual addresses are unavailable because no file-backed image base was observed."] : []
|
|
3695
|
+
];
|
|
3696
|
+
return inspectMachoSchema.parse({
|
|
3697
|
+
format: "mach-o",
|
|
3698
|
+
selected_architecture: selectedArchitecture,
|
|
3699
|
+
endian: parseEndian(byTool("file").stdout),
|
|
3700
|
+
word_size: parseWordSize(byTool("file").stdout),
|
|
3701
|
+
file_type: load.fileType,
|
|
3702
|
+
flags: load.flags,
|
|
3703
|
+
uuid: uuid.value,
|
|
3704
|
+
entrypoints: covered(load.entrypoints, !threadEntrypoint, threadEntrypoint ? [threadEntrypointLimitation] : []),
|
|
3705
|
+
architectures: covered(architectures, true),
|
|
3706
|
+
build_metadata: covered(load.builds, true),
|
|
3707
|
+
load_commands: covered(load.commands, true),
|
|
3708
|
+
dependencies: covered(load.dependencies, true),
|
|
3709
|
+
imports: covered(imports, false, ["dyld_info textual imports may omit chained or toolchain-unsupported metadata."]),
|
|
3710
|
+
exports: covered(exports, false, ["Merged nm/dyld_info results may be incomplete for stripped binaries."]),
|
|
3711
|
+
segments: covered(load.segments.map((segment) => ({
|
|
3712
|
+
...segment,
|
|
3713
|
+
sections: covered(segment.sections, true)
|
|
3714
|
+
})), true),
|
|
3715
|
+
provenance,
|
|
3716
|
+
limitations
|
|
3717
|
+
});
|
|
3718
|
+
};
|
|
3719
|
+
sliceOutput = (capture) => withoutEchoedPathHeader(capture.stdout, capture.arguments.at(-1));
|
|
3720
|
+
captureLookup = (captures) => (tool, occurrence = 0) => {
|
|
3721
|
+
const capture = captures.filter((item) => item.tool === tool)[occurrence];
|
|
3722
|
+
if (capture === undefined) throw new TypeError(`Missing ${tool} capture`);
|
|
3723
|
+
return capture;
|
|
3724
|
+
};
|
|
3725
|
+
parseNmExports = (output) => output.split(/\r?\n/u).filter((name) => name.length > 0).map((name) => ({
|
|
3726
|
+
name,
|
|
3727
|
+
address: null,
|
|
3728
|
+
weak: null,
|
|
3729
|
+
reexport: null,
|
|
3730
|
+
source: "nm"
|
|
3731
|
+
}));
|
|
3732
|
+
parseEndian = (output) => /little-endian/iu.test(output) ? "little" : /big-endian/iu.test(output) ? "big" : null;
|
|
3733
|
+
parseWordSize = (output) => /64-bit/iu.test(output) ? 64 : /32-bit/iu.test(output) ? 32 : null;
|
|
3734
|
+
covered = (items, exhaustive, limitations = []) => ({
|
|
3735
|
+
items: [...items],
|
|
3736
|
+
total: exhaustive ? items.length : null,
|
|
3737
|
+
exhaustive,
|
|
3738
|
+
limitations: [...limitations]
|
|
3739
|
+
});
|
|
3740
|
+
uniqueSymbols = (items) => {
|
|
3741
|
+
const unique = new Map();
|
|
3742
|
+
for (const item of items) if (!unique.has(item.name)) unique.set(item.name, item);
|
|
3743
|
+
return [...unique.values()].sort((left, right) => compareUnicodeCodePoints(left.name, right.name));
|
|
3744
|
+
};
|
|
3745
|
+
fileOffsetLocations = (macho, containerOffset) => {
|
|
3746
|
+
const locations = architectureLocations(macho.architectures.items);
|
|
3747
|
+
if (containerOffset === undefined) return locations;
|
|
3748
|
+
for (const entrypoint of macho.entrypoints.items) locations.push({
|
|
3749
|
+
kind: "file-offset",
|
|
3750
|
+
offset: containerOffset + entrypoint.file_offset
|
|
3751
|
+
});
|
|
3752
|
+
for (const segment of macho.segments.items) {
|
|
3753
|
+
if (segment.file_offset === null || segment.file_size === null || segment.file_size === 0) continue;
|
|
3754
|
+
locations.push({
|
|
3755
|
+
kind: "file-offset-range",
|
|
3756
|
+
start: containerOffset + segment.file_offset,
|
|
3757
|
+
end: containerOffset + segment.file_offset + segment.file_size
|
|
3758
|
+
});
|
|
3759
|
+
}
|
|
3760
|
+
return locations;
|
|
3761
|
+
};
|
|
3762
|
+
architectureLocations = (architectures) => {
|
|
3763
|
+
const locations = [];
|
|
3764
|
+
for (const { file_offset: offset, size } of architectures) {
|
|
3765
|
+
if (offset === null) continue;
|
|
3766
|
+
locations.push(size === null ? {
|
|
3767
|
+
kind: "file-offset",
|
|
3768
|
+
offset
|
|
3769
|
+
} : {
|
|
3770
|
+
kind: "file-offset-range",
|
|
3771
|
+
start: offset,
|
|
3772
|
+
end: offset + size
|
|
3773
|
+
});
|
|
3774
|
+
}
|
|
3775
|
+
return locations;
|
|
3776
|
+
};
|
|
3777
|
+
selectedArchitectureArguments = (tool, architecture) => {
|
|
3778
|
+
if (architecture === null) return [];
|
|
3779
|
+
const baseArchitecture = architecture.split(".")[0] ?? architecture;
|
|
3780
|
+
const toolArchitecture = tool === "dyld_info" ? architecture : baseArchitecture;
|
|
3781
|
+
return tool === "dwarfdump" ? [`--arch=${toolArchitecture}`] : ["-arch", toolArchitecture];
|
|
3782
|
+
};
|
|
3783
|
+
selectArchitecture = (target, available) => {
|
|
3784
|
+
if (target.kind !== "executable" || target.availableArchitectures.length < 2) return { status: "unfiltered" };
|
|
3785
|
+
const normalized = target.architecture === "x86" ? "i386" : target.architecture;
|
|
3786
|
+
if (available.includes(normalized)) return {
|
|
3787
|
+
status: "selected",
|
|
3788
|
+
architecture: normalized
|
|
3789
|
+
};
|
|
3790
|
+
if (normalized === "arm64") {
|
|
3791
|
+
const arm64e = available.find((architecture) => architecture === "arm64e");
|
|
3792
|
+
if (arm64e !== undefined) return {
|
|
3793
|
+
status: "selected",
|
|
3794
|
+
architecture: arm64e
|
|
3795
|
+
};
|
|
3796
|
+
const variant = available.find((architecture) => /^arm64e\.[A-Za-z0-9_]+$/u.test(architecture));
|
|
3797
|
+
if (variant !== undefined) return {
|
|
3798
|
+
status: "selected",
|
|
3799
|
+
architecture: variant
|
|
3800
|
+
};
|
|
3801
|
+
}
|
|
3802
|
+
return {
|
|
3803
|
+
status: "absent",
|
|
3804
|
+
architecture: normalized
|
|
3805
|
+
};
|
|
3806
|
+
};
|
|
3807
|
+
})))();
|
|
3808
|
+
}
|
|
3809
|
+
|
|
3810
|
+
//#endregion
|
|
3811
|
+
//#region dist/native/NativeMacOSProvider.js
|
|
3812
|
+
var NativeMacOSProvider, NativeMacOSClient, nativeCommandCleanupFailure, isNativeOperation, translateCommandFailure, translateCodeSignExitFailure, commandOutput, isNonzeroUnsignedObservation, canonicalPath, codeSignCaptureFailure, codeSignArchitectures, invocation, parseEntitlements, unreadablePlist, plutilDiagnostic, requireRegularPlist, resolvePlistPath;
|
|
3813
|
+
function init_NativeMacOSProvider() {
|
|
3814
|
+
return (init_NativeMacOSProvider = __esmMin((() => {
|
|
3815
|
+
init_snapshotEnvironment();
|
|
3816
|
+
init_NativeMacOSProviderMetadata();
|
|
3817
|
+
init_AppleDispatchMetadata();
|
|
3818
|
+
init_NativeUiObservation();
|
|
3819
|
+
init_LldbCallTracer();
|
|
3820
|
+
init_NativeCallObservation();
|
|
3821
|
+
init_AnalysisProvider();
|
|
3822
|
+
init_nativeToolContracts();
|
|
3823
|
+
init_binaryTargetTypes();
|
|
3824
|
+
init_toolContracts();
|
|
3825
|
+
init_inputIssueProjection();
|
|
3826
|
+
init_analysisErrorCore();
|
|
3827
|
+
init_configurationErrors();
|
|
3828
|
+
init_providerAdapterError();
|
|
3829
|
+
init_providerCleanupError();
|
|
3830
|
+
init_analysisErrorBase();
|
|
3831
|
+
init_jsonValue();
|
|
3832
|
+
init_propertyListKeys();
|
|
3833
|
+
init_nativeInspection();
|
|
3834
|
+
init_result();
|
|
3835
|
+
init_CommandRunner();
|
|
3836
|
+
init_SignatureTargetBinding();
|
|
3837
|
+
init_codesign();
|
|
3838
|
+
init_demangle();
|
|
3839
|
+
init_lipo();
|
|
3840
|
+
init_plist();
|
|
3841
|
+
init_NativeMachoInspection();
|
|
3842
|
+
init_analysisErrorCleanup();
|
|
3843
|
+
init_NativeUiHelperRuntime();
|
|
3844
|
+
NativeMacOSProvider = class {
|
|
3845
|
+
runner;
|
|
3846
|
+
#capabilities;
|
|
3847
|
+
#environment;
|
|
3848
|
+
#tracerFactory;
|
|
3849
|
+
constructor(environment, runner = new XcrunCommandRunner(environment), platform = process.platform, tracerFactory) {
|
|
3850
|
+
this.runner = runner;
|
|
3851
|
+
this.#environment = snapshotEnvironment(environment, platform);
|
|
3852
|
+
this.#tracerFactory = tracerFactory ?? (() => new LldbCallTracer(this.#environment));
|
|
3853
|
+
this.#capabilities = nativeMacOSCapabilities(platform);
|
|
3854
|
+
}
|
|
3855
|
+
identity() {
|
|
3856
|
+
return NATIVE_MACOS_PROVIDER_IDENTITY;
|
|
3857
|
+
}
|
|
3858
|
+
capabilities() {
|
|
3859
|
+
return this.#capabilities;
|
|
3860
|
+
}
|
|
3861
|
+
createClient(target) {
|
|
3862
|
+
return new NativeMacOSClient(target, this.runner, this.#tracerFactory(), this.#environment);
|
|
3863
|
+
}
|
|
3864
|
+
};
|
|
3865
|
+
NativeMacOSClient = class {
|
|
3866
|
+
target;
|
|
3867
|
+
runner;
|
|
3868
|
+
tracer;
|
|
3869
|
+
environment;
|
|
3870
|
+
#pendingNativeUiRuntimes = new Set();
|
|
3871
|
+
#pendingCommands = new Set();
|
|
3872
|
+
#nativeUiTail = Promise.resolve();
|
|
3873
|
+
#closed = false;
|
|
3874
|
+
constructor(target, runner, tracer, environment) {
|
|
3875
|
+
this.target = target;
|
|
3876
|
+
this.runner = runner;
|
|
3877
|
+
this.tracer = tracer;
|
|
3878
|
+
this.environment = environment;
|
|
3879
|
+
}
|
|
3880
|
+
async execute(operation, parameters, options) {
|
|
3881
|
+
if (this.#closed) return err(new AnalysisCapabilityUnavailableError(NATIVE_MACOS_PROVIDER_IDENTITY.id, operation, "Native provider client is closed"));
|
|
3882
|
+
if (options?.signal?.aborted === true) return err(new AnalysisCancelledError(operation));
|
|
3883
|
+
if (operation === "health") return ok(createAnalysisExecution(null, NATIVE_MACOS_PROVIDER_IDENTITY));
|
|
3884
|
+
if (operation === "inspect_native_dispatch_metadata") {
|
|
3885
|
+
const input = toolContract(operation).inputSchema.safeParse(parameters);
|
|
3886
|
+
if (!input.success) return err(analysisInputErrorFromIssues(operation, input.error.issues, parameters, { cause: input.error }));
|
|
3887
|
+
if (this.target.kind !== "executable" || !isMachOFormat(this.target.format)) return err(new AnalysisCapabilityUnavailableError(NATIVE_MACOS_PROVIDER_IDENTITY.id, operation, "Binary Apple metadata requires Mach-O; other providers can report symbol-only metadata"));
|
|
3888
|
+
try {
|
|
3889
|
+
const result = await inspectAppleDispatchMetadata(this.target, input.data.max_records, options?.signal);
|
|
3890
|
+
return ok(createAnalysisExecution(result, result.provider, {
|
|
3891
|
+
locations: [{
|
|
3892
|
+
kind: "artifact-path",
|
|
3893
|
+
path: this.target.path
|
|
3894
|
+
}],
|
|
3895
|
+
limitations: result.result.coverage.flatMap(({ reason }) => reason === null ? [] : [reason])
|
|
3896
|
+
}));
|
|
3897
|
+
} catch (cause) {
|
|
3898
|
+
if (cause instanceof AnalysisError) return err(cause);
|
|
3899
|
+
return err(options?.signal?.aborted ? new AnalysisCancelledError(operation) : new ProviderAdapterError(NATIVE_MACOS_PROVIDER_IDENTITY.id, operation, {
|
|
3900
|
+
cause,
|
|
3901
|
+
diagnostics: {
|
|
3902
|
+
target_path: this.target.path,
|
|
3903
|
+
reason: cause instanceof Error ? cause.message : String(cause)
|
|
3904
|
+
}
|
|
3905
|
+
}));
|
|
3906
|
+
}
|
|
3907
|
+
}
|
|
3908
|
+
if (!isNativeOperation(operation)) return err(new AnalysisCapabilityUnavailableError(NATIVE_MACOS_PROVIDER_IDENTITY.id, operation, "Operation is not implemented by native macOS tools."));
|
|
3909
|
+
if (operation === "observe_native_calls") {
|
|
3910
|
+
const result = await observeNativeCalls(this.target, parameters, this.tracer, options?.signal);
|
|
3911
|
+
return result.ok ? ok(createAnalysisExecution(result.value, NATIVE_MACOS_PROVIDER_IDENTITY, {
|
|
3912
|
+
limitations: result.value.limitations,
|
|
3913
|
+
locations: [{
|
|
3914
|
+
kind: "artifact-path",
|
|
3915
|
+
path: this.target.path
|
|
3916
|
+
}]
|
|
3917
|
+
})) : result;
|
|
3918
|
+
}
|
|
3919
|
+
if (operation === "observe_native_ui" || operation === "capture_native_ui_scenario") {
|
|
3920
|
+
return this.#observeNativeUi(operation, parameters, options?.signal);
|
|
3921
|
+
}
|
|
3922
|
+
try {
|
|
3923
|
+
const observation = await this.#dispatch(operation, parameters, options?.signal);
|
|
3924
|
+
return observation.ok ? ok(createAnalysisExecution(observation.value.result, NATIVE_MACOS_PROVIDER_IDENTITY, {
|
|
3925
|
+
limitations: observation.value.limitations,
|
|
3926
|
+
locations: observation.value.locations
|
|
3927
|
+
})) : observation;
|
|
3928
|
+
} catch (cause) {
|
|
3929
|
+
return err(new AnalysisOutputError(operation, "Native output parsing failed", { cause }));
|
|
3930
|
+
}
|
|
3931
|
+
}
|
|
3932
|
+
async close() {
|
|
3933
|
+
this.#closed = true;
|
|
3934
|
+
await Promise.allSettled(this.#pendingCommands);
|
|
3935
|
+
const uiCleanupFailures = await this.#serializeNativeUi(() => this.#retryNativeUiCleanup());
|
|
3936
|
+
const commandCleanup = await this.#retryNativeCommandCleanup();
|
|
3937
|
+
let result = await this.tracer.close();
|
|
3938
|
+
const cleanupErrors = [...uiCleanupFailures.length === 0 ? [] : [this.#nativeUiCleanupFailure(uiCleanupFailures, "close_binary")], ...commandCleanup === undefined ? [] : [commandCleanup]];
|
|
3939
|
+
for (const cleanupError of cleanupErrors) result = result.ok ? err(cleanupError) : err(analysisErrorWithCleanupFailure(result.error, cleanupError));
|
|
3940
|
+
return result;
|
|
3941
|
+
}
|
|
3942
|
+
#observeNativeUi(operation, parameters, signal) {
|
|
3943
|
+
return this.#serializeNativeUi(async () => {
|
|
3944
|
+
if (this.#closed) return err(new AnalysisCapabilityUnavailableError(NATIVE_MACOS_PROVIDER_IDENTITY.id, operation, "Native provider client is closed"));
|
|
3945
|
+
const earlierCleanupFailures = await this.#retryNativeUiCleanup();
|
|
3946
|
+
if (earlierCleanupFailures.length > 0) return err(this.#nativeUiCleanupFailure(earlierCleanupFailures, operation));
|
|
3947
|
+
const runtime = createNativeUiHelperRuntime(this.environment);
|
|
3948
|
+
this.#pendingNativeUiRuntimes.add(runtime);
|
|
3949
|
+
let result;
|
|
3950
|
+
try {
|
|
3951
|
+
result = await observeNativeUi(this.target, operation, parameters, {
|
|
3952
|
+
environment: this.environment,
|
|
3953
|
+
signal,
|
|
3954
|
+
runtime
|
|
3955
|
+
});
|
|
3956
|
+
} catch (cause) {
|
|
3957
|
+
result = err(cause instanceof AnalysisError ? cause : new ProviderAdapterError(NATIVE_MACOS_PROVIDER_IDENTITY.id, operation, { cause }));
|
|
3958
|
+
}
|
|
3959
|
+
try {
|
|
3960
|
+
await runtime.close();
|
|
3961
|
+
this.#pendingNativeUiRuntimes.delete(runtime);
|
|
3962
|
+
} catch (cause) {
|
|
3963
|
+
const cleanup = this.#nativeUiCleanupFailure([{
|
|
3964
|
+
runtime,
|
|
3965
|
+
cause
|
|
3966
|
+
}], operation, result.ok ? result.value : undefined);
|
|
3967
|
+
return err(result.ok ? cleanup : analysisErrorWithCleanupFailure(result.error, cleanup, operation));
|
|
3968
|
+
}
|
|
3969
|
+
return result.ok ? ok(createAnalysisExecution(result.value, NATIVE_MACOS_PROVIDER_IDENTITY, { limitations: result.value.limitations })) : result;
|
|
3970
|
+
});
|
|
3971
|
+
}
|
|
3972
|
+
#serializeNativeUi(operation) {
|
|
3973
|
+
const call = this.#nativeUiTail.then(operation, operation);
|
|
3974
|
+
this.#nativeUiTail = call.then(() => undefined, () => undefined);
|
|
3975
|
+
return call;
|
|
3976
|
+
}
|
|
3977
|
+
async #retryNativeUiCleanup() {
|
|
3978
|
+
const failures = [];
|
|
3979
|
+
for (const runtime of this.#pendingNativeUiRuntimes) {
|
|
3980
|
+
try {
|
|
3981
|
+
await runtime.close();
|
|
3982
|
+
this.#pendingNativeUiRuntimes.delete(runtime);
|
|
3983
|
+
} catch (cause) {
|
|
3984
|
+
failures.push({
|
|
3985
|
+
runtime,
|
|
3986
|
+
cause
|
|
3987
|
+
});
|
|
3988
|
+
}
|
|
3989
|
+
}
|
|
3990
|
+
return failures;
|
|
3991
|
+
}
|
|
3992
|
+
async #retryNativeCommandCleanup() {
|
|
3993
|
+
if (this.runner.retryCleanup === undefined) return undefined;
|
|
3994
|
+
try {
|
|
3995
|
+
const failures = await this.runner.retryCleanup();
|
|
3996
|
+
return failures.length === 0 ? undefined : nativeCommandCleanupFailure(failures);
|
|
3997
|
+
} catch (cause) {
|
|
3998
|
+
return new ProviderCleanupError(NATIVE_MACOS_PROVIDER_IDENTITY.id, ["native-command-process-cleanup"], { reason: cause instanceof Error ? cause.message || cause.name : String(cause) || "native command cleanup failed unexpectedly" }, { cause });
|
|
3999
|
+
}
|
|
4000
|
+
}
|
|
4001
|
+
#nativeUiCleanupFailure(failures, operation, partialObservation) {
|
|
4002
|
+
const resources = failures.flatMap(({ runtime }) => runtime.resources());
|
|
4003
|
+
return new ProviderCleanupError(NATIVE_MACOS_PROVIDER_IDENTITY.id, resources.length === 0 ? ["native-ui-runtime"] : resources, {
|
|
4004
|
+
reason: "Native UI runtime cleanup remains incomplete",
|
|
4005
|
+
failures: failures.map(({ runtime, cause }) => ({
|
|
4006
|
+
resources: [...runtime.resources()],
|
|
4007
|
+
reason: cause instanceof Error ? cause.message : String(cause)
|
|
4008
|
+
}))
|
|
4009
|
+
}, {
|
|
4010
|
+
operation,
|
|
4011
|
+
cause: new AggregateError(failures.map(({ cause }) => cause), "Native UI runtime cleanup failed"),
|
|
4012
|
+
...partialObservation === undefined ? {} : { partialObservation }
|
|
4013
|
+
});
|
|
4014
|
+
}
|
|
4015
|
+
#dispatch(operation, parameters, signal) {
|
|
4016
|
+
switch (operation) {
|
|
4017
|
+
case "observe_native_ui":
|
|
4018
|
+
case "capture_native_ui_scenario":
|
|
4019
|
+
case "observe_native_calls": return Promise.resolve(err(new AnalysisCapabilityUnavailableError(NATIVE_MACOS_PROVIDER_IDENTITY.id, operation, "UI observation uses its explicit authority boundary")));
|
|
4020
|
+
case "inspect_macho": return this.#inspectMacho(signal);
|
|
4021
|
+
case "inspect_signature": return this.#inspectSignature(signal);
|
|
4022
|
+
case "inspect_plist": return this.#inspectPlist(parameters, signal);
|
|
4023
|
+
case "list_architectures": return this.#listArchitectures(signal);
|
|
4024
|
+
case "demangle_swift": return this.#demangle(parameters, signal);
|
|
4025
|
+
}
|
|
4026
|
+
}
|
|
4027
|
+
async #listArchitectures(signal) {
|
|
4028
|
+
if (!isMachOFormat(this.target.format)) return err(new AnalysisCapabilityUnavailableError(NATIVE_MACOS_PROVIDER_IDENTITY.id, "list_architectures", "Active artifact is not Mach-O."));
|
|
4029
|
+
const capture = await this.#run("list_architectures", "lipo", ["-detailed_info", this.target.path], { signal });
|
|
4030
|
+
if (!capture.ok) return capture;
|
|
4031
|
+
const provenance = [invocation(capture.value, this.target.path)];
|
|
4032
|
+
const architectures = parseLipoArchitectures(capture.value.stdout);
|
|
4033
|
+
const result = listArchitecturesSchema.parse({
|
|
4034
|
+
architectures: {
|
|
4035
|
+
items: architectures,
|
|
4036
|
+
total: architectures.length,
|
|
4037
|
+
exhaustive: true,
|
|
4038
|
+
limitations: []
|
|
4039
|
+
},
|
|
4040
|
+
provenance,
|
|
4041
|
+
limitations: []
|
|
4042
|
+
});
|
|
4043
|
+
return ok({
|
|
4044
|
+
result: jsonValueSchema.parse(result),
|
|
4045
|
+
limitations: [],
|
|
4046
|
+
locations: architectureLocations(result.architectures.items)
|
|
4047
|
+
});
|
|
4048
|
+
}
|
|
4049
|
+
async #demangle(parameters, signal) {
|
|
4050
|
+
const symbols = z.array(z.string()).safeParse(parameters.symbols);
|
|
4051
|
+
if (!symbols.success) return err(new AnalysisOutputError("demangle_swift", "symbols were not parsed strings"));
|
|
4052
|
+
const capture = await this.#run("demangle_swift", "swift-demangle", [
|
|
4053
|
+
"--compact",
|
|
4054
|
+
"--",
|
|
4055
|
+
...symbols.data
|
|
4056
|
+
], { signal });
|
|
4057
|
+
if (!capture.ok) return capture;
|
|
4058
|
+
const provenance = [invocation(capture.value, this.target.path)];
|
|
4059
|
+
const result = demangleSwiftSchema.parse({
|
|
4060
|
+
symbols: parseDemangledSymbols(symbols.data, capture.value.stdout),
|
|
4061
|
+
provenance,
|
|
4062
|
+
limitations: []
|
|
4063
|
+
});
|
|
4064
|
+
return ok({
|
|
4065
|
+
result: jsonValueSchema.parse(result),
|
|
4066
|
+
limitations: [],
|
|
4067
|
+
locations: []
|
|
4068
|
+
});
|
|
4069
|
+
}
|
|
4070
|
+
async #inspectSignature(signal) {
|
|
4071
|
+
return withSignatureTarget(this.target, (binding) => this.#inspectBoundSignature(binding, signal), signal);
|
|
4072
|
+
}
|
|
4073
|
+
async #inspectBoundSignature(binding, signal) {
|
|
4074
|
+
const display = await this.#captureSignature(binding, ["-d", "--verbose=4"], signal);
|
|
4075
|
+
if (!display.ok) return display;
|
|
4076
|
+
const unsigned = isNonzeroUnsignedObservation(display.value);
|
|
4077
|
+
const displayFailure = codeSignCaptureFailure(display.value);
|
|
4078
|
+
if (displayFailure !== null) return err(displayFailure);
|
|
4079
|
+
const requirements = await this.#captureSignature(binding, ["-d", "-r-"], signal);
|
|
4080
|
+
if (!requirements.ok) return requirements;
|
|
4081
|
+
const requirementsFailure = codeSignCaptureFailure(requirements.value);
|
|
4082
|
+
if (requirementsFailure !== null) return err(requirementsFailure);
|
|
4083
|
+
const entitlements = await this.#captureSignature(binding, [
|
|
4084
|
+
"-d",
|
|
4085
|
+
"--entitlements",
|
|
4086
|
+
":-"
|
|
4087
|
+
], signal);
|
|
4088
|
+
if (!entitlements.ok) return entitlements;
|
|
4089
|
+
const entitlementsFailure = codeSignCaptureFailure(entitlements.value);
|
|
4090
|
+
if (entitlementsFailure !== null) return err(entitlementsFailure);
|
|
4091
|
+
const parsed = parseCodeSignature(display.value.stderr, unsigned, [binding.snapshotPath, ...await canonicalPath(binding.snapshotPath)]);
|
|
4092
|
+
const requirementText = /designated\s*=>\s*(.+)$/mu.exec(requirements.value.stdout)?.[1] ?? null;
|
|
4093
|
+
const entitlementValue = parseEntitlements(entitlements.value.stdout);
|
|
4094
|
+
const captures = [
|
|
4095
|
+
display.value,
|
|
4096
|
+
requirements.value,
|
|
4097
|
+
entitlements.value
|
|
4098
|
+
];
|
|
4099
|
+
const limitations = [
|
|
4100
|
+
...parsed.limitations,
|
|
4101
|
+
"Inspected a digest-verified Mach-O byte snapshot; filesystem-bound signing context and trust validation are not examined.",
|
|
4102
|
+
...entitlementValue.omittedPrototypeKeys === 0 ? [] : [`Entitlements: ${omittedPrototypeKeysLimitation(entitlementValue.omittedPrototypeKeys)}`]
|
|
4103
|
+
];
|
|
4104
|
+
const mixedSigning = !unsigned && (isNonzeroUnsignedObservation(requirements.value) || isNonzeroUnsignedObservation(entitlements.value));
|
|
4105
|
+
if (mixedSigning) {
|
|
4106
|
+
const slices = await this.#inspectMixedSignatureSlices(binding, parsed.format, {
|
|
4107
|
+
requirements: requirements.value.exitCode,
|
|
4108
|
+
entitlements: entitlements.value.exitCode
|
|
4109
|
+
}, signal);
|
|
4110
|
+
if (!slices.ok) return slices;
|
|
4111
|
+
captures.push(...slices.value.captures);
|
|
4112
|
+
limitations.push(...slices.value.limitations);
|
|
4113
|
+
}
|
|
4114
|
+
const provenance = captures.map((capture) => invocation(capture, binding.snapshotPath));
|
|
4115
|
+
const version = await verifySignatureTarget(this.target, binding, signal);
|
|
4116
|
+
if (!version.ok) return version;
|
|
4117
|
+
const result = inspectSignatureSchema.parse({
|
|
4118
|
+
...parsed,
|
|
4119
|
+
designated_requirement: requirementText,
|
|
4120
|
+
entitlements: entitlementValue.value,
|
|
4121
|
+
provenance,
|
|
4122
|
+
limitations
|
|
4123
|
+
});
|
|
4124
|
+
return ok({
|
|
4125
|
+
result: jsonValueSchema.parse(result),
|
|
4126
|
+
limitations: result.limitations,
|
|
4127
|
+
locations: []
|
|
4128
|
+
});
|
|
4129
|
+
}
|
|
4130
|
+
async #inspectMixedSignatureSlices(binding, format, aggregateExits, signal) {
|
|
4131
|
+
const captures = [];
|
|
4132
|
+
const unsigned = [];
|
|
4133
|
+
const unclassified = [];
|
|
4134
|
+
for (const architecture of codeSignArchitectures(format, this.target)) {
|
|
4135
|
+
const slice = await this.#captureSignature(binding, [
|
|
4136
|
+
"-d",
|
|
4137
|
+
"-a",
|
|
4138
|
+
architecture,
|
|
4139
|
+
"--verbose=4"
|
|
4140
|
+
], signal);
|
|
4141
|
+
if (!slice.ok) return slice;
|
|
4142
|
+
captures.push(slice.value);
|
|
4143
|
+
if (slice.value.exitCode === 0) continue;
|
|
4144
|
+
if (isNonzeroUnsignedObservation(slice.value)) unsigned.push(architecture);
|
|
4145
|
+
else unclassified.push(architecture);
|
|
4146
|
+
}
|
|
4147
|
+
const limitations = [unsigned.length > 0 ? `Unsigned Mach-O slices: ${unsigned.join(", ")}.` : "One or more Mach-O slices are unsigned, but their architectures could not be classified."];
|
|
4148
|
+
if (unclassified.length > 0) limitations.push(`Signature state could not be classified for Mach-O slices: ${unclassified.join(", ")}.`);
|
|
4149
|
+
if (aggregateExits.requirements !== 0) limitations.push("The aggregate designated requirement is unavailable because Mach-O slices have mixed signing states.");
|
|
4150
|
+
if (aggregateExits.entitlements !== 0) limitations.push("The aggregate entitlements are unavailable because Mach-O slices have mixed signing states.");
|
|
4151
|
+
return ok({
|
|
4152
|
+
captures,
|
|
4153
|
+
limitations
|
|
4154
|
+
});
|
|
4155
|
+
}
|
|
4156
|
+
async #captureSignature(binding, args, signal) {
|
|
4157
|
+
const before = await verifySignatureTarget(this.target, binding, signal);
|
|
4158
|
+
if (!before.ok) return before;
|
|
4159
|
+
let capture;
|
|
4160
|
+
try {
|
|
4161
|
+
capture = await this.#run("inspect_signature", "codesign", [...args, binding.snapshotPath], {
|
|
4162
|
+
signal,
|
|
4163
|
+
acceptNonZero: true
|
|
4164
|
+
});
|
|
4165
|
+
} catch (cause) {
|
|
4166
|
+
capture = err(new ProviderAdapterError(NATIVE_MACOS_PROVIDER_IDENTITY.id, "inspect_signature", {
|
|
4167
|
+
cause,
|
|
4168
|
+
diagnostics: {
|
|
4169
|
+
phase: "codesign-capture",
|
|
4170
|
+
path: this.target.path,
|
|
4171
|
+
reason: cause instanceof Error ? cause.message : String(cause)
|
|
4172
|
+
}
|
|
4173
|
+
}));
|
|
4174
|
+
}
|
|
4175
|
+
const after = await verifySignatureTarget(this.target, binding, signal);
|
|
4176
|
+
return after.ok ? capture : after;
|
|
4177
|
+
}
|
|
4178
|
+
async #inspectPlist(parameters, signal) {
|
|
4179
|
+
const requested = parameters.path;
|
|
4180
|
+
if (requested !== undefined && typeof requested !== "string") return err(new AnalysisOutputError("inspect_plist", "path was not a string"));
|
|
4181
|
+
const plist = await resolvePlistPath(this.target, requested);
|
|
4182
|
+
if (!plist.ok) return plist;
|
|
4183
|
+
const selected = await requireRegularPlist(plist.value, requested);
|
|
4184
|
+
if (!selected.ok) return selected;
|
|
4185
|
+
const classified = await this.#run("inspect_plist", "file", ["-b", plist.value], { signal });
|
|
4186
|
+
if (!classified.ok) return classified;
|
|
4187
|
+
const json = await this.#run("inspect_plist", "plutil", [
|
|
4188
|
+
"-convert",
|
|
4189
|
+
"json",
|
|
4190
|
+
"-o",
|
|
4191
|
+
"-",
|
|
4192
|
+
"--",
|
|
4193
|
+
plist.value
|
|
4194
|
+
], {
|
|
4195
|
+
signal,
|
|
4196
|
+
acceptNonZero: true
|
|
4197
|
+
});
|
|
4198
|
+
if (!json.ok) return json;
|
|
4199
|
+
const jsonDecoded = json.value.exitCode === 0;
|
|
4200
|
+
const xml = jsonDecoded && !plistJsonNeedsNumberTypes(json.value.stdout) ? undefined : await this.#run("inspect_plist", "plutil", [
|
|
4201
|
+
"-convert",
|
|
4202
|
+
"xml1",
|
|
4203
|
+
"-o",
|
|
4204
|
+
"-",
|
|
4205
|
+
"--",
|
|
4206
|
+
plist.value
|
|
4207
|
+
], {
|
|
4208
|
+
signal,
|
|
4209
|
+
acceptNonZero: !jsonDecoded
|
|
4210
|
+
});
|
|
4211
|
+
if (xml !== undefined && !xml.ok) return xml;
|
|
4212
|
+
if (xml !== undefined && xml.value.exitCode !== 0) return err(unreadablePlist(plist.value, requested, `plutil could not decode it as a property list (${plutilDiagnostic(xml.value.stderr, plist.value)})`));
|
|
4213
|
+
const parsed = xml === undefined ? parsePlistJson(json.value.stdout) : jsonDecoded ? parsePlistJson(json.value.stdout, xml.value.stdout) : parsePlistXml(xml.value.stdout);
|
|
4214
|
+
if (!parsed.ok) return parsed;
|
|
4215
|
+
const provenance = [
|
|
4216
|
+
classified.value,
|
|
4217
|
+
json.value,
|
|
4218
|
+
...xml === undefined ? [] : [xml.value]
|
|
4219
|
+
].map((item) => invocation(item, plist.value, "$PLIST"));
|
|
4220
|
+
const result = inspectPlistSchema.parse({
|
|
4221
|
+
format: /binary property list/iu.test(classified.value.stdout) ? "binary" : /XML|text/iu.test(classified.value.stdout) ? "xml" : "unknown",
|
|
4222
|
+
value: parsed.value.value,
|
|
4223
|
+
bundle: parsed.value.bundle,
|
|
4224
|
+
source_path: plist.value,
|
|
4225
|
+
provenance,
|
|
4226
|
+
limitations: parsed.value.limitations
|
|
4227
|
+
});
|
|
4228
|
+
return ok({
|
|
4229
|
+
result: jsonValueSchema.parse(result),
|
|
4230
|
+
limitations: parsed.value.limitations,
|
|
4231
|
+
locations: [{
|
|
4232
|
+
kind: "artifact-path",
|
|
4233
|
+
path: plist.value
|
|
4234
|
+
}]
|
|
4235
|
+
});
|
|
4236
|
+
}
|
|
4237
|
+
async #inspectMacho(signal) {
|
|
4238
|
+
if (!isMachOFormat(this.target.format)) return err(new AnalysisCapabilityUnavailableError(NATIVE_MACOS_PROVIDER_IDENTITY.id, "inspect_macho", "Active artifact is not Mach-O."));
|
|
4239
|
+
return inspectNativeMacho({
|
|
4240
|
+
target: this.target,
|
|
4241
|
+
...signal === undefined ? {} : { signal },
|
|
4242
|
+
run: (tool, arguments_, commandSignal) => this.#run("inspect_macho", tool, arguments_, { signal: commandSignal }),
|
|
4243
|
+
invocation: (capture) => invocation(capture, this.target.path)
|
|
4244
|
+
});
|
|
4245
|
+
}
|
|
4246
|
+
async #run(operation, tool, arguments_, options = {}) {
|
|
4247
|
+
if (this.#closed) return err(new AnalysisCapabilityUnavailableError(NATIVE_MACOS_PROVIDER_IDENTITY.id, operation, "Native provider client is closed"));
|
|
4248
|
+
const command = this.runner.run(tool, arguments_, {
|
|
4249
|
+
...options.signal === undefined ? {} : { signal: options.signal },
|
|
4250
|
+
acceptNonZero: options.acceptNonZero ?? false
|
|
4251
|
+
});
|
|
4252
|
+
this.#pendingCommands.add(command);
|
|
4253
|
+
let captured;
|
|
4254
|
+
try {
|
|
4255
|
+
captured = await command;
|
|
4256
|
+
} finally {
|
|
4257
|
+
this.#pendingCommands.delete(command);
|
|
4258
|
+
}
|
|
4259
|
+
if (captured.ok) return captured;
|
|
4260
|
+
return err(translateCommandFailure(operation, captured.error));
|
|
4261
|
+
}
|
|
4262
|
+
};
|
|
4263
|
+
nativeCommandCleanupFailure = (failures) => new ProviderCleanupError(NATIVE_MACOS_PROVIDER_IDENTITY.id, [...new Set(failures.flatMap(({ resources }) => resources))], {
|
|
4264
|
+
reason: "Native command process cleanup remains incomplete",
|
|
4265
|
+
failures: failures.map(({ reason, resources }) => ({
|
|
4266
|
+
reason,
|
|
4267
|
+
resources: [...resources]
|
|
4268
|
+
}))
|
|
4269
|
+
});
|
|
4270
|
+
isNativeOperation = (operation) => NATIVE_TOOL_CONTRACTS.some(({ name }) => name === operation);
|
|
4271
|
+
translateCommandFailure = (operation, failure) => {
|
|
4272
|
+
const capturedOutput = failure.capture === null ? undefined : {
|
|
4273
|
+
stdout: failure.capture.stdout,
|
|
4274
|
+
stderr: failure.capture.stderr,
|
|
4275
|
+
truncated: failure.capture.truncated,
|
|
4276
|
+
stdout_bytes: failure.capture.stdoutBytes,
|
|
4277
|
+
stderr_bytes: failure.capture.stderrBytes,
|
|
4278
|
+
exit_code: failure.capture.exitCode,
|
|
4279
|
+
signal: failure.capture.signal
|
|
4280
|
+
};
|
|
4281
|
+
const cleanup = failure.cleanupFailure === null ? undefined : {
|
|
4282
|
+
reason: failure.cleanupFailure,
|
|
4283
|
+
resources: [...failure.cleanupResources]
|
|
4284
|
+
};
|
|
4285
|
+
const errorOptions = {
|
|
4286
|
+
...capturedOutput === undefined ? {} : { capturedOutput },
|
|
4287
|
+
...cleanup === undefined ? {} : { cleanup }
|
|
4288
|
+
};
|
|
4289
|
+
if (failure.reason === "unavailable") {
|
|
4290
|
+
const reason = `${failure.tool} is unavailable through xcrun.`;
|
|
4291
|
+
return new AnalysisCapabilityUnavailableError(NATIVE_MACOS_PROVIDER_IDENTITY.id, operation, reason, {
|
|
4292
|
+
...errorOptions,
|
|
4293
|
+
userMessage: reason
|
|
4294
|
+
});
|
|
4295
|
+
}
|
|
4296
|
+
if (failure.reason === "cancelled") return new AnalysisCancelledError(operation, errorOptions);
|
|
4297
|
+
if (failure.reason === "timeout") return new AnalysisTimeoutError(operation, NATIVE_COMMAND_TIMEOUT_MS, errorOptions);
|
|
4298
|
+
if (failure.reason === "output-limit") return new AnalysisResourceConstraintError(operation, "memory", `Native command output exceeded ${String(NATIVE_COMMAND_OUTPUT_BUDGET_BYTES)} bytes; complete output is required for analysis.`, { max_output_bytes: NATIVE_COMMAND_OUTPUT_BUDGET_BYTES }, errorOptions);
|
|
4299
|
+
return new ProviderAdapterError(NATIVE_MACOS_PROVIDER_IDENTITY.id, operation, {
|
|
4300
|
+
cause: failure,
|
|
4301
|
+
...errorOptions,
|
|
4302
|
+
diagnostics: {
|
|
4303
|
+
tool: failure.tool,
|
|
4304
|
+
reason: failure.reason,
|
|
4305
|
+
exit_code: failure.capture?.exitCode ?? failure.exitCode,
|
|
4306
|
+
signal: failure.capture?.signal ?? null,
|
|
4307
|
+
stdout_bytes: failure.capture?.stdoutBytes ?? 0,
|
|
4308
|
+
stderr_bytes: failure.capture?.stderrBytes ?? 0
|
|
4309
|
+
}
|
|
4310
|
+
});
|
|
4311
|
+
};
|
|
4312
|
+
translateCodeSignExitFailure = (capture) => translateCommandFailure("inspect_signature", new NativeCommandFailure("codesign", "nonzero-exit", capture.exitCode, undefined, {
|
|
4313
|
+
stdout: capture.stdout,
|
|
4314
|
+
stderr: capture.stderr,
|
|
4315
|
+
stdoutBytes: capture.stdoutBytes,
|
|
4316
|
+
stderrBytes: capture.stderrBytes,
|
|
4317
|
+
exitCode: capture.exitCode,
|
|
4318
|
+
signal: capture.signal,
|
|
4319
|
+
truncated: false
|
|
4320
|
+
}));
|
|
4321
|
+
commandOutput = (capture) => `${capture.stdout}\n${capture.stderr}`;
|
|
4322
|
+
isNonzeroUnsignedObservation = (capture) => capture.exitCode !== null && capture.exitCode !== 0 && /not signed at all|code object is not signed/iu.test(commandOutput(capture));
|
|
4323
|
+
canonicalPath = async (path) => {
|
|
4324
|
+
try {
|
|
4325
|
+
return [await realpath(path)];
|
|
4326
|
+
} catch {
|
|
4327
|
+
return [];
|
|
4328
|
+
}
|
|
4329
|
+
};
|
|
4330
|
+
codeSignCaptureFailure = (capture) => capture.exitCode === 0 || isNonzeroUnsignedObservation(capture) ? null : translateCodeSignExitFailure(capture);
|
|
4331
|
+
codeSignArchitectures = (format, target) => {
|
|
4332
|
+
const universal = /^Mach-O universal \(([^)\r\n]+)\)$/u.exec(format ?? "")?.[1];
|
|
4333
|
+
if (universal !== undefined) {
|
|
4334
|
+
const architectures = universal.split(/\s+/u).filter((architecture) => /^(?:i386|x86_64|armv7|arm64|arm64e)$/u.test(architecture));
|
|
4335
|
+
if (architectures.length > 0) return [...new Set(architectures)];
|
|
4336
|
+
}
|
|
4337
|
+
if (target.kind !== "executable" || !isMachOFormat(target.format)) return [];
|
|
4338
|
+
return target.availableArchitectures.map((architecture) => architecture === "x86" ? "i386" : architecture);
|
|
4339
|
+
};
|
|
4340
|
+
invocation = (capture, artifactPath, alias = "$ARTIFACT") => ({
|
|
4341
|
+
tool: capture.tool,
|
|
4342
|
+
command: [capture.executable, ...capture.arguments.map((argument) => argument === artifactPath ? alias : argument)],
|
|
4343
|
+
tool_version: capture.toolVersion,
|
|
4344
|
+
version_reason: capture.versionReason,
|
|
4345
|
+
executable_sha256: capture.executableSha256,
|
|
4346
|
+
exit: {
|
|
4347
|
+
code: capture.exitCode,
|
|
4348
|
+
signal: capture.signal
|
|
4349
|
+
},
|
|
4350
|
+
stdout_bytes: capture.stdoutBytes,
|
|
4351
|
+
stderr_bytes: capture.stderrBytes
|
|
4352
|
+
});
|
|
4353
|
+
parseEntitlements = (output) => {
|
|
4354
|
+
const start = output.indexOf("<?xml");
|
|
4355
|
+
const end = output.lastIndexOf("</plist>");
|
|
4356
|
+
if (start < 0 || end < start) return {
|
|
4357
|
+
value: null,
|
|
4358
|
+
omittedPrototypeKeys: 0
|
|
4359
|
+
};
|
|
4360
|
+
const { value, omittedPrototypeKeys } = parseXmlPropertyList(output.slice(start, end + "</plist>".length));
|
|
4361
|
+
return {
|
|
4362
|
+
value: jsonValueSchema.parse(value),
|
|
4363
|
+
omittedPrototypeKeys
|
|
4364
|
+
};
|
|
4365
|
+
};
|
|
4366
|
+
unreadablePlist = (path, requested, reason) => {
|
|
4367
|
+
const sentence = reason.endsWith(".") ? reason : `${reason}.`;
|
|
4368
|
+
const missingDefault = `The target has no readable Contents/Info.plist at ${path}: ${sentence} Select another plist in the target with the path input (CLI: --relative-path).`;
|
|
4369
|
+
return requested === undefined ? new AnalysisCapabilityUnavailableError(NATIVE_MACOS_PROVIDER_IDENTITY.id, "inspect_plist", missingDefault, { userMessage: missingDefault }) : new AnalysisInputError("inspect_plist", undefined, [{
|
|
4370
|
+
path: ["path"],
|
|
4371
|
+
reason: "invalid_value",
|
|
4372
|
+
message: `Cannot inspect ${path}: ${sentence}`
|
|
4373
|
+
}]);
|
|
4374
|
+
};
|
|
4375
|
+
plutilDiagnostic = (stderr, path) => {
|
|
4376
|
+
const text = stderr.trim();
|
|
4377
|
+
return text.startsWith(`${path}: `) ? text.slice(path.length + 2) : text;
|
|
4378
|
+
};
|
|
4379
|
+
requireRegularPlist = async (path, requested) => {
|
|
4380
|
+
try {
|
|
4381
|
+
if (!(await stat(path)).isFile()) return err(unreadablePlist(path, requested, "it is not a regular file"));
|
|
4382
|
+
await (await open(path, "r")).close();
|
|
4383
|
+
return ok(null);
|
|
4384
|
+
} catch (cause) {
|
|
4385
|
+
const code = cause instanceof Error && "code" in cause ? cause.code : undefined;
|
|
4386
|
+
if (code === "ENOENT" || code === "ENOTDIR") return err(unreadablePlist(path, requested, "no file exists there"));
|
|
4387
|
+
if (code === "EACCES" || code === "EPERM") return err(new BinaryTargetError(path, `permission denied while reading plist (${code})`, { cause }));
|
|
4388
|
+
return err(new ProviderAdapterError(NATIVE_MACOS_PROVIDER_IDENTITY.id, "inspect_plist", { cause }));
|
|
4389
|
+
}
|
|
4390
|
+
};
|
|
4391
|
+
resolvePlistPath = async (target, requested) => {
|
|
4392
|
+
try {
|
|
4393
|
+
const source = target.sourcePath ?? target.path;
|
|
4394
|
+
if (requested !== undefined && isAbsolute(requested)) return ok(resolve(requested));
|
|
4395
|
+
const sourceMetadata = await stat(source);
|
|
4396
|
+
const root = sourceMetadata.isDirectory() ? source : dirname(target.path);
|
|
4397
|
+
if (requested !== undefined) return ok(resolve(root, requested));
|
|
4398
|
+
return ok(target.bundleInfoPlist ?? resolve(root, "Contents/Info.plist"));
|
|
4399
|
+
} catch (cause) {
|
|
4400
|
+
return err(new ProviderAdapterError(NATIVE_MACOS_PROVIDER_IDENTITY.id, "inspect_plist", { cause }));
|
|
4401
|
+
}
|
|
4402
|
+
};
|
|
4403
|
+
})))();
|
|
4404
|
+
}
|
|
4405
|
+
|
|
4406
|
+
//#endregion
|
|
4407
|
+
init_NativeMacOSProvider();
|
|
4408
|
+
export { NativeMacOSProvider };
|