rea-agents 6.0.0 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -18
- package/bridge/android/ReaJadxBridge.java +14 -5
- package/bridge/ghidra/ReaGhidraBridge.java +205 -51
- package/bridge/hopper_bridge.py +314 -127
- package/bridge/mitmproxy/capture.py +0 -2
- package/bridge/native/rea_lldb_tracer.py +630 -94
- package/bridge/process/ProcessRunTokenReader.swift +39 -5
- package/bridge/pwntools/recorded_crash_impl.py +4 -0
- package/dist/android/JadxConfiguration.js +274 -31
- package/dist/android/JadxMcpTransport.js +18 -2
- package/dist/android/JadxProtocol.js +6 -0
- package/dist/android/JadxProvider.js +76 -37
- package/dist/android/JadxSession.js +23 -4
- package/dist/application/AnalysisContextQueries.js +8 -35
- package/dist/application/AnalysisDocument.js +32 -0
- package/dist/application/AppBundleExecutable.js +67 -21
- package/dist/application/BinaryTargetResolver.js +5 -3
- package/dist/application/BrowserEvidence.js +3 -8
- package/dist/application/BrowserScenarioEvidence.js +2 -18
- package/dist/application/CallPathTracing.js +19 -3
- package/dist/application/CapabilityInventory.js +48 -11
- package/dist/application/ClientConfigurationDocument.js +917 -8
- package/dist/application/ClientRegistrationIdentity.js +26 -5
- package/dist/application/ClientRegistrationStatus.js +29 -14
- package/dist/application/DirectAnalysis.js +56 -51
- package/dist/application/DirectAnalysisCleanup.js +72 -0
- package/dist/application/DirectAnalysisStatus.js +4 -5
- package/dist/application/Doctor.js +19 -21
- package/dist/application/DoctorDiagnostics.js +1 -2
- package/dist/application/DoctorScope.js +25 -13
- package/dist/application/EnhancedLiteralTracing.js +22 -25
- package/dist/application/EnhancedTools.js +64 -17
- package/dist/application/EvidenceBundleFiles.js +30 -13
- package/dist/application/FunctionAnalysisEvidence.js +2 -3
- package/dist/application/InventoryProjectionEvidence.js +4 -3
- package/dist/application/InvestigationProviders.js +11 -2
- package/dist/application/JsonFiles.js +83 -28
- package/dist/application/LinuxHopper.js +9 -6
- package/dist/application/MacHopper.js +15 -18
- package/dist/application/ProcedureAddressResolution.js +11 -0
- package/dist/application/RealHopperAssertions.js +0 -11
- package/dist/application/ReconstructionCoverageService.js +7 -4
- package/dist/application/ReconstructionObligationCandidates.js +1 -1
- package/dist/application/ReconstructionObligationLedgerService.js +4 -3
- package/dist/application/ReferenceSourceImportEntries.js +1 -1
- package/dist/application/Setup.js +21 -17
- package/dist/application/SetupClientConfiguration.js +10 -15
- package/dist/application/SetupHost.js +21 -29
- package/dist/application/SetupPlan.js +11 -9
- package/dist/application/SupportedClients.js +34 -1
- package/dist/application/Uninstall.js +82 -29
- package/dist/application/Update.js +18 -3
- package/dist/application/UpdateMaintenance.js +7 -5
- package/dist/application/UpdateRuntime.js +57 -36
- package/dist/application/WebModuleTraceService.js +4 -2
- package/dist/application/WebNetworkCaptureService.js +4 -2
- package/dist/application/WebRuntimeService.js +5 -3
- package/dist/application/WebScriptExportService.js +32 -6
- package/dist/application/WebSourceLocationService.js +4 -2
- package/dist/application/WorkflowEvidence.js +105 -0
- package/dist/application/XrefsAddressResolution.js +45 -0
- package/dist/application/analysisView/AnalysisViewService.js +76 -0
- package/dist/application/binary/AnalysisClientCleanup.js +30 -5
- package/dist/application/binary/AnalysisProviderEvaluation.js +22 -7
- package/dist/application/binary/AnalysisProviderRegistry.js +4 -6
- package/dist/application/binary/AnalysisSnapshotCache.js +13 -14
- package/dist/application/binary/BinarySession.js +161 -93
- package/dist/application/binary/BinarySessionComposition.js +1 -3
- package/dist/application/binary/BinarySessionExecution.js +3 -5
- package/dist/application/binary/BinarySessionOpen.js +4 -4
- package/dist/application/binary/BinarySessionRecords.js +26 -4
- package/dist/application/binary/BinarySessionStatus.js +18 -7
- package/dist/application/binary/CompositeProvider.js +16 -17
- package/dist/application/binary/LazyAnalysisProvider.js +8 -5
- package/dist/application/binary/SessionProviderRouter.js +27 -135
- package/dist/application/binaryDiagnostics/BinaryLayoutService.js +4 -2
- package/dist/application/binaryDiagnostics/RecordedCrashService.js +4 -2
- package/dist/application/evm/EvmInterfaceService.js +4 -2
- package/dist/application/homebrew.js +48 -0
- package/dist/application/investigation/EvidenceLedger.js +21 -7
- package/dist/application/investigation/InvestigationRecords.js +8 -0
- package/dist/application/javascript/ElectronActiveEvidence.js +9 -13
- package/dist/application/javascript/JavaScriptAnalysisControl.js +34 -0
- package/dist/application/javascript/JavaScriptApplicationEvidence.js +21 -4
- package/dist/application/javascript/JavaScriptApplicationEvidenceGraph.js +19 -2
- package/dist/application/javascript/JavaScriptApplicationService.js +27 -15
- package/dist/application/javascript/JavaScriptApplicationWorkflowService.js +5 -5
- package/dist/application/javascript/JavaScriptArtifactAnalysis.js +10 -7
- package/dist/application/javascript/JavaScriptArtifactGraphBuilder.js +44 -10
- package/dist/application/javascript/JavaScriptArtifactGraphBundlers.js +11 -3
- package/dist/application/javascript/JavaScriptArtifactGraphContext.js +9 -0
- package/dist/application/javascript/JavaScriptArtifactGraphDocuments.js +8 -5
- package/dist/application/javascript/JavaScriptArtifactGraphFindings.js +12 -3
- package/dist/application/javascript/JavaScriptArtifactGraphStructure.js +0 -1
- package/dist/application/javascript/JavaScriptArtifactPathResolution.js +49 -19
- package/dist/application/javascript/JavaScriptArtifactReconstruction.js +56 -8
- package/dist/application/javascript/JavaScriptModuleRelationships.js +38 -9
- package/dist/application/javascript/JavaScriptRecoveryService.js +4 -2
- package/dist/application/javascript/JavaScriptRuntimeObservationService.js +6 -4
- package/dist/application/javascript/JavaScriptRuntimeReconciliationService.js +3 -3
- package/dist/application/javascript/JavaScriptSemanticGraphAsyncProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphBuilder.js +63 -61
- package/dist/application/javascript/JavaScriptSemanticGraphChildProcessProjection.js +1 -2
- package/dist/application/javascript/JavaScriptSemanticGraphDataProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphFlowProjection.js +1 -5
- package/dist/application/javascript/JavaScriptSemanticGraphObjectProjection.js +75 -46
- package/dist/application/javascript/JavaScriptSemanticGraphResourceProjection.js +2 -3
- package/dist/application/javascript/JavaScriptSemanticGraphValueProjection.js +64 -19
- package/dist/application/managed/ManagedApplicationGraphService.js +4 -3
- package/dist/application/managed/ManagedMemberComparisonService.js +9 -5
- package/dist/application/managed/ManagedNativeVerificationService.js +6 -4
- package/dist/application/managed/ManagedReconstructionService.js +4 -3
- package/dist/application/process/ProcessCli.js +25 -17
- package/dist/application/process/ProcessEvidence.js +4 -4
- package/dist/application/workflowInputError.js +18 -0
- package/dist/artifacts/ArtifactProvider.js +48 -13
- package/dist/artifacts/ArtifactReader.js +31 -0
- package/dist/artifacts/DirectoryArtifactReader.js +2 -1
- package/dist/artifacts/MachOSliceArtifactReader.js +106 -15
- package/dist/artifacts/NativeDmgArtifactReader.js +73 -21
- package/dist/artifacts/SafeOutputTree.js +16 -2
- package/dist/artifacts/ZipArtifactReader.js +11 -4
- package/dist/artifacts/apple/AppleAssetCatalogAnalysis.js +26 -5
- package/dist/artifacts/apple/DylibResolutionReader.js +17 -7
- package/dist/artifacts/apple/InterfaceBuilderAnalysis.js +176 -56
- package/dist/artifacts/apple/InterfaceBuilderDecodeBudget.js +195 -0
- package/dist/artifacts/apple/KeyedArchiveReader.js +55 -23
- package/dist/artifacts/apple/MachoLoadCommandReader.js +92 -31
- package/dist/artifacts/apple/NibArchive.js +81 -14
- package/dist/artifacts/apple/NibViewHierarchy.js +10 -3
- package/dist/artifacts/apple/PlistNumberLiterals.js +164 -0
- package/dist/artifacts/extraction/ArtifactExtraction.js +78 -21
- package/dist/artifacts/inventory/ArtifactGraphConstruction.js +79 -68
- package/dist/artifacts/inventory/ArtifactInventory.js +0 -1
- package/dist/artifacts/inventory/reader.js +3 -3
- package/dist/artifacts/inventory/scanCanonical.js +59 -38
- package/dist/artifacts/inventory/scanReader.js +5 -9
- package/dist/artifacts/javascript/JavaScriptArtifactFiles.js +6 -2
- package/dist/browser/BrowserScenarioPartialObservation.js +106 -0
- package/dist/browser/CdpBrowserProvider.js +2 -3
- package/dist/browser/CdpCaptureCompleteness.js +2 -0
- package/dist/browser/CdpCaptureEventHandlers.js +78 -15
- package/dist/browser/CdpCaptureEventTypes.js +5 -1
- package/dist/browser/CdpCaptureEvents.js +25 -1
- package/dist/browser/CdpCaptureValues.js +20 -0
- package/dist/browser/CdpConnection.js +30 -11
- package/dist/browser/CdpElectronProvider.js +0 -2
- package/dist/browser/CdpElectronScriptEvents.js +2 -8
- package/dist/browser/CdpElectronScripts.js +2 -3
- package/dist/browser/CdpOptionalCommand.js +2 -3
- package/dist/browser/CdpPageCapture.js +23 -1
- package/dist/browser/CdpPageCaptureScripts.js +2 -3
- package/dist/browser/CdpSafeMetadata.js +10 -10
- package/dist/browser/PlaywrightBrowserScenarioProvider.js +59 -44
- package/dist/browser/PlaywrightElectronActiveActions.js +34 -79
- package/dist/browser/PlaywrightElectronActiveProjection.js +141 -0
- package/dist/browser/PlaywrightElectronActiveProvider.js +133 -130
- package/dist/browser/PlaywrightScenarioArtifacts.js +1 -1
- package/dist/browser/PlaywrightScenarioBrowser.js +139 -39
- package/dist/browser/PlaywrightScenarioEvents.js +1 -1
- package/dist/browser/PlaywrightScenarioSession.js +39 -22
- package/dist/browser/WebSourceMapFetcher.js +426 -72
- package/dist/browser/assets/LocalWebScriptArtifacts.js +2 -2
- package/dist/browser/assets/ScriptCaptureAdapters.js +1 -1
- package/dist/browser/history/CaptureFailures.js +41 -1
- package/dist/browser/history/CaptureRelease.js +5 -0
- package/dist/browser/history/HarCaptureAdapter.js +3 -3
- package/dist/browser/history/HarJson.js +3 -2
- package/dist/browser/history/HistoricalCaptureDecoder.js +4 -2
- package/dist/browser/history/MitmproxyCaptureAdapter.js +4 -2
- package/dist/catalogIdentity.js +0 -1
- package/dist/cli/analysisSelector.js +23 -0
- package/dist/cli/analysisViewCommands.js +36 -0
- package/dist/cli/applicationCommands.js +2 -3
- package/dist/cli/artifactCommands.js +11 -12
- package/dist/cli/coreAnalysisCommands.js +3 -3
- package/dist/cli/coreBinaryCommands.js +100 -37
- package/dist/cli/coreNativeCommands.js +9 -10
- package/dist/cli/electronCommands.js +10 -9
- package/dist/cli/interactiveSetup.js +6 -6
- package/dist/cli/javascriptApplicationAnalysis.js +7 -3
- package/dist/cli/jsonOutput.js +4 -99
- package/dist/cli/managedCommands.js +7 -8
- package/dist/cli/nativeCallCommands.js +3 -5
- package/dist/cli/omittableDefaults.js +50 -0
- package/dist/cli/processCommands.js +3 -2
- package/dist/cli/setupCommands.js +16 -15
- package/dist/cli/utilityCommands.js +9 -9
- package/dist/cli/webRuntimeCommands.js +8 -8
- package/dist/cli.js +18 -9
- package/dist/cliBrowserScenarioCommands.js +2 -2
- package/dist/cliCommandNames.js +1 -1
- package/dist/cliJsonInput.js +24 -5
- package/dist/cliOutput.js +0 -38
- package/dist/composition/auxiliaryAnalysisProviders.js +27 -23
- package/dist/composition/binary.js +9 -9
- package/dist/composition/browserScenario.js +2 -1
- package/dist/composition/directAnalysis.js +20 -13
- package/dist/composition/electronScenario.js +1 -1
- package/dist/composition/optionalObservationProviders.js +12 -7
- package/dist/config/environment.js +10 -0
- package/dist/config/ghidraStartupTimeout.js +12 -0
- package/dist/config/homeDirectory.js +12 -0
- package/dist/config/mcpResponseBudget.js +30 -0
- package/dist/config/parseConfig.js +8 -3
- package/dist/config/parsers.js +19 -22
- package/dist/contracts/analysisViewToolContracts.js +56 -0
- package/dist/contracts/applicationToolContracts.js +5 -4
- package/dist/contracts/artifactComparisonExample.js +2 -2
- package/dist/contracts/artifactToolContracts.js +1 -1
- package/dist/contracts/browserScenarioToolContracts.js +1 -1
- package/dist/contracts/browserToolContracts.js +19 -15
- package/dist/contracts/enhancedInputs.js +7 -5
- package/dist/contracts/enhancedToolContracts.js +7 -6
- package/dist/contracts/evm/evmToolContracts.js +1 -1
- package/dist/contracts/functionWorkflowToolContracts.js +1 -1
- package/dist/contracts/hopperMemoryContracts.js +2 -5
- package/dist/contracts/inputSchemaPresentation.js +90 -0
- package/dist/contracts/investigationExamples.js +4 -3
- package/dist/contracts/javascript/electronToolContracts.js +2 -2
- package/dist/contracts/javascript/javascriptApplicationWorkflowExamples.js +0 -20
- package/dist/contracts/javascript/javascriptExportShapeComparisonExample.js +245 -0
- package/dist/contracts/javascript/javascriptRuntimeObservationToolContracts.js +1 -1
- package/dist/contracts/managed/managedToolContracts.js +7 -14
- package/dist/contracts/managed/managedWorkflowToolContracts.js +1 -1
- package/dist/contracts/mobileApplicationGraphExamples.js +3 -3
- package/dist/contracts/native/binaryDiagnosticsToolContracts.js +1 -1
- package/dist/contracts/native/nativeToolContracts.js +5 -3
- package/dist/contracts/officialToolContracts.js +16 -16
- package/dist/contracts/promptContracts.js +5 -5
- package/dist/contracts/providerSelection.js +1 -1
- package/dist/contracts/sessionLifecycleInputs.js +3 -7
- package/dist/contracts/sessionStatusContract.js +2 -4
- package/dist/contracts/sessionToolContracts.js +18 -8
- package/dist/contracts/sessionToolSchemas.js +3 -19
- package/dist/contracts/toolContractExamples.js +0 -1
- package/dist/contracts/toolContractHelpers.js +4 -1
- package/dist/contracts/toolContracts.js +2 -0
- package/dist/contracts/toolEffects.js +1 -1
- package/dist/contracts/toolOutputSchemaGroups.js +160 -115
- package/dist/contracts/toolOutputSchemaPrimitives.js +28 -20
- package/dist/contracts/toolSchemaMetadata.js +41 -33
- package/dist/contracts/webNetworkCaptureToolContracts.js +2 -2
- package/dist/contracts/webRuntimeToolContracts.js +1 -1
- package/dist/contracts/webScriptToolContracts.js +1 -1
- package/dist/doctorRuntime.js +7 -5
- package/dist/domain/analysisErrorBase.js +8 -3
- package/dist/domain/analysisErrorCore.js +6 -1
- package/dist/domain/analysisErrorPresentation.js +90 -20
- package/dist/domain/analysisErrorProjection.js +130 -32
- package/dist/domain/analysisSnapshot.js +29 -31
- package/dist/domain/analysisView/analysisView.js +243 -0
- package/dist/domain/analysisView/analysisViewCoverage.js +19 -0
- package/dist/domain/analysisView/binaryLayoutView.js +159 -0
- package/dist/domain/analysisView/javascriptApplicationView.js +238 -0
- package/dist/domain/android/androidAnalysis.js +2 -4
- package/dist/domain/android/androidApplication.js +18 -10
- package/dist/domain/apple/appleApplication.js +42 -15
- package/dist/domain/apple/dyldEnvironment.js +73 -0
- package/dist/domain/apple/dylibResolution.js +130 -12
- package/dist/domain/apple/dylibResolutionFindings.js +9 -7
- package/dist/domain/apple/interfaceBuilderGraph.js +25 -14
- package/dist/domain/apple/interfaceBuilderKeyedArchive.js +13 -3
- package/dist/domain/apple/keyedArchive.js +35 -3
- package/dist/domain/apple/machoContainer.js +54 -0
- package/dist/domain/apple/plistNumbers.js +76 -0
- package/dist/domain/artifactComparison.js +15 -6
- package/dist/domain/artifactGraph.js +16 -3
- package/dist/domain/artifactIdentity.js +29 -0
- package/dist/domain/artifactInventoryEvidence.js +28 -40
- package/dist/domain/artifactOperationError.js +3 -3
- package/dist/domain/artifactPartialObservation.js +1 -0
- package/dist/domain/artifactPathSyntax.js +49 -0
- package/dist/domain/binaryTarget.js +39 -13
- package/dist/domain/bridgeCandidateProjection.js +71 -0
- package/dist/domain/browserCaptureComparison.js +13 -49
- package/dist/domain/browserCompleteness.js +1 -0
- package/dist/domain/browserNetworkEvidence.js +10 -4
- package/dist/domain/browserObservation.js +0 -1
- package/dist/domain/browserObservationError.js +24 -5
- package/dist/domain/browserObservationSchemas.js +14 -3
- package/dist/domain/browserScenario.js +0 -1
- package/dist/domain/browserScenarioCapture.js +1 -2
- package/dist/domain/browserScenarioDiff.js +0 -2
- package/dist/domain/browserScenarioDiffEvidence.js +0 -12
- package/dist/domain/browserScenarioDiffValues.js +2 -2
- package/dist/domain/browserScenarioValues.js +5 -10
- package/dist/domain/bundleComparison.js +3 -2
- package/dist/domain/callPath.js +8 -9
- package/dist/domain/callPathSchemas.js +2 -2
- package/dist/domain/canonicalJsonDigestSteps.js +133 -0
- package/dist/domain/canonicalOrdering.js +9 -5
- package/dist/domain/changedBehavior.js +9 -9
- package/dist/domain/comparisonSourceEvidence.js +40 -0
- package/dist/domain/completionLedgerGeneration.js +2 -1
- package/dist/domain/configurationErrors.js +13 -1
- package/dist/domain/conformancePackage.js +4 -3
- package/dist/domain/evidence.js +65 -36
- package/dist/domain/evidenceBundle.js +47 -8
- package/dist/domain/evidenceCompletionLedger.js +2 -1
- package/dist/domain/evidenceErrors.js +12 -1
- package/dist/domain/explicitSensitiveFailure.js +17 -1
- package/dist/domain/firmware/firmwareAnalysis.js +6 -7
- package/dist/domain/functionComparison.js +4 -5
- package/dist/domain/functionComparisonDimensions.js +120 -87
- package/dist/domain/functionComparisonNormalization.js +23 -34
- package/dist/domain/functionComparisonResults.js +1 -4
- package/dist/domain/functionComparisonSchemas.js +2 -8
- package/dist/domain/functionDossierEvidence.js +2 -37
- package/dist/domain/hopperErrors.js +23 -2
- package/dist/domain/hopperValues.js +51 -8
- package/dist/domain/immutableJson.js +114 -0
- package/dist/domain/inputIssueProjection.js +3 -0
- package/dist/domain/javascript/electronActiveObservation.js +47 -64
- package/dist/domain/javascript/electronObservation.js +14 -3
- package/dist/domain/javascript/electronStaticAnalysisBrowser.js +10 -9
- package/dist/domain/javascript/electronStaticAnalysisIpc.js +2 -1
- package/dist/domain/javascript/electronStaticAnalysisNative.js +2 -1
- package/dist/domain/javascript/electronStaticAnalysisValues.js +6 -12
- package/dist/domain/javascript/javascriptApplicationAnalysis.js +71 -23
- package/dist/domain/javascript/javascriptApplicationEvidenceSchemas.js +2 -0
- package/dist/domain/javascript/javascriptApplicationGraph.js +39 -3
- package/dist/domain/javascript/javascriptApplicationGraphSchemas.js +9 -2
- package/dist/domain/javascript/javascriptApplicationVersionItems.js +5 -2
- package/dist/domain/javascript/javascriptApplicationVersionKeys.js +2 -1
- package/dist/domain/javascript/javascriptAstValues.js +20 -0
- package/dist/{application/javascript/JavaScriptReturnShapeProjection.js → domain/javascript/javascriptExportReturnShapeProjection.js} +4 -4
- package/dist/domain/javascript/javascriptExportShapeComparison.js +7 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonIdentity.js +6 -1
- package/dist/domain/javascript/javascriptExportShapeComparisonSchemas.js +29 -1
- package/dist/domain/javascript/javascriptExportShapeSelection.js +5 -5
- package/dist/domain/javascript/javascriptExportShapeVariants.js +67 -14
- package/dist/domain/javascript/javascriptFeatureSeed.js +20 -0
- package/dist/domain/javascript/javascriptFeatureTraversal.js +0 -1
- package/dist/domain/javascript/javascriptNativeHandoff.js +1 -1
- package/dist/domain/javascript/javascriptRecovery.js +3 -8
- package/dist/domain/javascript/javascriptRuntimeLoadState.js +0 -1
- package/dist/domain/javascript/javascriptRuntimeObservation.js +10 -2
- package/dist/domain/javascript/javascriptRuntimeReconciliationMatching.js +1 -1
- package/dist/domain/javascript/javascriptRuntimeReconciliationParsing.js +3 -2
- package/dist/domain/javascript/javascriptRuntimeStaticCandidates.js +0 -1
- package/dist/domain/javascript/javascriptSemanticAnalysis.js +106 -5
- package/dist/domain/javascript/javascriptSemanticAsyncEffects.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCalls.js +2 -1
- package/dist/domain/javascript/javascriptSemanticChildProcesses.js +2 -1
- package/dist/domain/javascript/javascriptSemanticCoverage.js +6 -5
- package/dist/domain/javascript/javascriptSemanticDataEffectHelpers.js +9 -17
- package/dist/domain/javascript/javascriptSemanticDataEffects.js +23 -6
- package/dist/domain/javascript/javascriptSemanticGraph.js +98 -43
- package/dist/domain/javascript/javascriptSemanticGraphSchemas.js +1 -0
- package/dist/domain/javascript/javascriptSemanticMemberMutations.js +77 -20
- package/dist/domain/javascript/javascriptSemanticMutationValues.js +21 -27
- package/dist/domain/javascript/javascriptSemanticObjects.js +83 -42
- package/dist/domain/javascript/javascriptSemanticPrimitives.js +18 -21
- package/dist/domain/javascript/javascriptSemanticProjection.js +2 -3
- package/dist/domain/javascript/javascriptSemanticPromises.js +2 -1
- package/dist/domain/javascript/javascriptSemanticQuerySchemas.js +8 -4
- package/dist/domain/javascript/javascriptSemanticResourceLimits.js +77 -0
- package/dist/domain/javascript/javascriptSemanticResources.js +1 -1
- package/dist/domain/javascript/javascriptSemanticReturns.js +32 -17
- package/dist/domain/javascript/javascriptSemanticSlots.js +72 -0
- package/dist/domain/javascript/javascriptSemanticValues.js +126 -61
- package/dist/domain/javascript/javascriptSourceMapPaths.js +104 -0
- package/dist/domain/javascript/javascriptSourceParser.js +6 -2
- package/dist/domain/javascript/javascriptStaticAnalysis.js +22 -17
- package/dist/domain/javascript/javascriptStaticAnalysisBundler.js +5 -3
- package/dist/domain/javascript/javascriptStaticAnalysisCalls.js +16 -5
- package/dist/domain/javascript/javascriptStaticAnalysisFindings.js +66 -7
- package/dist/domain/javascript/javascriptStaticAnalysisHelpers.js +28 -17
- package/dist/domain/javascript/javascriptStaticAnalysisState.js +3 -2
- package/dist/domain/javascript/sourceToBundleComparison.js +12 -3
- package/dist/domain/javascript/sourceToBundleSignals.js +47 -19
- package/dist/domain/jsonSerialization.js +109 -0
- package/dist/domain/jsonValue.js +90 -6
- package/dist/domain/localPath.js +6 -0
- package/dist/domain/managed/managedApplicationGraph.js +10 -10
- package/dist/domain/managed/managedArtifact.js +6 -4
- package/dist/domain/managed/managedInspectionEvidence.js +16 -0
- package/dist/domain/managed/managedMemberComparison.js +2 -9
- package/dist/domain/managed/managedMemberComparisonMatch.js +5 -9
- package/dist/domain/managed/managedNativeVerification.js +3 -11
- package/dist/domain/managed/managedNativeVerificationMatch.js +9 -3
- package/dist/domain/native/binaryLayout.js +2 -3
- package/dist/domain/native/fileOffsetPartialObservation.js +1 -0
- package/dist/domain/native/nativeApiBoundary.js +1 -1
- package/dist/domain/native/nativeCallObservation.js +37 -13
- package/dist/domain/native/nativeCallPartialObservation.js +33 -0
- package/dist/domain/native/nativeInstruction.js +7 -0
- package/dist/domain/native/recordedCrash.js +2 -3
- package/dist/domain/offsetDateTime.js +17 -0
- package/dist/domain/process/processCapture.js +21 -16
- package/dist/domain/process/processCaptureCoverage.js +67 -0
- package/dist/domain/process/processCaptureExample.js +2 -1
- package/dist/domain/process/processCaptureParsing.js +1 -34
- package/dist/domain/process/processCaptureValidation.js +81 -13
- package/dist/domain/process/processComparison.js +79 -26
- package/dist/domain/process/processObservation.js +10 -2
- package/dist/domain/process/processScenario.js +35 -12
- package/dist/domain/process/processTraceComparison.js +0 -2
- package/dist/domain/process/processTraceDimensionProjection.js +1 -1
- package/dist/domain/process/processTraceEvaluation.js +15 -11
- package/dist/domain/process/processTraceSpecification.js +3 -4
- package/dist/domain/propertyListKeys.js +1 -1
- package/dist/domain/propertyListXmlText.js +19 -0
- package/dist/domain/providerAdapterError.js +3 -1
- package/dist/domain/providerOperationHealth.js +54 -0
- package/dist/domain/reconstructionCoverage.js +5 -2
- package/dist/domain/reconstructionObligationLedgerSchemas.js +2 -1
- package/dist/domain/reconstructionReadinessSchemas.js +2 -1
- package/dist/domain/reconstructionVerification.js +9 -46
- package/dist/domain/reconstructionVerificationSchemas.js +4 -3
- package/dist/domain/referenceSourceGraph.js +20 -21
- package/dist/domain/staticRuntimeCorrelation.js +8 -45
- package/dist/domain/stringPatterns.js +6 -0
- package/dist/domain/swiftSymbolClassification.js +61 -0
- package/dist/domain/symbolAnalysis.js +66 -18
- package/dist/domain/webBundleAnalysis.js +20 -8
- package/dist/domain/webBundleAnalyzerInspection.js +13 -8
- package/dist/domain/webBundleAnalyzerResult.js +41 -2
- package/dist/domain/webCaptureDiff.js +0 -1
- package/dist/domain/webCaptureDiffSchemas.js +6 -3
- package/dist/domain/webEventListeners.js +3 -2
- package/dist/domain/webExecution.js +3 -2
- package/dist/domain/webRuntime.js +19 -7
- package/dist/domain/webScriptExport.js +1 -1
- package/dist/domain/webSourceLocation.js +1 -0
- package/dist/dotnet/ManagedArtifactInspector.js +2 -19
- package/dist/dotnet/ManagedMemberInspector.js +12 -18
- package/dist/dotnet/ManagedMemberInspectorCore.js +47 -44
- package/dist/dotnet/ManagedMemberRows.js +75 -62
- package/dist/dotnet/ManagedMetadataInventory.js +16 -22
- package/dist/dotnet/ManagedMethodBodyReader.js +4 -0
- package/dist/dotnet/ManagedNativeBoundaryHelpers.js +109 -94
- package/dist/dotnet/ManagedNativeBoundaryInspector.js +12 -21
- package/dist/dotnet/ManagedReaderFailure.js +16 -0
- package/dist/dotnet/ManagedStaticProvider.js +3 -5
- package/dist/evaluation/AgentEvaluationFixtures.js +250 -0
- package/dist/evaluation/AgentEvaluationReport.js +28 -0
- package/dist/evaluation/CodexAgentEval.js +12 -8
- package/dist/evaluation/KnownAnswerEvaluation.js +281 -0
- package/dist/evm/EvmoleInterfaceProvider.js +2 -1
- package/dist/firmware/FirmwareCommand.js +9 -5
- package/dist/firmware/FirmwareFiles.js +1 -1
- package/dist/firmware/FirmwareProvider.js +4 -4
- package/dist/generatedPackageMetadata.js +2 -2
- package/dist/ghidra/GhidraAnalysisProfile.js +7 -5
- package/dist/ghidra/GhidraClient.js +126 -34
- package/dist/ghidra/GhidraClientStartup.js +0 -2
- package/dist/ghidra/GhidraDiagnostics.js +7 -7
- package/dist/ghidra/GhidraDoctor.js +6 -5
- package/dist/ghidra/GhidraFunctionValues.js +13 -12
- package/dist/ghidra/GhidraInstallation.js +58 -33
- package/dist/ghidra/GhidraInventoryValues.js +14 -4
- package/dist/ghidra/GhidraJavaLaunch.js +66 -0
- package/dist/ghidra/GhidraLauncher.js +47 -22
- package/dist/ghidra/GhidraProvider.js +6 -2
- package/dist/ghidra/GhidraProviderCapabilities.js +20 -2
- package/dist/ghidra/GhidraProviderClient.js +36 -15
- package/dist/ghidra/GhidraSessionError.js +13 -7
- package/dist/ghidra/GhidraSessionRoot.js +39 -0
- package/dist/ghidra/GhidraTargetSnapshot.js +47 -12
- package/dist/ghidra/GhidraTransport.js +20 -0
- package/dist/ghidra/extensions/GhidraExtensions.js +17 -10
- package/dist/ghidra/extensions/nativeaot/NativeAotAdapter.js +8 -2
- package/dist/hopper/BridgeLauncher.js +65 -56
- package/dist/hopper/HopperAnalysisProfile.js +65 -12
- package/dist/hopper/HopperCleanup.js +63 -22
- package/dist/hopper/HopperClient.js +288 -59
- package/dist/hopper/HopperFileOffset.js +237 -0
- package/dist/hopper/HopperMachOImage.js +197 -0
- package/dist/hopper/HopperOperationStage.js +6 -0
- package/dist/hopper/HopperProvider.js +71 -19
- package/dist/hopper/HopperProviderCapabilities.js +19 -1
- package/dist/hopper/HopperRegexSearch.js +134 -0
- package/dist/hopper/HopperRegexWorker.js +27 -0
- package/dist/hopper/HopperRequestQueue.js +68 -19
- package/dist/hopper/HopperTargetLease.js +133 -49
- package/dist/hopper/LinuxPrivateDisplayProbe.js +6 -0
- package/dist/ida/IdaConfiguration.js +8 -3
- package/dist/ida/IdaInput.js +1 -7
- package/dist/ida/IdaMcpConnection.js +8 -4
- package/dist/ida/IdaOperationRunner.js +3 -3
- package/dist/ida/IdaProvider.js +8 -12
- package/dist/ida/IdaSessionClient.js +20 -18
- package/dist/ida/IdaWorkspace.js +12 -13
- package/dist/inspector/JavaScriptRuntimeScope.js +9 -1
- package/dist/inspector/V8InspectorCaptureProjection.js +9 -4
- package/dist/inspector/V8InspectorProvider.js +82 -36
- package/dist/javascript/recovery/WakaruCommand.js +7 -2
- package/dist/javascript/recovery/WakaruExecution.js +5 -2
- package/dist/javascript/sourceMaps/DecodedSourceMap.js +47 -0
- package/dist/javascript/sourceMaps/SourceMapCommand.js +16 -0
- package/dist/javascript/sourceMaps/SourceMapFormat.js +79 -31
- package/dist/javascript/sourceMaps/TraceSourceMap.js +14 -28
- package/dist/main/shutdown.js +11 -3
- package/dist/main/startup.js +9 -2
- package/dist/main/transport.js +22 -2
- package/dist/main.js +11 -18
- package/dist/mcpDoctor.js +62 -2
- package/dist/native/AppleDispatchCoverage.js +47 -6
- package/dist/native/AppleDispatchDecodeFacts.js +6 -0
- package/dist/native/AppleDispatchMetadata.js +6 -3
- package/dist/native/AppleMachoFixups.js +48 -24
- package/dist/native/AppleMachoSelection.js +48 -22
- package/dist/native/AppleObjcCategories.js +6 -2
- package/dist/native/AppleObjcDispatchFacets.js +5 -2
- package/dist/native/AppleObjcProperties.js +2 -1
- package/dist/native/AppleSwiftDispatchFacets.js +27 -21
- package/dist/native/AppleSwiftVtables.js +21 -15
- package/dist/native/CommandRunner.js +87 -88
- package/dist/native/LldbCallTracer.js +372 -103
- package/dist/native/LldbRetainedObservations.js +178 -0
- package/dist/native/NativeCallObservation.js +62 -3
- package/dist/native/NativeMacOSProvider.js +122 -31
- package/dist/native/NativeUiHelperRuntime.js +11 -2
- package/dist/native/NativeUiObservation.js +2 -2
- package/dist/native/SignatureTargetBinding.js +155 -0
- package/dist/native/parsers/lipo.js +71 -1
- package/dist/native/pwndbg/PwndbgCoreContext.js +25 -5
- package/dist/native/pwntools/PwntoolsDecoder.js +2 -1
- package/dist/native/pwntools/RecordedCrashStructureBindings.js +2 -0
- package/dist/process/DarwinProcessRunTokenReader.js +23 -10
- package/dist/process/ExecFileOutput.js +108 -6
- package/dist/process/OwnedCommand.js +7 -2
- package/dist/process/PrivateRuntimeRoot.js +10 -5
- package/dist/process/ProcessOwnership.js +204 -57
- package/dist/process/ProcessOwnershipObservation.js +60 -9
- package/dist/process/ProviderProcess.js +39 -10
- package/dist/process/capture/FilesystemSnapshot.js +50 -13
- package/dist/process/capture/ProcessCaptureError.js +15 -2
- package/dist/process/capture/ProcessCaptureLifecycle.js +235 -81
- package/dist/process/capture/ProcessFilesystemEffects.js +33 -3
- package/dist/process/capture/ProcessHarness.js +21 -25
- package/dist/process/capture/ProcessNormalization.js +20 -2
- package/dist/process/capture/ProcessSampling.js +25 -2
- package/dist/process/capture/TerminalRenderer.js +14 -0
- package/dist/process/snapshotEnvironment.js +14 -0
- package/dist/server/EvidenceMcpServer.js +157 -0
- package/dist/server/createServer.js +61 -41
- package/dist/server/mcpClientMetadata.js +12 -5
- package/dist/server/promptCompletion.js +3 -8
- package/dist/server/registerAnalysisViewTool.js +15 -0
- package/dist/server/registerAndroidTools.js +2 -5
- package/dist/server/registerApplicationTools/compareExportShapes.js +4 -5
- package/dist/server/registerApplicationTools/compareSourceToBundle.js +4 -5
- package/dist/server/registerApplicationTools/compareVersions.js +4 -5
- package/dist/server/registerApplicationTools/coverage.js +1 -2
- package/dist/server/registerApplicationTools/helpers.js +1 -4
- package/dist/server/registerApplicationTools/obligationLedger.js +4 -5
- package/dist/server/registerApplicationTools/projectMobileApplicationGraph.js +3 -4
- package/dist/server/registerApplicationTools/traceFeature.js +4 -5
- package/dist/server/registerApplicationTools/traceSemantics.js +4 -5
- package/dist/server/registerArtifactComparisonTool.js +13 -10
- package/dist/server/registerBinaryDiagnosticsTools.js +2 -5
- package/dist/server/registerBrowserScenarioTool.js +3 -6
- package/dist/server/registerBrowserTools.js +13 -18
- package/dist/server/registerBundleComparisonTool.js +5 -7
- package/dist/server/registerCloseLifecycleTool.js +9 -20
- package/dist/server/registerElectronTools.js +10 -15
- package/dist/server/registerEnhancedTools.js +36 -77
- package/dist/server/registerEvidenceTools.js +3 -6
- package/dist/server/registerEvmTools.js +2 -5
- package/dist/server/registerFirmwareTools.js +2 -5
- package/dist/server/registerFunctionComparisonTool.js +15 -12
- package/dist/server/registerInvestigationTools.js +16 -17
- package/dist/server/registerJavaScriptRecoveryTool.js +2 -5
- package/dist/server/registerJavaScriptRuntimeObservationTools.js +6 -8
- package/dist/server/registerManagedWorkflowTools/compareManagedMembers.js +5 -8
- package/dist/server/registerManagedWorkflowTools/importManagedReconstruction.js +4 -7
- package/dist/server/registerManagedWorkflowTools/projectManagedApplicationGraph.js +6 -9
- package/dist/server/registerManagedWorkflowTools/verifyManagedNativeBoundaries.js +6 -9
- package/dist/server/registerOfficialTools.js +4 -21
- package/dist/server/registerProcessComparisonTool.js +74 -48
- package/dist/server/registerRecordedCrashTools.js +2 -5
- package/dist/server/registerSessionRecordTools.js +19 -24
- package/dist/server/registerSessionStatusTool.js +19 -6
- package/dist/server/registerSessionTools.js +20 -18
- package/dist/server/registerWebModuleTool.js +2 -5
- package/dist/server/registerWebNetworkCaptureTool.js +2 -5
- package/dist/server/registerWebRuntimeTools.js +4 -9
- package/dist/server/registerWebScriptTool.js +2 -5
- package/dist/server/registerWebSourceLocationTool.js +2 -5
- package/dist/server/runDerivedOperation.js +15 -3
- package/dist/server/sessionAvailabilityPolicy.js +0 -1
- package/dist/server/toolRegistrationOptions.js +2 -2
- package/dist/server/toolResult.js +75 -51
- package/dist/server/toolResultEncoding.js +34 -0
- package/dist/windows/WindowsNativeLoader.js +1 -0
- package/dist/windows/WindowsOwnedProcess.js +60 -15
- package/dist/windows/WindowsPrivateRuntime.js +7 -8
- package/install.sh +1 -1
- package/native/windows/README.md +3 -1
- package/native/windows/build/manifest.json +2 -2
- package/native/windows/build/rea-windows-x64.node +0 -0
- package/package.json +44 -30
- package/scripts/electron-active-hook-boundaries.cjs +18 -20
- package/scripts/electron-active-hook.cjs +241 -37
- package/scripts/rea.mjs +3 -6
- package/skills/reverse-engineer-anything/SKILL.md +12 -3
- package/skills/reverse-engineer-anything/references/android-applications.md +6 -3
- package/skills/reverse-engineer-anything/references/evidence-workflows.md +8 -4
- package/skills/reverse-engineer-anything/references/javascript-applications.md +20 -3
- package/skills/reverse-engineer-anything/references/native-and-artifacts.md +9 -0
- package/dist/config.js +0 -1
- package/dist/contracts/browserCaptureToolInputSchema.js +0 -43
- package/dist/contracts/process/processCaptureExample.js +0 -2
- package/dist/contracts/toolOutputSchemas.js +0 -2
- package/dist/ghidra/GhidraDefaults.js +0 -2
- package/dist/main/reload.js +0 -12
- package/dist/main/state.js +0 -3
- package/dist/server/sessionToolPolicies.js +0 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<div align="center">
|
|
2
2
|
|
|
3
|
-
**English** · [简体中文](README_zh.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [العربية](README_ar.md)
|
|
3
|
+
**English** · [简体中文](README_zh.md) · [繁體中文](README_zh-TW.md) · [日本語](README_ja.md) · [한국어](README_ko.md) · [Türkçe](README_tr.md) · [Русский](README_ru.md) · [Tiếng Việt](README_vi.md) · [ไทย](README_th.md) · [Deutsch](README_de.md) · [Español](README_es.md) · [Français](README_fr.md) · [Українська](README_uk.md) · [Polski](README_pl.md) · [Português (Brasil)](README_pt-BR.md) · [العربية](README_ar.md) · [فارسی](README_fa.md)
|
|
4
4
|
|
|
5
5
|
# REA: Reverse Engineer Anything
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
[](https://www.npmjs.com/package/rea-agents)
|
|
12
12
|
[](https://github.com/morluto/rea/actions/workflows/ci.yml)
|
|
13
|
-
[](docs/
|
|
13
|
+
[](docs/mcp-contracts.md#generated-catalog)
|
|
14
14
|
[](https://nodejs.org/)
|
|
15
15
|
[](https://skills.sh/morluto/rea/reverse-engineer-anything)
|
|
16
16
|
[](LICENSE)
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
<a href="https://trendshift.io/repositories/82054?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-82054" target="_blank" rel="noopener noreferrer"><img src="https://trendshift.io/api/badge/repositories/82054" alt="morluto%2Frea | Trendshift" width="250" height="55"/></a>
|
|
20
20
|
|
|
21
|
-
**[Website](https://
|
|
21
|
+
**[Website](https://rea.tools/) · [Guides](https://rea.tools/guides/) · [Showcases](https://rea.tools/showcase/)**
|
|
22
22
|
|
|
23
23
|
[Quick start](#quick-start) · [How REA works](#how-rea-works) · [What you can analyze](#what-you-can-analyze) · [Showcases](#showcases) · [FAQ](#faq) · [Documentation](#documentation)
|
|
24
24
|
|
|
@@ -54,7 +54,7 @@ REA connects your agent to tools for inspecting native binaries, JavaScript and
|
|
|
54
54
|
|
|
55
55
|
Setup registers REA with your agent and installs matching workflow instructions. Native analysis can use an existing Hopper or Ghidra installation; setup can optionally install Hopper with approval. Static JavaScript analysis needs neither engine.
|
|
56
56
|
|
|
57
|
-
> **[Visit the REA website](https://
|
|
57
|
+
> **[Visit the REA website](https://rea.tools/)** for setup instructions, illustrated guides, and real case studies.
|
|
58
58
|
|
|
59
59
|
## Quick start
|
|
60
60
|
|
|
@@ -70,7 +70,7 @@ Choose your agents, review the proposed changes, and approve them. Setup adds
|
|
|
70
70
|
REA's MCP server and matching workflow instructions, with backups of existing
|
|
71
71
|
configuration. Restart your agent afterward.
|
|
72
72
|
|
|
73
|
-
Setup supports Claude Code, Codex, Cursor, Gemini CLI and
|
|
73
|
+
Setup supports Claude Code, Codex, Cursor, Gemini CLI, Grok Build and
|
|
74
74
|
[other agents](docs/installation.md#supported-agents). See
|
|
75
75
|
[installation and setup](docs/installation.md) for provider configuration and
|
|
76
76
|
manual MCP registration.
|
|
@@ -149,15 +149,15 @@ Additional tools and host support depend on the target:
|
|
|
149
149
|
|
|
150
150
|
| Target | What REA returns | Requirements and guide |
|
|
151
151
|
| ---------------------- | ------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------- |
|
|
152
|
-
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra or IDA; [native analysis](https://
|
|
152
|
+
| Native binaries | Pseudocode, assembly, strings, symbols, calls and references | Hopper, Ghidra or IDA; [native analysis](https://rea.tools/guides/native/) |
|
|
153
153
|
| Offline ELF layout | Sections, segments, original symbols/relocations and static mitigation candidates | Caller-supplied pwntools on Linux x64; [binary diagnostics](docs/binary-diagnostics.md) |
|
|
154
154
|
| EVM bytecode | Dispatch selectors, byte offsets, inferred arguments and mutability | Local raw/hex carrier; [offline EVM guide](docs/evm-bytecode.md) |
|
|
155
155
|
| Recorded Linux crashes | Raw notes, every recorded thread's registers/signals and optional mapping candidates | Caller-supplied pwntools; optional GDB/pwndbg; [recorded crashes](docs/recorded-crashes.md) |
|
|
156
|
-
| JavaScript / Electron | Modules, imports, source maps, routes, IPC and native add-on relationships | Node.js and npm; [application analysis](https://
|
|
157
|
-
| Websites | Page structure, scripts, network observations and requested screenshots | A Chrome-family browser; [browser analysis](https://
|
|
156
|
+
| JavaScript / Electron | Modules, imports, source maps, routes, IPC and native add-on relationships | Node.js and npm; [application analysis](https://rea.tools/guides/javascript/) |
|
|
157
|
+
| Websites | Page structure, scripts, network observations and requested screenshots | A Chrome-family browser; [browser analysis](https://rea.tools/guides/browser/) |
|
|
158
158
|
| Saved network captures | Requests, responses, exposed payloads and source locations | HAR; mitmdump on Linux for native mitmproxy captures; [capture guide](docs/web-network-captures.md) |
|
|
159
159
|
| .NET assemblies | Metadata, CIL instructions, declared native dependencies and build comparisons | Static inspection; [managed-code guide](docs/managed-code-analysis.md) |
|
|
160
|
-
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS; [Android guide](docs/android-analysis.md)
|
|
160
|
+
| Android APKs | Manifest declarations, classes, decompiled methods and references | Headless JADX and a full JDK on Linux/macOS/Windows x64; [Android guide](docs/android-analysis.md) |
|
|
161
161
|
| Firmware | Regions, extraction results and native-analysis handoffs | Binwalk / Unblob on Linux; [firmware guide](docs/firmware-analysis.md) |
|
|
162
162
|
| Packages and resources | File inventories, digests, plists, Apple bundle anatomy and extracted resources | [Artifact and JavaScript guide](docs/javascript-artifact-reconstruction.md), [Apple applications](docs/apple-application-analysis.md) |
|
|
163
163
|
| Process behavior | Terminal output, interactions, exit and filesystem observations, and run comparisons | Linux/macOS with a native PTY; [process capture](docs/process-capture.md) |
|
|
@@ -173,6 +173,8 @@ Native formats and host support vary by provider. See
|
|
|
173
173
|
[IDA guide](docs/ida-provider.md), and
|
|
174
174
|
[experimental Windows Ghidra support](docs/windows-ghidra-p0.md).
|
|
175
175
|
Ghidra also supports [16-bit DOS analysis](docs/ghidra-dos.md).
|
|
176
|
+
For large binaries, raise its startup deadline with
|
|
177
|
+
`REA_GHIDRA_STARTUP_TIMEOUT_MS`.
|
|
176
178
|
For provider selection, see the [CLI guide](docs/cli.md#choose-a-provider).
|
|
177
179
|
Check [release availability](docs/installation.md#released-package-and-main)
|
|
178
180
|
for features added since the latest npm release.
|
|
@@ -185,7 +187,7 @@ Follow a sound call into its position-to-pan helper, inspect the instructions,
|
|
|
185
187
|
and turn incomplete pseudocode into C. The reconstruction passes 3,205
|
|
186
188
|
original-x86 cases and reproduces all 63 compiled function bytes.
|
|
187
189
|
|
|
188
|
-
[Read the case study](https://
|
|
190
|
+
[Read the case study](https://rea.tools/showcase/dx-ball/) ·
|
|
189
191
|
[Reconstruction repository](https://github.com/N0zoM1z0/dx-ball)
|
|
190
192
|
|
|
191
193
|
### Notion: trace the Electron clipboard bridge
|
|
@@ -193,7 +195,7 @@ original-x86 cases and reproduces all 63 compiled function bytes.
|
|
|
193
195
|
Find the renderer's clipboard API, follow it through preload and IPC into the
|
|
194
196
|
main process, and inspect the rich clipboard format.
|
|
195
197
|
|
|
196
|
-
[Read the case study](https://
|
|
198
|
+
[Read the case study](https://rea.tools/showcase/notion/)
|
|
197
199
|
|
|
198
200
|
### TH04: recover a DOS bullet-ring calculation
|
|
199
201
|
|
|
@@ -201,7 +203,7 @@ Inspect the original PC-98 game's 16-bit instructions, recover the fixed and
|
|
|
201
203
|
aimed angle calculations, and compare the reconstructed C++ with the
|
|
202
204
|
historical compiler output.
|
|
203
205
|
|
|
204
|
-
[Read the case study](https://
|
|
206
|
+
[Read the case study](https://rea.tools/showcase/th04/) ·
|
|
205
207
|
[Reconstruction repository](https://github.com/N0zoM1z0/th04)
|
|
206
208
|
|
|
207
209
|
If you've used REA on something interesting, we'd love to see it. Share your
|
|
@@ -289,14 +291,14 @@ with your REA version, target type, steps to reproduce and error output.
|
|
|
289
291
|
|
|
290
292
|
## Documentation
|
|
291
293
|
|
|
292
|
-
Start with the website's [worked guides](https://
|
|
294
|
+
Start with the website's [worked guides](https://rea.tools/guides/).
|
|
293
295
|
For exact options, prerequisites and result contracts:
|
|
294
296
|
|
|
295
297
|
- [Installation and setup](docs/installation.md): agent registration, provider configuration, updates and uninstall.
|
|
296
298
|
- [Readiness and troubleshooting](docs/installation.md#check-readiness-for-your-task): diagnose one agent or analysis engine.
|
|
297
299
|
- [CLI and Evidence](docs/cli.md): commands, provider selection, snapshots, import/export and exit statuses.
|
|
298
300
|
- [MCP contracts](docs/mcp-contracts.md) and [agent prompts](docs/mcp-prompts.md): tool results, sessions and guided investigations.
|
|
299
|
-
- [Tool catalog](docs/
|
|
301
|
+
- [Tool catalog](docs/mcp-contracts.md#generated-catalog): generated inventory of tools, providers and CLI commands.
|
|
300
302
|
- [Roadmap](docs/roadmap.md): planned work and capability trackers.
|
|
301
303
|
|
|
302
304
|
Report vulnerabilities through [SECURITY.md](SECURITY.md).
|
|
@@ -313,13 +315,13 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and checks,
|
|
|
313
315
|
|
|
314
316
|
## Project links
|
|
315
317
|
|
|
316
|
-
[Website](https://
|
|
318
|
+
[Website](https://rea.tools/) · [npm](https://www.npmjs.com/package/rea-agents) · [skills.sh](https://skills.sh/morluto/rea/reverse-engineer-anything) · [Issues](https://github.com/morluto/rea/issues) · [Security](SECURITY.md)
|
|
317
319
|
|
|
318
|
-
##
|
|
320
|
+
## Star history
|
|
319
321
|
|
|
320
|
-
|
|
322
|
+
🎉 **30,000 GitHub stars — thank you!**
|
|
321
323
|
|
|
322
|
-
|
|
324
|
+
Thanks to everyone using REA, reporting bugs, requesting features, testing builds, and contributing fixes.
|
|
323
325
|
|
|
324
326
|
<a href="https://www.star-history.com/?repos=morluto%2Frea&type=date">
|
|
325
327
|
<picture>
|
|
@@ -332,3 +334,9 @@ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and checks,
|
|
|
332
334
|
## Disclaimer
|
|
333
335
|
|
|
334
336
|
REA provides tools for lawful reverse-engineering research, analysis, and reconstruction. You are responsible for obtaining any required authorization and complying with applicable laws. The project does not endorse illegal or unauthorized use.
|
|
337
|
+
|
|
338
|
+
REA is an open-source software project. We have not issued or endorsed any cryptocurrency or token. Tokens using the REA name are not affiliated with the project.
|
|
339
|
+
|
|
340
|
+
## License
|
|
341
|
+
|
|
342
|
+
[MIT](LICENSE)
|
|
@@ -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;
|
|
@@ -865,6 +866,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
865
866
|
JsonArray operands = new JsonArray();
|
|
866
867
|
JsonArray references = new JsonArray();
|
|
867
868
|
JsonArray destinations = new JsonArray();
|
|
869
|
+
JsonArray flowEvidence = new JsonArray();
|
|
868
870
|
JsonObject flow = new JsonObject();
|
|
869
871
|
flow.addProperty("kind", "unavailable");
|
|
870
872
|
flow.addProperty("conditional", false);
|
|
@@ -880,7 +882,20 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
880
882
|
result.addProperty("mnemonic", instruction.getMnemonicString());
|
|
881
883
|
result.addProperty("raw_disassembly", instruction.toString());
|
|
882
884
|
RefType type = instruction.getFlowType();
|
|
883
|
-
|
|
885
|
+
JsonObject listingFlow = new JsonObject();
|
|
886
|
+
listingFlow.addProperty("source", "ghidra-listing-flow-type");
|
|
887
|
+
listingFlow.addProperty("value", type.getName());
|
|
888
|
+
flowEvidence.add(listingFlow);
|
|
889
|
+
boolean decodedReturn = false;
|
|
890
|
+
for (PcodeOp operation : instruction.getPcode()) {
|
|
891
|
+
if (operation.getOpcode() != PcodeOp.RETURN) continue;
|
|
892
|
+
decodedReturn = true;
|
|
893
|
+
JsonObject returnEvidence = new JsonObject();
|
|
894
|
+
returnEvidence.addProperty("source", "ghidra-instruction-pcode");
|
|
895
|
+
returnEvidence.addProperty("value", operation.getMnemonic());
|
|
896
|
+
flowEvidence.add(returnEvidence);
|
|
897
|
+
}
|
|
898
|
+
flow.addProperty("kind", type.isCall() ? "call" : type.isJump() ? "jump" : decodedReturn ? "return" : type.isTerminal() ? "terminal" : "fallthrough");
|
|
884
899
|
flow.addProperty("conditional", type.isConditional());
|
|
885
900
|
flow.addProperty("computed", type.isComputed());
|
|
886
901
|
if (!type.isComputed()) for (Address target : instruction.getFlows()) destinations.add(canonicalAddress(target));
|
|
@@ -916,10 +931,13 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
916
931
|
}
|
|
917
932
|
}
|
|
918
933
|
flow.add("direct_destinations", destinations);
|
|
934
|
+
flow.add("classification_evidence", flowEvidence);
|
|
919
935
|
result.add("operands", operands);
|
|
920
936
|
result.add("flow", flow);
|
|
921
937
|
result.add("references", references);
|
|
922
|
-
|
|
938
|
+
List<String> limitations = new ArrayList<>(List.of("Operand components are Ghidra Listing decoder tokens; effective memory base/index/displacement roles and per-instruction context mode are unavailable. The mode field is the program language variant."));
|
|
939
|
+
if (flow.get("kind").getAsString().equals("terminal")) limitations.add("No RETURN operation was observed in the provider's instruction p-code; terminal classification remains generic.");
|
|
940
|
+
result.add("limitations", GSON.toJsonTree(limitations));
|
|
923
941
|
return result;
|
|
924
942
|
}
|
|
925
943
|
|
|
@@ -1007,6 +1025,11 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1007
1025
|
Address entry = function.getEntryPoint();
|
|
1008
1026
|
if (function.isExternal() || !currentProgram.getMemory().contains(entry))
|
|
1009
1027
|
throw new RequestFailure("invalid_request", "Annotations require a local function entry: " + canonicalAddress(entry));
|
|
1028
|
+
for (String field : List.of("name", "comment", "inline_comment")) {
|
|
1029
|
+
if (params.has(field)) validateAnnotationText(requireText(params, field), field);
|
|
1030
|
+
}
|
|
1031
|
+
String leafName = params.has("name")
|
|
1032
|
+
? annotationLeafName(function, requireString(params, "name")) : null;
|
|
1010
1033
|
int transaction = currentProgram.startTransaction("REA function annotations");
|
|
1011
1034
|
boolean commit = false;
|
|
1012
1035
|
try {
|
|
@@ -1020,7 +1043,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1020
1043
|
}
|
|
1021
1044
|
}
|
|
1022
1045
|
if (params.has("name"))
|
|
1023
|
-
function.setName(
|
|
1046
|
+
function.setName(leafName, SourceType.USER_DEFINED);
|
|
1024
1047
|
monitor.checkCancelled();
|
|
1025
1048
|
invalidateAnalysisCaches();
|
|
1026
1049
|
JsonObject readback = annotationReadback(function);
|
|
@@ -1028,7 +1051,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1028
1051
|
if (!params.has(field)) continue;
|
|
1029
1052
|
String requested = requireText(params, field);
|
|
1030
1053
|
JsonElement measured = readback.get(field);
|
|
1031
|
-
String expected =
|
|
1054
|
+
String expected = field.equals("name") ? leafName : requested.isEmpty() ? null : requested;
|
|
1032
1055
|
String observed = field.equals("name") ? function.getName() :
|
|
1033
1056
|
(measured.isJsonNull() ? null : measured.getAsString());
|
|
1034
1057
|
if (!java.util.Objects.equals(expected, observed))
|
|
@@ -1058,6 +1081,22 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1058
1081
|
}
|
|
1059
1082
|
}
|
|
1060
1083
|
|
|
1084
|
+
private String annotationLeafName(Function function, String requested) {
|
|
1085
|
+
// Fully qualified readback must be usable as an idempotent rename input.
|
|
1086
|
+
if (requested.equals(procedureName(function))) return function.getName();
|
|
1087
|
+
String namespace = function.getParentNamespace().isGlobal()
|
|
1088
|
+
? "" : function.getParentNamespace().getName(true);
|
|
1089
|
+
String prefix = namespace + "::";
|
|
1090
|
+
if (!namespace.isEmpty() && requested.startsWith(prefix)) {
|
|
1091
|
+
String leaf = requested.substring(prefix.length());
|
|
1092
|
+
if (!leaf.isEmpty()) return leaf;
|
|
1093
|
+
throw new RequestFailure("invalid_function_name",
|
|
1094
|
+
"Function name has an empty leaf within namespace " + namespace + " at " +
|
|
1095
|
+
canonicalAddress(function.getEntryPoint()) + ": " + requested);
|
|
1096
|
+
}
|
|
1097
|
+
return requested;
|
|
1098
|
+
}
|
|
1099
|
+
|
|
1061
1100
|
private static String requireText(JsonObject params, String field) {
|
|
1062
1101
|
JsonElement value = params.get(field);
|
|
1063
1102
|
if (value == null || !value.isJsonPrimitive() || !value.getAsJsonPrimitive().isString())
|
|
@@ -1065,6 +1104,21 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1065
1104
|
return value.getAsString();
|
|
1066
1105
|
}
|
|
1067
1106
|
|
|
1107
|
+
private static void validateAnnotationText(String text, String field) {
|
|
1108
|
+
for (int index = 0; index < text.length(); index++) {
|
|
1109
|
+
char character = text.charAt(index);
|
|
1110
|
+
if (character == 0)
|
|
1111
|
+
throw new RequestFailure("invalid_request", "Annotation " + field + " contains NUL at UTF-16 index " + index + "; Ghidra's decompiler cannot marshal NUL text");
|
|
1112
|
+
if (Character.isHighSurrogate(character) && index + 1 < text.length() &&
|
|
1113
|
+
Character.isLowSurrogate(text.charAt(index + 1))) {
|
|
1114
|
+
index++;
|
|
1115
|
+
continue;
|
|
1116
|
+
}
|
|
1117
|
+
if (Character.isSurrogate(character))
|
|
1118
|
+
throw new RequestFailure("invalid_request", "Annotation " + field + " contains an unpaired Unicode surrogate at UTF-16 index " + index + "; Ghidra cannot preserve it as annotation text");
|
|
1119
|
+
}
|
|
1120
|
+
}
|
|
1121
|
+
|
|
1068
1122
|
private JsonObject analyzeFunction(JsonObject params) throws Exception {
|
|
1069
1123
|
requireKeys(params, Set.of("procedure"));
|
|
1070
1124
|
Function function = resolveProcedure(requireString(params, "procedure"));
|
|
@@ -1074,11 +1128,11 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1074
1128
|
if (pseudocode == null) {
|
|
1075
1129
|
pseudocode = "";
|
|
1076
1130
|
}
|
|
1077
|
-
List<Reference> incomingReferences = collectReferences(
|
|
1131
|
+
List<Reference> incomingReferences = collectReferences(function, "incoming")
|
|
1078
1132
|
.stream()
|
|
1079
1133
|
.filter(reference -> !function.getBody().contains(reference.getFromAddress()))
|
|
1080
1134
|
.toList();
|
|
1081
|
-
List<Reference> outgoingReferences = collectReferences(
|
|
1135
|
+
List<Reference> outgoingReferences = collectReferences(function, "outgoing");
|
|
1082
1136
|
JsonArray incoming = referenceEdges(incomingReferences);
|
|
1083
1137
|
JsonArray outgoing = referenceEdges(outgoingReferences);
|
|
1084
1138
|
JsonArray comments = comments(scan.instructions);
|
|
@@ -1471,6 +1525,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1471
1525
|
: regexMatcher(expression, caseSensitive);
|
|
1472
1526
|
JsonArray items = new JsonArray();
|
|
1473
1527
|
for (InventoryItem item : inventory) {
|
|
1528
|
+
monitor.checkCancelled();
|
|
1474
1529
|
if (!matcher.matches(item.value)) {
|
|
1475
1530
|
continue;
|
|
1476
1531
|
}
|
|
@@ -1581,33 +1636,47 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
1581
1636
|
}
|
|
1582
1637
|
|
|
1583
1638
|
private Function resolveProcedure(String value) throws Exception {
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1639
|
+
// Explicit address syntax wins; an unprefixed identifier is first an
|
|
1640
|
+
// exact symbol name, even when every character is a hexadecimal digit.
|
|
1641
|
+
boolean explicitAddress = isExplicitReaAddress(value);
|
|
1642
|
+
if (!explicitAddress) {
|
|
1643
|
+
List<Function> matches = new ArrayList<>();
|
|
1644
|
+
for (FunctionEntry entry : procedures()) {
|
|
1645
|
+
monitor.checkCancelled();
|
|
1646
|
+
Function function = entry.function;
|
|
1647
|
+
Symbol symbol = function.getSymbol();
|
|
1648
|
+
String qualified = symbol == null ? function.getName() : symbol.getName(true);
|
|
1649
|
+
boolean matchesName = function.getName().equals(value) || qualified.equals(value);
|
|
1650
|
+
if (!matchesName) {
|
|
1651
|
+
// Imported labels (for example Mach-O _main) can share a
|
|
1652
|
+
// function entry without becoming its primary symbol. Only
|
|
1653
|
+
// exact entries qualify; an interior label is not a selector.
|
|
1654
|
+
for (Symbol entrySymbol : currentProgram.getSymbolTable().getSymbols(function.getEntryPoint())) {
|
|
1655
|
+
monitor.checkCancelled();
|
|
1656
|
+
if (entrySymbol.getName().equals(value) || entrySymbol.getName(true).equals(value)) {
|
|
1657
|
+
matchesName = true;
|
|
1658
|
+
break;
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
}
|
|
1662
|
+
if (matchesName) matches.add(function);
|
|
1663
|
+
}
|
|
1664
|
+
if (matches.size() > 1)
|
|
1665
|
+
throw new RequestFailure("ambiguous", "Ghidra procedure name is ambiguous: " + value +
|
|
1666
|
+
"; select an exact entry address from " + matches.stream()
|
|
1667
|
+
.map(function -> canonicalAddress(function.getEntryPoint())).toList());
|
|
1668
|
+
if (matches.size() == 1) return matches.get(0);
|
|
1669
|
+
}
|
|
1670
|
+
// Retain legacy bare-hex address input only when no symbol matches.
|
|
1671
|
+
Address address = explicitAddress ? parseReaAddress(value) : tryParseAddress(value);
|
|
1672
|
+
if (address == null)
|
|
1673
|
+
throw new RequestFailure("not_found", "Unknown Ghidra procedure name or address: " + value);
|
|
1674
|
+
Function function = currentProgram.getFunctionManager().getFunctionAt(address);
|
|
1675
|
+
if (function == null && address.isMemoryAddress())
|
|
1676
|
+
function = currentProgram.getFunctionManager().getFunctionContaining(address);
|
|
1677
|
+
if (function == null)
|
|
1678
|
+
throw new RequestFailure("not_found", "No procedure exists at the requested address: " + value);
|
|
1679
|
+
return function;
|
|
1611
1680
|
}
|
|
1612
1681
|
|
|
1613
1682
|
private JsonObject nativeApiBoundary(
|
|
@@ -2530,21 +2599,32 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
2530
2599
|
}
|
|
2531
2600
|
|
|
2532
2601
|
private List<Reference> collectReferences(
|
|
2533
|
-
|
|
2602
|
+
Function function,
|
|
2534
2603
|
String direction) throws Exception {
|
|
2604
|
+
// References can target instruction interiors or originate in embedded
|
|
2605
|
+
// data. Use actual body ownership, including an external's exact entry.
|
|
2606
|
+
AddressSet scope = new AddressSet(function.getBody());
|
|
2607
|
+
scope.add(function.getEntryPoint());
|
|
2608
|
+
boolean outgoing = direction.equals("outgoing");
|
|
2609
|
+
AddressIterator addresses = outgoing
|
|
2610
|
+
? currentProgram.getReferenceManager().getReferenceSourceIterator(scope, true)
|
|
2611
|
+
: currentProgram.getReferenceManager().getReferenceDestinationIterator(scope, true);
|
|
2535
2612
|
TreeMap<String, Reference> observed = new TreeMap<>();
|
|
2536
|
-
|
|
2613
|
+
while (addresses.hasNext()) {
|
|
2537
2614
|
monitor.checkCancelled();
|
|
2538
|
-
|
|
2615
|
+
Address address = addresses.next();
|
|
2616
|
+
if (outgoing) {
|
|
2539
2617
|
for (Reference reference : currentProgram.getReferenceManager()
|
|
2540
|
-
.getReferencesFrom(
|
|
2618
|
+
.getReferencesFrom(address)) {
|
|
2619
|
+
monitor.checkCancelled();
|
|
2541
2620
|
addReference(observed, reference);
|
|
2542
2621
|
}
|
|
2543
2622
|
}
|
|
2544
2623
|
else {
|
|
2545
2624
|
ReferenceIterator iterator = currentProgram.getReferenceManager()
|
|
2546
|
-
.getReferencesTo(
|
|
2625
|
+
.getReferencesTo(address);
|
|
2547
2626
|
while (iterator.hasNext()) {
|
|
2627
|
+
monitor.checkCancelled();
|
|
2548
2628
|
addReference(observed, iterator.next());
|
|
2549
2629
|
}
|
|
2550
2630
|
}
|
|
@@ -2944,10 +3024,46 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
2944
3024
|
return parseReaAddress(requireString(params, name));
|
|
2945
3025
|
}
|
|
2946
3026
|
|
|
3027
|
+
private static boolean isExplicitReaAddress(String value) {
|
|
3028
|
+
if (value.regionMatches(true, 0, "0x", 0, 2) &&
|
|
3029
|
+
isHexadecimal(value, 2, value.length()))
|
|
3030
|
+
return true;
|
|
3031
|
+
int separator = value.toLowerCase(Locale.ROOT).lastIndexOf(":0x");
|
|
3032
|
+
if (separator <= 0 || !isHexadecimal(value, separator + 3, value.length()))
|
|
3033
|
+
return false;
|
|
3034
|
+
// Classify the encoded space iteratively. A repeated regex alternation
|
|
3035
|
+
// can exhaust Java's stack on a long ordinary symbol name.
|
|
3036
|
+
for (int index = 0; index < separator; index++) {
|
|
3037
|
+
char item = value.charAt(index);
|
|
3038
|
+
if ((item >= 'A' && item <= 'Z') ||
|
|
3039
|
+
(item >= 'a' && item <= 'z') ||
|
|
3040
|
+
(item >= '0' && item <= '9') ||
|
|
3041
|
+
item == '.' || item == '_' || item == '~' || item == '-')
|
|
3042
|
+
continue;
|
|
3043
|
+
if (item != '%' || index + 2 >= separator ||
|
|
3044
|
+
!isHexadecimal(value, index + 1, index + 3))
|
|
3045
|
+
return false;
|
|
3046
|
+
index += 2;
|
|
3047
|
+
}
|
|
3048
|
+
return true;
|
|
3049
|
+
}
|
|
3050
|
+
|
|
3051
|
+
private static boolean isHexadecimal(String value, int start, int end) {
|
|
3052
|
+
if (start >= end) return false;
|
|
3053
|
+
for (int index = start; index < end; index++) {
|
|
3054
|
+
char item = value.charAt(index);
|
|
3055
|
+
if (!((item >= '0' && item <= '9') ||
|
|
3056
|
+
(item >= 'a' && item <= 'f') ||
|
|
3057
|
+
(item >= 'A' && item <= 'F')))
|
|
3058
|
+
return false;
|
|
3059
|
+
}
|
|
3060
|
+
return true;
|
|
3061
|
+
}
|
|
3062
|
+
|
|
2947
3063
|
private Address parseReaAddress(String value) {
|
|
2948
3064
|
Address address = tryParseAddress(value);
|
|
2949
3065
|
if (address == null) {
|
|
2950
|
-
throw new RequestFailure("invalid_request", "Unknown or invalid Ghidra address");
|
|
3066
|
+
throw new RequestFailure("invalid_request", "Unknown or invalid Ghidra address: " + value);
|
|
2951
3067
|
}
|
|
2952
3068
|
return address;
|
|
2953
3069
|
}
|
|
@@ -2956,22 +3072,31 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
2956
3072
|
try {
|
|
2957
3073
|
String spaceName = null;
|
|
2958
3074
|
String offset = value;
|
|
2959
|
-
int separator = value.lastIndexOf(":0x");
|
|
3075
|
+
int separator = value.toLowerCase(Locale.ROOT).lastIndexOf(":0x");
|
|
2960
3076
|
if (separator >= 0) {
|
|
2961
3077
|
spaceName = decodeAddressSpace(value.substring(0, separator));
|
|
2962
3078
|
offset = value.substring(separator + 3);
|
|
2963
3079
|
}
|
|
2964
|
-
else if (value.startsWith("0x")) {
|
|
3080
|
+
else if (value.startsWith("0x") || value.startsWith("0X")) {
|
|
2965
3081
|
offset = value.substring(2);
|
|
2966
3082
|
}
|
|
2967
|
-
if (!offset.
|
|
3083
|
+
if (!isHexadecimal(offset, 0, offset.length())) {
|
|
2968
3084
|
return null;
|
|
2969
3085
|
}
|
|
2970
3086
|
AddressSpace space = spaceName == null
|
|
2971
3087
|
? currentProgram.getAddressFactory().getDefaultAddressSpace()
|
|
2972
3088
|
: currentProgram.getAddressFactory().getAddressSpace(spaceName);
|
|
2973
|
-
|
|
2974
|
-
|
|
3089
|
+
if (space == null) return null;
|
|
3090
|
+
Address address = space.getAddress(offset);
|
|
3091
|
+
BigInteger requestedOffset = new BigInteger(offset, 16);
|
|
3092
|
+
BigInteger parsedOffset = new BigInteger(Long.toUnsignedString(address.getOffset()));
|
|
3093
|
+
if (!requestedOffset.equals(parsedOffset))
|
|
3094
|
+
throw new RequestFailure("invalid_request",
|
|
3095
|
+
"Ghidra address offset cannot be represented without truncation in space " +
|
|
3096
|
+
space.getName() + ": requested " + value + ", parsed " + canonicalAddress(address));
|
|
3097
|
+
return address;
|
|
3098
|
+
}
|
|
3099
|
+
catch (RequestFailure failure) { throw failure; }
|
|
2975
3100
|
catch (Exception exception) {
|
|
2976
3101
|
return null;
|
|
2977
3102
|
}
|
|
@@ -3055,9 +3180,29 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
3055
3180
|
);
|
|
3056
3181
|
}
|
|
3057
3182
|
catch (PatternSyntaxException exception) {
|
|
3058
|
-
|
|
3183
|
+
// Java wraps compiler stack exhaustion in PatternSyntaxException
|
|
3184
|
+
// without retaining its cause. This producer reason is not bad syntax.
|
|
3185
|
+
if (exception.getDescription().equals("Stack overflow during pattern compilation"))
|
|
3186
|
+
throw regexStackExhausted(expression, "compiling");
|
|
3187
|
+
throw new RequestFailure("invalid_request", "Invalid regex pattern " + expression + ": " + exception.getDescription() + " at index " + exception.getIndex());
|
|
3059
3188
|
}
|
|
3060
|
-
|
|
3189
|
+
catch (StackOverflowError exhausted) {
|
|
3190
|
+
throw regexStackExhausted(expression, "compiling");
|
|
3191
|
+
}
|
|
3192
|
+
return value -> {
|
|
3193
|
+
try {
|
|
3194
|
+
return pattern.matcher(value).find();
|
|
3195
|
+
}
|
|
3196
|
+
catch (StackOverflowError exhausted) {
|
|
3197
|
+
throw regexStackExhausted(expression, "matching");
|
|
3198
|
+
}
|
|
3199
|
+
};
|
|
3200
|
+
}
|
|
3201
|
+
|
|
3202
|
+
private static RequestFailure regexStackExhausted(String expression, String stage) {
|
|
3203
|
+
return new RequestFailure("regex_stack_exhausted",
|
|
3204
|
+
"Ghidra's Java regex engine exhausted its stack while " + stage +
|
|
3205
|
+
" pattern " + expression + ". Use literal mode or simplify the regex; the session remains usable.");
|
|
3061
3206
|
}
|
|
3062
3207
|
|
|
3063
3208
|
private static SessionDescriptor readDescriptor(Path path) throws IOException {
|
|
@@ -3114,7 +3259,7 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
3114
3259
|
private void requireDocument(JsonObject params) {
|
|
3115
3260
|
String document = optionalString(params, "document");
|
|
3116
3261
|
if (document != null && !document.equals(currentProgram.getName())) {
|
|
3117
|
-
throw new RequestFailure("not_found", "Unknown Ghidra Program identity");
|
|
3262
|
+
throw new RequestFailure("not_found", "Unknown Ghidra Program identity: " + document + "; active program: " + currentProgram.getName());
|
|
3118
3263
|
}
|
|
3119
3264
|
}
|
|
3120
3265
|
|
|
@@ -3226,7 +3371,16 @@ public final class ReaGhidraBridge extends HeadlessScript {
|
|
|
3226
3371
|
|
|
3227
3372
|
private static void writeResponse(BufferedWriter writer, JsonObject response) throws IOException {
|
|
3228
3373
|
String encoded = GSON.toJson(response);
|
|
3229
|
-
|
|
3374
|
+
// Gson leaves UTF-16 surrogates literal. Escape them in JSON so even
|
|
3375
|
+
// diagnostics quoting ill-formed caller text remain lossless UTF-8.
|
|
3376
|
+
int start = 0;
|
|
3377
|
+
for (int index = 0; index < encoded.length(); index++) {
|
|
3378
|
+
if (!Character.isSurrogate(encoded.charAt(index))) continue;
|
|
3379
|
+
writer.write(encoded, start, index - start);
|
|
3380
|
+
writer.write("\\u" + Integer.toHexString(encoded.charAt(index)));
|
|
3381
|
+
start = index + 1;
|
|
3382
|
+
}
|
|
3383
|
+
writer.write(encoded, start, encoded.length() - start);
|
|
3230
3384
|
writer.newLine();
|
|
3231
3385
|
writer.flush();
|
|
3232
3386
|
}
|