rea-agents 6.3.0 → 6.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +7 -4
- package/bridge/ghidra/ReaGhidraApplySeeds.java +151 -0
- package/bridge/ghidra/ReaGhidraBridge.java +597 -209
- package/bridge/ghidra/ReaGhidraNoReturnFix.java +123 -0
- package/dist/adb/AdbConfiguration.js +88 -0
- package/dist/adb/AdbDeviceOutput.js +186 -0
- package/dist/adb/AdbProvider.js +1190 -0
- package/dist/adb/AdbShellOutput.js +309 -0
- package/dist/android/AndroidTargetSnapshot.js +104 -22
- package/dist/android/JadxConfiguration.js +44 -24
- package/dist/android/JadxProvider.js +51 -19
- package/dist/apktool/ApktoolConfiguration.js +84 -0
- package/dist/apktool/ApktoolDecodeOutput.js +59 -0
- package/dist/apktool/ApktoolProvider.js +506 -0
- package/dist/application/AnalysisProvider.js +8 -2
- package/dist/application/AppBundleExecutable.js +27 -22
- package/dist/application/BinaryTargetResolver.js +22 -2
- package/dist/application/CapabilityInventory.js +11 -1
- package/dist/application/ClientConfigurationDocument.js +70 -0
- package/dist/application/ClientConfigurationFiles.js +91 -0
- package/dist/application/ClientRegistrationEnvironment.js +35 -0
- package/dist/application/ClientRegistrationStatus.js +66 -31
- package/dist/application/DirectAnalysis.js +2 -2
- package/dist/application/DirectAnalysisCleanup.js +1 -1
- package/dist/application/DirectAnalysisStatus.js +1 -1
- package/dist/application/Doctor.js +5 -3
- package/dist/application/DoctorDiagnostics.js +1 -1
- package/dist/application/EvidenceBundleCommands.js +6 -12
- package/dist/application/GeminiClientSettings.js +139 -0
- package/dist/application/HermesClientHome.js +115 -0
- package/dist/application/HopperDownload.js +39 -0
- package/dist/application/InvestigationProviders.js +6 -0
- package/dist/application/JsonFiles.js +6 -5
- package/dist/{cliJsonFile.js → application/JsonInputFile.js} +108 -35
- package/dist/application/LinuxHopper.js +4 -12
- package/dist/application/MacHopper.js +172 -149
- package/dist/application/MipsElfAbiFlags.js +140 -0
- package/dist/application/ProviderOperationExecution.js +31 -0
- package/dist/application/ReconstructionObligationCandidates.js +9 -3
- package/dist/application/ReferenceSourceImport.js +76 -29
- package/dist/application/ReferenceSourceImportEntries.js +18 -9
- package/dist/application/ReferenceSourceImportPolicy.js +99 -23
- package/dist/application/ReferenceSourceImportTypes.js +30 -22
- package/dist/application/ReferenceSourceVcsAdapter.js +145 -30
- package/dist/application/RegularFileRead.js +93 -7
- package/dist/application/Setup.js +54 -6
- package/dist/application/SetupClientConfiguration.js +116 -16
- package/dist/application/SetupHost.js +102 -24
- package/dist/application/SetupPlan.js +5 -8
- package/dist/application/SetupSkill.js +58 -39
- package/dist/application/SupportedClients.js +290 -65
- package/dist/application/Uninstall.js +158 -10
- package/dist/application/UpdateMaintenance.js +17 -21
- package/dist/application/Utf8JsonInput.js +7 -0
- package/dist/application/WebScriptExportService.js +131 -65
- package/dist/application/WebSourceLocationService.js +3 -0
- package/dist/application/adb/AdbDeviceAnalysisPort.js +1 -0
- package/dist/application/adb/AdbDeviceAnalysisService.js +13 -0
- package/dist/application/analysisView/AnalysisViewService.js +40 -2
- package/dist/application/apktool/ApktoolResourceAnalysisPort.js +1 -0
- package/dist/application/apktool/ApktoolResourceAnalysisService.js +13 -0
- package/dist/application/binary/AnalysisClientCleanup.js +0 -24
- package/dist/application/binary/BinarySession.js +2 -1
- package/dist/application/binaryDiagnostics/BinaryLayoutService.js +2 -1
- package/dist/application/binaryDiagnostics/PeResourcesPort.js +1 -0
- package/dist/application/binaryDiagnostics/PeResourcesService.js +111 -0
- package/dist/application/binaryDiagnostics/RecordedCrashService.js +2 -1
- package/dist/application/evm/EvmInterfaceService.js +3 -0
- package/dist/application/firmware/FirmwareAnalysisService.js +3 -0
- package/dist/application/investigation/InspectEvidenceBundle.js +18 -0
- package/dist/application/javascript/ElectronBoundaryGraphContext.js +3 -2
- package/dist/application/javascript/ElectronBoundaryGraphIpc.js +2 -2
- package/dist/application/javascript/ElectronBoundaryGraphNative.js +19 -6
- package/dist/application/javascript/ElectronBoundaryGraphWindows.js +3 -3
- package/dist/application/javascript/JavaScriptApplicationService.js +22 -11
- package/dist/application/javascript/JavaScriptApplicationWorkflowEvidence.js +5 -6
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +171 -30
- package/dist/application/javascript/JavaScriptArtifactGraphAccumulator.js +14 -16
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +67 -19
- package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +4 -3
- package/dist/application/javascript/JavaScriptArtifactGraphContext.js +11 -5
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +19 -16
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +92 -10
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +258 -235
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +115 -26
- package/dist/application/javascript/JavaScriptArtifactReconstructionInput.js +4 -1
- package/dist/application/javascript/JavaScriptModuleRelationships.js +6 -4
- package/dist/application/javascript/JavaScriptRecoveryService.js +3 -0
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +9 -3
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +199 -61
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +12 -19
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +4 -1
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -3
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +5 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +19 -8
- package/dist/application/jeb/JebAnalysisPort.js +1 -0
- package/dist/application/jeb/JebAnalysisService.js +13 -0
- package/dist/application/managed/ManagedApplicationGraphService.js +1 -1
- package/dist/application/native/NativeUiActionTrace.js +16 -8
- package/dist/application/native/NativeValueTrace.js +23 -6
- package/dist/application/process/ProcessCli.js +25 -20
- package/dist/artifacts/ArtifactPaths.js +129 -8
- package/dist/artifacts/ArtifactProvider.js +20 -15
- package/dist/artifacts/ArtifactReader.js +23 -0
- package/dist/artifacts/ArtifactResourceScope.js +100 -0
- package/dist/artifacts/AsarArtifactReader.js +176 -102
- package/dist/artifacts/AsarHeader.js +24 -0
- package/dist/artifacts/DirectoryArtifactReader.js +168 -65
- package/dist/artifacts/MachOSliceArtifactReader.js +116 -39
- package/dist/artifacts/NativeDmgArtifactReader.js +29 -22
- package/dist/artifacts/SafeOutputTree.js +245 -70
- package/dist/artifacts/SafeOutputTreeCleanup.js +45 -0
- package/dist/artifacts/SafeOutputTreeCreationFailure.js +20 -0
- package/dist/artifacts/SafeOutputTreeIdentity.js +42 -0
- package/dist/artifacts/SafeOutputTreeReadback.js +33 -0
- package/dist/artifacts/ZipArtifactReader.js +77 -27
- package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +58 -18
- package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +62 -24
- package/dist/artifacts/apple/KeyedArchiveReader.js +32 -13
- package/dist/artifacts/extraction/ArtifactExtraction.js +110 -86
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +110 -43
- package/dist/artifacts/inventory/ArtifactInventory.js +5 -4
- package/dist/artifacts/inventory/classify.js +75 -32
- package/dist/artifacts/inventory/hashStableRootArtifact.js +48 -15
- package/dist/artifacts/inventory/reader.js +13 -5
- package/dist/artifacts/inventory/scanCanonical.js +62 -25
- package/dist/artifacts/inventory/scanReader.js +38 -11
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +15 -9
- package/dist/artifacts/javascript/JavaScriptSourceAnalysis.js +3 -0
- package/dist/browser/BrowserScenarioPartialObservation.js +8 -2
- package/dist/browser/BrowserScenarioSecrets.js +52 -37
- package/dist/browser/CdpBrowserProvider.js +5 -0
- package/dist/browser/CdpCaptureDocuments.js +40 -6
- package/dist/browser/CdpCaptureDomSvg.js +210 -0
- package/dist/browser/CdpCaptureEventBodyShapes.js +4 -8
- package/dist/browser/CdpCaptureEventHandlers.js +26 -9
- package/dist/browser/CdpCaptureEvents.js +4 -9
- package/dist/browser/CdpConnection.js +22 -5
- package/dist/browser/CdpPageCapture.js +1 -1
- package/dist/browser/CdpTargetSession.js +30 -34
- package/dist/browser/CdpWebMcpDiscovery.js +32 -10
- package/dist/browser/ElectronFileScope.js +99 -9
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +60 -4
- package/dist/browser/PlaywrightElectronActiveProvider.js +11 -6
- package/dist/browser/PlaywrightScenarioArtifacts.js +5 -5
- package/dist/browser/PlaywrightScenarioBrowser.js +69 -7
- package/dist/browser/PlaywrightScenarioSession.js +127 -54
- package/dist/browser/PlaywrightScenarioStorage.js +507 -0
- package/dist/browser/PngVisualDiff.js +198 -29
- package/dist/browser/WebSourceMapFetcher.js +3 -3
- package/dist/browser/assets/LocalWebScriptArtifacts.js +3 -1
- package/dist/browser/assets/PublishWebScripts.js +75 -20
- package/dist/browser/assets/WebArtifactReads.js +23 -1
- package/dist/browser/assets/WebSourceLocationArtifacts.js +1 -0
- package/dist/browser/execution/CdpExecutionCapture.js +3 -3
- package/dist/browser/execution/CdpPreciseCoverage.js +5 -8
- package/dist/browser/history/HarCapture.js +14 -0
- package/dist/browser/history/HarCaptureProcess.js +2 -10
- package/dist/browser/history/MitmproxyCaptureAdapter.js +3 -1
- package/dist/browser/modules/WebModuleArtifacts.js +1 -0
- package/dist/cli/adbCommands.js +337 -0
- package/dist/cli/analysisViewCommands.js +39 -1
- package/dist/cli/apktoolCommands.js +53 -0
- package/dist/cli/artifactCommands.js +8 -11
- package/dist/cli/binaryDiagnosticsCommands.js +19 -1
- package/dist/cli/browserAdvancedCommands.js +65 -36
- package/dist/cli/coreBinaryCommands.js +0 -5
- package/dist/cli/coreNativeCommands.js +1 -14
- package/dist/cli/electronCommands.js +6 -1
- package/dist/cli/evmCommands.js +13 -4
- package/dist/cli/firmwareCommands.js +7 -2
- package/dist/cli/javascriptApplicationAnalysis.js +17 -1
- package/dist/cli/javascriptRecoveryCommands.js +22 -15
- package/dist/cli/jebCommands.js +99 -0
- package/dist/cli/jsonOutput.js +11 -4
- package/dist/cli/referenceSourceImportStatus.js +7 -0
- package/dist/cli/setupCommands.js +15 -3
- package/dist/cli/utilityCommands.js +66 -18
- package/dist/cli/webScriptCommands.js +20 -1
- package/dist/cli/webSourceLocationCommands.js +21 -9
- package/dist/cli.js +6 -0
- package/dist/cliBrowserScenarioCommands.js +2 -1
- package/dist/cliCommandNames.js +32 -0
- package/dist/cliJsonInput.js +2 -2
- package/dist/cliObservationOptions.js +3 -0
- package/dist/composition/adb.js +3 -0
- package/dist/composition/apktool.js +3 -0
- package/dist/composition/binaryDiagnostics.js +4 -0
- package/dist/composition/directAnalysis.js +12 -4
- package/dist/composition/javascriptAnalysisWorkerProcess.js +48 -0
- package/dist/composition/jeb.js +6 -0
- package/dist/config/environment.js +10 -0
- package/dist/config/ghidraLanguageOverride.js +9 -0
- package/dist/config/mcpInputSchemaProfile.js +27 -0
- package/dist/config/parseConfig.js +28 -1
- package/dist/contracts/adb/adbToolContracts.js +353 -0
- package/dist/contracts/advertisedInputExamples.js +48 -0
- package/dist/contracts/analysisDetail.js +10 -0
- package/dist/contracts/analysisViewToolContracts.js +17 -2
- package/dist/contracts/apktool/apktoolToolContracts.js +33 -0
- package/dist/contracts/artifactToolContracts.js +8 -5
- package/dist/contracts/browserToolContracts.js +1 -1
- package/dist/contracts/compactInputSchema.js +256 -0
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/inputSchemaPresentation.js +10 -10
- package/dist/contracts/javascript/electronToolContracts.js +15 -3
- package/dist/contracts/javascript/javascriptRecoveryToolContracts.js +1 -1
- package/dist/contracts/jeb/jebToolContracts.js +64 -0
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +25 -3
- package/dist/contracts/officialToolContracts.js +5 -5
- package/dist/contracts/sessionToolContracts.js +2 -2
- package/dist/contracts/sessionToolSchemas.js +6 -2
- package/dist/contracts/toolContractExamples.js +6 -0
- package/dist/contracts/toolContractTypes.js +3 -0
- package/dist/contracts/toolContracts.js +6 -0
- package/dist/contracts/toolEffects.js +167 -0
- package/dist/contracts/toolOutputSchemaGroups.js +5 -3
- package/dist/contracts/toolSchemaMetadata.js +82 -7
- package/dist/domain/adb/adbDeviceAnalysis.js +583 -0
- package/dist/domain/analysisErrorCleanup.js +29 -0
- package/dist/domain/analysisErrorPresentation.js +18 -6
- package/dist/domain/analysisErrorProjection.js +4 -1
- package/dist/domain/analysisSnapshot.js +2 -1
- package/dist/domain/analysisView/analysisView.js +52 -2
- package/dist/domain/analysisView/binaryLayoutView.js +2 -0
- package/dist/domain/analysisView/javascriptApplicationView.js +2 -0
- package/dist/domain/analysisView/nativeFunctionView.js +155 -0
- package/dist/domain/android/androidApplication.js +25 -20
- package/dist/domain/apktool/apktoolResourceAnalysis.js +77 -0
- package/dist/domain/apple/appleApplication.js +40 -23
- package/dist/domain/apple/appleBundleAnatomy.js +95 -28
- package/dist/domain/apple/dyldPaths.js +9 -1
- package/dist/domain/apple/dylibResolution.js +2 -2
- package/dist/domain/apple/interfaceBuilderGraph.js +22 -19
- package/dist/domain/apple/interfaceBuilderKeyedArchive.js +10 -1
- package/dist/domain/artifactComparison.js +35 -7
- package/dist/domain/artifactGraph.js +5 -3
- package/dist/domain/artifactIdentity.js +30 -2
- package/dist/domain/artifactInspection.js +3 -43
- package/dist/domain/artifactIntegrityPolicy.js +10 -0
- package/dist/domain/artifactInventoryEvidence.js +11 -12
- package/dist/domain/artifactPathSyntax.js +1 -1
- package/dist/domain/binaryTarget.js +16 -0
- package/dist/domain/binaryTargetTypes.js +8 -1
- package/dist/domain/browserObservationSchemas.js +8 -4
- package/dist/domain/canonicalJsonDigestSteps.js +34 -12
- package/dist/domain/compactStringIdentity.js +9 -0
- package/dist/domain/evidence.js +2 -1
- package/dist/domain/evidenceRecordSummary.js +144 -0
- package/dist/domain/inputIssueProjection.js +16 -1
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +12 -13
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +11 -20
- package/dist/domain/javascript/electronStaticAnalysisNative.js +70 -40
- package/dist/domain/javascript/electronStaticAnalysisValues.js +16 -0
- package/dist/domain/javascript/javascriptAnalysisResourceControls.js +45 -0
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +4 -1
- package/dist/domain/javascript/javascriptApplicationChangeGraph.js +6 -6
- package/dist/domain/javascript/javascriptApplicationGraph.js +79 -18
- package/dist/domain/javascript/javascriptApplicationProjectionResources.js +35 -0
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +28 -12
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +9 -1
- package/dist/domain/javascript/javascriptAstFingerprint.js +58 -31
- package/dist/domain/javascript/javascriptAstValues.js +32 -0
- package/dist/domain/javascript/javascriptElectronMemberWrites.js +50 -0
- package/dist/domain/javascript/javascriptModuleSemanticIr.js +15 -0
- package/dist/domain/javascript/javascriptNativeHandoff.js +6 -1
- package/dist/domain/javascript/javascriptRpcEndpoints.js +253 -0
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +1 -3
- package/dist/domain/javascript/javascriptRuntimeReconciliationGraph.js +7 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +8 -11
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +190 -33
- package/dist/domain/javascript/javascriptSemanticCallableResults.js +42 -0
- package/dist/domain/javascript/javascriptSemanticCalls.js +8 -1
- package/dist/domain/javascript/javascriptSemanticDerivedAnalysis.js +15 -4
- package/dist/domain/javascript/javascriptSemanticFileProjection.js +1 -0
- package/dist/domain/javascript/javascriptSemanticFingerprints.js +42 -41
- package/dist/domain/javascript/javascriptSemanticGraph.js +69 -23
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +2 -10
- package/dist/domain/javascript/javascriptSemanticIterationSources.js +40 -7
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +341 -87
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +78 -35
- package/dist/domain/javascript/javascriptSemanticObjectReferences.js +381 -0
- package/dist/domain/javascript/javascriptSemanticObjects.js +7 -1
- package/dist/domain/javascript/javascriptSemanticProjection.js +52 -14
- package/dist/domain/javascript/javascriptSemanticPropertyPaths.js +77 -0
- package/dist/domain/javascript/javascriptSemanticQuery.js +27 -29
- package/dist/domain/javascript/javascriptSemanticQueryIdentity.js +1 -3
- package/dist/domain/javascript/javascriptSemanticReturnedReferences.js +219 -0
- package/dist/domain/javascript/javascriptSemanticReturns.js +13 -23
- package/dist/domain/javascript/javascriptSemanticState.js +22 -2
- package/dist/domain/javascript/javascriptSemanticTraversal.js +19 -1
- package/dist/domain/javascript/javascriptSemanticValues.js +47 -19
- package/dist/domain/javascript/javascriptSourceAnalysis.js +1 -0
- package/dist/domain/javascript/javascriptStaticAnalysis.js +29 -17
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +8 -6
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +49 -5
- package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +8 -4
- package/dist/domain/javascript/javascriptStaticAnalysisState.js +1 -0
- package/dist/domain/jeb/jebAnalysis.js +114 -0
- package/dist/domain/jsonShape.js +63 -52
- package/dist/domain/jsonValue.js +3 -0
- package/dist/domain/managed/managedApplicationGraph.js +37 -0
- package/dist/domain/managed/managedApplicationGraphCoverage.js +8 -2
- package/dist/domain/managed/managedApplicationGraphNodes.js +32 -22
- package/dist/domain/managed/managedArtifact.js +1 -0
- package/dist/domain/managed/managedInspectionEvidence.js +13 -0
- package/dist/domain/native/nativeAotPe.js +1408 -0
- package/dist/domain/native/nativeInstruction.js +21 -0
- package/dist/domain/native/nativeMetadataRecovery.js +79 -6
- package/dist/domain/native/peResources.js +94 -0
- package/dist/domain/nativeConvention.js +33 -0
- package/dist/domain/process/processCapture.js +91 -1
- package/dist/domain/process/processCaptureExample.js +24 -0
- package/dist/domain/process/processCaptureValidation.js +79 -0
- package/dist/domain/process/processScenario.js +59 -7
- package/dist/domain/propertyListKeys.js +3 -1
- package/dist/domain/referenceSourceGraph.js +25 -16
- package/dist/domain/referenceSourceImportParsing.js +6 -3
- package/dist/domain/referenceSourcePathIdentity.js +22 -0
- package/dist/domain/referenceSourceRequireBindings.js +137 -0
- package/dist/domain/webBundleAnalyzerInspection.js +14 -2
- package/dist/domain/webCaptureDiff.js +102 -4
- package/dist/domain/webScriptExportError.js +10 -4
- package/dist/domain/webScriptExportPlan.js +7 -13
- package/dist/domain/zipPackageFormat.js +4 -1
- package/dist/domain/zodCollectionSteps.js +24 -0
- package/dist/dotnet/ManagedArtifactInspector.js +55 -43
- package/dist/dotnet/ManagedDecodeBudget.js +80 -0
- package/dist/dotnet/ManagedMemberInspector.js +13 -6
- package/dist/dotnet/ManagedMemberInspectorCore.js +2 -2
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +4 -2
- package/dist/dotnet/ManagedMemberRows.js +9 -4
- package/dist/dotnet/ManagedMetadataHeaps.js +15 -5
- package/dist/dotnet/ManagedMetadataInventoryRows.js +20 -11
- package/dist/dotnet/ManagedMetadataLayout.js +10 -4
- package/dist/dotnet/ManagedMethodBodyReader.js +8 -3
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +3 -2
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +49 -34
- package/dist/dotnet/ManagedPeReader.js +41 -25
- package/dist/dotnet/ManagedReaderFailure.js +2 -1
- package/dist/dotnet/ManagedStaticProvider.js +55 -24
- package/dist/evaluation/AgentEvaluationReport.js +9 -5
- package/dist/evaluation/CodexAgentEval.js +43 -13
- package/dist/evm/EvmoleFailures.js +0 -2
- package/dist/evm/EvmoleInterfaceProvider.js +67 -2
- package/dist/filesystem/OwnedDirectoryHandle.js +29 -0
- package/dist/filesystem/OwnedFileHandle.js +36 -0
- package/dist/filesystem/RegularFile.js +33 -1
- package/dist/filesystem/StableFileHash.js +46 -0
- package/dist/filesystem/readFileHandleChunks.js +26 -0
- package/dist/firmware/FirmwareCommand.js +25 -3
- package/dist/firmware/FirmwareFiles.js +23 -8
- package/dist/firmware/FirmwareProvider.js +156 -32
- package/dist/firmware/FirmwarePublication.js +24 -3
- package/dist/firmware/FirmwareRelease.js +1 -0
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +55 -4
- package/dist/ghidra/GhidraAnalysisSeeds.js +211 -0
- package/dist/ghidra/GhidraClient.js +76 -4
- package/dist/ghidra/GhidraDiagnostics.js +11 -8
- package/dist/ghidra/GhidraFunctionValues.js +26 -2
- package/dist/ghidra/GhidraInstallation.js +1 -1
- package/dist/ghidra/GhidraInventoryValues.js +23 -1
- package/dist/ghidra/GhidraLanguageCatalog.js +99 -0
- package/dist/ghidra/GhidraLauncher.js +80 -39
- package/dist/ghidra/GhidraLoadImageAttest.js +49 -2
- package/dist/ghidra/GhidraMipsProfile.js +79 -0
- package/dist/ghidra/GhidraProvider.js +57 -9
- package/dist/ghidra/GhidraProviderCapabilities.js +18 -8
- package/dist/ghidra/GhidraProviderClient.js +282 -21
- package/dist/ghidra/GhidraSessionValues.js +9 -2
- package/dist/hopper/HopperAnalysisProfile.js +2 -0
- package/dist/hopper/HopperClient.js +15 -6
- package/dist/hopper/HopperMachOImage.js +2 -0
- package/dist/hopper/HopperProvider.js +13 -2
- package/dist/ida/IdaOperationRunner.js +8 -2
- package/dist/ida/IdaProvider.js +7 -0
- package/dist/ida/IdaSessionClient.js +3 -1
- package/dist/ida/IdaWorkspace.js +4 -2
- package/dist/javascript/analysis/JavaScriptAnalysisTransfer.js +326 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorker.js +520 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerProtocol.js +63 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerSchemas.js +521 -0
- package/dist/javascript/analysis/JavaScriptAnalysisWorkerServer.js +116 -0
- package/dist/javascript/recovery/RecoveryFiles.js +18 -7
- package/dist/javascript/recovery/WakaruCommand.js +22 -9
- package/dist/javascript/recovery/WakaruExecution.js +11 -7
- package/dist/javascript/recovery/WakaruProvider.js +139 -16
- package/dist/javascript/recovery/WakaruPublication.js +14 -4
- package/dist/javascript/recovery/WakaruRelease.js +10 -3
- package/dist/javascript/recovery/WakaruReport.js +12 -7
- package/dist/javascript/recovery/WakaruVersion.js +24 -0
- package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -3
- package/dist/javascript/sourceMaps/SourceMapDecoder.js +63 -7
- package/dist/javascript/sourceMaps/SourceMapFormat.js +15 -4
- package/dist/jeb/JebMcpConnection.js +179 -0
- package/dist/jeb/JebMcpEndpoint.js +40 -0
- package/dist/jeb/JebProvider.js +299 -0
- package/dist/mcpDoctor.js +15 -6
- package/dist/native/AppleDispatchCoverage.js +25 -12
- package/dist/native/AppleDispatchMetadata.js +14 -7
- package/dist/native/AppleMachoFixups.js +71 -15
- package/dist/native/AppleMachoSelection.js +23 -3
- package/dist/native/NativeMacOSProvider.js +91 -16
- package/dist/native/NativeMachoInspection.js +11 -7
- package/dist/native/NativeUiHelperRuntime.js +6 -1
- package/dist/native/NativeUiObservation.js +4 -3
- package/dist/native/pe/PeResourceLayout.js +120 -0
- package/dist/native/pe/PeResourceParser.js +286 -0
- package/dist/native/pe/PeResourcesProvider.js +63 -0
- package/dist/process/BoundedFileBytes.js +30 -7
- package/dist/process/DarwinProcessRunTokenReader.js +8 -3
- package/dist/process/OwnedCommand.js +4 -3
- package/dist/process/ProcessOwnership.js +104 -112
- package/dist/process/ProcessOwnershipObservation.js +96 -39
- package/dist/process/ProcessOwnershipProcessTree.js +4 -4
- package/dist/process/ProcessRunTokenObservations.js +48 -0
- package/dist/process/ProviderDiagnosticRedaction.js +17 -0
- package/dist/process/ProviderProcess.js +4 -3
- package/dist/process/capture/FilesystemSnapshot.js +28 -4
- package/dist/process/capture/ProcessCaptureLifecycle.js +350 -59
- package/dist/process/capture/ProcessCaptureProgress.js +62 -0
- package/dist/process/capture/ProcessHarness.js +194 -26
- package/dist/process/capture/ProcessNormalization.js +3 -1
- package/dist/process/capture/ProcessScenarioRuntimeValidation.js +5 -2
- package/dist/process/capture/TerminalRenderer.js +24 -7
- package/dist/reference/ReferenceSourceReader.js +22 -5
- package/dist/reference/ReferenceSourceReaderEntries.js +114 -51
- package/dist/reference/ReferenceSourceReaderErrors.js +12 -0
- package/dist/reference/ReferenceSourceReaderFile.js +50 -10
- package/dist/reference/ReferenceSourceReaderValidate.js +4 -4
- package/dist/server/EvidenceMcpServer.js +36 -1
- package/dist/server/admittedToolOperation.js +9 -0
- package/dist/server/contractToolHandler.js +21 -0
- package/dist/server/createServer.js +97 -25
- package/dist/server/registerAdbTools.js +36 -0
- package/dist/server/registerAnalysisViewTool.js +4 -9
- package/dist/server/registerAndroidTools.js +3 -12
- package/dist/server/registerApktoolTools.js +14 -0
- package/dist/server/registerApplicationTools/compareExportShapes.js +4 -6
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
- package/dist/server/registerApplicationTools/compareVersions.js +3 -2
- package/dist/server/registerApplicationTools/coverage.js +3 -2
- package/dist/server/registerApplicationTools/obligationLedger.js +3 -2
- package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -2
- package/dist/server/registerApplicationTools/traceFeature.js +3 -2
- package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
- package/dist/server/registerArtifactComparisonTool.js +5 -2
- package/dist/server/registerBinaryDiagnosticsTools.js +16 -4
- package/dist/server/registerBrowserScenarioTool.js +10 -7
- package/dist/server/registerBrowserTools.js +12 -9
- package/dist/server/registerBundleComparisonTool.js +16 -2
- package/dist/server/registerCloseLifecycleTool.js +32 -3
- package/dist/server/registerElectronTools.js +28 -10
- package/dist/server/registerEvmTools.js +4 -9
- package/dist/server/registerFirmwareTools.js +3 -11
- package/dist/server/registerFunctionComparisonTool.js +5 -2
- package/dist/server/registerJavaScriptRecoveryTool.js +4 -9
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +9 -6
- package/dist/server/registerJebTools.js +16 -0
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +4 -6
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +3 -2
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +3 -2
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +3 -2
- package/dist/server/registerPeResourcesTool.js +9 -0
- package/dist/server/registerProcessComparisonTool.js +5 -2
- package/dist/server/registerRecordedCrashTools.js +4 -9
- package/dist/server/registerSessionRecordTools.js +2 -1
- package/dist/server/registerSessionTools.js +49 -18
- package/dist/server/registerWebModuleTool.js +4 -9
- package/dist/server/registerWebNetworkCaptureTool.js +4 -9
- package/dist/server/registerWebRuntimeTools.js +6 -5
- package/dist/server/registerWebScriptTool.js +6 -3
- package/dist/server/registerWebSourceLocationTool.js +4 -9
- package/dist/server/toolResult.js +21 -2
- package/dist/windows/WindowsPrivateRuntime.js +12 -5
- package/install.sh +7 -4
- package/licenses/nativeaot-parser-MIT.txt +28 -0
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +33 -5
- package/scripts/rea.mjs +16 -1
- package/skills/reverse-engineer-anything/SKILL.md +52 -51
- package/skills/reverse-engineer-anything/references/connection-and-recovery.md +127 -0
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -0
- package/skills/reverse-engineer-anything/references/javascript-applications.md +92 -13
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +22 -1
|
@@ -2,6 +2,7 @@ import { posix } from "node:path";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { canonicalJson } from "./comparisonSemantics.js";
|
|
4
4
|
import { digestCanonicalValue } from "./canonicalDigest.js";
|
|
5
|
+
import { createReferenceSourcePathLookup, isPortableAbsoluteReferenceTarget, } from "./referenceSourcePathIdentity.js";
|
|
5
6
|
import { compareUnicodeCodePoints } from "./unicodeCodePointOrder.js";
|
|
6
7
|
import { digestSchema } from "./../domain/digests.js";
|
|
7
8
|
import { prefixedDigestSchema } from "./../domain/digests.js";
|
|
@@ -67,13 +68,10 @@ const sourceDirectorySchema = z.strictObject({
|
|
|
67
68
|
const symlinkTargetSchema = z
|
|
68
69
|
.string()
|
|
69
70
|
.min(1)
|
|
70
|
-
.refine((target) =>
|
|
71
|
+
.refine((target) => isPortableAbsoluteReferenceTarget(target) ||
|
|
71
72
|
(!target.startsWith("/") &&
|
|
72
73
|
!target.includes("\\") &&
|
|
73
74
|
posix.normalize(target) === target), "Expected a normalized POSIX symlink target");
|
|
74
|
-
const isPortableAbsoluteSymlinkTarget = (target) => target.startsWith("/") ||
|
|
75
|
-
/^[A-Za-z]:[\\/]/u.test(target) ||
|
|
76
|
-
/^\\\\[^\\/]+[\\/][^\\/]+/u.test(target);
|
|
77
75
|
const sourceSymlinkSchema = z.union([
|
|
78
76
|
z.strictObject({
|
|
79
77
|
...entryBaseShape,
|
|
@@ -105,15 +103,22 @@ const parseFailureSchema = z.strictObject({
|
|
|
105
103
|
parser: z.string().min(1),
|
|
106
104
|
reason: boundedTextSchema,
|
|
107
105
|
});
|
|
108
|
-
const exclusionSchema = z.
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
106
|
+
const exclusionSchema = z.discriminatedUnion("reason", [
|
|
107
|
+
z.strictObject({
|
|
108
|
+
path: relativePathSchema,
|
|
109
|
+
reason: z.enum([
|
|
110
|
+
"configured-secret",
|
|
111
|
+
"project-ignored",
|
|
112
|
+
"default-ignored",
|
|
113
|
+
"caller-excluded",
|
|
114
|
+
]),
|
|
115
|
+
pattern: boundedTextSchema,
|
|
116
|
+
}),
|
|
117
|
+
z.strictObject({
|
|
118
|
+
path: relativePathSchema,
|
|
119
|
+
reason: z.enum(["symlink-escape", "unreadable"]),
|
|
120
|
+
}),
|
|
121
|
+
]);
|
|
117
122
|
const vcsSchema = z
|
|
118
123
|
.discriminatedUnion("kind", [
|
|
119
124
|
z.strictObject({
|
|
@@ -229,12 +234,13 @@ const checkRelationships = (graph, paths, context) => {
|
|
|
229
234
|
}
|
|
230
235
|
};
|
|
231
236
|
const checkSymlinks = (graph, paths, context) => {
|
|
237
|
+
const lookupPath = createReferenceSourcePathLookup(paths);
|
|
232
238
|
for (const [index, entry] of graph.entries.entries()) {
|
|
233
239
|
if (entry.kind !== "symlink")
|
|
234
240
|
continue;
|
|
235
241
|
if (entry.target === null)
|
|
236
242
|
continue;
|
|
237
|
-
const absolute =
|
|
243
|
+
const absolute = isPortableAbsoluteReferenceTarget(entry.target);
|
|
238
244
|
if ((entry.target_state === "external" && !absolute) ||
|
|
239
245
|
(entry.target_state === "internal" && absolute))
|
|
240
246
|
context.addIssue({
|
|
@@ -245,7 +251,10 @@ const checkSymlinks = (graph, paths, context) => {
|
|
|
245
251
|
if (entry.target_state !== "internal")
|
|
246
252
|
continue;
|
|
247
253
|
const resolved = posix.normalize(posix.join(posix.dirname(entry.path), entry.target));
|
|
248
|
-
if (resolved.startsWith("../") ||
|
|
254
|
+
if (resolved.startsWith("../") ||
|
|
255
|
+
resolved === ".." ||
|
|
256
|
+
// The inventory root is implicit rather than an entry with path ".".
|
|
257
|
+
(resolved !== "." && lookupPath.resolve(resolved) === undefined))
|
|
249
258
|
context.addIssue({
|
|
250
259
|
code: "custom",
|
|
251
260
|
message: "Internal symlink target must resolve to an inventoried entry",
|
|
@@ -282,7 +291,7 @@ function checkGraphInvariants(graph, context) {
|
|
|
282
291
|
checkSortedUnique(graph.manifests, "manifests", context);
|
|
283
292
|
checkSortedUnique(graph.relationships.map(relationshipKey), "relationships", context);
|
|
284
293
|
checkSortedUnique(graph.parse_failures.map(historicalSourceParseFailureKey), "parse_failures", context);
|
|
285
|
-
checkSortedUnique(graph.exclusions.map((
|
|
294
|
+
checkSortedUnique(graph.exclusions.map((exclusion) => `${exclusion.path}\u0000${exclusion.reason}\u0000${"pattern" in exclusion ? exclusion.pattern : ""}`), "exclusions", context);
|
|
286
295
|
if (canonicalJson(graph.languages, "Reference source graph") !==
|
|
287
296
|
canonicalJson(historicalSourceLanguages(graph.entries), "Reference source graph"))
|
|
288
297
|
context.addIssue({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { parse } from "@babel/parser";
|
|
2
2
|
import { traverseJavaScriptAst } from "./javascript/javascriptSemanticTraversal.js";
|
|
3
3
|
import { parserPluginsForPath } from "./javascript/javascriptSourceParser.js";
|
|
4
|
+
import { unshadowedReferenceSourceRequireCalls } from "./referenceSourceRequireBindings.js";
|
|
4
5
|
import { isCallExpression, isExportAllDeclaration, isExportNamedDeclaration, isIdentifier, isImport, isImportDeclaration, isImportExpression, isMemberExpression, isStringLiteral, isTSExternalModuleReference, isTSImportEqualsDeclaration, isTSModuleDeclaration, } from "@babel/types";
|
|
5
6
|
const codeSourceLanguages = new Set(["JavaScript", "TypeScript", "JSX", "TSX"]);
|
|
6
7
|
const safeModuleName = (node) => {
|
|
@@ -114,7 +115,7 @@ const isRequireCallee = (callee) => {
|
|
|
114
115
|
}
|
|
115
116
|
return false;
|
|
116
117
|
};
|
|
117
|
-
const extractRequireAndDynamicImports = (body, from_path, relationships) => {
|
|
118
|
+
const extractRequireAndDynamicImports = (body, from_path, relationships, unshadowedRequireCalls) => {
|
|
118
119
|
// Single traversal owner: iterative, VISITOR_KEYS-gated, no recursion over
|
|
119
120
|
// loc/comment objects. Survives deeply nested generated member chains that
|
|
120
121
|
// overflowed the previous hand-rolled Object.values walker.
|
|
@@ -139,7 +140,9 @@ const extractRequireAndDynamicImports = (body, from_path, relationships) => {
|
|
|
139
140
|
continue;
|
|
140
141
|
}
|
|
141
142
|
const first = call.arguments[0];
|
|
142
|
-
if (isRequireCallee(call.callee) &&
|
|
143
|
+
if (isRequireCallee(call.callee) &&
|
|
144
|
+
unshadowedRequireCalls.has(call) &&
|
|
145
|
+
isModuleExpression(first)) {
|
|
143
146
|
const result = moduleSpecifierFromExpression(first);
|
|
144
147
|
if (result !== undefined) {
|
|
145
148
|
appendRelationship(relationships, {
|
|
@@ -222,7 +225,7 @@ export const parseReferenceSourceImports = (path, bytes, language) => {
|
|
|
222
225
|
}
|
|
223
226
|
const relationships = [];
|
|
224
227
|
extractImportDeclarations(ast.program.body, path, relationships);
|
|
225
|
-
extractRequireAndDynamicImports(ast.program.body, path, relationships);
|
|
228
|
+
extractRequireAndDynamicImports(ast.program.body, path, relationships, unshadowedReferenceSourceRequireCalls(ast, path));
|
|
226
229
|
return {
|
|
227
230
|
relationships: relationships.map((relationship) => ({
|
|
228
231
|
...relationship,
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Reference inventories retain filesystem spelling. Prefer that exact identity;
|
|
3
|
+
* canonical Unicode equivalence is a fallback only when it identifies one entry.
|
|
4
|
+
*/
|
|
5
|
+
export const createReferenceSourcePathLookup = (paths) => {
|
|
6
|
+
const exact = new Set(paths);
|
|
7
|
+
const canonical = new Map();
|
|
8
|
+
for (const path of exact) {
|
|
9
|
+
const key = path.normalize("NFC");
|
|
10
|
+
canonical.set(key, canonical.has(key) ? null : path);
|
|
11
|
+
}
|
|
12
|
+
const equivalent = (path) => canonical.get(path.normalize("NFC")) ?? undefined;
|
|
13
|
+
return {
|
|
14
|
+
resolve: (path) => (exact.has(path) ? path : equivalent(path)),
|
|
15
|
+
resolveCandidates: (candidates) => candidates.find((path) => exact.has(path)) ??
|
|
16
|
+
candidates.map(equivalent).find((path) => path !== undefined),
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
/** Symlink evidence can originate on a different OS from the graph reader. */
|
|
20
|
+
export const isPortableAbsoluteReferenceTarget = (target) => target.startsWith("/") ||
|
|
21
|
+
/^[A-Za-z]:[\\/]/u.test(target) ||
|
|
22
|
+
/^\\\\[^\\/]+[\\/][^\\/]+/u.test(target);
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
import { analyzeParsedJavaScriptReferences } from "./javascript/javascriptSemanticAnalysis.js";
|
|
3
|
+
import { semanticBindingId, semanticScopeId, } from "./javascript/javascriptSemanticState.js";
|
|
4
|
+
import { traverseJavaScriptAst } from "./javascript/javascriptSemanticTraversal.js";
|
|
5
|
+
/**
|
|
6
|
+
* Keep calls that resolve either to Node's CommonJS wrapper loader or to a
|
|
7
|
+
* direct ESM `createRequire(import.meta.url)` binding. The shared lexical
|
|
8
|
+
* analyzer supplies binding ownership; this boundary accounts for the two
|
|
9
|
+
* Node loader bindings without evaluating arbitrary values.
|
|
10
|
+
*/
|
|
11
|
+
export const unshadowedReferenceSourceRequireCalls = (file, path) => {
|
|
12
|
+
const references = new Map(analyzeParsedJavaScriptReferences(file).map((reference) => [
|
|
13
|
+
`${reference.location.start.line}:${reference.location.start.column}`,
|
|
14
|
+
reference,
|
|
15
|
+
]));
|
|
16
|
+
const programRequireBinding = semanticBindingId(semanticScopeId("program", file.program), "require");
|
|
17
|
+
const allowsUnboundRequire = !isExplicitModuleSource(path);
|
|
18
|
+
const hasTopLevelVarRequire = allowsUnboundRequire && hasUninitializedTopLevelVarRequire(file.program);
|
|
19
|
+
const createRequireBinding = directCreateRequireBinding(file.program, references);
|
|
20
|
+
const requireLoaderWasWritten = [...references.values()].some((reference) => reference.name === "require" &&
|
|
21
|
+
reference.role === "write" &&
|
|
22
|
+
(reference.resolution === "unbound" ||
|
|
23
|
+
reference.bindingId === programRequireBinding));
|
|
24
|
+
const calls = new Set();
|
|
25
|
+
traverseJavaScriptAst(file.program, {
|
|
26
|
+
enter: (node, _parent, readAncestors) => {
|
|
27
|
+
if (!t.isCallExpression(node))
|
|
28
|
+
return;
|
|
29
|
+
const identifier = requireCalleeIdentifier(node.callee);
|
|
30
|
+
const start = identifier?.loc?.start;
|
|
31
|
+
if (start === undefined)
|
|
32
|
+
return;
|
|
33
|
+
if (readAncestors().some((ancestor) => t.isWithStatement(ancestor) && contains(ancestor.body, node)))
|
|
34
|
+
return;
|
|
35
|
+
const reference = references.get(`${start.line}:${start.column}`);
|
|
36
|
+
if ((allowsUnboundRequire &&
|
|
37
|
+
!requireLoaderWasWritten &&
|
|
38
|
+
reference?.resolution === "unbound") ||
|
|
39
|
+
(((hasTopLevelVarRequire && !requireLoaderWasWritten) ||
|
|
40
|
+
createRequireBinding) &&
|
|
41
|
+
reference?.resolution === "resolved" &&
|
|
42
|
+
reference.bindingId === programRequireBinding))
|
|
43
|
+
calls.add(node);
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
return calls;
|
|
47
|
+
};
|
|
48
|
+
const contains = (container, node) => typeof container.start === "number" &&
|
|
49
|
+
typeof container.end === "number" &&
|
|
50
|
+
typeof node.start === "number" &&
|
|
51
|
+
typeof node.end === "number" &&
|
|
52
|
+
container.start <= node.start &&
|
|
53
|
+
node.end <= container.end;
|
|
54
|
+
const isExplicitModuleSource = (path) => {
|
|
55
|
+
const lower = path.toLowerCase();
|
|
56
|
+
if (lower.endsWith(".mjs") || lower.endsWith(".mts"))
|
|
57
|
+
return true;
|
|
58
|
+
if (lower.endsWith(".cjs") || lower.endsWith(".cts"))
|
|
59
|
+
return false;
|
|
60
|
+
// Syntax alone cannot establish Node's runtime mode: `.js` depends on its
|
|
61
|
+
// package scope, and `.ts` may be compiled with a CommonJS module target.
|
|
62
|
+
// Keep unmarked paths runtime-unknown and preserve candidate require edges.
|
|
63
|
+
return false;
|
|
64
|
+
};
|
|
65
|
+
const hasUninitializedTopLevelVarRequire = (program) => {
|
|
66
|
+
let found = false;
|
|
67
|
+
let initialized = false;
|
|
68
|
+
traverseJavaScriptAst(program, {
|
|
69
|
+
enter: (node, _parent, readAncestors) => {
|
|
70
|
+
if (!t.isVariableDeclaration(node, { kind: "var" }))
|
|
71
|
+
return;
|
|
72
|
+
if (readAncestors().some((ancestor) => t.isFunction(ancestor) || t.isStaticBlock(ancestor)))
|
|
73
|
+
return;
|
|
74
|
+
for (const declaration of node.declarations) {
|
|
75
|
+
if (!Object.hasOwn(t.getBindingIdentifiers(declaration.id), "require"))
|
|
76
|
+
continue;
|
|
77
|
+
found = true;
|
|
78
|
+
initialized ||= declaration.init !== null;
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
});
|
|
82
|
+
return found && !initialized;
|
|
83
|
+
};
|
|
84
|
+
const directCreateRequireBinding = (program, references) => {
|
|
85
|
+
const programScope = semanticScopeId("program", program);
|
|
86
|
+
const importedNames = new Set();
|
|
87
|
+
for (const declaration of program.body) {
|
|
88
|
+
if (!t.isImportDeclaration(declaration) ||
|
|
89
|
+
(declaration.source.value !== "node:module" &&
|
|
90
|
+
declaration.source.value !== "module"))
|
|
91
|
+
continue;
|
|
92
|
+
for (const specifier of declaration.specifiers) {
|
|
93
|
+
if (t.isImportSpecifier(specifier) &&
|
|
94
|
+
t.isIdentifier(specifier.imported, { name: "createRequire" }))
|
|
95
|
+
importedNames.add(specifier.local.name);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return program.body.some((statement) => t.isVariableDeclaration(statement, { kind: "const" }) &&
|
|
99
|
+
statement.declarations.some((declaration) => {
|
|
100
|
+
if (!t.isIdentifier(declaration.id, { name: "require" }) ||
|
|
101
|
+
!t.isCallExpression(declaration.init) ||
|
|
102
|
+
!t.isIdentifier(declaration.init.callee) ||
|
|
103
|
+
!importedNames.has(declaration.init.callee.name) ||
|
|
104
|
+
!isImportMetaUrl(declaration.init.arguments[0]))
|
|
105
|
+
return false;
|
|
106
|
+
const start = declaration.init.callee.loc?.start;
|
|
107
|
+
if (start === undefined)
|
|
108
|
+
return false;
|
|
109
|
+
const reference = references.get(`${start.line}:${start.column}`);
|
|
110
|
+
return (reference?.resolution === "resolved" &&
|
|
111
|
+
reference.bindingId ===
|
|
112
|
+
semanticBindingId(programScope, declaration.init.callee.name));
|
|
113
|
+
}));
|
|
114
|
+
};
|
|
115
|
+
const isImportMetaUrl = (node) => t.isMemberExpression(node) &&
|
|
116
|
+
!node.computed &&
|
|
117
|
+
t.isIdentifier(node.property, { name: "url" }) &&
|
|
118
|
+
t.isMetaProperty(node.object) &&
|
|
119
|
+
t.isIdentifier(node.object.meta, { name: "import" }) &&
|
|
120
|
+
t.isIdentifier(node.object.property, { name: "meta" });
|
|
121
|
+
const requireCalleeIdentifier = (callee) => {
|
|
122
|
+
if (t.isIdentifier(callee, { name: "require" }))
|
|
123
|
+
return callee;
|
|
124
|
+
if (!t.isMemberExpression(callee) ||
|
|
125
|
+
!t.isIdentifier(callee.object, { name: "require" }) ||
|
|
126
|
+
((!t.isIdentifier(callee.property) || callee.computed) &&
|
|
127
|
+
!t.isStringLiteral(callee.property)))
|
|
128
|
+
return undefined;
|
|
129
|
+
const propertyName = t.isIdentifier(callee.property)
|
|
130
|
+
? callee.property.name
|
|
131
|
+
: t.isStringLiteral(callee.property)
|
|
132
|
+
? callee.property.value
|
|
133
|
+
: undefined;
|
|
134
|
+
return propertyName === "resolve" || propertyName === "main"
|
|
135
|
+
? callee.object
|
|
136
|
+
: undefined;
|
|
137
|
+
};
|
|
@@ -2,11 +2,12 @@ import { parse } from "@babel/parser";
|
|
|
2
2
|
import * as t from "@babel/types";
|
|
3
3
|
import { sanitizeEndpointCandidate } from "./browserObservation.js";
|
|
4
4
|
import { compositeKey } from "./unicodeCodePointOrder.js";
|
|
5
|
-
import { traverseJavaScriptAst } from "./javascript/javascriptSemanticTraversal.js";
|
|
6
|
-
import { classifyParsedJavaScriptOpenReceivers } from "./javascript/javascriptSemanticAnalysis.js";
|
|
5
|
+
import { completeSemanticSteps, traverseJavaScriptAst, } from "./javascript/javascriptSemanticTraversal.js";
|
|
6
|
+
import { classifyParsedJavaScriptOpenReceivers, classifyParsedJavaScriptRpcClientRootsSteps, } from "./javascript/javascriptSemanticAnalysis.js";
|
|
7
7
|
import { semanticStaticPropertyName } from "./javascript/javascriptAstValues.js";
|
|
8
8
|
import { calleeName, endpointArgument, stringValue, } from "./javascript/javascriptStaticAnalysisHelpers.js";
|
|
9
9
|
import { location, locationFields, objectString, objectValue, resolveSpecifier, isUrlLikeModuleSpecifier, } from "./webBundleAnalyzerAst.js";
|
|
10
|
+
import { createJavaScriptRpcScan } from "./javascript/javascriptRpcEndpoints.js";
|
|
10
11
|
export const analyzeScript = (script, accumulator) => {
|
|
11
12
|
let file;
|
|
12
13
|
try {
|
|
@@ -25,10 +26,21 @@ export const analyzeScript = (script, accumulator) => {
|
|
|
25
26
|
accumulator.parsedScripts += 1;
|
|
26
27
|
detectVendorFingerprints(script, accumulator);
|
|
27
28
|
const openReceiverFacts = classifyParsedJavaScriptOpenReceivers(file);
|
|
29
|
+
const rpc = createJavaScriptRpcScan(script.source.artifact.text, completeSemanticSteps(classifyParsedJavaScriptRpcClientRootsSteps(file)));
|
|
28
30
|
traverseJavaScriptAst(file, {
|
|
29
31
|
enter: (node) => {
|
|
30
32
|
accumulator.visitedNodes += 1;
|
|
31
33
|
inspectNode(script, node, accumulator, openReceiverFacts);
|
|
34
|
+
const endpoint = rpc.inspect(node);
|
|
35
|
+
if (endpoint !== undefined)
|
|
36
|
+
addFinding({
|
|
37
|
+
collection: accumulator.endpoints,
|
|
38
|
+
script,
|
|
39
|
+
rawValue: endpoint.value,
|
|
40
|
+
mechanism: endpoint.mechanism,
|
|
41
|
+
node,
|
|
42
|
+
accumulator,
|
|
43
|
+
});
|
|
32
44
|
},
|
|
33
45
|
});
|
|
34
46
|
};
|
|
@@ -24,7 +24,7 @@ export const compareWebCaptures = (input) => {
|
|
|
24
24
|
dimensions,
|
|
25
25
|
limitations: [
|
|
26
26
|
"A changed status proves an observed difference; an unknown status means absence could not be established from capture completeness.",
|
|
27
|
-
"Network comparison covers only activity observed after each CDP attachment.",
|
|
27
|
+
"Network comparison covers only activity observed after each CDP attachment. WebSocket connections with the same URL are compared as an unordered collection of ordered frame streams, retaining connection counts; their individual identities are not stable across captures.",
|
|
28
28
|
"Accessibility roles, ignored state, text, and hierarchy are compared only when the accessibility tree was fully captured and text capture was selected and not truncated.",
|
|
29
29
|
"Storage key inventories are compared only when selected and complete; usage and quota are compared only when reported. Redacted content is compared through complete SHA-256 fingerprints.",
|
|
30
30
|
],
|
|
@@ -106,9 +106,11 @@ const keyed = (values, identity) => new Map(values.map((value) => [identity(valu
|
|
|
106
106
|
const bodyShapesSelected = (inspection) => !inspection.completeness.excluded.some(({ section, reason }) => section === "json_body_shapes" && reason === "not_approved") &&
|
|
107
107
|
(inspection.network.requests.length === 0 ||
|
|
108
108
|
inspection.network.requests.some(({ body_shapes }) => body_shapes.status !== "not_approved"));
|
|
109
|
+
const webSocketShapesSelected = (inspection) => !inspection.completeness.excluded.some(({ section, reason }) => section === "websocket_shapes" && reason === "not_approved");
|
|
109
110
|
const networkIdentity = (request) => `net_${digestCanonicalValue({ method: request.method, url: request.url, resource_type: request.resource_type })}`;
|
|
110
111
|
const networkDimension = (before, after) => {
|
|
111
112
|
const selected = bodyShapesSelected(before) && bodyShapesSelected(after);
|
|
113
|
+
const webSocketShapes = webSocketShapesSelected(before) && webSocketShapesSelected(after);
|
|
112
114
|
const sources = new Map();
|
|
113
115
|
if (selected) {
|
|
114
116
|
const observedSources = (inspection) => {
|
|
@@ -137,9 +139,29 @@ const networkDimension = (before, after) => {
|
|
|
137
139
|
const shapesComplete = !selected ||
|
|
138
140
|
[before, after].every((inspection) => sectionsComplete(inspection, ["json_body_shapes"]) &&
|
|
139
141
|
inspection.network.requests.every(({ body_shapes }) => body_shapes.status === "included"));
|
|
140
|
-
|
|
141
|
-
sectionsComplete(
|
|
142
|
-
|
|
142
|
+
const webSocketShapesComplete = !webSocketShapes ||
|
|
143
|
+
[before, after].every((inspection) => sectionsComplete(inspection, ["websocket_shapes"]) &&
|
|
144
|
+
inspection.network.websocket_connections.every((connection) => connection.events.every((event) => event.payload_shape !== null)));
|
|
145
|
+
const webSocketPayloadBytesComplete = [before, after].every((inspection) => inspection.network.websocket_connections.every((connection) => connection.events.every((event) => event.payload_bytes !== null)));
|
|
146
|
+
const beforeWebSockets = webSocketGroups(before);
|
|
147
|
+
const afterWebSockets = webSocketGroups(after);
|
|
148
|
+
const [beforeWebSocketPayload, afterWebSocketPayload] = webSocketPayloadMaps(beforeWebSockets, afterWebSockets, webSocketShapes);
|
|
149
|
+
return compareDimension(new Map([
|
|
150
|
+
...networkMap(before, sources),
|
|
151
|
+
...webSocketMetadataMap(beforeWebSockets),
|
|
152
|
+
...beforeWebSocketPayload,
|
|
153
|
+
]), new Map([
|
|
154
|
+
...networkMap(after, sources),
|
|
155
|
+
...webSocketMetadataMap(afterWebSockets),
|
|
156
|
+
...afterWebSocketPayload,
|
|
157
|
+
]), [before, after].every((inspection) => sectionsComplete(inspection, [
|
|
158
|
+
"network_requests",
|
|
159
|
+
"websocket_connections",
|
|
160
|
+
"websocket_frames",
|
|
161
|
+
])) &&
|
|
162
|
+
shapesComplete &&
|
|
163
|
+
webSocketPayloadBytesComplete &&
|
|
164
|
+
webSocketShapesComplete, "Network capture or selected HTTP/WebSocket payload-shape coverage is attach-window limited, unavailable, or incomplete.");
|
|
143
165
|
};
|
|
144
166
|
const networkMap = (inspection, sources) => {
|
|
145
167
|
const grouped = new Map();
|
|
@@ -167,6 +189,82 @@ const networkMap = (inspection, sources) => {
|
|
|
167
189
|
digestCanonicalValue(values.map((value) => digestCanonicalValue(value)).sort()),
|
|
168
190
|
]));
|
|
169
191
|
};
|
|
192
|
+
const webSocketGroups = (inspection) => {
|
|
193
|
+
const groups = new Map();
|
|
194
|
+
for (const connection of inspection.network.websocket_connections) {
|
|
195
|
+
const stream = digestCanonicalValue(connection.events.map(({ direction, opcode }) => ({
|
|
196
|
+
direction,
|
|
197
|
+
opcode,
|
|
198
|
+
})));
|
|
199
|
+
const key = digestCanonicalValue({ url: connection.url, stream });
|
|
200
|
+
const previous = groups.get(key);
|
|
201
|
+
if (previous !== undefined)
|
|
202
|
+
previous.connections.push(connection);
|
|
203
|
+
else
|
|
204
|
+
groups.set(key, {
|
|
205
|
+
url: connection.url,
|
|
206
|
+
stream,
|
|
207
|
+
connections: [connection],
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
return groups;
|
|
211
|
+
};
|
|
212
|
+
const webSocketMetadataMap = (groups) => {
|
|
213
|
+
const byUrl = new Map();
|
|
214
|
+
for (const group of groups.values()) {
|
|
215
|
+
const streams = byUrl.get(group.url) ?? [];
|
|
216
|
+
for (let index = 0; index < group.connections.length; index += 1)
|
|
217
|
+
streams.push(group.stream);
|
|
218
|
+
byUrl.set(group.url, streams);
|
|
219
|
+
}
|
|
220
|
+
return new Map([...byUrl].map(([url, streams]) => [
|
|
221
|
+
`ws_${digestCanonicalValue(url)}`,
|
|
222
|
+
digestCanonicalValue(streams.sort(compareUnicodeCodePoints)),
|
|
223
|
+
]));
|
|
224
|
+
};
|
|
225
|
+
const webSocketPayloadMaps = (beforeGroups, afterGroups, selected) => {
|
|
226
|
+
const left = new Map();
|
|
227
|
+
const right = new Map();
|
|
228
|
+
for (const [groupKey, beforeGroup] of beforeGroups) {
|
|
229
|
+
const afterGroup = afterGroups.get(groupKey);
|
|
230
|
+
if (afterGroup === undefined ||
|
|
231
|
+
beforeGroup.connections.length !== afterGroup.connections.length)
|
|
232
|
+
continue;
|
|
233
|
+
const eventCount = beforeGroup.connections[0]?.events.length ?? 0;
|
|
234
|
+
const comparableBytes = new Set();
|
|
235
|
+
const comparableShapes = new Set();
|
|
236
|
+
for (let index = 0; index < eventCount; index += 1) {
|
|
237
|
+
if (beforeGroup.connections.every((connection) => connection.events[index]?.payload_bytes !== null) &&
|
|
238
|
+
afterGroup.connections.every((connection) => connection.events[index]?.payload_bytes !== null))
|
|
239
|
+
comparableBytes.add(index);
|
|
240
|
+
// Compare only when every same-metadata connection has shape evidence
|
|
241
|
+
// on both sides; this avoids assigning an unknown shape to a known one.
|
|
242
|
+
if (selected &&
|
|
243
|
+
beforeGroup.connections.every((connection) => connection.events[index]?.payload_shape !== null) &&
|
|
244
|
+
afterGroup.connections.every((connection) => connection.events[index]?.payload_shape !== null))
|
|
245
|
+
comparableShapes.add(index);
|
|
246
|
+
}
|
|
247
|
+
if (comparableBytes.size === 0 && comparableShapes.size === 0)
|
|
248
|
+
continue;
|
|
249
|
+
const project = (group) => digestCanonicalValue(group.connections
|
|
250
|
+
.map((connection) => connection.events.map((event, index) => {
|
|
251
|
+
const comparablePayload = {};
|
|
252
|
+
if (comparableBytes.has(index))
|
|
253
|
+
comparablePayload.payload_bytes = event.payload_bytes;
|
|
254
|
+
if (comparableShapes.has(index))
|
|
255
|
+
comparablePayload.payload_shape = event.payload_shape;
|
|
256
|
+
return Object.keys(comparablePayload).length === 0
|
|
257
|
+
? null
|
|
258
|
+
: comparablePayload;
|
|
259
|
+
}))
|
|
260
|
+
.map((stream) => digestCanonicalValue(stream))
|
|
261
|
+
.sort(compareUnicodeCodePoints));
|
|
262
|
+
const identity = `wss_${groupKey}`;
|
|
263
|
+
left.set(identity, project(beforeGroup));
|
|
264
|
+
right.set(identity, project(afterGroup));
|
|
265
|
+
}
|
|
266
|
+
return [left, right];
|
|
267
|
+
};
|
|
170
268
|
const webMcpMap = (discovery) => discovery === null
|
|
171
269
|
? new Map()
|
|
172
270
|
: keyed(discovery.tools.items, (tool) => tool.tool_key);
|
|
@@ -4,10 +4,16 @@ export class WebScriptExportError extends ArtifactOperationError {
|
|
|
4
4
|
userMessage;
|
|
5
5
|
cleanupIncomplete;
|
|
6
6
|
cleanupResources;
|
|
7
|
-
constructor(reason, target, diagnostic,
|
|
8
|
-
super("export_web_scripts", reason);
|
|
7
|
+
constructor(reason, target, diagnostic, options = {}) {
|
|
8
|
+
super("export_web_scripts", reason, undefined, undefined, options);
|
|
9
9
|
this.userMessage = `Script export failed for ${target}: ${diagnostic}`;
|
|
10
|
-
this.cleanupResources =
|
|
11
|
-
|
|
10
|
+
this.cleanupResources = [
|
|
11
|
+
...new Set([
|
|
12
|
+
...(options.cleanup?.resources ?? []),
|
|
13
|
+
...(options.residualPaths ?? []),
|
|
14
|
+
]),
|
|
15
|
+
];
|
|
16
|
+
this.cleanupIncomplete =
|
|
17
|
+
options.cleanup !== undefined || (options.residualPaths?.length ?? 0) > 0;
|
|
12
18
|
}
|
|
13
19
|
}
|
|
@@ -18,7 +18,7 @@ export const planWebScriptExport = (scripts) => {
|
|
|
18
18
|
};
|
|
19
19
|
const candidate = candidates[index];
|
|
20
20
|
const reason = conflicts.has(index)
|
|
21
|
-
? "Captured paths collide by content version
|
|
21
|
+
? "Captured paths collide by content version or file/directory prefix."
|
|
22
22
|
: (candidate?.reason ?? null);
|
|
23
23
|
const path = reason === null ? candidate?.path : undefined;
|
|
24
24
|
return {
|
|
@@ -74,8 +74,9 @@ const candidatePath = (script) => {
|
|
|
74
74
|
: null,
|
|
75
75
|
};
|
|
76
76
|
};
|
|
77
|
-
// Register every prefix so
|
|
78
|
-
//
|
|
77
|
+
// Register every exact prefix so a repeated path, or a file that is also a
|
|
78
|
+
// directory prefix, isolates every affected source. Case-distinct spellings
|
|
79
|
+
// stay distinct until the destination filesystem reports a collision.
|
|
79
80
|
const conflictingPaths = (candidates) => {
|
|
80
81
|
const prefixes = new Map();
|
|
81
82
|
candidates.forEach(({ path }, index) => {
|
|
@@ -84,23 +85,16 @@ const conflictingPaths = (candidates) => {
|
|
|
84
85
|
const parts = path.split("/");
|
|
85
86
|
parts.forEach((_, position) => {
|
|
86
87
|
const spelling = parts.slice(0, position + 1).join("/");
|
|
87
|
-
const
|
|
88
|
-
const entry = prefixes.get(key) ?? {
|
|
89
|
-
spellings: new Set(),
|
|
90
|
-
indices: [],
|
|
91
|
-
files: [],
|
|
92
|
-
};
|
|
93
|
-
entry.spellings.add(spelling);
|
|
88
|
+
const entry = prefixes.get(spelling) ?? { indices: [], files: [] };
|
|
94
89
|
entry.indices.push(index);
|
|
95
90
|
if (position === parts.length - 1)
|
|
96
91
|
entry.files.push(index);
|
|
97
|
-
prefixes.set(
|
|
92
|
+
prefixes.set(spelling, entry);
|
|
98
93
|
});
|
|
99
94
|
});
|
|
100
95
|
const conflicts = new Set();
|
|
101
96
|
for (const entry of prefixes.values())
|
|
102
|
-
if (entry.
|
|
103
|
-
entry.files.length > 1 ||
|
|
97
|
+
if (entry.files.length > 1 ||
|
|
104
98
|
(entry.files.length > 0 && entry.indices.length > entry.files.length))
|
|
105
99
|
for (const index of entry.indices)
|
|
106
100
|
conflicts.add(index);
|
|
@@ -17,7 +17,8 @@ export const zipPackageFormatForPath = (path) => {
|
|
|
17
17
|
return "zip";
|
|
18
18
|
if (lower.endsWith(".ipa"))
|
|
19
19
|
return "ipa";
|
|
20
|
-
|
|
20
|
+
// An Android App Bundle is a ZIP archive, not a standalone APK.
|
|
21
|
+
if (lower.endsWith(".apk"))
|
|
21
22
|
return "apk";
|
|
22
23
|
if (lower.endsWith(".msix") || lower.endsWith(".msixbundle"))
|
|
23
24
|
return "msix";
|
|
@@ -25,3 +26,5 @@ export const zipPackageFormatForPath = (path) => {
|
|
|
25
26
|
return "appx";
|
|
26
27
|
return undefined;
|
|
27
28
|
};
|
|
29
|
+
/** Inventory cannot see bytes that are not central-directory entries. */
|
|
30
|
+
export const ZIP_NON_ENTRY_TAIL_LIMITATION = "ZIP inventory lists central-directory entries only. Bytes after the central directory, including an APK Signing Block or a ZIP comment, are not occurrences.";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/**
|
|
3
|
+
* An array schema's own constraints, such as a minimum length, without its
|
|
4
|
+
* element schema. Pair it with {@link parseElementSteps} to validate a large
|
|
5
|
+
* collection in cooperative steps.
|
|
6
|
+
*/
|
|
7
|
+
export const arrayContainerSchema = (array) => array.clone({ ...array.def, element: z.unknown() });
|
|
8
|
+
/** Elements validated between yields, in the issues and paths a whole-array parse reports. */
|
|
9
|
+
export function* parseElementSteps(element, values, path, issues) {
|
|
10
|
+
const parsed = [];
|
|
11
|
+
for (const [index, value] of values.entries()) {
|
|
12
|
+
if (index % 64 === 0)
|
|
13
|
+
yield;
|
|
14
|
+
const result = element.safeParse(value);
|
|
15
|
+
if (result.success)
|
|
16
|
+
parsed.push(result.data);
|
|
17
|
+
else
|
|
18
|
+
issues.push(...result.error.issues.map((issue) => ({
|
|
19
|
+
...issue,
|
|
20
|
+
path: [...path, index, ...issue.path],
|
|
21
|
+
})));
|
|
22
|
+
}
|
|
23
|
+
return parsed;
|
|
24
|
+
}
|