rea-agents 5.0.0 → 6.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +168 -655
- package/bridge/android/ReaJadxBridge.java +14 -5
- package/bridge/ghidra/ReaGhidraBridge.java +173 -47
- package/bridge/hopper_bridge.py +310 -128
- package/bridge/mitmproxy/capture.py +208 -0
- package/bridge/native/rea_lldb_tracer.py +839 -0
- package/bridge/process/ProcessRunTokenReader.swift +297 -0
- package/bridge/process/ProcessRunTokenReaderMain.swift +35 -0
- package/bridge/pwndbg/core_context.py +101 -0
- package/bridge/pwndbg/launch.py +39 -0
- package/bridge/pwndbg/launch_impl.py +34 -0
- package/bridge/pwntools/decoder_runtime.py +59 -0
- package/bridge/pwntools/layout.py +39 -0
- package/bridge/pwntools/layout_impl.py +309 -0
- package/bridge/pwntools/recorded_crash.py +39 -0
- package/bridge/pwntools/recorded_crash_impl.py +147 -0
- package/dist/android/JadxConfiguration.js +196 -33
- package/dist/android/JadxMcpTransport.js +4 -0
- package/dist/android/JadxProtocol.js +6 -0
- package/dist/android/JadxProvider.js +20 -2
- 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/CallPathTracing.js +19 -3
- package/dist/application/CapabilityInventory.js +27 -3
- package/dist/application/ClientConfigurationDocument.js +871 -6
- package/dist/application/ClientRegistrationIdentity.js +26 -5
- package/dist/application/ClientRegistrationStatus.js +29 -14
- package/dist/application/DirectAnalysis.js +97 -33
- package/dist/application/Doctor.js +4 -2
- package/dist/application/DoctorScope.js +25 -13
- package/dist/application/EnhancedLiteralTracing.js +22 -25
- package/dist/application/EnhancedTools.js +13 -11
- package/dist/application/EvidenceBundleFiles.js +24 -12
- package/dist/application/FunctionAnalysisEvidence.js +2 -3
- package/dist/application/InventoryProjectionEvidence.js +4 -3
- package/dist/application/InvestigationProviders.js +3 -2
- package/dist/application/JsonFiles.js +50 -28
- package/dist/application/ProcedureAddressResolution.js +11 -0
- package/dist/application/ReconstructionCoverageService.js +7 -4
- package/dist/application/ReconstructionObligationCandidates.js +5 -1
- package/dist/application/ReconstructionObligationLedgerService.js +4 -3
- package/dist/application/Setup.js +13 -1
- package/dist/application/SetupClientConfiguration.js +10 -15
- package/dist/application/SetupHost.js +5 -2
- package/dist/application/SetupPlan.js +5 -3
- package/dist/application/SupportedClients.js +34 -1
- package/dist/application/Uninstall.js +4 -3
- package/dist/application/Update.js +18 -3
- package/dist/application/UpdateRuntime.js +46 -25
- package/dist/application/WebModuleTraceService.js +4 -2
- package/dist/application/WebNetworkCapturePort.js +1 -0
- package/dist/application/WebNetworkCaptureService.js +134 -0
- package/dist/application/WebRuntimeService.js +5 -3
- package/dist/application/WebScriptExportService.js +2 -2
- package/dist/application/WebSourceLocationService.js +4 -2
- package/dist/application/WindowsCapabilities.js +1 -1
- package/dist/application/WorkflowEvidence.js +82 -0
- package/dist/application/binary/AnalysisProviderEvaluation.js +21 -5
- package/dist/application/binary/AnalysisProviderRegistry.js +2 -0
- package/dist/application/binary/AnalysisSnapshotCache.js +52 -12
- package/dist/application/binary/BinarySession.js +131 -76
- package/dist/application/binary/BinarySessionOpen.js +19 -6
- package/dist/application/binary/BinarySessionRecords.js +45 -3
- package/dist/application/binary/BinarySessionStatus.js +17 -1
- package/dist/application/binary/CompositeProvider.js +13 -0
- package/dist/application/binary/LazyAnalysisProvider.js +3 -0
- package/dist/application/binaryDiagnostics/BinaryLayoutPort.js +1 -0
- package/dist/application/binaryDiagnostics/BinaryLayoutService.js +59 -0
- package/dist/application/binaryDiagnostics/RecordedCrashPort.js +1 -0
- package/dist/application/binaryDiagnostics/RecordedCrashService.js +62 -0
- package/dist/application/evm/EvmInterfacePort.js +1 -0
- package/dist/application/evm/EvmInterfaceService.js +64 -0
- package/dist/application/investigation/EvidenceLedger.js +21 -7
- package/dist/application/investigation/InvestigationRecords.js +8 -0
- package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +25 -5
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
- package/dist/application/javascript/JavaScriptApplicationService.js +34 -14
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +47 -27
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +39 -7
- package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +26 -2
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +80 -27
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +33 -12
- package/dist/application/javascript/JavaScriptModuleRelationships.js +37 -8
- package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +3 -1
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +7 -7
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +149 -72
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +14 -15
- package/dist/application/javascript/JavaScriptSemanticGraphConstruction.js +41 -1
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +7 -7
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +5 -9
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphProjection.js +118 -12
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +27 -5
- package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
- package/dist/application/managed/ManagedMemberComparisonService.js +7 -4
- package/dist/application/managed/ManagedNativeVerificationService.js +4 -3
- package/dist/application/managed/ManagedReconstructionService.js +4 -3
- package/dist/application/{ProcessCli.js → process/ProcessCli.js} +23 -15
- package/dist/application/{ProcessEvidence.js → process/ProcessEvidence.js} +8 -7
- package/dist/application/workflowInputError.js +18 -0
- package/dist/artifacts/ArtifactProvider.js +42 -5
- package/dist/artifacts/ArtifactProviderMetadata.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +98 -14
- package/dist/artifacts/NativeDmgArtifactReader.js +13 -6
- package/dist/artifacts/ZipArtifactReader.js +3 -0
- package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +22 -3
- package/dist/artifacts/apple/DylibResolutionReader.js +259 -0
- package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
- package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
- package/dist/artifacts/apple/KeyedArchiveReader.js +36 -22
- package/dist/artifacts/apple/MachoLoadCommandReader.js +355 -0
- 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/{application → artifacts/extraction}/ArtifactExtraction.js +10 -10
- package/dist/{application → artifacts/inventory}/ArtifactGraphConstruction.js +16 -11
- package/dist/{application → artifacts/inventory}/ArtifactInventory.js +4 -4
- package/dist/{application/ArtifactInventory → artifacts/inventory}/classify.js +2 -2
- package/dist/{application/ArtifactInventory → artifacts/inventory}/reader.js +5 -5
- package/dist/{application/ArtifactInventory → artifacts/inventory}/scanCanonical.js +14 -17
- package/dist/{application/ArtifactInventory → artifacts/inventory}/scanReader.js +5 -5
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
- package/dist/artifacts/readStableArtifact.js +20 -4
- package/dist/browser/CdpCaptureCompleteness.js +2 -0
- package/dist/browser/CdpCaptureEventHandlers.js +165 -12
- package/dist/browser/CdpCaptureEventTypes.js +5 -1
- package/dist/browser/CdpCaptureEvents.js +34 -0
- package/dist/browser/CdpConnection.js +30 -11
- package/dist/browser/CdpOptionalCommand.js +2 -3
- package/dist/browser/CdpPageCapture.js +23 -1
- package/dist/browser/PlaywrightElectronActiveActions.js +32 -23
- package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
- package/dist/browser/PlaywrightElectronActiveProvider.js +130 -122
- package/dist/browser/WebSourceMapFetcher.js +426 -72
- package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
- package/dist/browser/history/CaptureFailures.js +137 -0
- package/dist/browser/history/CaptureFormatError.js +10 -0
- package/dist/browser/history/CaptureRedaction.js +65 -0
- package/dist/browser/history/CaptureRelease.js +17 -0
- package/dist/browser/history/HarCapture.js +165 -0
- package/dist/browser/history/HarCaptureAdapter.js +20 -0
- package/dist/browser/history/HarCaptureProcess.js +57 -0
- package/dist/browser/history/HarJson.js +92 -0
- package/dist/browser/history/HarSchema.js +72 -0
- package/dist/browser/history/HistoricalCaptureDecoder.js +188 -0
- package/dist/browser/history/HistoricalCaptureFormatAdapter.js +1 -0
- package/dist/browser/history/MitmproxyCaptureAdapter.js +42 -0
- package/dist/cli/analysisSelector.js +23 -0
- package/dist/cli/applicationCommands.js +2 -3
- package/dist/cli/artifactCommands.js +26 -1
- package/dist/cli/binaryDiagnosticsCommands.js +39 -0
- package/dist/cli/coreAnalysisCommands.js +2 -2
- package/dist/cli/coreBinaryCommands.js +78 -20
- package/dist/cli/electronCommands.js +21 -13
- package/dist/cli/evmCommands.js +24 -0
- package/dist/cli/firmwareCommands.js +6 -3
- package/dist/cli/javascriptApplicationAnalysis.js +20 -3
- package/dist/cli/jsonOutput.js +38 -0
- package/dist/cli/nativeCallCommands.js +34 -0
- package/dist/cli/processCommands.js +1 -1
- package/dist/cli/streamedJsonOutput.js +56 -0
- package/dist/cli/utilityCommands.js +2 -0
- package/dist/cli/webNetworkCaptureCommands.js +40 -0
- package/dist/cli/webRuntimeCommands.js +8 -8
- package/dist/cli.js +11 -4
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +6 -1
- package/dist/cliJsonInput.js +35 -1
- package/dist/cliOutput.js +21 -6
- package/dist/composition/binaryDiagnostics.js +8 -0
- package/dist/composition/evm.js +4 -0
- package/dist/composition/webNetworkCaptures.js +6 -0
- package/dist/config/environment.js +4 -0
- package/dist/config/ghidraStartupTimeout.js +17 -0
- package/dist/config/mcpResponseBudget.js +22 -0
- package/dist/config/parseConfig.js +2 -1
- package/dist/contracts/artifactToolContracts.js +6 -0
- package/dist/contracts/browserCaptureToolInputSchema.js +43 -0
- package/dist/contracts/browserToolContracts.js +4 -3
- package/dist/contracts/enhancedInputs.js +5 -3
- package/dist/contracts/enhancedToolContracts.js +3 -3
- package/dist/contracts/errorSchemas.js +8 -1
- package/dist/contracts/evm/evmToolContracts.js +20 -0
- package/dist/contracts/hopperMemoryContracts.js +2 -5
- package/dist/contracts/investigationExamples.js +2 -2
- package/dist/contracts/javascript/electronToolContracts.js +1 -1
- package/dist/contracts/managed/managedToolContracts.js +8 -6
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +42 -0
- package/dist/contracts/native/nativeToolContracts.js +21 -3
- package/dist/contracts/officialToolContracts.js +26 -24
- package/dist/contracts/process/processCaptureExample.js +2 -0
- package/dist/contracts/promptContracts.js +3 -3
- package/dist/contracts/sessionLifecycleInputs.js +18 -5
- package/dist/contracts/sessionStatusContract.js +8 -2
- package/dist/contracts/sessionToolContracts.js +8 -3
- package/dist/contracts/sessionToolSchemas.js +8 -4
- package/dist/contracts/toolContractExamples.js +1 -2
- package/dist/contracts/toolContractHelpers.js +4 -1
- package/dist/contracts/toolContracts.js +6 -0
- package/dist/contracts/toolEffects.js +30 -1
- package/dist/contracts/toolOutputSchemaGroups.js +33 -28
- package/dist/contracts/toolOutputSchemaPrimitives.js +19 -1
- package/dist/contracts/toolSchemaMetadata.js +69 -10
- package/dist/contracts/webNetworkCaptureToolContracts.js +24 -0
- package/dist/domain/analysisErrorBase.js +22 -2
- package/dist/domain/analysisErrorCore.js +61 -5
- package/dist/domain/analysisErrorPresentation.js +95 -12
- package/dist/domain/analysisErrorProjection.js +148 -19
- package/dist/domain/analysisSnapshot.js +166 -2
- package/dist/domain/android/androidAnalysis.js +2 -4
- package/dist/domain/android/androidApplication.js +17 -9
- package/dist/domain/apple/appleApplication.js +41 -14
- package/dist/domain/apple/dyldEnvironment.js +73 -0
- package/dist/domain/apple/dyldPaths.js +81 -0
- package/dist/domain/apple/dylibResolution.js +478 -0
- package/dist/domain/apple/dylibResolutionFindings.js +77 -0
- package/dist/domain/apple/interfaceBuilderGraph.js +25 -13
- package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
- package/dist/domain/apple/keyedArchive.js +9 -1
- package/dist/domain/apple/machoContainer.js +54 -0
- package/dist/domain/apple/plistNumbers.js +76 -0
- package/dist/domain/artifactIdentity.js +29 -0
- package/dist/domain/artifactInventoryEvidence.js +19 -24
- package/dist/domain/artifactPathSyntax.js +1 -1
- package/dist/domain/bridgeCandidateProjection.js +71 -0
- package/dist/domain/browserCompleteness.js +1 -0
- package/dist/domain/browserObservation.js +1 -1
- package/dist/domain/browserObservationError.js +24 -5
- package/dist/domain/browserObservationSchemas.js +13 -0
- package/dist/domain/browserScenarioValues.js +5 -2
- package/dist/domain/bundleComparison.js +3 -2
- package/dist/domain/callPathSchemas.js +1 -1
- package/dist/domain/canonicalDigest.js +13 -1
- 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/comparisonStatus.js +2 -30
- package/dist/domain/configurationErrors.js +1 -1
- package/dist/domain/conformanceTrustGate.js +0 -16
- package/dist/domain/evidence.js +78 -11
- package/dist/domain/evidenceBundle.js +42 -1
- package/dist/domain/evidenceErrors.js +12 -1
- package/dist/domain/evm/evmInterface.js +63 -0
- package/dist/domain/explicitSensitiveFailure.js +108 -0
- package/dist/domain/explicitSensitiveValues.js +10 -0
- package/dist/domain/firmware/firmwareAnalysis.js +10 -4
- 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 +37 -6
- package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
- package/dist/domain/javascript/htmlArtifactReferences.js +40 -0
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
- package/dist/domain/javascript/javascriptApplicationGraph.js +13 -0
- package/dist/domain/javascript/javascriptAstValues.js +20 -0
- package/dist/domain/javascript/javascriptExportShapeComparison.js +21 -5
- package/dist/domain/javascript/javascriptExportShapeVariants.js +0 -10
- package/dist/domain/javascript/javascriptRecovery.js +3 -8
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +97 -2
- package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +22 -5
- package/dist/domain/javascript/javascriptSemanticGraph.js +34 -5
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +25 -17
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
- package/dist/domain/javascript/javascriptSemanticValues.js +83 -11
- 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 +14 -4
- package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -16
- package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
- package/dist/domain/jsonSerialization.js +109 -0
- package/dist/domain/jsonValue.js +91 -3
- package/dist/domain/localPath.js +8 -0
- package/dist/domain/managed/managedApplicationGraph.js +10 -10
- package/dist/domain/managed/managedInspectionEvidence.js +16 -0
- package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
- package/dist/domain/managed/managedNativeVerification.js +3 -9
- package/dist/domain/native/binaryLayout.js +357 -0
- package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
- package/dist/domain/native/nativeCallObservation.js +186 -0
- package/dist/domain/native/nativeCallPartialObservation.js +33 -0
- package/dist/domain/native/objcSwiftMetadata.js +0 -39
- package/dist/domain/native/recordedCrash.js +266 -0
- package/dist/domain/native/recordedCrashNoteCoverage.js +73 -0
- package/dist/domain/{processCapture.js → process/processCapture.js} +143 -2
- package/dist/domain/{processCaptureExample.js → process/processCaptureExample.js} +5 -0
- package/dist/domain/process/processCaptureParsing.js +54 -0
- package/dist/domain/{processCaptureValidation.js → process/processCaptureValidation.js} +18 -2
- package/dist/domain/{processComparison.js → process/processComparison.js} +39 -5
- package/dist/domain/{processObservation.js → process/processObservation.js} +1 -1
- package/dist/domain/{processScenario.js → process/processScenario.js} +11 -10
- package/dist/domain/{processTraceSpecification.js → process/processTraceSpecification.js} +1 -1
- package/dist/domain/propertyListKeys.js +1 -1
- package/dist/domain/propertyListXmlText.js +19 -0
- package/dist/domain/providerAdapterError.js +1 -1
- package/dist/domain/providerOperationHealth.js +54 -0
- package/dist/domain/providerSelectionError.js +4 -2
- package/dist/domain/reconstructionVerification.js +9 -46
- package/dist/domain/reconstructionVerificationSchemas.js +3 -3
- package/dist/domain/residualUnknown.js +3 -2
- package/dist/domain/staticRuntimeCorrelation.js +9 -46
- 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 +1 -0
- package/dist/domain/webNetworkCapture.js +118 -0
- package/dist/domain/webNetworkCaptureCoordinates.js +58 -0
- package/dist/domain/webRuntime.js +19 -5
- package/dist/domain/webSourceLocation.js +1 -0
- package/dist/dotnet/ManagedExceptionRegionValidation.js +41 -0
- package/dist/dotnet/ManagedMemberInspector.js +4 -2
- package/dist/dotnet/ManagedMemberInspectorCore.js +38 -32
- package/dist/dotnet/ManagedMemberInstructionDecoder.js +23 -7
- package/dist/dotnet/ManagedMemberRows.js +14 -3
- package/dist/dotnet/ManagedMetadataHeaps.js +20 -2
- package/dist/dotnet/ManagedMetadataInventory.js +38 -28
- package/dist/dotnet/ManagedMetadataInventoryRows.js +24 -10
- package/dist/dotnet/ManagedMethodBodyReader.js +7 -1
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +15 -3
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +3 -1
- package/dist/dotnet/ManagedPeReader.js +11 -0
- package/dist/evm/EvmBytecodeCarrier.js +21 -0
- package/dist/evm/EvmWorkerLimits.js +40 -0
- package/dist/evm/EvmoleFailures.js +126 -0
- package/dist/evm/EvmoleInterfaceAdapter.js +53 -0
- package/dist/evm/EvmoleInterfaceProvider.js +273 -0
- package/dist/evm/EvmoleInterfaceWorker.js +87 -0
- package/dist/evm/EvmoleRelease.js +16 -0
- package/dist/firmware/FirmwareCommand.js +1 -0
- package/dist/firmware/FirmwareFiles.js +1 -1
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +5 -0
- package/dist/ghidra/GhidraClient.js +47 -14
- package/dist/ghidra/GhidraDiagnostics.js +7 -7
- package/dist/ghidra/GhidraFunctionValues.js +10 -7
- package/dist/ghidra/GhidraInstallation.js +18 -21
- package/dist/ghidra/GhidraInventoryValues.js +14 -4
- package/dist/ghidra/GhidraJavaLaunch.js +62 -0
- package/dist/ghidra/GhidraLauncher.js +34 -16
- package/dist/ghidra/GhidraProvider.js +2 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +15 -3
- package/dist/ghidra/GhidraProviderClient.js +23 -12
- package/dist/ghidra/GhidraSessionError.js +11 -7
- package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
- package/dist/ghidra/GhidraTransport.js +20 -0
- package/dist/hopper/BridgeLauncher.js +33 -11
- package/dist/hopper/HopperAnalysisProfile.js +62 -4
- package/dist/hopper/HopperCleanup.js +15 -3
- package/dist/hopper/HopperClient.js +222 -14
- package/dist/hopper/HopperFileOffset.js +237 -0
- package/dist/hopper/HopperMachOImage.js +196 -0
- package/dist/hopper/HopperOperationStage.js +6 -0
- package/dist/hopper/HopperProvider.js +63 -9
- package/dist/hopper/HopperProviderCapabilities.js +19 -1
- package/dist/hopper/HopperRegexSearch.js +137 -0
- package/dist/hopper/HopperRegexWorker.js +27 -0
- package/dist/hopper/HopperRequestQueue.js +68 -19
- package/dist/hopper/HopperTargetLease.js +3 -2
- package/dist/hopper/LinuxPrivateDisplayProbe.js +4 -2
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
- package/dist/inspector/V8InspectorCaptureProjection.js +8 -3
- package/dist/inspector/V8InspectorProvider.js +47 -11
- package/dist/javascript/recovery/WakaruCommand.js +3 -0
- package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
- package/dist/javascript/sourceMaps/SourceMapCommand.js +17 -0
- package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
- package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
- 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 +32 -16
- 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 +82 -84
- package/dist/native/LldbCallTracer.js +541 -0
- package/dist/native/LldbRetainedObservations.js +178 -0
- package/dist/native/NativeCallObservation.js +194 -0
- package/dist/native/NativeMacOSProvider.js +117 -20
- package/dist/native/NativeMacOSProviderMetadata.js +8 -3
- package/dist/native/SignatureTargetBinding.js +155 -0
- package/dist/native/parsers/lipo.js +71 -1
- package/dist/native/pwndbg/PwndbgCoreContext.js +180 -0
- package/dist/native/pwntools/PwntoolsDecoder.js +203 -0
- package/dist/native/pwntools/PwntoolsFailures.js +180 -0
- package/dist/native/pwntools/PwntoolsLayoutProvider.js +36 -0
- package/dist/native/pwntools/PwntoolsRecordedCrashProvider.js +75 -0
- package/dist/native/pwntools/PwntoolsRelease.js +19 -0
- package/dist/native/pwntools/PwntoolsResourceLimits.js +76 -0
- package/dist/native/pwntools/RecordedCrashSourceBindings.js +46 -0
- package/dist/native/pwntools/RecordedCrashStructureBindings.js +103 -0
- package/dist/process/DarwinProcessRunTokenReader.js +293 -0
- package/dist/process/ExecFileOutput.js +20 -0
- package/dist/process/OwnedCommand.js +118 -0
- package/dist/process/ProcessOwnership.js +431 -51
- package/dist/process/ProcessOwnershipObservation.js +209 -27
- package/dist/process/ProviderProcess.js +68 -10
- package/dist/{application → process/capture}/ProcessCaptureCapability.js +15 -0
- package/dist/{application → process/capture}/ProcessCaptureError.js +18 -2
- package/dist/process/capture/ProcessCaptureLifecycle.js +681 -0
- package/dist/{application → process/capture}/ProcessHarness.js +195 -29
- package/dist/{application → process/capture}/ProcessSampling.js +2 -2
- package/dist/server/EvidenceMcpServer.js +146 -0
- package/dist/server/createServer.js +37 -8
- package/dist/server/promptCompletion.js +10 -3
- package/dist/server/registerAndroidTools.js +2 -4
- package/dist/server/registerApplicationTools/helpers.js +2 -4
- package/dist/server/registerArtifactComparisonTool.js +11 -7
- package/dist/server/registerBinaryDiagnosticsTools.js +15 -0
- package/dist/server/registerBrowserScenarioTool.js +2 -4
- package/dist/server/registerBrowserTools.js +2 -4
- package/dist/server/registerBundleComparisonTool.js +2 -3
- package/dist/server/registerCloseLifecycleTool.js +8 -18
- package/dist/server/registerElectronTools.js +2 -4
- package/dist/server/registerEnhancedTools.js +18 -59
- package/dist/server/registerEvidenceTools.js +3 -5
- package/dist/server/registerEvmTools.js +15 -0
- package/dist/server/registerFirmwareTools.js +2 -4
- package/dist/server/registerFunctionComparisonTool.js +10 -6
- package/dist/server/registerInvestigationTools.js +7 -7
- package/dist/server/registerJavaScriptRecoveryTool.js +2 -4
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +2 -4
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +2 -4
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +2 -4
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +2 -4
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +2 -4
- package/dist/server/registerOfficialTools.js +2 -4
- package/dist/server/registerProcessComparisonTool.js +72 -46
- package/dist/server/registerRecordedCrashTools.js +15 -0
- package/dist/server/registerSessionRecordTools.js +5 -6
- package/dist/server/registerSessionStatusTool.js +17 -3
- package/dist/server/registerSessionTools.js +13 -5
- package/dist/server/registerWebModuleTool.js +2 -4
- package/dist/server/registerWebNetworkCaptureTool.js +26 -0
- package/dist/server/registerWebRuntimeTools.js +3 -7
- package/dist/server/registerWebScriptTool.js +2 -4
- package/dist/server/registerWebSourceLocationTool.js +2 -4
- package/dist/server/runDerivedOperation.js +15 -3
- package/dist/server/sessionAvailabilityPolicy.js +3 -1
- package/dist/server/sessionToolPolicies.js +1 -1
- package/dist/server/toolRegistrationOptions.js +2 -2
- package/dist/server/toolResult.js +63 -11
- package/dist/server/toolResultEncoding.js +33 -0
- package/install.sh +1 -1
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +42 -9
- package/scripts/electron-active-hook-boundaries.cjs +18 -20
- package/scripts/electron-active-hook.cjs +241 -37
- package/scripts/rea.mjs +11 -3
- package/skills/reverse-engineer-anything/SKILL.md +32 -4
- package/skills/reverse-engineer-anything/references/javascript-applications.md +8 -1
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +29 -0
- package/third_party/README.md +60 -0
- package/third_party/evmole/LICENSE +21 -0
- package/third_party/evmole/README.md +22 -0
- package/third_party/pwndbg/LICENSE.md +21 -0
- package/third_party/pwndbg/README.md +23 -0
- package/third_party/pwntools/README.md +40 -0
- package/dist/application/AuthorizedArtifactInventory.js +0 -7
- package/dist/application/ProcessCaptureLifecycle.js +0 -299
- package/dist/application/StoreFileLock.js +0 -124
- package/dist/contracts/processCaptureExample.js +0 -2
- package/dist/domain/bytecodeProvider.js +0 -178
- package/dist/domain/customProtocolCapture.js +0 -137
- package/dist/domain/eventProcessTree.js +0 -225
- package/dist/domain/mobileApplicationInvestigation.js +0 -159
- package/dist/domain/packageAnalysis.js +0 -123
- package/dist/domain/peInspection.js +0 -197
- package/dist/domain/processCaptureParsing.js +0 -21
- package/dist/domain/protocolCapture.js +0 -217
- package/dist/domain/runtimeIdentification.js +0 -212
- package/dist/generatedMcpToolCatalog.js +0 -37
- package/dist/ghidra/GhidraDefaults.js +0 -2
- /package/dist/application/{ArtifactExtractionDestination.js → artifacts/ArtifactExtractionDestination.js} +0 -0
- /package/dist/{application/ArtifactInventory → artifacts/inventory}/policy.js +0 -0
- /package/dist/{application/ArtifactInventory → artifacts/inventory}/types.js +0 -0
- /package/dist/domain/{processEvidenceProvider.js → process/processEvidenceProvider.js} +0 -0
- /package/dist/domain/{processTraceComparison.js → process/processTraceComparison.js} +0 -0
- /package/dist/domain/{processTraceDimensionProjection.js → process/processTraceDimensionProjection.js} +0 -0
- /package/dist/domain/{processTraceEvaluation.js → process/processTraceEvaluation.js} +0 -0
- /package/dist/{application → process/capture}/FilesystemSnapshot.js +0 -0
- /package/dist/{application → process/capture}/ProcessCaptureEnvironment.js +0 -0
- /package/dist/{application → process/capture}/ProcessCaptureJournal.js +0 -0
- /package/dist/{application → process/capture}/ProcessFilesystemEffects.js +0 -0
- /package/dist/{application → process/capture}/ProcessNormalization.js +0 -0
- /package/dist/{application → process/capture}/ProcessScenarioRuntimeValidation.js +0 -0
- /package/dist/{application → process/capture}/ProcessTimer.js +0 -0
- /package/dist/{application → process/capture}/TerminalRenderer.js +0 -0
|
@@ -25,6 +25,11 @@ class ReaJadxBridge {
|
|
|
25
25
|
private record MethodSnapshot(String name, String shortId, Map<String, Object> summary) {}
|
|
26
26
|
private record ClassSnapshot(JavaClass node, List<MethodSnapshot> methods, Map<String, Object> summary) {}
|
|
27
27
|
|
|
28
|
+
private static final class InputFailure extends IllegalArgumentException {
|
|
29
|
+
final String field;
|
|
30
|
+
InputFailure(String field, String message) { super(message); this.field = field; }
|
|
31
|
+
}
|
|
32
|
+
|
|
28
33
|
private ReaJadxBridge(SessionHolder holder) { this.holder = holder; }
|
|
29
34
|
|
|
30
35
|
private static CallToolResult text(String value, boolean failed) {
|
|
@@ -100,8 +105,9 @@ class ReaJadxBridge {
|
|
|
100
105
|
}
|
|
101
106
|
String name = string(args, "class_name");
|
|
102
107
|
List<ClassSnapshot> candidates = classes.get(name);
|
|
103
|
-
if (candidates == null) throw new
|
|
104
|
-
|
|
108
|
+
if (candidates == null) throw new InputFailure("class_name", "Exact class not found: " + name
|
|
109
|
+
+ "; use search_android_classes to discover fully qualified names.");
|
|
110
|
+
if (candidates.size() != 1) throw new InputFailure("class_name", "Ambiguous metadata class identity: " + name
|
|
105
111
|
+ "; raw identities: " + candidates.stream().map(candidate -> candidate.node().getRawName()).toList());
|
|
106
112
|
return candidates.get(0);
|
|
107
113
|
}
|
|
@@ -109,7 +115,8 @@ class ReaJadxBridge {
|
|
|
109
115
|
private List<MethodSnapshot> methods(ClassSnapshot cls, JsonObject args) {
|
|
110
116
|
String name = string(args, "method_name");
|
|
111
117
|
List<MethodSnapshot> result = cls.methods().stream().filter(method -> method.name().equals(name)).toList();
|
|
112
|
-
if (result.isEmpty()) throw new
|
|
118
|
+
if (result.isEmpty()) throw new InputFailure("method_name", "Method not found: " + name
|
|
119
|
+
+ "; use inspect_android_class to discover available methods.");
|
|
113
120
|
return result;
|
|
114
121
|
}
|
|
115
122
|
|
|
@@ -141,7 +148,7 @@ class ReaJadxBridge {
|
|
|
141
148
|
if (name.equals("get_method_body")) {
|
|
142
149
|
List<MethodSnapshot> overloads = methods(cls, args);
|
|
143
150
|
int index = integer(args, "overload_index", 0);
|
|
144
|
-
if (index >= overloads.size()) throw new
|
|
151
|
+
if (index >= overloads.size()) throw new InputFailure("overload_index", "overload_index out of range: " + index);
|
|
145
152
|
JavaMethod method = method(cls, overloads.get(index));
|
|
146
153
|
JadxSession.SmartCode code = current.getMethodBodySmart(method, current.getMaxSourceBytes(), true);
|
|
147
154
|
return json(Map.of("class_name", cls.summary().get("full_name"),
|
|
@@ -155,7 +162,7 @@ class ReaJadxBridge {
|
|
|
155
162
|
if (name.equals("get_xrefs_to_class")) uses = cls.node().getUseIn();
|
|
156
163
|
else {
|
|
157
164
|
List<MethodSnapshot> overloads = methods(cls, args);
|
|
158
|
-
if (overloads.size() != 1) throw new
|
|
165
|
+
if (overloads.size() != 1) throw new InputFailure("method_name", "Method references require a unique overload");
|
|
159
166
|
target += "." + overloads.get(0).name();
|
|
160
167
|
uses = method(cls, overloads.get(0)).getUseIn();
|
|
161
168
|
}
|
|
@@ -211,6 +218,8 @@ class ReaJadxBridge {
|
|
|
211
218
|
tool.getInputSchema().getRequired(), null), description, null, null, null, null, null, null);
|
|
212
219
|
server.addTool(narrowed, (connection, request, continuation) -> {
|
|
213
220
|
try { return bridge.handle(name, request.getArguments()); }
|
|
221
|
+
catch (InputFailure error) { return text(JSON.toJson(Map.of(
|
|
222
|
+
"kind", "invalid-input", "field", error.field, "message", error.getMessage())), true); }
|
|
214
223
|
catch (IllegalArgumentException error) { return text(error.getMessage(), true); }
|
|
215
224
|
});
|
|
216
225
|
}
|
|
@@ -52,6 +52,8 @@ import ghidra.app.decompiler.ClangCaseToken;
|
|
|
52
52
|
import ghidra.app.decompiler.ClangNode;
|
|
53
53
|
import ghidra.framework.Application;
|
|
54
54
|
import ghidra.program.model.address.Address;
|
|
55
|
+
import ghidra.program.model.address.AddressIterator;
|
|
56
|
+
import ghidra.program.model.address.AddressSet;
|
|
55
57
|
import ghidra.program.model.address.AddressSpace;
|
|
56
58
|
import ghidra.program.model.address.AddressRange;
|
|
57
59
|
import ghidra.program.model.address.AddressRangeIterator;
|
|
@@ -723,8 +725,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
723
725
|
if (!direction.equals("incoming") && !direction.equals("outgoing")) {
|
|
724
726
|
throw new RequestFailure("invalid_request", "direction must be incoming or outgoing");
|
|
725
727
|
}
|
|
726
|
-
|
|
727
|
-
List<Reference> references = collectReferences(scan.instructions, direction);
|
|
728
|
+
List<Reference> references = collectReferences(function, direction);
|
|
728
729
|
JsonArray edges = new JsonArray();
|
|
729
730
|
for (Reference reference : references) {
|
|
730
731
|
edges.add(referenceEdge(reference));
|
|
@@ -735,7 +736,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
735
736
|
result.add("references", edges);
|
|
736
737
|
result.addProperty("reference_kinds_available", true);
|
|
737
738
|
JsonArray unresolvedCalls = new JsonArray();
|
|
738
|
-
if (direction.equals("outgoing")) for (Instruction instruction :
|
|
739
|
+
if (direction.equals("outgoing")) for (Instruction instruction : scanInstructions(function, Integer.MAX_VALUE).instructions) {
|
|
739
740
|
if (!instruction.getFlowType().isCall()) continue;
|
|
740
741
|
boolean resolved = false;
|
|
741
742
|
for (Reference reference : instruction.getReferencesFrom()) if (reference.getReferenceType().isCall()) resolved = true;
|
|
@@ -1007,6 +1008,11 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1007
1008
|
Address entry = function.getEntryPoint();
|
|
1008
1009
|
if (function.isExternal() || !currentProgram.getMemory().contains(entry))
|
|
1009
1010
|
throw new RequestFailure("invalid_request", "Annotations require a local function entry: " + canonicalAddress(entry));
|
|
1011
|
+
for (String field : List.of("name", "comment", "inline_comment")) {
|
|
1012
|
+
if (params.has(field)) validateAnnotationText(requireText(params, field), field);
|
|
1013
|
+
}
|
|
1014
|
+
String leafName = params.has("name")
|
|
1015
|
+
? annotationLeafName(function, requireString(params, "name")) : null;
|
|
1010
1016
|
int transaction = currentProgram.startTransaction("REA function annotations");
|
|
1011
1017
|
boolean commit = false;
|
|
1012
1018
|
try {
|
|
@@ -1020,7 +1026,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1020
1026
|
}
|
|
1021
1027
|
}
|
|
1022
1028
|
if (params.has("name"))
|
|
1023
|
-
function.setName(
|
|
1029
|
+
function.setName(leafName, SourceType.USER_DEFINED);
|
|
1024
1030
|
monitor.checkCancelled();
|
|
1025
1031
|
invalidateAnalysisCaches();
|
|
1026
1032
|
JsonObject readback = annotationReadback(function);
|
|
@@ -1028,7 +1034,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1028
1034
|
if (!params.has(field)) continue;
|
|
1029
1035
|
String requested = requireText(params, field);
|
|
1030
1036
|
JsonElement measured = readback.get(field);
|
|
1031
|
-
String expected =
|
|
1037
|
+
String expected = field.equals("name") ? leafName : requested.isEmpty() ? null : requested;
|
|
1032
1038
|
String observed = field.equals("name") ? function.getName() :
|
|
1033
1039
|
(measured.isJsonNull() ? null : measured.getAsString());
|
|
1034
1040
|
if (!java.util.Objects.equals(expected, observed))
|
|
@@ -1058,6 +1064,22 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1058
1064
|
}
|
|
1059
1065
|
}
|
|
1060
1066
|
|
|
1067
|
+
private String annotationLeafName(Function function, String requested) {
|
|
1068
|
+
// Fully qualified readback must be usable as an idempotent rename input.
|
|
1069
|
+
if (requested.equals(procedureName(function))) return function.getName();
|
|
1070
|
+
String namespace = function.getParentNamespace().isGlobal()
|
|
1071
|
+
? "" : function.getParentNamespace().getName(true);
|
|
1072
|
+
String prefix = namespace + "::";
|
|
1073
|
+
if (!namespace.isEmpty() && requested.startsWith(prefix)) {
|
|
1074
|
+
String leaf = requested.substring(prefix.length());
|
|
1075
|
+
if (!leaf.isEmpty()) return leaf;
|
|
1076
|
+
throw new RequestFailure("invalid_function_name",
|
|
1077
|
+
"Function name has an empty leaf within namespace " + namespace + " at " +
|
|
1078
|
+
canonicalAddress(function.getEntryPoint()) + ": " + requested);
|
|
1079
|
+
}
|
|
1080
|
+
return requested;
|
|
1081
|
+
}
|
|
1082
|
+
|
|
1061
1083
|
private static String requireText(JsonObject params, String field) {
|
|
1062
1084
|
JsonElement value = params.get(field);
|
|
1063
1085
|
if (value == null || !value.isJsonPrimitive() || !value.getAsJsonPrimitive().isString())
|
|
@@ -1065,6 +1087,21 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1065
1087
|
return value.getAsString();
|
|
1066
1088
|
}
|
|
1067
1089
|
|
|
1090
|
+
private static void validateAnnotationText(String text, String field) {
|
|
1091
|
+
for (int index = 0; index < text.length(); index++) {
|
|
1092
|
+
char character = text.charAt(index);
|
|
1093
|
+
if (character == 0)
|
|
1094
|
+
throw new RequestFailure("invalid_request", "Annotation " + field + " contains NUL at UTF-16 index " + index + "; Ghidra's decompiler cannot marshal NUL text");
|
|
1095
|
+
if (Character.isHighSurrogate(character) && index + 1 < text.length() &&
|
|
1096
|
+
Character.isLowSurrogate(text.charAt(index + 1))) {
|
|
1097
|
+
index++;
|
|
1098
|
+
continue;
|
|
1099
|
+
}
|
|
1100
|
+
if (Character.isSurrogate(character))
|
|
1101
|
+
throw new RequestFailure("invalid_request", "Annotation " + field + " contains an unpaired Unicode surrogate at UTF-16 index " + index + "; Ghidra cannot preserve it as annotation text");
|
|
1102
|
+
}
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1068
1105
|
private JsonObject analyzeFunction(JsonObject params) throws Exception {
|
|
1069
1106
|
requireKeys(params, Set.of("procedure"));
|
|
1070
1107
|
Function function = resolveProcedure(requireString(params, "procedure"));
|
|
@@ -1074,11 +1111,11 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1074
1111
|
if (pseudocode == null) {
|
|
1075
1112
|
pseudocode = "";
|
|
1076
1113
|
}
|
|
1077
|
-
List<Reference> incomingReferences = collectReferences(
|
|
1114
|
+
List<Reference> incomingReferences = collectReferences(function, "incoming")
|
|
1078
1115
|
.stream()
|
|
1079
1116
|
.filter(reference -> !function.getBody().contains(reference.getFromAddress()))
|
|
1080
1117
|
.toList();
|
|
1081
|
-
List<Reference> outgoingReferences = collectReferences(
|
|
1118
|
+
List<Reference> outgoingReferences = collectReferences(function, "outgoing");
|
|
1082
1119
|
JsonArray incoming = referenceEdges(incomingReferences);
|
|
1083
1120
|
JsonArray outgoing = referenceEdges(outgoingReferences);
|
|
1084
1121
|
JsonArray comments = comments(scan.instructions);
|
|
@@ -1471,6 +1508,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1471
1508
|
: regexMatcher(expression, caseSensitive);
|
|
1472
1509
|
JsonArray items = new JsonArray();
|
|
1473
1510
|
for (InventoryItem item : inventory) {
|
|
1511
|
+
monitor.checkCancelled();
|
|
1474
1512
|
if (!matcher.matches(item.value)) {
|
|
1475
1513
|
continue;
|
|
1476
1514
|
}
|
|
@@ -1581,33 +1619,36 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1581
1619
|
}
|
|
1582
1620
|
|
|
1583
1621
|
private Function resolveProcedure(String value) throws Exception {
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
Function function = entry.function;
|
|
1598
|
-
Symbol symbol = function.getSymbol();
|
|
1599
|
-
String qualified = symbol == null ? function.getName() : symbol.getName(true);
|
|
1600
|
-
if (function.getName().equals(value) || qualified.equals(value)) {
|
|
1601
|
-
matches.add(function);
|
|
1622
|
+
// Explicit address syntax wins; an unprefixed identifier is first an
|
|
1623
|
+
// exact symbol name, even when every character is a hexadecimal digit.
|
|
1624
|
+
boolean explicitAddress = isExplicitReaAddress(value);
|
|
1625
|
+
if (!explicitAddress) {
|
|
1626
|
+
List<Function> matches = new ArrayList<>();
|
|
1627
|
+
for (FunctionEntry entry : procedures()) {
|
|
1628
|
+
monitor.checkCancelled();
|
|
1629
|
+
Function function = entry.function;
|
|
1630
|
+
Symbol symbol = function.getSymbol();
|
|
1631
|
+
String qualified = symbol == null ? function.getName() : symbol.getName(true);
|
|
1632
|
+
if (function.getName().equals(value) || qualified.equals(value)) {
|
|
1633
|
+
matches.add(function);
|
|
1634
|
+
}
|
|
1602
1635
|
}
|
|
1636
|
+
if (matches.size() > 1)
|
|
1637
|
+
throw new RequestFailure("ambiguous", "Ghidra procedure name is ambiguous: " + value +
|
|
1638
|
+
"; select an exact entry address from " + matches.stream()
|
|
1639
|
+
.map(function -> canonicalAddress(function.getEntryPoint())).toList());
|
|
1640
|
+
if (matches.size() == 1) return matches.get(0);
|
|
1603
1641
|
}
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1642
|
+
// Retain legacy bare-hex address input only when no symbol matches.
|
|
1643
|
+
Address address = explicitAddress ? parseReaAddress(value) : tryParseAddress(value);
|
|
1644
|
+
if (address == null)
|
|
1645
|
+
throw new RequestFailure("not_found", "Unknown Ghidra procedure name or address: " + value);
|
|
1646
|
+
Function function = currentProgram.getFunctionManager().getFunctionAt(address);
|
|
1647
|
+
if (function == null && address.isMemoryAddress())
|
|
1648
|
+
function = currentProgram.getFunctionManager().getFunctionContaining(address);
|
|
1649
|
+
if (function == null)
|
|
1650
|
+
throw new RequestFailure("not_found", "No procedure exists at the requested address: " + value);
|
|
1651
|
+
return function;
|
|
1611
1652
|
}
|
|
1612
1653
|
|
|
1613
1654
|
private JsonObject nativeApiBoundary(
|
|
@@ -2530,21 +2571,32 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
2530
2571
|
}
|
|
2531
2572
|
|
|
2532
2573
|
private List<Reference> collectReferences(
|
|
2533
|
-
|
|
2574
|
+
Function function,
|
|
2534
2575
|
String direction) throws Exception {
|
|
2576
|
+
// References can target instruction interiors or originate in embedded
|
|
2577
|
+
// data. Use actual body ownership, including an external's exact entry.
|
|
2578
|
+
AddressSet scope = new AddressSet(function.getBody());
|
|
2579
|
+
scope.add(function.getEntryPoint());
|
|
2580
|
+
boolean outgoing = direction.equals("outgoing");
|
|
2581
|
+
AddressIterator addresses = outgoing
|
|
2582
|
+
? currentProgram.getReferenceManager().getReferenceSourceIterator(scope, true)
|
|
2583
|
+
: currentProgram.getReferenceManager().getReferenceDestinationIterator(scope, true);
|
|
2535
2584
|
TreeMap<String, Reference> observed = new TreeMap<>();
|
|
2536
|
-
|
|
2585
|
+
while (addresses.hasNext()) {
|
|
2537
2586
|
monitor.checkCancelled();
|
|
2538
|
-
|
|
2587
|
+
Address address = addresses.next();
|
|
2588
|
+
if (outgoing) {
|
|
2539
2589
|
for (Reference reference : currentProgram.getReferenceManager()
|
|
2540
|
-
.getReferencesFrom(
|
|
2590
|
+
.getReferencesFrom(address)) {
|
|
2591
|
+
monitor.checkCancelled();
|
|
2541
2592
|
addReference(observed, reference);
|
|
2542
2593
|
}
|
|
2543
2594
|
}
|
|
2544
2595
|
else {
|
|
2545
2596
|
ReferenceIterator iterator = currentProgram.getReferenceManager()
|
|
2546
|
-
.getReferencesTo(
|
|
2597
|
+
.getReferencesTo(address);
|
|
2547
2598
|
while (iterator.hasNext()) {
|
|
2599
|
+
monitor.checkCancelled();
|
|
2548
2600
|
addReference(observed, iterator.next());
|
|
2549
2601
|
}
|
|
2550
2602
|
}
|
|
@@ -2944,10 +2996,46 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
2944
2996
|
return parseReaAddress(requireString(params, name));
|
|
2945
2997
|
}
|
|
2946
2998
|
|
|
2999
|
+
private static boolean isExplicitReaAddress(String value) {
|
|
3000
|
+
if (value.regionMatches(true, 0, "0x", 0, 2) &&
|
|
3001
|
+
isHexadecimal(value, 2, value.length()))
|
|
3002
|
+
return true;
|
|
3003
|
+
int separator = value.toLowerCase(Locale.ROOT).lastIndexOf(":0x");
|
|
3004
|
+
if (separator <= 0 || !isHexadecimal(value, separator + 3, value.length()))
|
|
3005
|
+
return false;
|
|
3006
|
+
// Classify the encoded space iteratively. A repeated regex alternation
|
|
3007
|
+
// can exhaust Java's stack on a long ordinary symbol name.
|
|
3008
|
+
for (int index = 0; index < separator; index++) {
|
|
3009
|
+
char item = value.charAt(index);
|
|
3010
|
+
if ((item >= 'A' && item <= 'Z') ||
|
|
3011
|
+
(item >= 'a' && item <= 'z') ||
|
|
3012
|
+
(item >= '0' && item <= '9') ||
|
|
3013
|
+
item == '.' || item == '_' || item == '~' || item == '-')
|
|
3014
|
+
continue;
|
|
3015
|
+
if (item != '%' || index + 2 >= separator ||
|
|
3016
|
+
!isHexadecimal(value, index + 1, index + 3))
|
|
3017
|
+
return false;
|
|
3018
|
+
index += 2;
|
|
3019
|
+
}
|
|
3020
|
+
return true;
|
|
3021
|
+
}
|
|
3022
|
+
|
|
3023
|
+
private static boolean isHexadecimal(String value, int start, int end) {
|
|
3024
|
+
if (start >= end) return false;
|
|
3025
|
+
for (int index = start; index < end; index++) {
|
|
3026
|
+
char item = value.charAt(index);
|
|
3027
|
+
if (!((item >= '0' && item <= '9') ||
|
|
3028
|
+
(item >= 'a' && item <= 'f') ||
|
|
3029
|
+
(item >= 'A' && item <= 'F')))
|
|
3030
|
+
return false;
|
|
3031
|
+
}
|
|
3032
|
+
return true;
|
|
3033
|
+
}
|
|
3034
|
+
|
|
2947
3035
|
private Address parseReaAddress(String value) {
|
|
2948
3036
|
Address address = tryParseAddress(value);
|
|
2949
3037
|
if (address == null) {
|
|
2950
|
-
throw new RequestFailure("invalid_request", "Unknown or invalid Ghidra address");
|
|
3038
|
+
throw new RequestFailure("invalid_request", "Unknown or invalid Ghidra address: " + value);
|
|
2951
3039
|
}
|
|
2952
3040
|
return address;
|
|
2953
3041
|
}
|
|
@@ -2956,22 +3044,31 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
2956
3044
|
try {
|
|
2957
3045
|
String spaceName = null;
|
|
2958
3046
|
String offset = value;
|
|
2959
|
-
int separator = value.lastIndexOf(":0x");
|
|
3047
|
+
int separator = value.toLowerCase(Locale.ROOT).lastIndexOf(":0x");
|
|
2960
3048
|
if (separator >= 0) {
|
|
2961
3049
|
spaceName = decodeAddressSpace(value.substring(0, separator));
|
|
2962
3050
|
offset = value.substring(separator + 3);
|
|
2963
3051
|
}
|
|
2964
|
-
else if (value.startsWith("0x")) {
|
|
3052
|
+
else if (value.startsWith("0x") || value.startsWith("0X")) {
|
|
2965
3053
|
offset = value.substring(2);
|
|
2966
3054
|
}
|
|
2967
|
-
if (!offset.
|
|
3055
|
+
if (!isHexadecimal(offset, 0, offset.length())) {
|
|
2968
3056
|
return null;
|
|
2969
3057
|
}
|
|
2970
3058
|
AddressSpace space = spaceName == null
|
|
2971
3059
|
? currentProgram.getAddressFactory().getDefaultAddressSpace()
|
|
2972
3060
|
: currentProgram.getAddressFactory().getAddressSpace(spaceName);
|
|
2973
|
-
|
|
2974
|
-
|
|
3061
|
+
if (space == null) return null;
|
|
3062
|
+
Address address = space.getAddress(offset);
|
|
3063
|
+
BigInteger requestedOffset = new BigInteger(offset, 16);
|
|
3064
|
+
BigInteger parsedOffset = new BigInteger(Long.toUnsignedString(address.getOffset()));
|
|
3065
|
+
if (!requestedOffset.equals(parsedOffset))
|
|
3066
|
+
throw new RequestFailure("invalid_request",
|
|
3067
|
+
"Ghidra address offset cannot be represented without truncation in space " +
|
|
3068
|
+
space.getName() + ": requested " + value + ", parsed " + canonicalAddress(address));
|
|
3069
|
+
return address;
|
|
3070
|
+
}
|
|
3071
|
+
catch (RequestFailure failure) { throw failure; }
|
|
2975
3072
|
catch (Exception exception) {
|
|
2976
3073
|
return null;
|
|
2977
3074
|
}
|
|
@@ -3055,9 +3152,29 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
3055
3152
|
);
|
|
3056
3153
|
}
|
|
3057
3154
|
catch (PatternSyntaxException exception) {
|
|
3058
|
-
|
|
3155
|
+
// Java wraps compiler stack exhaustion in PatternSyntaxException
|
|
3156
|
+
// without retaining its cause. This producer reason is not bad syntax.
|
|
3157
|
+
if (exception.getDescription().equals("Stack overflow during pattern compilation"))
|
|
3158
|
+
throw regexStackExhausted(expression, "compiling");
|
|
3159
|
+
throw new RequestFailure("invalid_request", "Invalid regex pattern " + expression + ": " + exception.getDescription() + " at index " + exception.getIndex());
|
|
3160
|
+
}
|
|
3161
|
+
catch (StackOverflowError exhausted) {
|
|
3162
|
+
throw regexStackExhausted(expression, "compiling");
|
|
3059
3163
|
}
|
|
3060
|
-
return value ->
|
|
3164
|
+
return value -> {
|
|
3165
|
+
try {
|
|
3166
|
+
return pattern.matcher(value).find();
|
|
3167
|
+
}
|
|
3168
|
+
catch (StackOverflowError exhausted) {
|
|
3169
|
+
throw regexStackExhausted(expression, "matching");
|
|
3170
|
+
}
|
|
3171
|
+
};
|
|
3172
|
+
}
|
|
3173
|
+
|
|
3174
|
+
private static RequestFailure regexStackExhausted(String expression, String stage) {
|
|
3175
|
+
return new RequestFailure("regex_stack_exhausted",
|
|
3176
|
+
"Ghidra's Java regex engine exhausted its stack while " + stage +
|
|
3177
|
+
" pattern " + expression + ". Use literal mode or simplify the regex; the session remains usable.");
|
|
3061
3178
|
}
|
|
3062
3179
|
|
|
3063
3180
|
private static SessionDescriptor readDescriptor(Path path) throws IOException {
|
|
@@ -3114,7 +3231,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
3114
3231
|
private void requireDocument(JsonObject params) {
|
|
3115
3232
|
String document = optionalString(params, "document");
|
|
3116
3233
|
if (document != null && !document.equals(currentProgram.getName())) {
|
|
3117
|
-
throw new RequestFailure("not_found", "Unknown Ghidra Program identity");
|
|
3234
|
+
throw new RequestFailure("not_found", "Unknown Ghidra Program identity: " + document + "; active program: " + currentProgram.getName());
|
|
3118
3235
|
}
|
|
3119
3236
|
}
|
|
3120
3237
|
|
|
@@ -3226,7 +3343,16 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
3226
3343
|
|
|
3227
3344
|
private static void writeResponse(BufferedWriter writer, JsonObject response) throws IOException {
|
|
3228
3345
|
String encoded = GSON.toJson(response);
|
|
3229
|
-
|
|
3346
|
+
// Gson leaves UTF-16 surrogates literal. Escape them in JSON so even
|
|
3347
|
+
// diagnostics quoting ill-formed caller text remain lossless UTF-8.
|
|
3348
|
+
int start = 0;
|
|
3349
|
+
for (int index = 0; index < encoded.length(); index++) {
|
|
3350
|
+
if (!Character.isSurrogate(encoded.charAt(index))) continue;
|
|
3351
|
+
writer.write(encoded, start, index - start);
|
|
3352
|
+
writer.write("\\u" + Integer.toHexString(encoded.charAt(index)));
|
|
3353
|
+
start = index + 1;
|
|
3354
|
+
}
|
|
3355
|
+
writer.write(encoded, start, encoded.length() - start);
|
|
3230
3356
|
writer.newLine();
|
|
3231
3357
|
writer.flush();
|
|
3232
3358
|
}
|