rea-agents 6.0.0 → 6.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/README.md +26 -18
- package/bridge/android/ReaJadxBridge.java +14 -5
- package/bridge/ghidra/ReaGhidraBridge.java +205 -51
- package/bridge/hopper_bridge.py +314 -127
- package/bridge/mitmproxy/capture.py +0 -2
- package/bridge/native/rea_lldb_tracer.py +630 -94
- package/bridge/process/ProcessRunTokenReader.swift +39 -5
- package/bridge/pwntools/recorded_crash_impl.py +4 -0
- package/dist/android/JadxConfiguration.js +274 -31
- package/dist/android/JadxMcpTransport.js +18 -2
- package/dist/android/JadxProtocol.js +6 -0
- package/dist/android/JadxProvider.js +76 -37
- package/dist/android/JadxSession.js +23 -4
- package/dist/application/AnalysisContextQueries.js +8 -35
- package/dist/application/AnalysisDocument.js +32 -0
- package/dist/application/AppBundleExecutable.js +67 -21
- package/dist/application/BinaryTargetResolver.js +5 -3
- package/dist/application/BrowserEvidence.js +3 -8
- package/dist/application/BrowserScenarioEvidence.js +2 -18
- package/dist/application/CallPathTracing.js +19 -3
- package/dist/application/CapabilityInventory.js +48 -11
- package/dist/application/ClientConfigurationDocument.js +917 -8
- package/dist/application/ClientRegistrationIdentity.js +26 -5
- package/dist/application/ClientRegistrationStatus.js +29 -14
- package/dist/application/DirectAnalysis.js +56 -51
- package/dist/application/DirectAnalysisCleanup.js +72 -0
- package/dist/application/DirectAnalysisStatus.js +4 -5
- package/dist/application/Doctor.js +19 -21
- package/dist/application/DoctorDiagnostics.js +1 -2
- package/dist/application/DoctorScope.js +25 -13
- package/dist/application/EnhancedLiteralTracing.js +22 -25
- package/dist/application/EnhancedTools.js +64 -17
- package/dist/application/EvidenceBundleFiles.js +30 -13
- package/dist/application/FunctionAnalysisEvidence.js +2 -3
- package/dist/application/InventoryProjectionEvidence.js +4 -3
- package/dist/application/InvestigationProviders.js +11 -2
- package/dist/application/JsonFiles.js +83 -28
- package/dist/application/LinuxHopper.js +9 -6
- package/dist/application/MacHopper.js +15 -18
- package/dist/application/ProcedureAddressResolution.js +11 -0
- package/dist/application/RealHopperAssertions.js +0 -11
- package/dist/application/ReconstructionCoverageService.js +7 -4
- package/dist/application/ReconstructionObligationCandidates.js +1 -1
- package/dist/application/ReconstructionObligationLedgerService.js +4 -3
- package/dist/application/ReferenceSourceImportEntries.js +1 -1
- package/dist/application/Setup.js +21 -17
- package/dist/application/SetupClientConfiguration.js +10 -15
- package/dist/application/SetupHost.js +21 -29
- package/dist/application/SetupPlan.js +11 -9
- package/dist/application/SupportedClients.js +34 -1
- package/dist/application/Uninstall.js +82 -29
- package/dist/application/Update.js +18 -3
- package/dist/application/UpdateMaintenance.js +7 -5
- package/dist/application/UpdateRuntime.js +57 -36
- package/dist/application/WebModuleTraceService.js +4 -2
- package/dist/application/WebNetworkCaptureService.js +4 -2
- package/dist/application/WebRuntimeService.js +5 -3
- package/dist/application/WebScriptExportService.js +32 -6
- package/dist/application/WebSourceLocationService.js +4 -2
- package/dist/application/WorkflowEvidence.js +105 -0
- package/dist/application/XrefsAddressResolution.js +45 -0
- package/dist/application/analysisView/AnalysisViewService.js +76 -0
- package/dist/application/binary/AnalysisClientCleanup.js +30 -5
- package/dist/application/binary/AnalysisProviderEvaluation.js +22 -7
- package/dist/application/binary/AnalysisProviderRegistry.js +4 -6
- package/dist/application/binary/AnalysisSnapshotCache.js +13 -14
- package/dist/application/binary/BinarySession.js +161 -93
- package/dist/application/binary/BinarySessionComposition.js +1 -3
- package/dist/application/binary/BinarySessionExecution.js +3 -5
- package/dist/application/binary/BinarySessionOpen.js +4 -4
- package/dist/application/binary/BinarySessionRecords.js +26 -4
- package/dist/application/binary/BinarySessionStatus.js +18 -7
- package/dist/application/binary/CompositeProvider.js +16 -17
- package/dist/application/binary/LazyAnalysisProvider.js +8 -5
- package/dist/application/binary/SessionProviderRouter.js +27 -135
- package/dist/application/binaryDiagnostics/BinaryLayoutService.js +4 -2
- package/dist/application/binaryDiagnostics/RecordedCrashService.js +4 -2
- package/dist/application/evm/EvmInterfaceService.js +4 -2
- package/dist/application/homebrew.js +48 -0
- package/dist/application/investigation/EvidenceLedger.js +21 -7
- package/dist/application/investigation/InvestigationRecords.js +8 -0
- package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
- package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +21 -4
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
- package/dist/application/javascript/JavaScriptApplicationService.js +27 -15
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +10 -7
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +44 -10
- package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
- package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
- package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +49 -19
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +56 -8
- package/dist/application/javascript/JavaScriptModuleRelationships.js +38 -9
- package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +6 -4
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +63 -61
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +64 -19
- package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
- package/dist/application/managed/ManagedMemberComparisonService.js +9 -5
- package/dist/application/managed/ManagedNativeVerificationService.js +6 -4
- package/dist/application/managed/ManagedReconstructionService.js +4 -3
- package/dist/application/process/ProcessCli.js +25 -17
- package/dist/application/process/ProcessEvidence.js +4 -4
- package/dist/application/workflowInputError.js +18 -0
- package/dist/artifacts/ArtifactProvider.js +48 -13
- package/dist/artifacts/ArtifactReader.js +31 -0
- package/dist/artifacts/DirectoryArtifactReader.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +106 -15
- package/dist/artifacts/NativeDmgArtifactReader.js +73 -21
- package/dist/artifacts/SafeOutputTree.js +16 -2
- package/dist/artifacts/ZipArtifactReader.js +11 -4
- package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +26 -5
- package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
- package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
- package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
- package/dist/artifacts/apple/KeyedArchiveReader.js +55 -23
- package/dist/artifacts/apple/MachoLoadCommandReader.js +92 -31
- package/dist/artifacts/apple/NibArchive.js +81 -14
- package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
- package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
- package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +79 -68
- package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
- package/dist/artifacts/inventory/reader.js +3 -3
- package/dist/artifacts/inventory/scanCanonical.js +59 -38
- package/dist/artifacts/inventory/scanReader.js +5 -9
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
- package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
- package/dist/browser/CdpBrowserProvider.js +2 -3
- package/dist/browser/CdpCaptureCompleteness.js +2 -0
- package/dist/browser/CdpCaptureEventHandlers.js +78 -15
- package/dist/browser/CdpCaptureEventTypes.js +5 -1
- package/dist/browser/CdpCaptureEvents.js +25 -1
- package/dist/browser/CdpCaptureValues.js +20 -0
- package/dist/browser/CdpConnection.js +30 -11
- package/dist/browser/CdpElectronProvider.js +0 -2
- package/dist/browser/CdpElectronScriptEvents.js +2 -8
- package/dist/browser/CdpElectronScripts.js +2 -3
- package/dist/browser/CdpOptionalCommand.js +2 -3
- package/dist/browser/CdpPageCapture.js +23 -1
- package/dist/browser/CdpPageCaptureScripts.js +2 -3
- package/dist/browser/CdpSafeMetadata.js +10 -10
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
- package/dist/browser/PlaywrightElectronActiveActions.js +34 -79
- package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
- package/dist/browser/PlaywrightElectronActiveProvider.js +133 -130
- package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
- package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
- package/dist/browser/PlaywrightScenarioEvents.js +1 -1
- package/dist/browser/PlaywrightScenarioSession.js +39 -22
- package/dist/browser/WebSourceMapFetcher.js +426 -72
- package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
- package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
- package/dist/browser/history/CaptureFailures.js +41 -1
- package/dist/browser/history/CaptureRelease.js +5 -0
- package/dist/browser/history/HarCaptureAdapter.js +3 -3
- package/dist/browser/history/HarJson.js +3 -2
- package/dist/browser/history/HistoricalCaptureDecoder.js +4 -2
- package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
- package/dist/catalogIdentity.js +0 -1
- package/dist/cli/analysisSelector.js +23 -0
- package/dist/cli/analysisViewCommands.js +36 -0
- package/dist/cli/applicationCommands.js +2 -3
- package/dist/cli/artifactCommands.js +11 -12
- package/dist/cli/coreAnalysisCommands.js +3 -3
- package/dist/cli/coreBinaryCommands.js +100 -37
- package/dist/cli/coreNativeCommands.js +9 -10
- package/dist/cli/electronCommands.js +10 -9
- package/dist/cli/interactiveSetup.js +6 -6
- package/dist/cli/javascriptApplicationAnalysis.js +7 -3
- package/dist/cli/jsonOutput.js +4 -99
- package/dist/cli/managedCommands.js +7 -8
- package/dist/cli/nativeCallCommands.js +3 -5
- package/dist/cli/omittableDefaults.js +50 -0
- package/dist/cli/processCommands.js +3 -2
- package/dist/cli/setupCommands.js +16 -15
- package/dist/cli/utilityCommands.js +9 -9
- package/dist/cli/webRuntimeCommands.js +8 -8
- package/dist/cli.js +18 -9
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +1 -1
- package/dist/cliJsonInput.js +24 -5
- package/dist/cliOutput.js +0 -38
- package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
- package/dist/composition/binary.js +9 -9
- package/dist/composition/browserScenario.js +2 -1
- package/dist/composition/directAnalysis.js +20 -13
- package/dist/composition/electronScenario.js +1 -1
- package/dist/composition/optionalObservationProviders.js +12 -7
- package/dist/config/environment.js +10 -0
- package/dist/config/ghidraStartupTimeout.js +12 -0
- package/dist/config/homeDirectory.js +12 -0
- package/dist/config/mcpResponseBudget.js +30 -0
- package/dist/config/parseConfig.js +8 -3
- package/dist/config/parsers.js +19 -22
- package/dist/contracts/analysisViewToolContracts.js +56 -0
- package/dist/contracts/applicationToolContracts.js +5 -4
- package/dist/contracts/artifactComparisonExample.js +2 -2
- package/dist/contracts/artifactToolContracts.js +1 -1
- package/dist/contracts/browserScenarioToolContracts.js +1 -1
- package/dist/contracts/browserToolContracts.js +19 -15
- package/dist/contracts/enhancedInputs.js +7 -5
- package/dist/contracts/enhancedToolContracts.js +7 -6
- package/dist/contracts/evm/evmToolContracts.js +1 -1
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/hopperMemoryContracts.js +2 -5
- package/dist/contracts/inputSchemaPresentation.js +90 -0
- package/dist/contracts/investigationExamples.js +4 -3
- package/dist/contracts/javascript/electronToolContracts.js +2 -2
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
- package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
- package/dist/contracts/managed/managedToolContracts.js +7 -14
- package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
- package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
- package/dist/contracts/native/nativeToolContracts.js +5 -3
- package/dist/contracts/officialToolContracts.js +16 -16
- package/dist/contracts/promptContracts.js +5 -5
- package/dist/contracts/providerSelection.js +1 -1
- package/dist/contracts/sessionLifecycleInputs.js +3 -7
- package/dist/contracts/sessionStatusContract.js +2 -4
- package/dist/contracts/sessionToolContracts.js +18 -8
- package/dist/contracts/sessionToolSchemas.js +3 -19
- package/dist/contracts/toolContractExamples.js +0 -1
- package/dist/contracts/toolContractHelpers.js +4 -1
- package/dist/contracts/toolContracts.js +2 -0
- package/dist/contracts/toolEffects.js +1 -1
- package/dist/contracts/toolOutputSchemaGroups.js +160 -115
- package/dist/contracts/toolOutputSchemaPrimitives.js +28 -20
- package/dist/contracts/toolSchemaMetadata.js +41 -33
- package/dist/contracts/webNetworkCaptureToolContracts.js +2 -2
- package/dist/contracts/webRuntimeToolContracts.js +1 -1
- package/dist/contracts/webScriptToolContracts.js +1 -1
- package/dist/doctorRuntime.js +7 -5
- package/dist/domain/analysisErrorBase.js +8 -3
- package/dist/domain/analysisErrorCore.js +6 -1
- package/dist/domain/analysisErrorPresentation.js +90 -20
- package/dist/domain/analysisErrorProjection.js +130 -32
- package/dist/domain/analysisSnapshot.js +29 -31
- package/dist/domain/analysisView/analysisView.js +243 -0
- package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
- package/dist/domain/analysisView/binaryLayoutView.js +159 -0
- package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
- package/dist/domain/android/androidAnalysis.js +2 -4
- package/dist/domain/android/androidApplication.js +18 -10
- package/dist/domain/apple/appleApplication.js +42 -15
- package/dist/domain/apple/dyldEnvironment.js +73 -0
- package/dist/domain/apple/dylibResolution.js +130 -12
- package/dist/domain/apple/dylibResolutionFindings.js +9 -7
- package/dist/domain/apple/interfaceBuilderGraph.js +25 -14
- package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
- package/dist/domain/apple/keyedArchive.js +35 -3
- package/dist/domain/apple/machoContainer.js +54 -0
- package/dist/domain/apple/plistNumbers.js +76 -0
- package/dist/domain/artifactComparison.js +15 -6
- package/dist/domain/artifactGraph.js +16 -3
- package/dist/domain/artifactIdentity.js +29 -0
- package/dist/domain/artifactInventoryEvidence.js +28 -40
- package/dist/domain/artifactOperationError.js +3 -3
- package/dist/domain/artifactPartialObservation.js +1 -0
- package/dist/domain/artifactPathSyntax.js +49 -0
- package/dist/domain/binaryTarget.js +39 -13
- package/dist/domain/bridgeCandidateProjection.js +71 -0
- package/dist/domain/browserCaptureComparison.js +13 -49
- package/dist/domain/browserCompleteness.js +1 -0
- package/dist/domain/browserNetworkEvidence.js +10 -4
- package/dist/domain/browserObservation.js +0 -1
- package/dist/domain/browserObservationError.js +24 -5
- package/dist/domain/browserObservationSchemas.js +14 -3
- package/dist/domain/browserScenario.js +0 -1
- package/dist/domain/browserScenarioCapture.js +1 -2
- package/dist/domain/browserScenarioDiff.js +0 -2
- package/dist/domain/browserScenarioDiffEvidence.js +0 -12
- package/dist/domain/browserScenarioDiffValues.js +2 -2
- package/dist/domain/browserScenarioValues.js +5 -10
- package/dist/domain/bundleComparison.js +3 -2
- package/dist/domain/callPath.js +8 -9
- package/dist/domain/callPathSchemas.js +2 -2
- package/dist/domain/canonicalJsonDigestSteps.js +133 -0
- package/dist/domain/canonicalOrdering.js +9 -5
- package/dist/domain/changedBehavior.js +9 -9
- package/dist/domain/comparisonSourceEvidence.js +40 -0
- package/dist/domain/completionLedgerGeneration.js +2 -1
- package/dist/domain/configurationErrors.js +13 -1
- package/dist/domain/conformancePackage.js +4 -3
- package/dist/domain/evidence.js +65 -36
- package/dist/domain/evidenceBundle.js +47 -8
- package/dist/domain/evidenceCompletionLedger.js +2 -1
- package/dist/domain/evidenceErrors.js +12 -1
- package/dist/domain/explicitSensitiveFailure.js +17 -1
- package/dist/domain/firmware/firmwareAnalysis.js +6 -7
- package/dist/domain/functionComparison.js +4 -5
- package/dist/domain/functionComparisonDimensions.js +120 -87
- package/dist/domain/functionComparisonNormalization.js +23 -34
- package/dist/domain/functionComparisonResults.js +1 -4
- package/dist/domain/functionComparisonSchemas.js +2 -8
- package/dist/domain/functionDossierEvidence.js +2 -37
- package/dist/domain/hopperErrors.js +23 -2
- package/dist/domain/hopperValues.js +51 -8
- package/dist/domain/immutableJson.js +114 -0
- package/dist/domain/inputIssueProjection.js +3 -0
- package/dist/domain/javascript/electronActiveObservation.js +47 -64
- package/dist/domain/javascript/electronObservation.js +14 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
- package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
- package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +39 -3
- package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
- package/dist/domain/javascript/javascriptAstValues.js +20 -0
- package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
- package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
- package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
- package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
- package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
- package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
- package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
- package/dist/domain/javascript/javascriptRecovery.js +3 -8
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
- package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +106 -5
- package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +23 -6
- package/dist/domain/javascript/javascriptSemanticGraph.js +98 -43
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
- package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +18 -21
- package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
- package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
- package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
- package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
- package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
- package/dist/domain/javascript/javascriptSemanticValues.js +126 -61
- package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
- package/dist/domain/javascript/javascriptSourceParser.js +6 -2
- package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +16 -5
- package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -17
- package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
- package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
- package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
- package/dist/domain/jsonSerialization.js +109 -0
- package/dist/domain/jsonValue.js +90 -6
- package/dist/domain/localPath.js +6 -0
- package/dist/domain/managed/managedApplicationGraph.js +10 -10
- package/dist/domain/managed/managedArtifact.js +6 -4
- package/dist/domain/managed/managedInspectionEvidence.js +16 -0
- package/dist/domain/managed/managedMemberComparison.js +2 -9
- package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
- package/dist/domain/managed/managedNativeVerification.js +3 -11
- package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
- package/dist/domain/native/binaryLayout.js +2 -3
- package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
- package/dist/domain/native/nativeApiBoundary.js +1 -1
- package/dist/domain/native/nativeCallObservation.js +37 -13
- package/dist/domain/native/nativeCallPartialObservation.js +33 -0
- package/dist/domain/native/nativeInstruction.js +7 -0
- package/dist/domain/native/recordedCrash.js +2 -3
- package/dist/domain/offsetDateTime.js +17 -0
- package/dist/domain/process/processCapture.js +21 -16
- package/dist/domain/process/processCaptureCoverage.js +67 -0
- package/dist/domain/process/processCaptureExample.js +2 -1
- package/dist/domain/process/processCaptureParsing.js +1 -34
- package/dist/domain/process/processCaptureValidation.js +81 -13
- package/dist/domain/process/processComparison.js +79 -26
- package/dist/domain/process/processObservation.js +10 -2
- package/dist/domain/process/processScenario.js +35 -12
- package/dist/domain/process/processTraceComparison.js +0 -2
- package/dist/domain/process/processTraceDimensionProjection.js +1 -1
- package/dist/domain/process/processTraceEvaluation.js +15 -11
- package/dist/domain/process/processTraceSpecification.js +3 -4
- package/dist/domain/propertyListKeys.js +1 -1
- package/dist/domain/propertyListXmlText.js +19 -0
- package/dist/domain/providerAdapterError.js +3 -1
- package/dist/domain/providerOperationHealth.js +54 -0
- package/dist/domain/reconstructionCoverage.js +5 -2
- package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
- package/dist/domain/reconstructionReadinessSchemas.js +2 -1
- package/dist/domain/reconstructionVerification.js +9 -46
- package/dist/domain/reconstructionVerificationSchemas.js +4 -3
- package/dist/domain/referenceSourceGraph.js +20 -21
- package/dist/domain/staticRuntimeCorrelation.js +8 -45
- package/dist/domain/stringPatterns.js +6 -0
- package/dist/domain/swiftSymbolClassification.js +61 -0
- package/dist/domain/symbolAnalysis.js +66 -18
- package/dist/domain/webBundleAnalysis.js +20 -8
- package/dist/domain/webBundleAnalyzerInspection.js +13 -8
- package/dist/domain/webBundleAnalyzerResult.js +41 -2
- package/dist/domain/webCaptureDiff.js +0 -1
- package/dist/domain/webCaptureDiffSchemas.js +6 -3
- package/dist/domain/webEventListeners.js +3 -2
- package/dist/domain/webExecution.js +3 -2
- package/dist/domain/webRuntime.js +19 -7
- package/dist/domain/webScriptExport.js +1 -1
- package/dist/domain/webSourceLocation.js +1 -0
- package/dist/dotnet/ManagedArtifactInspector.js +2 -19
- package/dist/dotnet/ManagedMemberInspector.js +12 -18
- package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
- package/dist/dotnet/ManagedMemberRows.js +75 -62
- package/dist/dotnet/ManagedMetadataInventory.js +16 -22
- package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
- package/dist/dotnet/ManagedReaderFailure.js +16 -0
- package/dist/dotnet/ManagedStaticProvider.js +3 -5
- package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
- package/dist/evaluation/AgentEvaluationReport.js +28 -0
- package/dist/evaluation/CodexAgentEval.js +12 -8
- package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
- package/dist/evm/EvmoleInterfaceProvider.js +2 -1
- package/dist/firmware/FirmwareCommand.js +9 -5
- package/dist/firmware/FirmwareFiles.js +1 -1
- package/dist/firmware/FirmwareProvider.js +4 -4
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +7 -5
- package/dist/ghidra/GhidraClient.js +126 -34
- package/dist/ghidra/GhidraClientStartup.js +0 -2
- package/dist/ghidra/GhidraDiagnostics.js +7 -7
- package/dist/ghidra/GhidraDoctor.js +6 -5
- package/dist/ghidra/GhidraFunctionValues.js +13 -12
- package/dist/ghidra/GhidraInstallation.js +58 -33
- package/dist/ghidra/GhidraInventoryValues.js +14 -4
- package/dist/ghidra/GhidraJavaLaunch.js +66 -0
- package/dist/ghidra/GhidraLauncher.js +47 -22
- package/dist/ghidra/GhidraProvider.js +6 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +20 -2
- package/dist/ghidra/GhidraProviderClient.js +36 -15
- package/dist/ghidra/GhidraSessionError.js +13 -7
- package/dist/ghidra/GhidraSessionRoot.js +39 -0
- package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
- package/dist/ghidra/GhidraTransport.js +20 -0
- package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
- package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
- package/dist/hopper/BridgeLauncher.js +65 -56
- package/dist/hopper/HopperAnalysisProfile.js +65 -12
- package/dist/hopper/HopperCleanup.js +63 -22
- package/dist/hopper/HopperClient.js +288 -59
- package/dist/hopper/HopperFileOffset.js +237 -0
- package/dist/hopper/HopperMachOImage.js +197 -0
- package/dist/hopper/HopperOperationStage.js +6 -0
- package/dist/hopper/HopperProvider.js +71 -19
- package/dist/hopper/HopperProviderCapabilities.js +19 -1
- package/dist/hopper/HopperRegexSearch.js +134 -0
- package/dist/hopper/HopperRegexWorker.js +27 -0
- package/dist/hopper/HopperRequestQueue.js +68 -19
- package/dist/hopper/HopperTargetLease.js +133 -49
- package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
- package/dist/ida/IdaConfiguration.js +8 -3
- package/dist/ida/IdaInput.js +1 -7
- package/dist/ida/IdaMcpConnection.js +8 -4
- package/dist/ida/IdaOperationRunner.js +3 -3
- package/dist/ida/IdaProvider.js +8 -12
- package/dist/ida/IdaSessionClient.js +20 -18
- package/dist/ida/IdaWorkspace.js +12 -13
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
- package/dist/inspector/V8InspectorCaptureProjection.js +9 -4
- package/dist/inspector/V8InspectorProvider.js +82 -36
- package/dist/javascript/recovery/WakaruCommand.js +7 -2
- package/dist/javascript/recovery/WakaruExecution.js +5 -2
- package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
- package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -0
- package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
- package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
- package/dist/main/shutdown.js +11 -3
- package/dist/main/startup.js +9 -2
- package/dist/main/transport.js +22 -2
- package/dist/main.js +11 -18
- package/dist/mcpDoctor.js +62 -2
- package/dist/native/AppleDispatchCoverage.js +47 -6
- package/dist/native/AppleDispatchDecodeFacts.js +6 -0
- package/dist/native/AppleDispatchMetadata.js +6 -3
- package/dist/native/AppleMachoFixups.js +48 -24
- package/dist/native/AppleMachoSelection.js +48 -22
- package/dist/native/AppleObjcCategories.js +6 -2
- package/dist/native/AppleObjcDispatchFacets.js +5 -2
- package/dist/native/AppleObjcProperties.js +2 -1
- package/dist/native/AppleSwiftDispatchFacets.js +27 -21
- package/dist/native/AppleSwiftVtables.js +21 -15
- package/dist/native/CommandRunner.js +87 -88
- package/dist/native/LldbCallTracer.js +372 -103
- package/dist/native/LldbRetainedObservations.js +178 -0
- package/dist/native/NativeCallObservation.js +62 -3
- package/dist/native/NativeMacOSProvider.js +122 -31
- package/dist/native/NativeUiHelperRuntime.js +11 -2
- package/dist/native/NativeUiObservation.js +2 -2
- package/dist/native/SignatureTargetBinding.js +155 -0
- package/dist/native/parsers/lipo.js +71 -1
- package/dist/native/pwndbg/PwndbgCoreContext.js +25 -5
- package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
- package/dist/native/pwntools/RecordedCrashStructureBindings.js +2 -0
- package/dist/process/DarwinProcessRunTokenReader.js +23 -10
- package/dist/process/ExecFileOutput.js +108 -6
- package/dist/process/OwnedCommand.js +7 -2
- package/dist/process/PrivateRuntimeRoot.js +10 -5
- package/dist/process/ProcessOwnership.js +204 -57
- package/dist/process/ProcessOwnershipObservation.js +60 -9
- package/dist/process/ProviderProcess.js +39 -10
- package/dist/process/capture/FilesystemSnapshot.js +50 -13
- package/dist/process/capture/ProcessCaptureError.js +15 -2
- package/dist/process/capture/ProcessCaptureLifecycle.js +235 -81
- package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
- package/dist/process/capture/ProcessHarness.js +21 -25
- package/dist/process/capture/ProcessNormalization.js +20 -2
- package/dist/process/capture/ProcessSampling.js +25 -2
- package/dist/process/capture/TerminalRenderer.js +14 -0
- package/dist/process/snapshotEnvironment.js +14 -0
- package/dist/server/EvidenceMcpServer.js +157 -0
- package/dist/server/createServer.js +61 -41
- package/dist/server/mcpClientMetadata.js +12 -5
- package/dist/server/promptCompletion.js +3 -8
- package/dist/server/registerAnalysisViewTool.js +15 -0
- package/dist/server/registerAndroidTools.js +2 -5
- package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
- package/dist/server/registerApplicationTools/compareVersions.js +4 -5
- package/dist/server/registerApplicationTools/coverage.js +1 -2
- package/dist/server/registerApplicationTools/helpers.js +1 -4
- package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
- package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
- package/dist/server/registerApplicationTools/traceFeature.js +4 -5
- package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
- package/dist/server/registerArtifactComparisonTool.js +13 -10
- package/dist/server/registerBinaryDiagnosticsTools.js +2 -5
- package/dist/server/registerBrowserScenarioTool.js +3 -6
- package/dist/server/registerBrowserTools.js +13 -18
- package/dist/server/registerBundleComparisonTool.js +5 -7
- package/dist/server/registerCloseLifecycleTool.js +9 -20
- package/dist/server/registerElectronTools.js +10 -15
- package/dist/server/registerEnhancedTools.js +36 -77
- package/dist/server/registerEvidenceTools.js +3 -6
- package/dist/server/registerEvmTools.js +2 -5
- package/dist/server/registerFirmwareTools.js +2 -5
- package/dist/server/registerFunctionComparisonTool.js +15 -12
- package/dist/server/registerInvestigationTools.js +16 -17
- package/dist/server/registerJavaScriptRecoveryTool.js +2 -5
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -8
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -8
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -7
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -9
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -9
- package/dist/server/registerOfficialTools.js +4 -21
- package/dist/server/registerProcessComparisonTool.js +74 -48
- package/dist/server/registerRecordedCrashTools.js +2 -5
- package/dist/server/registerSessionRecordTools.js +19 -24
- package/dist/server/registerSessionStatusTool.js +19 -6
- package/dist/server/registerSessionTools.js +20 -18
- package/dist/server/registerWebModuleTool.js +2 -5
- package/dist/server/registerWebNetworkCaptureTool.js +2 -5
- package/dist/server/registerWebRuntimeTools.js +4 -9
- package/dist/server/registerWebScriptTool.js +2 -5
- package/dist/server/registerWebSourceLocationTool.js +2 -5
- package/dist/server/runDerivedOperation.js +15 -3
- package/dist/server/sessionAvailabilityPolicy.js +0 -1
- package/dist/server/toolRegistrationOptions.js +2 -2
- package/dist/server/toolResult.js +75 -51
- package/dist/server/toolResultEncoding.js +34 -0
- package/dist/windows/WindowsNativeLoader.js +1 -0
- package/dist/windows/WindowsOwnedProcess.js +60 -15
- package/dist/windows/WindowsPrivateRuntime.js +7 -8
- package/install.sh +1 -1
- package/native/windows/README.md +3 -1
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +44 -30
- package/scripts/electron-active-hook-boundaries.cjs +18 -20
- package/scripts/electron-active-hook.cjs +241 -37
- package/scripts/rea.mjs +3 -6
- package/skills/reverse-engineer-anything/SKILL.md +12 -3
- package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
- package/skills/reverse-engineer-anything/references/javascript-applications.md +20 -3
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
- package/dist/config.js +0 -1
- package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
- package/dist/contracts/process/processCaptureExample.js +0 -2
- package/dist/contracts/toolOutputSchemas.js +0 -2
- package/dist/ghidra/GhidraDefaults.js +0 -2
- package/dist/main/reload.js +0 -12
- package/dist/main/state.js +0 -3
- package/dist/server/sessionToolPolicies.js +0 -2
|
@@ -1,10 +1,18 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { compatibleSlice, directoryOf, expandPrefix, joinPath, resolveTreePath, } from "./dyldPaths.js";
|
|
3
3
|
import { digestSchema } from "../digests.js";
|
|
4
|
+
import { hasApplicableDyldOverrides, embeddedDyldOverrides, } from "./dyldEnvironment.js";
|
|
4
5
|
import { DYLIB_RESOLUTION_LIMITATIONS, deriveFindings, } from "./dylibResolutionFindings.js";
|
|
5
|
-
/**
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Normalized path below the analyzed root: nonempty segments joined by single
|
|
8
|
+
* `/`, none of them `.` or `..`, without backslash or NUL. Advertised schema
|
|
9
|
+
* patterns avoid look-around, which RE2 and Rust validators reject.
|
|
10
|
+
*/
|
|
11
|
+
const ROOT_RELATIVE_PATH = /^(?:[^\x2f\\\u0000.][^\x2f\\\u0000]*|\.[^\x2f\\\u0000.][^\x2f\\\u0000]*|\.\.[^\x2f\\\u0000]+)(?:\x2f(?:[^\x2f\\\u0000.][^\x2f\\\u0000]*|\.[^\x2f\\\u0000.][^\x2f\\\u0000]*|\.\.[^\x2f\\\u0000]+))*$/u;
|
|
12
|
+
const rootRelativePathSchema = z
|
|
13
|
+
.string()
|
|
14
|
+
.min(1)
|
|
15
|
+
.regex(ROOT_RELATIVE_PATH, "Use a normalized path relative to the analyzed root, without a leading or trailing '/', '//', or '.' and '..' segments");
|
|
8
16
|
/** Caller selection of process roots and one CPU slice. */
|
|
9
17
|
export const dylibResolutionInputSchema = z.strictObject({
|
|
10
18
|
roots: z.array(rootRelativePathSchema).min(1).optional(),
|
|
@@ -31,7 +39,20 @@ const dependencySchema = z.strictObject({
|
|
|
31
39
|
/** Observed dylib-loading facts of one Mach-O slice. */
|
|
32
40
|
export const machoSliceSchema = z.strictObject({
|
|
33
41
|
architecture: z.string().min(1),
|
|
42
|
+
/** Physical identity observed in the thin header and, for FAT, its table. */
|
|
43
|
+
slice_offset: z.number().int().nonnegative(),
|
|
44
|
+
slice_size: z.number().int().positive(),
|
|
45
|
+
cpu_type: z.number().int().nonnegative(),
|
|
46
|
+
cpu_subtype: z.number().int().nonnegative(),
|
|
47
|
+
fat_cpu_type: z.number().int().nonnegative().nullable(),
|
|
48
|
+
fat_cpu_subtype: z.number().int().nonnegative().nullable(),
|
|
49
|
+
fat_alignment_exponent: z.number().int().nonnegative().nullable(),
|
|
34
50
|
file_type: z.enum(["execute", "dylib", "bundle", "other"]),
|
|
51
|
+
file_type_code: z.number().int().nonnegative(),
|
|
52
|
+
/** Raw LC_BUILD_VERSION platform number; null means no such command was observed. */
|
|
53
|
+
platform: z.number().int().nonnegative().nullable(),
|
|
54
|
+
/** Every distinct build platform declared by LC_BUILD_VERSION/version-min commands. */
|
|
55
|
+
platforms: z.array(z.number().int().nonnegative()),
|
|
35
56
|
install_name: z.string().nullable(),
|
|
36
57
|
dependencies: z.array(dependencySchema),
|
|
37
58
|
rpaths: z.array(z.string()),
|
|
@@ -56,6 +77,8 @@ const candidateSchema = z.strictObject({
|
|
|
56
77
|
"malformed",
|
|
57
78
|
"unsupported",
|
|
58
79
|
"architecture-missing",
|
|
80
|
+
"not-loadable",
|
|
81
|
+
"platform-mismatch",
|
|
59
82
|
"outside-target",
|
|
60
83
|
"escapes-target",
|
|
61
84
|
"undetermined",
|
|
@@ -168,13 +191,65 @@ const evaluateCandidate = async (template, context) => {
|
|
|
168
191
|
if (lookup.kind !== "file")
|
|
169
192
|
return { ...base, outcome: "absent", resolved_path: null };
|
|
170
193
|
const facts = await imageFacts(context, lookup.path);
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
194
|
+
let outcome;
|
|
195
|
+
if (facts.status !== "parsed")
|
|
196
|
+
outcome = facts.status;
|
|
197
|
+
else {
|
|
198
|
+
const slice = compatibleSlice(facts.slices, context.architecture);
|
|
199
|
+
if (slice === undefined)
|
|
200
|
+
outcome = "architecture-missing";
|
|
201
|
+
// Dependency commands require a dylib; generic dyld image loadability
|
|
202
|
+
// also admits main executables and bundles for different operations.
|
|
203
|
+
else if (slice.file_type_code !== 6)
|
|
204
|
+
outcome = "not-loadable";
|
|
205
|
+
else {
|
|
206
|
+
const platformResult = platformLoadability(context.platforms, slice.platforms, slice.file_type_code, context.architecture);
|
|
207
|
+
outcome =
|
|
208
|
+
platformResult === "compatible"
|
|
209
|
+
? "resolved"
|
|
210
|
+
: platformResult === "incompatible"
|
|
211
|
+
? "platform-mismatch"
|
|
212
|
+
: "undetermined";
|
|
213
|
+
}
|
|
214
|
+
}
|
|
176
215
|
return { ...base, outcome, resolved_path: lookup.path };
|
|
177
216
|
};
|
|
217
|
+
/** Apply dyld's documented cross-platform load cases and retain uncertain host cases. */
|
|
218
|
+
const platformLoadability = (processPlatforms, imagePlatforms, fileType, architecture) => {
|
|
219
|
+
if (processPlatforms.length === 0 || imagePlatforms.length === 0)
|
|
220
|
+
return "unknown";
|
|
221
|
+
const outcomes = processPlatforms.map((processPlatform) => imageLoadabilityForPlatform(processPlatform, imagePlatforms, fileType, architecture));
|
|
222
|
+
if (outcomes.every((outcome) => outcome === "compatible"))
|
|
223
|
+
return "compatible";
|
|
224
|
+
if (outcomes.every((outcome) => outcome === "incompatible"))
|
|
225
|
+
return "incompatible";
|
|
226
|
+
return "unknown";
|
|
227
|
+
};
|
|
228
|
+
const imageLoadabilityForPlatform = (processPlatform, imagePlatforms, fileType, architecture) => {
|
|
229
|
+
if (imagePlatforms.includes(processPlatform))
|
|
230
|
+
return "compatible";
|
|
231
|
+
// These are explicit dyld loadableIntoProcess cross-platform cases.
|
|
232
|
+
if (processPlatform === 6 && imagePlatforms.includes(1))
|
|
233
|
+
return "compatible"; // macOS dylibs in Mac Catalyst processes
|
|
234
|
+
if (processPlatform === 2 && imagePlatforms.includes(6))
|
|
235
|
+
return "compatible"; // Catalyst dylibs in iOS processes
|
|
236
|
+
if (processPlatform === 2 && imagePlatforms.includes(11))
|
|
237
|
+
return "compatible"; // visionOS dylibs in iOS processes
|
|
238
|
+
if (processPlatform === 7 && imagePlatforms.includes(12))
|
|
239
|
+
return "compatible"; // visionOS simulator dylibs in iOS simulator processes
|
|
240
|
+
if (processPlatform === 1 && fileType === 2 && imagePlatforms.includes(6))
|
|
241
|
+
return "compatible"; // Catalyst main executables run on macOS
|
|
242
|
+
// dyld's remaining exceptions depend on host architecture or a special path.
|
|
243
|
+
if ((processPlatform === 2 &&
|
|
244
|
+
imagePlatforms.includes(1) &&
|
|
245
|
+
architecture.startsWith("arm64")) ||
|
|
246
|
+
([7, 8, 9].includes(processPlatform) && imagePlatforms.includes(1)))
|
|
247
|
+
return "unknown";
|
|
248
|
+
if (isKnownPlatform(processPlatform) && imagePlatforms.every(isKnownPlatform))
|
|
249
|
+
return "incompatible";
|
|
250
|
+
return "unknown";
|
|
251
|
+
};
|
|
252
|
+
const isKnownPlatform = (platform) => platform >= 1 && platform <= 12;
|
|
178
253
|
const imageFacts = async (context, path) => {
|
|
179
254
|
const known = context.images.get(path);
|
|
180
255
|
if (known !== undefined)
|
|
@@ -222,7 +297,19 @@ const resolveDependency = async (dependency, loader, context) => {
|
|
|
222
297
|
if (candidate.outcome === "resolved")
|
|
223
298
|
break;
|
|
224
299
|
}
|
|
225
|
-
const
|
|
300
|
+
const modeled = resolution(candidates);
|
|
301
|
+
const searchUnknown = loaded === undefined &&
|
|
302
|
+
hasApplicableDyldOverrides(context.searchOverrides, dependency.install_name, modeled.image !== null);
|
|
303
|
+
if (searchUnknown)
|
|
304
|
+
context.environmentRoots.add(context.root);
|
|
305
|
+
// Fallbacks cannot preempt a modeled hit, and framework paths do not
|
|
306
|
+
// override ordinary dylibs. Reuse inherits uncertainty from the first load.
|
|
307
|
+
const searched = searchUnknown
|
|
308
|
+
? {
|
|
309
|
+
...modeled,
|
|
310
|
+
status: modeled.image === null ? "undetermined" : "conditional",
|
|
311
|
+
}
|
|
312
|
+
: modeled;
|
|
226
313
|
// Reusing an image that itself loads only conditionally is conditional too.
|
|
227
314
|
const resolved = loaded !== undefined &&
|
|
228
315
|
context.loaded.get(loaded)?.conditional === true &&
|
|
@@ -306,6 +393,7 @@ export const traceDylibLoading = async (view, request) => {
|
|
|
306
393
|
const roots = [];
|
|
307
394
|
const edges = [];
|
|
308
395
|
const withoutArchitecture = [];
|
|
396
|
+
const environmentRoots = new Set();
|
|
309
397
|
for (const root of request.roots) {
|
|
310
398
|
const facts = await view.image(root);
|
|
311
399
|
images.set(root, facts);
|
|
@@ -316,12 +404,23 @@ export const traceDylibLoading = async (view, request) => {
|
|
|
316
404
|
if (slices.length === 0)
|
|
317
405
|
withoutArchitecture.push(root);
|
|
318
406
|
for (const slice of slices) {
|
|
407
|
+
const executable = slice.file_type === "execute" ? root : null;
|
|
408
|
+
// Only the main executable supplies the process's embedded environment.
|
|
409
|
+
const searchOverrides = executable === null
|
|
410
|
+
? []
|
|
411
|
+
: embeddedDyldOverrides(slice.dyld_environment, slice.platforms);
|
|
412
|
+
// Inserted libraries introduce unexamined images even without dependencies.
|
|
413
|
+
if (searchOverrides.some(({ variable, value }) => variable === "DYLD_INSERT_LIBRARIES" && value !== ""))
|
|
414
|
+
environmentRoots.add(root);
|
|
319
415
|
roots.push({ image: root, architecture: slice.architecture });
|
|
320
416
|
edges.push(...(await traceProcess({
|
|
321
417
|
view,
|
|
322
418
|
root,
|
|
323
419
|
architecture: slice.architecture,
|
|
324
|
-
|
|
420
|
+
searchOverrides,
|
|
421
|
+
environmentRoots,
|
|
422
|
+
platforms: slice.platforms,
|
|
423
|
+
executable,
|
|
325
424
|
loaded: new Map(),
|
|
326
425
|
byInstallName: new Map(),
|
|
327
426
|
images,
|
|
@@ -347,18 +446,37 @@ export const traceDylibLoading = async (view, request) => {
|
|
|
347
446
|
edges,
|
|
348
447
|
findings: deriveFindings(edges, roots, images),
|
|
349
448
|
coverage: {
|
|
350
|
-
status: unparsed.length === 0 &&
|
|
449
|
+
status: unparsed.length === 0 &&
|
|
450
|
+
withoutArchitecture.length === 0 &&
|
|
451
|
+
environmentRoots.size === 0
|
|
351
452
|
? "complete"
|
|
352
453
|
: "partial",
|
|
353
454
|
unparsed_images: unparsed,
|
|
354
455
|
roots_without_architecture: withoutArchitecture,
|
|
355
456
|
},
|
|
356
|
-
limitations:
|
|
457
|
+
limitations: [
|
|
458
|
+
...DYLIB_RESOLUTION_LIMITATIONS,
|
|
459
|
+
...(environmentRoots.size === 0
|
|
460
|
+
? []
|
|
461
|
+
: [
|
|
462
|
+
`Roots ${[...environmentRoots].join(", ")} request applicable image-selection inputs through LC_DYLD_ENVIRONMENT that are not modeled; affected dependencies or inserted images remain uncertain.`,
|
|
463
|
+
]),
|
|
464
|
+
],
|
|
357
465
|
};
|
|
358
466
|
};
|
|
359
467
|
const withoutDependencies = (slice) => ({
|
|
360
468
|
architecture: slice.architecture,
|
|
469
|
+
slice_offset: slice.slice_offset,
|
|
470
|
+
slice_size: slice.slice_size,
|
|
471
|
+
cpu_type: slice.cpu_type,
|
|
472
|
+
cpu_subtype: slice.cpu_subtype,
|
|
473
|
+
fat_cpu_type: slice.fat_cpu_type,
|
|
474
|
+
fat_cpu_subtype: slice.fat_cpu_subtype,
|
|
475
|
+
fat_alignment_exponent: slice.fat_alignment_exponent,
|
|
361
476
|
file_type: slice.file_type,
|
|
477
|
+
file_type_code: slice.file_type_code,
|
|
478
|
+
platform: slice.platform,
|
|
479
|
+
platforms: slice.platforms,
|
|
362
480
|
install_name: slice.install_name,
|
|
363
481
|
rpaths: slice.rpaths,
|
|
364
482
|
dyld_environment: slice.dyld_environment,
|
|
@@ -14,22 +14,24 @@ export const deriveFindings = (edges, roots, images) => {
|
|
|
14
14
|
edge_index: index,
|
|
15
15
|
image: edge.loader,
|
|
16
16
|
basis: "derived",
|
|
17
|
-
explanation: `dyld
|
|
17
|
+
explanation: `The modeled dyld search checks ${earlier.join(", ")} before ${edge.resolution.image ?? edge.install_name}. A compatible Mach-O placed at an earlier modeled path could take precedence over that fallback, subject to unmodeled search inputs and code-signing library validation; library validation is not evaluated here (see inspect_signature).${edge.loader_conditional ? " This loader loads only conditionally; if it never loads, this search never occurs." : ""}${edge.resolution.status === "conditional" ? " Unmodeled environment overrides or earlier unknown candidates may take precedence; placing an image at this rpath does not establish which image dyld will load." : ""}`,
|
|
18
18
|
});
|
|
19
19
|
});
|
|
20
20
|
for (const { image, architecture } of roots) {
|
|
21
21
|
const facts = images.get(image);
|
|
22
|
-
const
|
|
23
|
-
?
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const slice = facts?.status === "parsed"
|
|
23
|
+
? facts.slices.find((candidate) => candidate.architecture === architecture)
|
|
24
|
+
: undefined;
|
|
25
|
+
const environment = slice?.dyld_environment ?? [];
|
|
26
26
|
if (environment.length > 0)
|
|
27
27
|
findings.push({
|
|
28
28
|
kind: "dyld-environment-present",
|
|
29
29
|
edge_index: null,
|
|
30
30
|
image,
|
|
31
31
|
basis: "derived",
|
|
32
|
-
explanation:
|
|
32
|
+
explanation: slice?.file_type === "execute"
|
|
33
|
+
? `${image} (${architecture}) sets dyld environment variables through LC_DYLD_ENVIRONMENT (${environment.join(", ")}); any image-selection overrides they request are not modeled. Diagnostic settings alone do not alter resolution.`
|
|
34
|
+
: `${image} (${architecture}) contains LC_DYLD_ENVIRONMENT (${environment.join(", ")}). Dyld reads these commands only from the main executable; entries in this non-executable root are observations and do not alter resolution.`,
|
|
33
35
|
});
|
|
34
36
|
}
|
|
35
37
|
return findings;
|
|
@@ -60,7 +62,7 @@ const unresolvedFinding = (edge, index) => {
|
|
|
60
62
|
: {
|
|
61
63
|
...base,
|
|
62
64
|
kind: "required-load-unresolved",
|
|
63
|
-
explanation: `${missing}${when}dyld would fail to
|
|
65
|
+
explanation: `${missing}${when}dyld would fail to load this required dependency for ${edge.root} (${edge.architecture}) unless the image is supplied elsewhere.`,
|
|
64
66
|
};
|
|
65
67
|
};
|
|
66
68
|
export const DYLIB_RESOLUTION_LIMITATIONS = [
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { firstString, parseInterfaceBuilderRecords, record, } from "./interfaceBuilderKeyedArchive.js";
|
|
3
3
|
import { nativeInvestigationEdgeSchema, nativeInvestigationGraphSchema, nativeInvestigationNodeSchema, nativeInvestigationTraceLimitsSchema, } from "../native/nativeInvestigationGraph.js";
|
|
4
|
-
export { parseInterfaceBuilderRecords } from "./interfaceBuilderKeyedArchive.js";
|
|
5
4
|
/** One compiled Interface Builder document projected from ibtool output. */
|
|
6
5
|
export const interfaceBuilderDocumentSchema = z.strictObject({
|
|
7
6
|
relative_path: z.string().min(1),
|
|
@@ -28,6 +27,7 @@ export const buildInterfaceBuilderAnalysis = (input) => {
|
|
|
28
27
|
let omittedObjects = 0;
|
|
29
28
|
let omittedConnections = 0;
|
|
30
29
|
let omittedGraphNodes = 0;
|
|
30
|
+
let omittedHierarchyReferences = 0;
|
|
31
31
|
for (const document of input.documents.slice(0, input.limits.max_documents)) {
|
|
32
32
|
const parsed = parseInterfaceBuilderRecords(document.raw);
|
|
33
33
|
const prefix = `ib:${document.relativePath}:`;
|
|
@@ -276,6 +276,8 @@ export const buildInterfaceBuilderAnalysis = (input) => {
|
|
|
276
276
|
}
|
|
277
277
|
}
|
|
278
278
|
const objectsTruncated = parsed.omittedObjects > 0 || parsed.objects.length > documentObjectCount;
|
|
279
|
+
const parserOmittedHierarchyReferences = parsed.omittedHierarchyReferences;
|
|
280
|
+
omittedHierarchyReferences += parserOmittedHierarchyReferences;
|
|
279
281
|
const parserOmittedConnections = parsed.omittedConnections;
|
|
280
282
|
const connectionsTruncated = parserOmittedConnections > 0 ||
|
|
281
283
|
parsed.connections.length > input.limits.max_connections;
|
|
@@ -291,7 +293,9 @@ export const buildInterfaceBuilderAnalysis = (input) => {
|
|
|
291
293
|
document_kind: document.documentKind,
|
|
292
294
|
object_count: parsed.objectCount,
|
|
293
295
|
connection_count: parsed.connections.length + parserOmittedConnections,
|
|
294
|
-
hierarchy_complete: parsed.hierarchy.length > 0 &&
|
|
296
|
+
hierarchy_complete: parsed.hierarchy.length > 0 &&
|
|
297
|
+
!truncated &&
|
|
298
|
+
parserOmittedHierarchyReferences === 0,
|
|
295
299
|
});
|
|
296
300
|
coverage.push({
|
|
297
301
|
facet: `objects:${document.relativePath}`,
|
|
@@ -314,18 +318,22 @@ export const buildInterfaceBuilderAnalysis = (input) => {
|
|
|
314
318
|
parserOmittedConnections,
|
|
315
319
|
}, {
|
|
316
320
|
facet: `hierarchy:${document.relativePath}`,
|
|
317
|
-
status:
|
|
318
|
-
? "
|
|
319
|
-
:
|
|
320
|
-
? "
|
|
321
|
-
:
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
321
|
+
status: parserOmittedHierarchyReferences > 0
|
|
322
|
+
? "partial"
|
|
323
|
+
: parsed.hierarchy.length === 0
|
|
324
|
+
? "unsupported"
|
|
325
|
+
: hierarchyTruncated || documentOmittedHierarchyEdges > 0
|
|
326
|
+
? "partial"
|
|
327
|
+
: "complete",
|
|
328
|
+
reason: parserOmittedHierarchyReferences > 0
|
|
329
|
+
? "archive_hierarchy_references_missing"
|
|
330
|
+
: parsed.hierarchy.length === 0
|
|
331
|
+
? "archive_hierarchy_not_decoded"
|
|
332
|
+
: hierarchyTruncated || documentOmittedHierarchyEdges > 0
|
|
333
|
+
? "graph_limit_reached"
|
|
334
|
+
: null,
|
|
327
335
|
examined: hierarchyCount,
|
|
328
|
-
omitted: documentOmittedHierarchyEdges,
|
|
336
|
+
omitted: documentOmittedHierarchyEdges + parserOmittedHierarchyReferences,
|
|
329
337
|
}, {
|
|
330
338
|
facet: `classes:${document.relativePath}`,
|
|
331
339
|
status: Object.keys(parsed.classes).length > 0 ? "complete" : "unsupported",
|
|
@@ -367,7 +375,10 @@ export const buildInterfaceBuilderAnalysis = (input) => {
|
|
|
367
375
|
nodes: [...nodes.values()],
|
|
368
376
|
edges,
|
|
369
377
|
coverage,
|
|
370
|
-
truncated: truncated ||
|
|
378
|
+
truncated: truncated ||
|
|
379
|
+
omittedObjects > 0 ||
|
|
380
|
+
omittedConnections > 0 ||
|
|
381
|
+
omittedHierarchyReferences > 0,
|
|
371
382
|
},
|
|
372
383
|
limitations: [
|
|
373
384
|
"The graph reflects recognized Interface Builder archive fields and connections; omitted private or unrecognized archive fields remain unknown.",
|
|
@@ -82,6 +82,7 @@ export const parseInterfaceBuilderRecords = (value) => {
|
|
|
82
82
|
objectCount: objectEntries.length,
|
|
83
83
|
omittedObjects: Math.max(0, objectEntries.length - 20_000),
|
|
84
84
|
omittedConnections,
|
|
85
|
+
omittedHierarchyReferences: 0,
|
|
85
86
|
};
|
|
86
87
|
};
|
|
87
88
|
/**
|
|
@@ -164,6 +165,7 @@ const keyedArchiveTable = (objectTable) => {
|
|
|
164
165
|
return output;
|
|
165
166
|
};
|
|
166
167
|
const hierarchy = (start) => {
|
|
168
|
+
let omittedReferences = 0;
|
|
167
169
|
const visited = new Set();
|
|
168
170
|
const root = [];
|
|
169
171
|
const pending = [
|
|
@@ -190,10 +192,17 @@ const keyedArchiveTable = (objectTable) => {
|
|
|
190
192
|
const { value, output } = entry;
|
|
191
193
|
const uid = archiveUid(value);
|
|
192
194
|
if (uid !== undefined) {
|
|
195
|
+
// UID0 is archived nil, not a missing hierarchy object.
|
|
196
|
+
if (uid === 0)
|
|
197
|
+
continue;
|
|
198
|
+
const target = objectTable[uid];
|
|
199
|
+
if (target === undefined) {
|
|
200
|
+
omittedReferences += 1;
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
193
203
|
if (visited.has(uid))
|
|
194
204
|
continue;
|
|
195
205
|
visited.add(uid);
|
|
196
|
-
const target = objectTable[uid];
|
|
197
206
|
if (Array.isArray(target)) {
|
|
198
207
|
for (let index = target.length - 1; index >= 0; index -= 1) {
|
|
199
208
|
const child = target[index];
|
|
@@ -229,7 +238,7 @@ const keyedArchiveTable = (objectTable) => {
|
|
|
229
238
|
appendNode(record(value), undefined, output);
|
|
230
239
|
}
|
|
231
240
|
}
|
|
232
|
-
return root;
|
|
241
|
+
return { items: root, omittedReferences };
|
|
233
242
|
};
|
|
234
243
|
const archivedArrayClass = (classReference) => {
|
|
235
244
|
const uid = archiveUid(classReference);
|
|
@@ -317,11 +326,12 @@ const parseKeyedArchive = (root) => {
|
|
|
317
326
|
return {
|
|
318
327
|
objects,
|
|
319
328
|
connections,
|
|
320
|
-
hierarchy,
|
|
329
|
+
hierarchy: hierarchy.items,
|
|
321
330
|
classes,
|
|
322
331
|
objectCount,
|
|
323
332
|
omittedObjects: Math.max(0, objectCount - 20_000),
|
|
324
333
|
omittedConnections,
|
|
334
|
+
omittedHierarchyReferences: hierarchy.omittedReferences,
|
|
325
335
|
};
|
|
326
336
|
};
|
|
327
337
|
/** Coerce unknown values to a string-keyed record; non-objects become `{}`. */
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
+
import { AnalysisInputError } from "../analysisErrorCore.js";
|
|
2
3
|
import { jsonValueSchema } from "../jsonValue.js";
|
|
4
|
+
/**
|
|
5
|
+
* The selected file is intact but is another kind of file, so another tool
|
|
6
|
+
* applies. A malformed NSKeyedArchiver archive is not this error.
|
|
7
|
+
*/
|
|
8
|
+
export class KeyedArchiveKindError extends TypeError {
|
|
9
|
+
kind;
|
|
10
|
+
name = "KeyedArchiveKindError";
|
|
11
|
+
constructor(message,
|
|
12
|
+
/** What the selected file is instead. */
|
|
13
|
+
kind) {
|
|
14
|
+
super(message);
|
|
15
|
+
this.kind = kind;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
3
18
|
/** Select one archive within the active bundle and optionally one named root. */
|
|
4
19
|
export const keyedArchiveInputSchema = z.strictObject({
|
|
5
20
|
path: z.string().min(1).default("."),
|
|
@@ -59,11 +74,21 @@ const uid = (value) => {
|
|
|
59
74
|
const marker = Object.hasOwn(object, "UID") ? object.UID : object["CF$UID"];
|
|
60
75
|
return typeof marker === "number" ? marker : undefined;
|
|
61
76
|
};
|
|
77
|
+
const archiverMismatch = (archive) => {
|
|
78
|
+
if (archive === undefined)
|
|
79
|
+
return "its root is not a dictionary";
|
|
80
|
+
if (!Object.hasOwn(archive, "$archiver"))
|
|
81
|
+
return "it has no $archiver key";
|
|
82
|
+
return typeof archive.$archiver === "string"
|
|
83
|
+
? `its $archiver is ${JSON.stringify(archive.$archiver)}`
|
|
84
|
+
: "its $archiver is not a string";
|
|
85
|
+
};
|
|
62
86
|
/** Interpret serialized Foundation references without instantiating archive classes. */
|
|
63
87
|
export const projectKeyedArchive = (value, selection) => {
|
|
64
88
|
const archive = record(jsonValueSchema.parse(value));
|
|
65
|
-
if (archive?.$archiver !== "NSKeyedArchiver"
|
|
66
|
-
|
|
89
|
+
if (archive?.$archiver !== "NSKeyedArchiver")
|
|
90
|
+
throw new KeyedArchiveKindError(`Selected property list is not an NSKeyedArchiver archive: ${archiverMismatch(archive)}`, "property-list");
|
|
91
|
+
if (!Array.isArray(archive.$objects))
|
|
67
92
|
throw new TypeError("Expected NSKeyedArchiver with an $objects array");
|
|
68
93
|
const table = archive.$objects;
|
|
69
94
|
if (table.length > 200_000)
|
|
@@ -72,7 +97,14 @@ export const projectKeyedArchive = (value, selection) => {
|
|
|
72
97
|
if (top === undefined || Object.keys(top).length === 0)
|
|
73
98
|
throw new TypeError("Keyed archive has no $top roots");
|
|
74
99
|
if (selection.root !== undefined && !Object.hasOwn(top, selection.root))
|
|
75
|
-
throw new
|
|
100
|
+
throw new AnalysisInputError("inspect_keyed_archive", undefined, [
|
|
101
|
+
{
|
|
102
|
+
path: ["root"],
|
|
103
|
+
reason: "invalid_value",
|
|
104
|
+
message: `Archive root does not exist: ${selection.root}. Select one of the archive's $top roots or omit root.`,
|
|
105
|
+
expected: Object.keys(top),
|
|
106
|
+
},
|
|
107
|
+
]);
|
|
76
108
|
const roots = selection.root === undefined
|
|
77
109
|
? top
|
|
78
110
|
: { [selection.root]: top[selection.root] ?? null };
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/** Decode FAT table entries once so artifact and native readers share identity facts. */
|
|
2
|
+
export const readFatSliceDeclarations = (tableBytes, options) => {
|
|
3
|
+
const { count, wide, littleEndian } = options;
|
|
4
|
+
const entrySize = wide ? 32 : 20;
|
|
5
|
+
if (tableBytes.byteLength < count * entrySize)
|
|
6
|
+
return { status: "malformed", reason: "FAT table is truncated" };
|
|
7
|
+
const view = new DataView(tableBytes.buffer, tableBytes.byteOffset, tableBytes.byteLength);
|
|
8
|
+
const slices = [];
|
|
9
|
+
for (let index = 0; index < count; index++) {
|
|
10
|
+
const base = index * entrySize;
|
|
11
|
+
const offset = wide
|
|
12
|
+
? safeNumber(view.getBigUint64(base + 8, littleEndian))
|
|
13
|
+
: view.getUint32(base + 8, littleEndian);
|
|
14
|
+
const size = wide
|
|
15
|
+
? safeNumber(view.getBigUint64(base + 16, littleEndian))
|
|
16
|
+
: view.getUint32(base + 12, littleEndian);
|
|
17
|
+
if (offset === null || size === null)
|
|
18
|
+
return {
|
|
19
|
+
status: "malformed",
|
|
20
|
+
reason: "FAT offset or size exceeds the safe range",
|
|
21
|
+
};
|
|
22
|
+
slices.push({
|
|
23
|
+
index,
|
|
24
|
+
offset,
|
|
25
|
+
size,
|
|
26
|
+
alignmentExponent: view.getUint32(base + (wide ? 24 : 16), littleEndian),
|
|
27
|
+
cpuType: view.getUint32(base, littleEndian),
|
|
28
|
+
cpuSubtype: view.getUint32(base + 4, littleEndian),
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return { status: "parsed", slices };
|
|
32
|
+
};
|
|
33
|
+
/** Validate byte-range and table/header identity facts shared by Mach-O readers. */
|
|
34
|
+
export const validateFatSlice = (declaration, containerSize, tableEnd, embedded) => {
|
|
35
|
+
const { index, offset, size, alignmentExponent, cpuType, cpuSubtype } = declaration;
|
|
36
|
+
if (!Number.isSafeInteger(offset) ||
|
|
37
|
+
!Number.isSafeInteger(size) ||
|
|
38
|
+
size <= 0 ||
|
|
39
|
+
offset < tableEnd)
|
|
40
|
+
return `FAT architecture ${index} has an invalid slice range`;
|
|
41
|
+
if (offset > containerSize || size > containerSize - offset)
|
|
42
|
+
return `FAT architecture ${index} slice range extends beyond the file`;
|
|
43
|
+
if (!Number.isInteger(alignmentExponent) ||
|
|
44
|
+
alignmentExponent < 0 ||
|
|
45
|
+
alignmentExponent > 52)
|
|
46
|
+
return `FAT architecture ${index} alignment exponent ${alignmentExponent} is unsupported`;
|
|
47
|
+
if (offset % 2 ** alignmentExponent !== 0)
|
|
48
|
+
return `FAT architecture ${index} offset is not aligned to 2^${alignmentExponent}`;
|
|
49
|
+
if (embedded !== undefined &&
|
|
50
|
+
(embedded.cpuType !== cpuType || embedded.cpuSubtype !== cpuSubtype))
|
|
51
|
+
return `FAT architecture ${index} CPU type/subtype disagrees with its Mach-O header`;
|
|
52
|
+
return null;
|
|
53
|
+
};
|
|
54
|
+
const safeNumber = (value) => value > BigInt(Number.MAX_SAFE_INTEGER) ? null : Number(value);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/** Preserve unambiguous exact integers; disclose rounded or unclassified numbers. */
|
|
2
|
+
export const createPlistNumberProjection = (literals) => {
|
|
3
|
+
let exactIntegerCount = 0;
|
|
4
|
+
let ambiguousNumberCount = 0;
|
|
5
|
+
const mapNumber = (item) => {
|
|
6
|
+
if (Number.isSafeInteger(item) || !Number.isInteger(item))
|
|
7
|
+
return item;
|
|
8
|
+
if (literals.incomplete) {
|
|
9
|
+
ambiguousNumberCount += 1;
|
|
10
|
+
return item;
|
|
11
|
+
}
|
|
12
|
+
const decimals = literals.integers.get(item);
|
|
13
|
+
if (decimals === undefined) {
|
|
14
|
+
if (!literals.reals.has(item))
|
|
15
|
+
ambiguousNumberCount += 1;
|
|
16
|
+
return item;
|
|
17
|
+
}
|
|
18
|
+
const [decimal] = decimals;
|
|
19
|
+
if (decimals.size !== 1 ||
|
|
20
|
+
decimal === undefined ||
|
|
21
|
+
literals.reals.has(item)) {
|
|
22
|
+
ambiguousNumberCount += 1;
|
|
23
|
+
return item;
|
|
24
|
+
}
|
|
25
|
+
exactIntegerCount += 1;
|
|
26
|
+
return { $plist_type: "integer", decimal };
|
|
27
|
+
};
|
|
28
|
+
const map = (item) => {
|
|
29
|
+
if (typeof item === "number")
|
|
30
|
+
return mapNumber(item);
|
|
31
|
+
if (Array.isArray(item))
|
|
32
|
+
return item.map(map);
|
|
33
|
+
if (item !== null && typeof item === "object") {
|
|
34
|
+
const keys = Object.keys(item);
|
|
35
|
+
const marker = item[keys[0] ?? ""];
|
|
36
|
+
const reference = keys.length === 1 &&
|
|
37
|
+
(keys[0] === "UID" || keys[0] === "CF$UID") &&
|
|
38
|
+
typeof marker === "number";
|
|
39
|
+
if (reference) {
|
|
40
|
+
// Keep malformed numeric reference markers recognizable by the graph reader.
|
|
41
|
+
if (typeof marker === "number" &&
|
|
42
|
+
!Number.isSafeInteger(marker) &&
|
|
43
|
+
(literals.integers.has(marker) || !literals.reals.has(marker)))
|
|
44
|
+
ambiguousNumberCount += 1;
|
|
45
|
+
return item;
|
|
46
|
+
}
|
|
47
|
+
return Object.fromEntries(Object.entries(item).map(([key, child]) => [key, map(child)]));
|
|
48
|
+
}
|
|
49
|
+
return item;
|
|
50
|
+
};
|
|
51
|
+
return {
|
|
52
|
+
project: map,
|
|
53
|
+
limitations: () => [
|
|
54
|
+
...(literals.incomplete
|
|
55
|
+
? [
|
|
56
|
+
"Original archive number metadata could not be completely observed; decoded numbers may lose integer precision and exact integer/real association is unavailable.",
|
|
57
|
+
]
|
|
58
|
+
: []),
|
|
59
|
+
...(literals.unsafeIntegerLiterals === 0
|
|
60
|
+
? []
|
|
61
|
+
: [
|
|
62
|
+
`${String(literals.unsafeIntegerLiterals)} observed integer literal(s) in the original archive exceed the exact range of a JSON number. Decoded numbers may lose integer precision unless represented as { "$plist_type": "integer", "decimal": "<exact digits>" }; the original archive bytes retain those literals.`,
|
|
63
|
+
]),
|
|
64
|
+
...(exactIntegerCount === 0
|
|
65
|
+
? []
|
|
66
|
+
: [
|
|
67
|
+
`${String(exactIntegerCount)} unambiguous integer value(s) are reported with exact decimal text as { "$plist_type": "integer", "decimal": "<exact digits>" }.`,
|
|
68
|
+
]),
|
|
69
|
+
...(ambiguousNumberCount === 0
|
|
70
|
+
? []
|
|
71
|
+
: [
|
|
72
|
+
`${String(ambiguousNumberCount)} number(s) beyond the exact integer range remain as decoded because their source integer/real type or reference marker cannot be associated unambiguously; integer precision loss remains possible.`,
|
|
73
|
+
]),
|
|
74
|
+
],
|
|
75
|
+
};
|
|
76
|
+
};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { compareCodePoints } from "./canonicalOrdering.js";
|
|
1
2
|
import { z } from "zod";
|
|
2
3
|
import {} from "./artifactGraph.js";
|
|
3
4
|
import { evidenceSchema } from "./evidence.js";
|
|
@@ -111,7 +112,7 @@ export const compareArtifacts = (leftEvidence, rightEvidence) => {
|
|
|
111
112
|
right_manifest_id: right.inventory.manifest.manifest_id,
|
|
112
113
|
summary,
|
|
113
114
|
changes,
|
|
114
|
-
limitations: [...new Set(limitations)].sort(
|
|
115
|
+
limitations: [...new Set(limitations)].sort(compareCodePoints),
|
|
115
116
|
});
|
|
116
117
|
};
|
|
117
118
|
const compareOccurrences = (left, right, evidenceLinks, complete) => {
|
|
@@ -123,7 +124,7 @@ const compareOccurrences = (left, right, evidenceLinks, complete) => {
|
|
|
123
124
|
const rightRelations = relationsByPath(right);
|
|
124
125
|
const paths = [
|
|
125
126
|
...new Set([...leftByPath.keys(), ...rightByPath.keys()]),
|
|
126
|
-
].sort(
|
|
127
|
+
].sort(compareCodePoints);
|
|
127
128
|
const output = [];
|
|
128
129
|
for (const path of paths) {
|
|
129
130
|
const leftOccurrence = leftByPath.get(path);
|
|
@@ -208,8 +209,17 @@ const changedDimensions = (input) => {
|
|
|
208
209
|
return ["availability"];
|
|
209
210
|
const checks = [
|
|
210
211
|
["content", left.sha256 !== right.sha256],
|
|
211
|
-
[
|
|
212
|
-
|
|
212
|
+
[
|
|
213
|
+
"kind",
|
|
214
|
+
input.leftOccurrence?.artifact_kind !==
|
|
215
|
+
input.rightOccurrence?.artifact_kind,
|
|
216
|
+
],
|
|
217
|
+
[
|
|
218
|
+
"format",
|
|
219
|
+
left.format !== right.format ||
|
|
220
|
+
input.leftOccurrence?.artifact_format !==
|
|
221
|
+
input.rightOccurrence?.artifact_format,
|
|
222
|
+
],
|
|
213
223
|
["size", left.size !== right.size],
|
|
214
224
|
[
|
|
215
225
|
"executable",
|
|
@@ -228,7 +238,6 @@ const changedDimensions = (input) => {
|
|
|
228
238
|
};
|
|
229
239
|
const metadataChanged = (input, left, right) => left.media_type !== right.media_type ||
|
|
230
240
|
left.architecture !== right.architecture ||
|
|
231
|
-
left.executable !== right.executable ||
|
|
232
241
|
left.content_state !== right.content_state ||
|
|
233
242
|
input.leftOccurrence?.entry_kind !== input.rightOccurrence?.entry_kind ||
|
|
234
243
|
input.leftOccurrence?.encrypted !== input.rightOccurrence?.encrypted ||
|
|
@@ -262,7 +271,7 @@ const relationsByPath = (inventory) => {
|
|
|
262
271
|
values.push(projection);
|
|
263
272
|
}
|
|
264
273
|
for (const values of output.values())
|
|
265
|
-
values.sort((left, right) => canonicalJson(left)
|
|
274
|
+
values.sort((left, right) => compareCodePoints(canonicalJson(left), canonicalJson(right)));
|
|
266
275
|
return output;
|
|
267
276
|
};
|
|
268
277
|
const summarize = (left, right, changes, covered) => {
|