reverse-engineering-assistant 7.2.1__tar.gz → 7.3.0__tar.gz
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.
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.gitattributes +3 -0
- reverse_engineering_assistant-7.3.0/.github/workflows/copilot-setup-steps.yml +91 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.github/workflows/publish-ghidra.yml +2 -1
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.github/workflows/test-ghidra.yml +4 -3
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.github/workflows/test-headless.yml +35 -2
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.gitignore +3 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/CLAUDE.md +13 -8
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/DEVELOPER.md +1 -1
- reverse_engineering_assistant-7.3.0/Module.manifest +1 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/PKG-INFO +10 -2
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/README.md +7 -0
- reverse_engineering_assistant-7.3.0/ReVa/skills/pyghidra-scripting/SKILL.md +240 -0
- reverse_engineering_assistant-7.3.0/ReVa/skills/pyghidra-scripting/references/decompiler-pcode.md +298 -0
- reverse_engineering_assistant-7.3.0/ReVa/skills/pyghidra-scripting/references/flat-api.md +292 -0
- reverse_engineering_assistant-7.3.0/ReVa/skills/pyghidra-scripting/references/jpype-interop.md +207 -0
- reverse_engineering_assistant-7.3.0/ReVa/skills/pyghidra-scripting/references/persistent-scripts.md +123 -0
- reverse_engineering_assistant-7.3.0/ReVa/skills/pyghidra-scripting/references/recipes.md +649 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/build.gradle +47 -9
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/pyproject.toml +3 -1
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/CLAUDE.md +3 -3
- reverse_engineering_assistant-7.3.0/src/main/help/CLAUDE.md +44 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/help/help/TOC_Source.xml +7 -2
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/help/help/topics/ReVa/ReVa_installation.html +71 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/help/help/topics/ReVa/map.xml +6 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/headless/CLAUDE.md +22 -1
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/headless/RevaHeadlessLauncher.java +114 -1
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/plugin/CLAUDE.md +2 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/plugin/ConfigManager.java +175 -5
- reverse_engineering_assistant-7.3.0/src/main/java/reva/plugin/FollowMeService.java +169 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/plugin/RevaPlugin.java +25 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/plugin/RevaProgramManager.java +55 -1
- reverse_engineering_assistant-7.3.0/src/main/java/reva/plugin/ToolGroup.java +96 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/plugin/config/ToolOptionsBackend.java +39 -19
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/server/CLAUDE.md +6 -3
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/server/McpServerManager.java +300 -35
- reverse_engineering_assistant-7.3.0/src/main/java/reva/server/PublicBindingConsentDialog.java +59 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/server/RequestLoggingFilter.java +4 -1
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/server/ResilientStreamableServerTransportProvider.java +36 -22
- reverse_engineering_assistant-7.3.0/src/main/java/reva/services/AnalysisJob.java +178 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/services/AnalysisJobManager.java +229 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/services/AnalysisJobRunner.java +272 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/services/AnalyzeRequest.java +47 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/services/CLAUDE.md +1 -1
- reverse_engineering_assistant-7.3.0/src/main/java/reva/services/DiffJob.java +72 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/services/DiffJobKind.java +8 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/services/DiffJobManager.java +135 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/services/DiffJobRunner.java +92 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/services/DiffWork.java +14 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/services/JobLog.java +103 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/services/JobStatus.java +24 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/AbstractToolProvider.java +159 -23
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/CLAUDE.md +10 -6
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/ToolProvider.java +6 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/bookmarks/BookmarkToolProvider.java +23 -26
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/callgraph/CallGraphToolProvider.java +16 -16
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/comments/CommentToolProvider.java +17 -19
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/constants/ConstantSearchToolProvider.java +27 -58
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/data/DataToolProvider.java +28 -61
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/dataflow/DataFlowToolProvider.java +27 -37
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/datatypes/CLAUDE.md +6 -7
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/datatypes/DataTypeToolProvider.java +29 -87
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/decompiler/DecompilerToolProvider.java +123 -18
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/diff/CLAUDE.md +160 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/diff/DiffSession.java +29 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/diff/DiffSessionManager.java +280 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/diff/DiffToolProvider.java +1349 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/functions/FunctionToolProvider.java +27 -17
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/imports/ImportExportToolProvider.java +36 -74
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/memory/MemoryToolProvider.java +3 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/project/CLAUDE.md +203 -18
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/project/ProjectToolProvider.java +815 -138
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/scripts/CLAUDE.md +85 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/scripts/CappedWriter.java +105 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/scripts/GhidraDirectoryFactory.java +81 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/scripts/GhidraScriptRunner.java +94 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/scripts/PyGhidraNotAvailableException.java +33 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/scripts/PythonScriptExecutor.java +120 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/scripts/ScriptDirectoryManager.java +211 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/scripts/ScriptFileEditor.java +148 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/tools/scripts/ScriptToolProvider.java +566 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/strings/StringToolProvider.java +11 -43
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/structures/StructureToolProvider.java +35 -78
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/symbols/CLAUDE.md +21 -21
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/symbols/SymbolToolProvider.java +18 -63
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/vtable/VtableToolProvider.java +190 -80
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/xrefs/CrossReferencesToolProvider.java +4 -1
- reverse_engineering_assistant-7.3.0/src/main/java/reva/ui/FollowMeAction.java +80 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/DataTypeParserUtil.java +48 -6
- reverse_engineering_assistant-7.3.0/src/main/java/reva/util/DecompilationDiffUtil.java +613 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/util/NetworkUtil.java +46 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/util/ProgramPersistenceUtil.java +102 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/RevaInternalServiceRegistry.java +6 -2
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/SchemaUtil.java +36 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/util/ToolResultBuilder.java +63 -0
- reverse_engineering_assistant-7.3.0/src/main/java/reva/util/VersionTrackingUtil.java +371 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reva_cli/__main__.py +40 -6
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reva_cli/_version.py +3 -3
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reva_cli/launcher.py +48 -19
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reva_cli/stdio_bridge.py +36 -18
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reverse_engineering_assistant.egg-info/PKG-INFO +10 -2
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reverse_engineering_assistant.egg-info/SOURCES.txt +111 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reverse_engineering_assistant.egg-info/requires.txt +2 -1
- reverse_engineering_assistant-7.3.0/src/test/java/reva/DecompilerNativeHint.java +58 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/DecompilerNativeHintTest.java +59 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test/java/reva/plugin/ConfigChangeTest.java +33 -3
- reverse_engineering_assistant-7.3.0/src/test/java/reva/plugin/ConfigManagerPortTest.java +48 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/plugin/ConfigManagerScriptOptionsTest.java +54 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/plugin/ConfigManagerToolGroupTest.java +55 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/plugin/FollowMeServiceTest.java +267 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/plugin/ToolGroupTest.java +78 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/server/PublicBindingConsentDialogTest.java +59 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/server/ResilientStreamableServerTransportProviderTest.java +172 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/services/AnalysisJobManagerTest.java +115 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/services/DiffJobManagerTest.java +75 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/services/DiffJobRunnerTest.java +56 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/services/JobLogTest.java +45 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/tools/AbstractToolProviderUnregisterTest.java +87 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/tools/PaginationResultHelperTest.java +62 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/tools/scripts/CappedWriterTest.java +175 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/tools/scripts/PyGhidraNotAvailableExceptionTest.java +55 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/tools/scripts/PythonScriptExecutorTest.java +218 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/tools/scripts/ScriptDirectoryManagerTest.java +278 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/tools/scripts/ScriptFileEditorTest.java +185 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/tools/scripts/ScriptToolProviderTest.java +198 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/util/DecompilationDiffUtilTest.java +329 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/util/NetworkUtilTest.java +54 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/util/ProgramPersistenceUtilTest.java +67 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/util/SchemaUtilBuilderTest.java +51 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/util/ToolResultBuilderTest.java +49 -0
- reverse_engineering_assistant-7.3.0/src/test/java/reva/util/VersionTrackingUtilTest.java +27 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/CLAUDE.md +34 -1
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/AnalyzedFixtureSupport.java +97 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/AnalyzedFixtureSupportIntegrationTest.java +53 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/RandomPortRegressionIntegrationTest.java +41 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/RevaIntegrationTestBase.java +51 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/headless/HeadlessLauncherApiKeyIntegrationTest.java +75 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/headless/HeadlessLauncherToolGroupIntegrationTest.java +108 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/plugin/RevaPluginMcpIntegrationTest.java +4 -2
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/server/PublicBindingGuardIntegrationTest.java +87 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/server/PublicBindingRevertIntegrationTest.java +76 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/server/ToolGroupRegistrationIntegrationTest.java +143 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/services/AnalysisJobCancelOnCloseIntegrationTest.java +84 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/services/AnalysisJobRunnerIntegrationTest.java +151 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/callgraph/CallGraphToolProviderIntegrationTest.java +143 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/constants/ConstantSearchToolProviderIntegrationTest.java +264 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/data/DataToolProviderIntegrationTest.java +2 -1
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/dataflow/DataFlowToolProviderIntegrationTest.java +296 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/datatypes/DataTypeToolProviderIntegrationTest.java +14 -44
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/decompiler/DecompilerToolProviderIntegrationTest.java +103 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/diff/DiffAddCorrelatorIntegrationTest.java +233 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/diff/DiffCalleeNamesIntegrationTest.java +325 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/diff/DiffCreateSessionAsyncIntegrationTest.java +117 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/diff/DiffSessionPersistenceIntegrationTest.java +323 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/diff/DiffStagedCorrelationIntegrationTest.java +211 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/diff/DiffStatusCancelIntegrationTest.java +175 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/diff/DiffTestPrograms.java +139 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/diff/DiffToolProviderIntegrationTest.java +879 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/diff/DiffTransferMarkupAsyncIntegrationTest.java +94 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/functions/CreateFunctionDisassembleIntegrationTest.java +99 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/imports/ImportExportToolProviderIntegrationTest.java +225 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/memory/MemoryToolProviderIntegrationTest.java +2 -1
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/project/AnalysisCancelIntegrationTest.java +215 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/project/AnalysisStatusIntegrationTest.java +273 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/project/AnalyzeProgramAsyncIntegrationTest.java +219 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/project/AnalyzeProgramToolProviderIntegrationTest.java +505 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/scripts/ScriptToolProviderIntegrationTest.java +424 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/symbols/SymbolToolProviderIntegrationTest.java +140 -0
- reverse_engineering_assistant-7.3.0/src/test.slow/java/reva/tools/vtable/VtableToolProviderIntegrationTest.java +305 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/conftest.py +82 -133
- reverse_engineering_assistant-7.3.0/tests/fixtures/test_cpp_arm64 +3 -0
- reverse_engineering_assistant-7.3.0/tests/fixtures/test_cpp_program.cpp +50 -0
- reverse_engineering_assistant-7.3.0/tests/fixtures/test_cpp_x86_64 +3 -0
- reverse_engineering_assistant-7.3.0/tests/fixtures/test_dataflow.c +18 -0
- reverse_engineering_assistant-7.3.0/tests/fixtures/test_dataflow_x86_64 +3 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/helpers.py +69 -205
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/requirements.txt +1 -1
- reverse_engineering_assistant-7.3.0/tests/test_analysis_jobs_e2e.py +238 -0
- reverse_engineering_assistant-7.3.0/tests/test_api_key_injection.py +45 -0
- reverse_engineering_assistant-7.3.0/tests/test_cli_e2e.py +315 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/test_cli_project_manager.py +9 -26
- reverse_engineering_assistant-7.3.0/tests/test_diff_e2e.py +410 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/test_e2e_workflow.py +128 -52
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/test_import_e2e.py +186 -134
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/test_launcher.py +26 -12
- reverse_engineering_assistant-7.3.0/tests/test_mcp_tools.py +100 -0
- reverse_engineering_assistant-7.3.0/tests/test_run_script_e2e.py +647 -0
- reverse_engineering_assistant-7.3.0/tests/test_tool_group_cli.py +53 -0
- reverse_engineering_assistant-7.3.0/tests/test_tool_group_cli_e2e.py +64 -0
- reverse_engineering_assistant-7.3.0/tests/test_tool_group_toggle_integration.py +62 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/test_vscode_mcp_client_compat.py +54 -22
- reverse_engineering_assistant-7.3.0/tests/test_workflow_correctness.py +3633 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/uv.lock +30 -4
- reverse_engineering_assistant-7.2.1/Module.manifest +0 -0
- reverse_engineering_assistant-7.2.1/src/main/java/reva/util/DecompilationDiffUtil.java +0 -253
- reverse_engineering_assistant-7.2.1/tests/test_cli_e2e.py +0 -195
- reverse_engineering_assistant-7.2.1/tests/test_mcp_tools.py +0 -136
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.claude/README.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.claude/agents/ghidra-api-expert.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.claude/agents/reva-setup-installer.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.claude/hooks/gradle-proxy.py +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.claude/hooks/setup-remote-env.sh +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.claude/launch.json +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.claude/settings.json +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.claude-plugin/marketplace.json +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.continue/docs/new-doc-1.yaml +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.continue/docs/new-doc.yaml +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.github/CI_WORKFLOWS.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.github/WORKFLOW_SETUP.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.github/copilot-instructions.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.github/dependabot.yml +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.github/workflows/claude.yml +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.github/workflows/publish-pypi.yml +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.vscode/extensions.json +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.vscode/launch.json +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/.vscode/settings.json +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/AGENTS.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/LICENSE +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/.claude-plugin/plugin.json +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/.mcp.json +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/LICENSE +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/skills/binary-triage/SKILL.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/skills/ctf-crypto/SKILL.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/skills/ctf-crypto/patterns.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/skills/ctf-pwn/SKILL.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/skills/ctf-pwn/patterns.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/skills/ctf-rev/SKILL.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/skills/ctf-rev/patterns.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/skills/deep-analysis/SKILL.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/skills/deep-analysis/examples.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ReVa/skills/deep-analysis/patterns.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/config/reva-headless-example.properties +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/data/README.txt +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/data/buildLanguage.xml +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/data/languages/skel.cspec +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/data/languages/skel.ldefs +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/data/languages/skel.opinion +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/data/languages/skel.pspec +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/data/languages/skel.sinc +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/data/languages/skel.slaspec +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/data/sleighArgs.txt +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/extension.properties +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ghidra_scripts/README.txt +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ghidra_scripts/SampleScript.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/ghidra_scripts/sample_script.py +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/lib/.gitignore +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/lib/README.txt +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/os/linux_x86_64/README.txt +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/os/mac_x86_64/README.txt +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/os/win_x86_64/README.txt +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/setup.cfg +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/help/help/topics/ReVa/ReVa_overview.html +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/help/help/topics/ReVa/ReVa_skills.html +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/help/help/topics/skeleton/help.html +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/debug/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/debug/DebugCaptureService.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/debug/DebugInfoCollector.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/plugin/ConfigChangeListener.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/plugin/RevaApplicationPlugin.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/plugin/config/ConfigurationBackend.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/plugin/config/ConfigurationBackendListener.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/plugin/config/FileBackend.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/plugin/config/InMemoryBackend.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/resources/AbstractResourceProvider.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/resources/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/resources/ResourceProvider.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/resources/impl/ProgramListResource.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/revaAnalyzer.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/revaExporter.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/revaFileSystem.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/server/ApiKeyAuthFilter.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/server/CachingRequestWrapper.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/server/CachingResponseWrapper.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/services/RevaMcpService.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/ProgramValidationException.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/bookmarks/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/callgraph/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/comments/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/constants/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/data/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/dataflow/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/decompiler/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/functions/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/imports/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/memory/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/strings/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/structures/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/vtable/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/tools/xrefs/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/ui/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/ui/CaptureDebugAction.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/ui/RevaProvider.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/AddressUtil.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/DebugLogger.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/DecompilationContextUtil.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/MemoryUtil.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/ProgramLookupUtil.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/RevaToolLogger.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/SimilarityComparator.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/java/reva/util/SymbolUtil.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/resources/help/shared/note.png +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/resources/help/shared/tip.png +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/resources/help/shared/warning.png +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/main/resources/images/README.txt +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reva_cli/.gitignore +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reva_cli/__init__.py +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reva_cli/project_manager.py +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reverse_engineering_assistant.egg-info/dependency_links.txt +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reverse_engineering_assistant.egg-info/entry_points.txt +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/reverse_engineering_assistant.egg-info/top_level.txt +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test/java/reva/RevaHeadlessIntegrationTestBase.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test/java/reva/plugin/RevaPluginHeadlessIntegrationTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test/java/reva/plugin/RevaPluginUnitTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test/java/reva/tools/decompiler/DecompilerToolProviderTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test/java/reva/tools/strings/StringToolProviderTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test/java/reva/util/AddressUtilTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test/java/reva/util/RevaPluginTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test/java/reva/util/SymbolUtilTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test/resources/defaultTools/TestCodeBrowser.tool +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/CLAUDE.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/plugin/ConfigManagerSecurityTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/plugin/RevaPluginIntegrationTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/bookmarks/BookmarkToolProviderIntegrationTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/comments/CommentToolProviderIntegrationTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/decompiler/DecompilerIncomingReferencesLimitTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/functions/FunctionPrototypeToolProviderIntegrationTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/project/ProjectToolProviderNestedArchiveIntegrationTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/project/ProjectToolProviderVersionControlIntegrationTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/strings/StringToolProviderIntegrationTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/structures/StructureToolProviderIntegrationTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/java/reva/tools/xrefs/CrossReferencesToolProviderIntegrationTest.java +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/src/test.slow/resources/logback.xml +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/README.md +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/__init__.py +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/fixtures/test_archive.zip +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/fixtures/test_arm64 +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/fixtures/test_fat_binary +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/fixtures/test_program.c +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/fixtures/test_x86_64 +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/test_config.py +0 -0
- {reverse_engineering_assistant-7.2.1 → reverse_engineering_assistant-7.3.0}/tests/test_pyghidra.py +0 -0
|
@@ -2,4 +2,7 @@ tests/fixtures/test_fat_binary filter=lfs diff=lfs merge=lfs -text
|
|
|
2
2
|
tests/fixtures/test_archive.zip filter=lfs diff=lfs merge=lfs -text
|
|
3
3
|
tests/fixtures/test_arm64 filter=lfs diff=lfs merge=lfs -text
|
|
4
4
|
tests/fixtures/test_x86_64 filter=lfs diff=lfs merge=lfs -text
|
|
5
|
+
tests/fixtures/test_cpp_arm64 filter=lfs diff=lfs merge=lfs -text
|
|
6
|
+
tests/fixtures/test_cpp_x86_64 filter=lfs diff=lfs merge=lfs -text
|
|
5
7
|
tests/fixtures/*.zip filter=lfs diff=lfs merge=lfs -text
|
|
8
|
+
tests/fixtures/test_dataflow_x86_64 filter=lfs diff=lfs merge=lfs -text
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
name: Copilot Setup Steps
|
|
2
|
+
|
|
3
|
+
# Provisions the environment for the GitHub Copilot coding agent.
|
|
4
|
+
# Mirrors the toolchain used by test-ghidra.yml and test-headless.yml so the
|
|
5
|
+
# agent can build the extension, run Java unit + integration tests, and
|
|
6
|
+
# exercise the Python CLI / PyGhidra paths without further setup.
|
|
7
|
+
#
|
|
8
|
+
# Schema constraints (see GitHub Copilot docs):
|
|
9
|
+
# - Job MUST be named `copilot-setup-steps`.
|
|
10
|
+
# - Only `steps`, `permissions`, `runs-on`, `services`, `snapshot`,
|
|
11
|
+
# and `timeout-minutes` (max 59) may be set on the job.
|
|
12
|
+
# - actions/checkout fetch-depth is overridden by the system.
|
|
13
|
+
|
|
14
|
+
on:
|
|
15
|
+
workflow_dispatch:
|
|
16
|
+
push:
|
|
17
|
+
paths:
|
|
18
|
+
- .github/workflows/copilot-setup-steps.yml
|
|
19
|
+
pull_request:
|
|
20
|
+
paths:
|
|
21
|
+
- .github/workflows/copilot-setup-steps.yml
|
|
22
|
+
|
|
23
|
+
jobs:
|
|
24
|
+
copilot-setup-steps:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 45
|
|
27
|
+
permissions:
|
|
28
|
+
contents: read
|
|
29
|
+
steps:
|
|
30
|
+
- name: Checkout code
|
|
31
|
+
uses: actions/checkout@v6
|
|
32
|
+
with:
|
|
33
|
+
lfs: true
|
|
34
|
+
|
|
35
|
+
- name: Install C/C++ toolchain and Xvfb
|
|
36
|
+
# build-essential covers gcc/g++/make for rebuilding tests/fixtures
|
|
37
|
+
# sources. clang is handy for cross-checks. xvfb lets the agent run
|
|
38
|
+
# Ghidra integration tests (which require a display) on demand.
|
|
39
|
+
run: |
|
|
40
|
+
sudo apt-get update
|
|
41
|
+
sudo apt-get install -y --no-install-recommends \
|
|
42
|
+
build-essential \
|
|
43
|
+
clang \
|
|
44
|
+
xvfb \
|
|
45
|
+
unzip
|
|
46
|
+
gcc --version
|
|
47
|
+
clang --version
|
|
48
|
+
|
|
49
|
+
- name: Set up Java 21
|
|
50
|
+
uses: actions/setup-java@v5
|
|
51
|
+
with:
|
|
52
|
+
java-version: "21"
|
|
53
|
+
distribution: "microsoft"
|
|
54
|
+
|
|
55
|
+
- name: Set up Python 3.10
|
|
56
|
+
uses: actions/setup-python@v6
|
|
57
|
+
with:
|
|
58
|
+
python-version: "3.10"
|
|
59
|
+
|
|
60
|
+
- name: Install Ghidra
|
|
61
|
+
# Sets GHIDRA_INSTALL_DIR for subsequent steps and the agent session.
|
|
62
|
+
uses: antoniovazquezblanco/setup-ghidra@v2.1.2
|
|
63
|
+
with:
|
|
64
|
+
version: "latest"
|
|
65
|
+
auth_token: ${{ secrets.GITHUB_TOKEN }}
|
|
66
|
+
|
|
67
|
+
- name: Setup Gradle
|
|
68
|
+
uses: gradle/actions/setup-gradle@v6
|
|
69
|
+
with:
|
|
70
|
+
gradle-version: "8.14"
|
|
71
|
+
|
|
72
|
+
- name: Install uv
|
|
73
|
+
uses: astral-sh/setup-uv@v7
|
|
74
|
+
with:
|
|
75
|
+
enable-cache: true
|
|
76
|
+
|
|
77
|
+
- name: Sync Python dependencies
|
|
78
|
+
run: uv sync --prerelease=allow
|
|
79
|
+
|
|
80
|
+
- name: Install PyGhidra from local Ghidra
|
|
81
|
+
run: uv pip install "${GHIDRA_INSTALL_DIR}/Ghidra/Features/PyGhidra/pypkg"
|
|
82
|
+
|
|
83
|
+
- name: Verify PyGhidra installation
|
|
84
|
+
run: |
|
|
85
|
+
uv run python -c "import pyghidra; print(f'PyGhidra version: {pyghidra.__version__}')"
|
|
86
|
+
|
|
87
|
+
- name: Pre-warm Gradle dependency cache
|
|
88
|
+
# Resolve Java deps and compile sources so the agent's first build
|
|
89
|
+
# is fast. Skipping `buildExtension` keeps setup under the timeout
|
|
90
|
+
# while still pulling every dependency the build graph needs.
|
|
91
|
+
run: gradle --no-daemon compileJava compileTestJava compileIntegrationTestJava
|
|
@@ -22,6 +22,7 @@ jobs:
|
|
|
22
22
|
"12.0.2",
|
|
23
23
|
"12.0.3",
|
|
24
24
|
"12.0.4",
|
|
25
|
+
"12.1",
|
|
25
26
|
]
|
|
26
27
|
name: Build distribution 📦
|
|
27
28
|
runs-on: ubuntu-latest
|
|
@@ -33,7 +34,7 @@ jobs:
|
|
|
33
34
|
java-version: "21"
|
|
34
35
|
distribution: "microsoft"
|
|
35
36
|
- name: Install Ghidra 🐉
|
|
36
|
-
uses: antoniovazquezblanco/setup-ghidra@v2.1.
|
|
37
|
+
uses: antoniovazquezblanco/setup-ghidra@v2.1.2
|
|
37
38
|
with:
|
|
38
39
|
version: ${{ matrix.ghidra-version }}
|
|
39
40
|
auth_token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -23,6 +23,7 @@ jobs:
|
|
|
23
23
|
"12.0.2",
|
|
24
24
|
"12.0.3",
|
|
25
25
|
"12.0.4",
|
|
26
|
+
"12.1",
|
|
26
27
|
"latest",
|
|
27
28
|
]
|
|
28
29
|
name: Test on Ghidra ${{ matrix.ghidra-version }}
|
|
@@ -39,7 +40,7 @@ jobs:
|
|
|
39
40
|
distribution: "microsoft"
|
|
40
41
|
|
|
41
42
|
- name: Install Ghidra 🐉
|
|
42
|
-
uses: antoniovazquezblanco/setup-ghidra@v2.1.
|
|
43
|
+
uses: antoniovazquezblanco/setup-ghidra@v2.1.2
|
|
43
44
|
with:
|
|
44
45
|
version: ${{ matrix.ghidra-version }}
|
|
45
46
|
auth_token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -104,7 +105,7 @@ jobs:
|
|
|
104
105
|
distribution: "microsoft"
|
|
105
106
|
|
|
106
107
|
- name: Install Ghidra 🐉
|
|
107
|
-
uses: antoniovazquezblanco/setup-ghidra@v2.1.
|
|
108
|
+
uses: antoniovazquezblanco/setup-ghidra@v2.1.2
|
|
108
109
|
with:
|
|
109
110
|
version: "latest"
|
|
110
111
|
auth_token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -155,7 +156,7 @@ jobs:
|
|
|
155
156
|
queries: security-extended,security-and-quality
|
|
156
157
|
|
|
157
158
|
- name: Install Ghidra 🐉
|
|
158
|
-
uses: antoniovazquezblanco/setup-ghidra@v2.1.
|
|
159
|
+
uses: antoniovazquezblanco/setup-ghidra@v2.1.2
|
|
159
160
|
with:
|
|
160
161
|
version: "latest"
|
|
161
162
|
auth_token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -23,7 +23,23 @@ jobs:
|
|
|
23
23
|
- "12.0.2"
|
|
24
24
|
- "12.0.3"
|
|
25
25
|
- "12.0.4"
|
|
26
|
+
- "12.1"
|
|
26
27
|
- "latest"
|
|
28
|
+
# macOS hosted runners are ~4x slower per e2e test and far scarcer
|
|
29
|
+
# (7 concurrent macOS jobs queued for hours). Linux carries full
|
|
30
|
+
# version coverage; macOS validates the platform itself (native
|
|
31
|
+
# decompiler build, arm64) on the oldest and newest Ghidra only.
|
|
32
|
+
exclude:
|
|
33
|
+
- os: macos-latest
|
|
34
|
+
ghidra-version: "12.0.1"
|
|
35
|
+
- os: macos-latest
|
|
36
|
+
ghidra-version: "12.0.2"
|
|
37
|
+
- os: macos-latest
|
|
38
|
+
ghidra-version: "12.0.3"
|
|
39
|
+
- os: macos-latest
|
|
40
|
+
ghidra-version: "12.0.4"
|
|
41
|
+
- os: macos-latest
|
|
42
|
+
ghidra-version: "12.1"
|
|
27
43
|
fail-fast: false # Continue other tests if one fails
|
|
28
44
|
|
|
29
45
|
name: Test on ${{ matrix.os }} / Ghidra ${{ matrix.ghidra-version }}
|
|
@@ -47,7 +63,7 @@ jobs:
|
|
|
47
63
|
python-version: "3.10"
|
|
48
64
|
|
|
49
65
|
- name: Install Ghidra ${{ matrix.ghidra-version }}
|
|
50
|
-
uses: antoniovazquezblanco/setup-ghidra@v2.1.
|
|
66
|
+
uses: antoniovazquezblanco/setup-ghidra@v2.1.2
|
|
51
67
|
with:
|
|
52
68
|
version: ${{ matrix.ghidra-version }}
|
|
53
69
|
auth_token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -57,6 +73,16 @@ jobs:
|
|
|
57
73
|
with:
|
|
58
74
|
gradle-version: "8.14"
|
|
59
75
|
|
|
76
|
+
# Ghidra releases ship prebuilt decompiler natives for Linux and Windows but
|
|
77
|
+
# NOT macOS. Without this, decompilation silently returns nothing on macOS
|
|
78
|
+
# runners and any decompiler-dependent headless test fails. Ghidra searches
|
|
79
|
+
# build/os/<platform> (where this task writes) before os/<platform>, so the
|
|
80
|
+
# installed PyGhidra runtime picks these up. Linux runners already have
|
|
81
|
+
# prebuilt natives, so the step is macOS-only.
|
|
82
|
+
- name: Build Ghidra natives (macOS only)
|
|
83
|
+
if: runner.os == 'macOS'
|
|
84
|
+
run: gradle -p "$GHIDRA_INSTALL_DIR/support/gradle" buildNatives
|
|
85
|
+
|
|
60
86
|
- name: Build ReVa Extension
|
|
61
87
|
run: gradle clean buildExtension --no-build-cache
|
|
62
88
|
|
|
@@ -89,11 +115,18 @@ jobs:
|
|
|
89
115
|
id: headless_test
|
|
90
116
|
run: |
|
|
91
117
|
echo "::group::Running headless integration tests"
|
|
92
|
-
uv run pytest tests/ -v --timeout=180 --tb=short --junitxml=test-results.xml
|
|
118
|
+
uv run pytest tests/ -v --timeout=180 --tb=short --junitxml=test-results.xml ${PYTEST_EXTRA_ARGS}
|
|
93
119
|
echo "::endgroup::"
|
|
120
|
+
# The e2e suite shares one mcp-reva server per pytest session (per
|
|
121
|
+
# xdist worker), so the dominant historical cost — a full JVM/PyGhidra
|
|
122
|
+
# boot per test (~40s on macOS, ~10s on Linux) — is paid once per
|
|
123
|
+
# worker instead of ~110 times. macOS additionally runs 2 xdist
|
|
124
|
+
# workers. If this times out again, suspect a server hang or a new
|
|
125
|
+
# per-test boot, not a slow suite.
|
|
94
126
|
timeout-minutes: 30
|
|
95
127
|
env:
|
|
96
128
|
GHIDRA_INSTALL_DIR: ${{ env.GHIDRA_INSTALL_DIR }}
|
|
129
|
+
PYTEST_EXTRA_ARGS: ${{ runner.os == 'macOS' && '-n 2' || '' }}
|
|
97
130
|
|
|
98
131
|
- name: Upload test artifacts
|
|
99
132
|
uses: actions/upload-artifact@v7
|
|
@@ -138,7 +138,7 @@ mcp-reva CLI → PyGhidra → ReVaLauncher → Jetty (HTTP)
|
|
|
138
138
|
- **Foundation Layer** (`util/`) - AddressUtil, ProgramLookupUtil, DataTypeParserUtil, etc.
|
|
139
139
|
- **Plugin Layer** (`plugin/`) - ConfigManager, RevaProgramManager, Ghidra lifecycle
|
|
140
140
|
- **Server Layer** (`server/`) - McpServerManager, Jetty server, streamable transport
|
|
141
|
-
- **Tool Layer** (`tools/`) -
|
|
141
|
+
- **Tool Layer** (`tools/`) - 19 specialized tool packages (decompiler, functions, strings, callgraph, dataflow, etc.)
|
|
142
142
|
- **Resource Layer** (`resources/`) - Read-only MCP resource providers
|
|
143
143
|
- **Headless Layer** (`headless/`) - RevaHeadlessLauncher for PyGhidra integration
|
|
144
144
|
|
|
@@ -154,7 +154,7 @@ src/main/java/reva/ # Java extension code
|
|
|
154
154
|
├── util/ # Foundational utilities (ALWAYS use these!)
|
|
155
155
|
├── plugin/ # ConfigManager, plugin lifecycle
|
|
156
156
|
├── server/ # McpServerManager, Jetty
|
|
157
|
-
├── tools/ #
|
|
157
|
+
├── tools/ # 19 tool provider packages
|
|
158
158
|
├── resources/ # MCP resource providers
|
|
159
159
|
├── headless/ # RevaHeadlessLauncher
|
|
160
160
|
└── ui/ # Optional GUI components
|
|
@@ -168,15 +168,17 @@ scripts/ # Helper scripts (reva_headless_server.py)
|
|
|
168
168
|
### Package-Level Documentation
|
|
169
169
|
Each major package contains its own CLAUDE.md file with detailed implementation guidance:
|
|
170
170
|
- **Essential Infrastructure**: `util/`, `plugin/`, `server/` - Core systems documentation
|
|
171
|
-
- **Tool Providers**: Each of the
|
|
171
|
+
- **Tool Providers**: Each of the 19 tool packages has comprehensive implementation guides
|
|
172
172
|
- **Supporting Systems**: `resources/`, `services/`, `ui/` - Specialized component documentation
|
|
173
173
|
|
|
174
174
|
### Tool Provider Categories
|
|
175
175
|
- **Core Analysis**: decompiler, functions, strings, symbols, xrefs, memory
|
|
176
176
|
- **Data & Types**: data, datatypes, structures
|
|
177
177
|
- **Advanced Analysis**: callgraph, dataflow, constants, vtable, imports
|
|
178
|
+
- **diff**: binary diffing via Version Tracking (match functions, explain changes, transfer analysis between variants)
|
|
178
179
|
- **Annotations**: comments, bookmarks
|
|
179
180
|
- **Project Management**: project
|
|
181
|
+
- **Scripting**: scripts (Python script run/list/read/write/edit; requires PyGhidra)
|
|
180
182
|
|
|
181
183
|
## Development Guidelines
|
|
182
184
|
|
|
@@ -224,6 +226,7 @@ When adding new tools to DecompilerToolProvider:
|
|
|
224
226
|
- Return structured JSON with success flags and program metadata
|
|
225
227
|
- Exception handling is automatic: `registerTool()` wraps all handlers to catch `IllegalArgumentException` and `ProgramValidationException` and convert them to error responses. Manual try-catch is only needed for custom error handling or resource cleanup (e.g., DecompInterface disposal).
|
|
226
228
|
- Use pagination for large datasets (functions, symbols, strings, etc.)
|
|
229
|
+
- Progress notifications: only emit when client opted in (`request.progressToken() != null` → `exchange.progressNotification(new ProgressNotification(token, progress, total, message))`). Examples: `ProjectToolProvider` import-file, `DecompilerToolProvider` search-decompilation.
|
|
227
230
|
|
|
228
231
|
## MCP Server Configuration
|
|
229
232
|
|
|
@@ -262,13 +265,13 @@ Install via: `claude plugin marketplace add cyberkaida/reverse-engineering-assis
|
|
|
262
265
|
### Java
|
|
263
266
|
- Ghidra: 12.0+ (source at `../ghidra`)
|
|
264
267
|
- Java: 21+
|
|
265
|
-
- MCP SDK: io.modelcontextprotocol.sdk
|
|
266
|
-
- Jackson: 2.
|
|
268
|
+
- MCP SDK: io.modelcontextprotocol.sdk v1.1.1 (BOM-managed)
|
|
269
|
+
- Jackson: 2.21.x (force-resolved for MCP SDK compatibility)
|
|
267
270
|
- Jetty: 11.0.26 (embedded servlet server)
|
|
268
271
|
|
|
269
272
|
### Python
|
|
270
273
|
- Python: 3.10+ (managed via uv)
|
|
271
|
-
- PyGhidra: 3.
|
|
274
|
+
- PyGhidra: 3.1.0+ (Ghidra initialization)
|
|
272
275
|
- MCP: Latest (stdio transport implementation)
|
|
273
276
|
- httpx + httpx-sse: MCP HTTP client (for StdioBridge)
|
|
274
277
|
|
|
@@ -301,7 +304,7 @@ Install via: `claude plugin marketplace add cyberkaida/reverse-engineering-assis
|
|
|
301
304
|
- **Testing (Java)**: Integration tests require `java.awt.headless=false`, fork=1
|
|
302
305
|
- **Testing (Python)**: pytest with markers (unit/integration/e2e/cli)
|
|
303
306
|
- **Build**: Use `gradle` directly, NOT `./gradlew`
|
|
304
|
-
- **MCP SDK**:
|
|
307
|
+
- **MCP SDK**: v1.1.1 with forced Jackson 2.21.x for compatibility
|
|
305
308
|
|
|
306
309
|
## Important Notes
|
|
307
310
|
|
|
@@ -313,9 +316,11 @@ Install via: `claude plugin marketplace add cyberkaida/reverse-engineering-assis
|
|
|
313
316
|
|
|
314
317
|
### Common Issues
|
|
315
318
|
- **Jackson conflicts**: `rm lib/*.jar` and rebuild to fix MCP SDK compatibility
|
|
316
|
-
- **Test reports**:
|
|
319
|
+
- **Test reports**: Parse `build/test-results/integrationTest/TEST-*.xml` with Read/Grep — don't trust `BUILD SUCCESSFUL` alone (compileIntegrationTestJava can fail silently in mixed output)
|
|
317
320
|
- **CI logs**: Use Task agent to read (very long logs, context-intensive)
|
|
318
321
|
- **Stdio mode**: Requires clean stdin/stdout - no debug prints to stdout
|
|
322
|
+
- **Help build (`gradle install`)**: JavaHelp validation fails the whole module on any cross-file anchor collision in `src/main/help/help/topics/` or any broken `help/shared/*` reference (note/tip/warning images live in `src/main/resources/help/shared/`, not under `src/main/help/`). See [help/CLAUDE.md](src/main/help/CLAUDE.md).
|
|
323
|
+
- **Test fixtures (binaries)**: All binary fixtures under `tests/fixtures/` MUST be tracked via git-lfs. Before `git add`-ing a new binary, register it in `.gitattributes` with `filter=lfs diff=lfs merge=lfs -text` (per-file or via glob like `tests/fixtures/test_cpp_*`). Verify the staged form is a 3-line LFS pointer (`version https://git-lfs.github.com/...`), not raw bytes — `git diff --cached <path>` should show ~3 insertions, not thousands. If a binary slipped into a commit as raw bytes, fix with `git reset --soft HEAD~1`, update `.gitattributes`, `git rm --cached <binary>`, then re-add (the LFS clean filter runs on add). CI's `actions/checkout@v6` is configured with `lfs: true` so pointers resolve to real binaries on remote runners.
|
|
319
324
|
|
|
320
325
|
### Testing Strategy
|
|
321
326
|
- **Java unit tests**: Fast, no Ghidra environment, test utilities/logic
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
MODULE DEPENDENCY: Ghidra/Features/VersionTracking
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: reverse-engineering-assistant
|
|
3
|
-
Version: 7.
|
|
3
|
+
Version: 7.3.0
|
|
4
4
|
Summary: ReVa - AI-powered Reverse Engineering Assistant for Ghidra with MCP server and Claude CLI integration
|
|
5
5
|
Author-email: cyberkaida <cyberkaida@users.noreply.github.com>
|
|
6
6
|
Maintainer: cyberkaida
|
|
@@ -28,7 +28,7 @@ Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
|
28
28
|
Requires-Python: >=3.10
|
|
29
29
|
Description-Content-Type: text/markdown
|
|
30
30
|
License-File: LICENSE
|
|
31
|
-
Requires-Dist: pyghidra>=3.
|
|
31
|
+
Requires-Dist: pyghidra>=3.1.0
|
|
32
32
|
Requires-Dist: mcp
|
|
33
33
|
Requires-Dist: httpx<1.0,>=0.27.0
|
|
34
34
|
Requires-Dist: httpx-sse>=0.4.0
|
|
@@ -37,6 +37,7 @@ Requires-Dist: pytest>=7.0.0; extra == "test"
|
|
|
37
37
|
Requires-Dist: pytest-asyncio>=0.21.0; extra == "test"
|
|
38
38
|
Requires-Dist: pytest-timeout>=2.0.0; extra == "test"
|
|
39
39
|
Requires-Dist: pytest-sugar>=0.9.0; extra == "test"
|
|
40
|
+
Requires-Dist: pytest-xdist>=3.0.0; extra == "test"
|
|
40
41
|
Requires-Dist: mcp; extra == "test"
|
|
41
42
|
Requires-Dist: httpx<1.0,>=0.27.0; extra == "test"
|
|
42
43
|
Requires-Dist: httpx-sse>=0.4.0; extra == "test"
|
|
@@ -90,6 +91,7 @@ You can ask questions like:
|
|
|
90
91
|
- What does `mmap` return?
|
|
91
92
|
- What does the function at address 0x80000 do?
|
|
92
93
|
- This is a CTF problem. Write a pwntools script to get the flag.
|
|
94
|
+
- Import these two binaries and diff them, explain the changes.
|
|
93
95
|
|
|
94
96
|
# Installation
|
|
95
97
|
|
|
@@ -110,6 +112,12 @@ After installing the extension you need to activate it in two places:
|
|
|
110
112
|
1. In the Project view, open the File menu and select "Configure". Click the "Configure all plugins" button on the top right of the menu (it looks like a plug). Check the "ReVa Application Plugin"
|
|
111
113
|
2. In the Code Browser tool (Click the Dragon icon or open a File), open the File menu and select "Configure". Click the "Configure all plugins" button on the top right of the menu (it looks like a plug). Check the "ReVa Plugin". Then Press File and select "Save Tool". This will enable ReVa by default.
|
|
112
114
|
|
|
115
|
+
> NOTE: ReVa provides access to the PyGhidra scripting environment. If
|
|
116
|
+
> you allow ReVa to listen on a public interface, either enable the API
|
|
117
|
+
> key authentication or disable the scripting tools in the settings.
|
|
118
|
+
> The default configuration is to listen on localhost and allow the
|
|
119
|
+
> scripting tools.
|
|
120
|
+
|
|
113
121
|
# Usage
|
|
114
122
|
|
|
115
123
|
There are two ways to use ReVa, with the Ghidra UI in assistant mode or in headless mode. Headless mode is ideal for automation and CI/CD pipelines, while the assistant mode is great for interactive analysis.
|
|
@@ -46,6 +46,7 @@ You can ask questions like:
|
|
|
46
46
|
- What does `mmap` return?
|
|
47
47
|
- What does the function at address 0x80000 do?
|
|
48
48
|
- This is a CTF problem. Write a pwntools script to get the flag.
|
|
49
|
+
- Import these two binaries and diff them, explain the changes.
|
|
49
50
|
|
|
50
51
|
# Installation
|
|
51
52
|
|
|
@@ -66,6 +67,12 @@ After installing the extension you need to activate it in two places:
|
|
|
66
67
|
1. In the Project view, open the File menu and select "Configure". Click the "Configure all plugins" button on the top right of the menu (it looks like a plug). Check the "ReVa Application Plugin"
|
|
67
68
|
2. In the Code Browser tool (Click the Dragon icon or open a File), open the File menu and select "Configure". Click the "Configure all plugins" button on the top right of the menu (it looks like a plug). Check the "ReVa Plugin". Then Press File and select "Save Tool". This will enable ReVa by default.
|
|
68
69
|
|
|
70
|
+
> NOTE: ReVa provides access to the PyGhidra scripting environment. If
|
|
71
|
+
> you allow ReVa to listen on a public interface, either enable the API
|
|
72
|
+
> key authentication or disable the scripting tools in the settings.
|
|
73
|
+
> The default configuration is to listen on localhost and allow the
|
|
74
|
+
> scripting tools.
|
|
75
|
+
|
|
69
76
|
# Usage
|
|
70
77
|
|
|
71
78
|
There are two ways to use ReVa, with the Ghidra UI in assistant mode or in headless mode. Headless mode is ideal for automation and CI/CD pipelines, while the assistant mode is great for interactive analysis.
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pyghidra-scripting
|
|
3
|
+
description: Write and run Python (PyGhidra) code inside the Ghidra session that ReVa's MCP server is already attached to, using the five ReVa scripting tools — `run-script`, `list-scripts`, `read-script`, `write-script`, `edit-script`. Use this whenever the user asks to execute Python against the current program, reach for the Ghidra Flat API directly, write a custom analysis pass, automate something the other ReVa tools don't expose, or persist a `.py` script in Ghidra's scripts directory. Also use when an existing ReVa MCP tool can't do what's needed and the right answer is "drop into PyGhidra for one call." Do NOT use this skill for plain ReVa tool calls that already have a dedicated MCP tool (use that tool instead); do NOT use it to build standalone Python programs that run pyghidra in their own process (the run-script tool runs *inside* the ReVa-hosted Ghidra).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# PyGhidra scripting via ReVa
|
|
7
|
+
|
|
8
|
+
ReVa exposes five MCP tools under the `scripts` provider that let an assistant write, edit, run, and inspect Python scripts inside the same Ghidra session ReVa is serving. The Python code runs under PyGhidra (CPython 3 + JPype), so it has the full Ghidra Java API available — the `FlatProgramAPI`, `DecompInterface`, `FunctionManager`, everything.
|
|
9
|
+
|
|
10
|
+
This skill teaches when to reach for these tools, how to structure the Python you send to `run-script`, and the pitfalls that bite in practice.
|
|
11
|
+
|
|
12
|
+
## The five tools at a glance
|
|
13
|
+
|
|
14
|
+
| Tool | Purpose | Use when |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `run-script` | Execute Python against a program. Inline `code`, or by `scriptPath` / `scriptName`. | The dedicated ReVa MCP tools don't cover what you need, or you want one tight pass over the program. |
|
|
17
|
+
| `list-scripts` | Enumerate scripts across registered directories. Filterable by name/path; paginated. | Discovering what's already saved before writing a new one. |
|
|
18
|
+
| `read-script` | `cat -n` view of a script with `offset` / `limit` and a `truncated` flag. | Reading an existing script before editing it. The numbered output is what `edit-script` lines up against. |
|
|
19
|
+
| `write-script` | Create a new `.py` file (or full overwrite with `overwrite: true`). User-writeable dirs only. | Saving a reusable script. Never reach for this just to bundle inline code — use `run-script` with `code` for one-shot use. |
|
|
20
|
+
| `edit-script` | `old_string` → `new_string` replacement. Errors if `old_string` matches multiple places unless `replace_all: true`. | Iterating on an existing script. Pair with `read-script` to see line context first. |
|
|
21
|
+
|
|
22
|
+
## Reach-for-it triggers
|
|
23
|
+
|
|
24
|
+
`run-script` is the escape hatch. Use it when:
|
|
25
|
+
|
|
26
|
+
- You need to run a custom predicate over every function/symbol/instruction and the existing list/find tools don't filter the right way.
|
|
27
|
+
- You need to combine multiple Ghidra API calls into one operation that would otherwise take many MCP round-trips.
|
|
28
|
+
- You want to use a Ghidra API ReVa doesn't expose — e.g. `DecompInterface` low-level features, `PCode` analysis, custom `AddressSet` arithmetic, the data flow API directly, `BinaryReader`, etc.
|
|
29
|
+
- You're prototyping; once it works and is reusable, save it with `write-script`.
|
|
30
|
+
|
|
31
|
+
Don't use `run-script` when a dedicated ReVa MCP tool already does the job — those tools have stable schemas and structured output that's easier to reason about than free-form `stdout`. The decompiler / functions / strings / symbols / xrefs tools cover the common path.
|
|
32
|
+
|
|
33
|
+
## Runtime gate: PyGhidra-only
|
|
34
|
+
|
|
35
|
+
`run-script` only works when Ghidra was launched **under PyGhidra**:
|
|
36
|
+
|
|
37
|
+
- ✅ `mcp-reva` (Claude CLI / stdio mode)
|
|
38
|
+
- ✅ `pyghidra-gui` (GUI mode launched with PyGhidra)
|
|
39
|
+
- ✅ `reva_headless_server.py` (headless mode via PyGhidra)
|
|
40
|
+
- ❌ Plain `ghidraRun` — PyGhidra is not wired in; you'll get a `PyGhidraNotAvailableException` error response with launch guidance.
|
|
41
|
+
|
|
42
|
+
If a `run-script` call comes back with that error, the right move is to tell the user how to relaunch (don't keep retrying). The other four tools (`list-scripts`, `read-script`, `write-script`, `edit-script`) work in every mode because they're plain file operations.
|
|
43
|
+
|
|
44
|
+
## The execution contract for `run-script`
|
|
45
|
+
|
|
46
|
+
This is the contract your inline `code` (or saved script) runs under. Internalise it — most failures come from getting one of these wrong.
|
|
47
|
+
|
|
48
|
+
**Pre-bound globals.** The script runs as a Ghidra PyGhidra script, so the standard `GhidraScript` globals are already defined: `currentProgram`, `currentAddress`, `currentSelection`, `currentHighlight`, `monitor`, `state`, plus `FlatProgramAPI` helpers like `toAddr`, `getFunctionAt`, `getFunctionContaining`, `getSymbolAt`, `getInstructionAt`, `getDataAt`, `getReferencesTo`, `getReferencesFrom`, `createLabel`, `setEOLComment`, `find`, `findBytes`, `clearListing`. You do **not** need to import or set these up. `currentProgram` is the program identified by the `programPath` argument.
|
|
49
|
+
|
|
50
|
+
**No automatic transaction.** Unlike GhidraScripts run from inside Ghidra's GUI, ReVa's `run-script` deliberately does **not** open a transaction around your code. Any mutation (rename, retype, comment, label, create function, etc.) must be wrapped manually:
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
tx = currentProgram.startTransaction("Describe the edit")
|
|
54
|
+
try:
|
|
55
|
+
# ... do stuff that mutates state ...
|
|
56
|
+
currentProgram.endTransaction(tx, True) # commit
|
|
57
|
+
except Exception:
|
|
58
|
+
currentProgram.endTransaction(tx, False) # roll back
|
|
59
|
+
raise
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
This is intentional — auto-wrapping at the tool layer would create nested-transaction footguns when scripts already handle their own. Read-only scripts (printing, counting, dumping) need no transaction at all.
|
|
63
|
+
|
|
64
|
+
**Inline header.** When you pass `code`, the tool prepends `# @runtime PyGhidra\n` automatically. Don't add it yourself.
|
|
65
|
+
|
|
66
|
+
**Cancellation is cooperative.** The configured timeout (default 60s, overridable per-call via `timeoutSeconds`) only fires if your code yields to the monitor. In long loops, call `monitor.isCancelled()` regularly and break:
|
|
67
|
+
|
|
68
|
+
```python
|
|
69
|
+
fm = currentProgram.getFunctionManager()
|
|
70
|
+
for func in fm.getFunctions(True):
|
|
71
|
+
if monitor.isCancelled():
|
|
72
|
+
break
|
|
73
|
+
# ... work ...
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
A tight Python loop without a monitor check will run past the timeout. The result will then come back with `timedOut: true` and partial output but the Ghidra session may still be busy for a moment.
|
|
77
|
+
|
|
78
|
+
**Output is captured and capped.** `stdout` and `stderr` are each capped at 64K chars by default (configurable via `SCRIPT_OUTPUT_CHAR_LIMIT`). If you blow the cap, the result has `stdoutTruncated: true` or `stderrTruncated: true`. Design output for an LLM consumer — terse, structured, line-per-record. Reach for JSON if downstream parsing matters:
|
|
79
|
+
|
|
80
|
+
```python
|
|
81
|
+
import json
|
|
82
|
+
results = []
|
|
83
|
+
for func in currentProgram.getFunctionManager().getFunctions(True):
|
|
84
|
+
if monitor.isCancelled(): break
|
|
85
|
+
if some_predicate(func):
|
|
86
|
+
results.append({"addr": str(func.getEntryPoint()), "name": func.getName()})
|
|
87
|
+
print(json.dumps(results))
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
**Result schema.** `run-script` returns:
|
|
91
|
+
|
|
92
|
+
```json
|
|
93
|
+
{
|
|
94
|
+
"success": true|false,
|
|
95
|
+
"programPath": "/binary.exe",
|
|
96
|
+
"stdout": "...",
|
|
97
|
+
"stderr": "...",
|
|
98
|
+
"stdoutTruncated": false,
|
|
99
|
+
"stderrTruncated": false,
|
|
100
|
+
"durationMs": 1234,
|
|
101
|
+
"timedOut": false,
|
|
102
|
+
"scriptSource": {"type": "inline|path|name", "value": "..."},
|
|
103
|
+
"error": "ClassName: message" // only when the executor itself threw
|
|
104
|
+
}
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
`success` is `false` if the script raised a Python exception (detected via the `Traceback (most recent call last)` marker in stderr), if it hit the timeout, or if the executor threw. Read `stderr` to see the actual traceback — Python exceptions don't surface as MCP errors, they come back in `stderr` with `success: false`.
|
|
108
|
+
|
|
109
|
+
## What you can call from inside
|
|
110
|
+
|
|
111
|
+
The script has the full Ghidra/PyGhidra surface. The most commonly useful entry points:
|
|
112
|
+
|
|
113
|
+
```python
|
|
114
|
+
# Program structure
|
|
115
|
+
prog = currentProgram # the Program object
|
|
116
|
+
listing = prog.getListing() # CodeUnits, data, comments
|
|
117
|
+
memory = prog.getMemory() # blocks, bytes
|
|
118
|
+
fm = prog.getFunctionManager() # functions
|
|
119
|
+
st = prog.getSymbolTable() # symbols/labels
|
|
120
|
+
rm = prog.getReferenceManager() # xrefs
|
|
121
|
+
dtm = prog.getDataTypeManager() # data types
|
|
122
|
+
|
|
123
|
+
# Flat-API one-liners (already global)
|
|
124
|
+
addr = toAddr(0x401000)
|
|
125
|
+
func = getFunctionAt(addr) or getFunctionContaining(addr)
|
|
126
|
+
sym = getSymbolAt(addr)
|
|
127
|
+
instr = getInstructionAt(addr)
|
|
128
|
+
xrefs_to = getReferencesTo(addr)
|
|
129
|
+
|
|
130
|
+
# Java classes — import as normal Python after PyGhidra is up (it is, when run-script runs)
|
|
131
|
+
from ghidra.program.model.symbol import SourceType
|
|
132
|
+
from ghidra.app.decompiler import DecompInterface, DecompileOptions
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
For everything else: see [references/flat-api.md](references/flat-api.md) for the categorised Flat-API cheat-sheet, and [references/jpype-interop.md](references/jpype-interop.md) for the Java-via-Python idioms (arrays, iterators, sign extension, type stubs).
|
|
136
|
+
|
|
137
|
+
## Workflow patterns
|
|
138
|
+
|
|
139
|
+
### Inline one-shot (most common)
|
|
140
|
+
|
|
141
|
+
```
|
|
142
|
+
run-script(programPath="/bin", code="""
|
|
143
|
+
fm = currentProgram.getFunctionManager()
|
|
144
|
+
total = 0
|
|
145
|
+
huge = []
|
|
146
|
+
for f in fm.getFunctions(True):
|
|
147
|
+
if monitor.isCancelled(): break
|
|
148
|
+
size = f.getBody().getNumAddresses()
|
|
149
|
+
total += size
|
|
150
|
+
if size > 4096:
|
|
151
|
+
huge.append((str(f.getEntryPoint()), f.getName(), size))
|
|
152
|
+
print(f'total bytes: {total}')
|
|
153
|
+
for addr, name, size in huge:
|
|
154
|
+
print(f'{addr} {size:6d} {name}')
|
|
155
|
+
""")
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Read the stdout, draw conclusions, move on. Nothing persisted.
|
|
159
|
+
|
|
160
|
+
### Iterate then save
|
|
161
|
+
|
|
162
|
+
1. Send a draft via `run-script` with inline `code`.
|
|
163
|
+
2. When it works, call `write-script` with `scriptName="MyAnalysis.py"` and the final `code`. (Pick a descriptive name — `list-scripts` will return it.)
|
|
164
|
+
3. Next time, `run-script` with `scriptName="MyAnalysis.py"`.
|
|
165
|
+
|
|
166
|
+
### Edit-in-place on a saved script
|
|
167
|
+
|
|
168
|
+
1. `list-scripts` (or remember the name).
|
|
169
|
+
2. `read-script` — note the line numbers around what you want to change.
|
|
170
|
+
3. `edit-script` with `old_string` set to a *uniquely identifying* slice (include enough surrounding context that there's exactly one match). The tool errors out on ambiguity unless you pass `replace_all: true`.
|
|
171
|
+
4. Re-run via `run-script(scriptName=...)`.
|
|
172
|
+
|
|
173
|
+
`edit-script` is preferred over re-writing the whole file — it preserves the rest of the script unchanged and is what the user can review as a diff.
|
|
174
|
+
|
|
175
|
+
## Pitfalls
|
|
176
|
+
|
|
177
|
+
These are the ones that account for most "why did my script misbehave."
|
|
178
|
+
|
|
179
|
+
### Forgot the transaction
|
|
180
|
+
Mutations without `startTransaction` throw `IllegalStateException: not in transaction`. If a `run-script` call mutates and you see this in `stderr`, that's the cause. Wrap the mutating block — see the contract section above.
|
|
181
|
+
|
|
182
|
+
### `monitor.isCancelled()` check missing
|
|
183
|
+
Tight loops that never check the monitor blow past the timeout silently — the `timedOut` flag still flips, but your script may have already done damage. Always check the monitor inside any loop touching every function / instruction / address.
|
|
184
|
+
|
|
185
|
+
### Java `Iterator` vs Python iterable
|
|
186
|
+
Most Ghidra iterators are Python-iterable thanks to JPype, but a few (notably `SymbolIterator` from some accessors and the older `ReferenceIterator`) only expose `hasNext()` / `next()`. If a `for x in it:` loop silently yields nothing, fall back to `while it.hasNext(): x = it.next()`. `FunctionManager.getFunctions(True)` is iterable directly.
|
|
187
|
+
|
|
188
|
+
### Java `byte` is signed
|
|
189
|
+
`MemoryBlock.getBytes(addr, byte[] buf)` fills you a Java `byte[]`. Values come back as `-128..127`. Mask with `b & 0xff` if you want `0..255`. Allocating the buffer: `import jpype; buf = jpype.JByte[16]`.
|
|
190
|
+
|
|
191
|
+
### `print()` is what shows up in stdout
|
|
192
|
+
The script's `print()` is rerouted to the captured stdout writer — that's how you get output back. Don't use logging frameworks expecting them to flush somewhere visible; `print(...)` is the contract.
|
|
193
|
+
|
|
194
|
+
### Decompiler is expensive to construct
|
|
195
|
+
If you decompile more than a handful of functions in one script, build the `DecompInterface` once and reuse it. Always `dispose()` it. With a per-function timeout of 30s, a 100-function pass that re-builds the decompiler each call can easily blow `run-script`'s overall timeout.
|
|
196
|
+
|
|
197
|
+
```python
|
|
198
|
+
from ghidra.app.decompiler import DecompInterface
|
|
199
|
+
decomp = DecompInterface()
|
|
200
|
+
decomp.openProgram(currentProgram)
|
|
201
|
+
try:
|
|
202
|
+
for f in currentProgram.getFunctionManager().getFunctions(True):
|
|
203
|
+
if monitor.isCancelled(): break
|
|
204
|
+
res = decomp.decompileFunction(f, 30, monitor)
|
|
205
|
+
if res.decompileCompleted():
|
|
206
|
+
# process res.getDecompiledFunction().getC()
|
|
207
|
+
pass
|
|
208
|
+
finally:
|
|
209
|
+
decomp.dispose()
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### `script` paths must live inside a registered scripts dir
|
|
213
|
+
`run-script(scriptPath=...)` refuses paths outside Ghidra's registered script directories (user dir, system dirs, bundle dirs). Same for `read-script`. For writes, you're additionally limited to the *writeable* set (user dir, typically `~/ghidra_scripts/`). System dirs are read-only.
|
|
214
|
+
|
|
215
|
+
### Inline `code` and saved scripts both bypass Ghidra's `# @category` UI metadata
|
|
216
|
+
`run-script(code=...)` writes a temp file with only the `# @runtime PyGhidra` header. `# @category`, `# @menupath`, `# @keybinding` headers in a *saved* script matter for the Ghidra GUI but are ignored by `run-script` — keep them if you want the script to appear in the Script Manager, drop them otherwise.
|
|
217
|
+
|
|
218
|
+
## Where to go next
|
|
219
|
+
|
|
220
|
+
These reference files are bundled with the skill. Load only the one(s) relevant.
|
|
221
|
+
|
|
222
|
+
- **[references/flat-api.md](references/flat-api.md)** — Categorised cheat-sheet for the program-inspection surface: `FlatProgramAPI` one-liners (`toAddr`, `getFunctionAt`, `createLabel`, `setEOLComment`, references, comments, bookmarks, search), `AddressSet` arithmetic for restricting iteration, imports/externals/thunks (`isThunk`, `getCallingFunctions`, `ExternalManager`), data types & structs (`StructureDataType`, `DataTypeManager`, `createData`), and `FlatDecompilerAPI` basics. Load when writing inline `code` that inspects or mutates program structure.
|
|
223
|
+
|
|
224
|
+
- **[references/decompiler-pcode.md](references/decompiler-pcode.md)** — The decompiler's internal representation: `HighFunction`, `LocalSymbolMap`, `HighSymbol`/`HighVariable`/`HighParam`, `Varnode` def-use chains, `PcodeOp` opcodes (COPY/LOAD/CALL/MULTIEQUAL/PTRSUB/…), `ParallelDecompiler` for batch passes, `HighFunctionDBUtil` for persisting decompiler-derived renames. Load when the question is "trace this value back to its source", "where does this argument come from", "which functions look like the decompiler got confused", "rename this `iVar3` to something useful", or any task that needs more than the C source string.
|
|
225
|
+
|
|
226
|
+
- **[references/jpype-interop.md](references/jpype-interop.md)** — Python ↔ Java boundary notes: arrays (`jpype.JByte[16]`), sign extension, varargs, overload resolution, exception types, getter/setter ↔ property, package collisions, type stubs (`from ghidra.ghidra_builtins import *` under `TYPE_CHECKING`). Load when JPype errors show up or you're doing anything beyond simple `for x in it:` iteration.
|
|
227
|
+
|
|
228
|
+
- **[references/recipes.md](references/recipes.md)** — Copy-pasteable inline `code` snippets covering the well-trodden paths: function iteration with predicates, xrefs to a symbol with caller context, batch rename by regex, thunks-aware callers of an import, decompile-and-grep, string dump with referencers, call-graph walk, plate/EOL annotations, raw byte reads — plus the heavier patterns: define a struct and apply it to memory, set a function signature with proper storage, trace argN back through Varnode def-use chains, register touches per function, `ParallelDecompiler` batch decompilation, `EmulatorHelper` for string deobfuscation, recursive xref-walking, and persisting a decompiler-derived rename via `HighFunctionDBUtil`. Load when the user asks "how do I do X" and X is a well-trodden path.
|
|
229
|
+
|
|
230
|
+
- **[references/persistent-scripts.md](references/persistent-scripts.md)** — Conventions for saved scripts: naming, where files land, GhidraScript headers (`# @category`, `# @runtime`), how to discover existing scripts before duplicating, the typical edit cycle. Load when the user wants to save / reuse / iterate on a script rather than one-shot it.
|
|
231
|
+
|
|
232
|
+
## Working style
|
|
233
|
+
|
|
234
|
+
A few things that keep PyGhidra-via-ReVa pleasant:
|
|
235
|
+
|
|
236
|
+
- **Prefer dedicated ReVa tools first.** `run-script` is powerful but free-form; the structured tools (decompiler, functions, strings, xrefs, …) have schemas the assistant can reason about more reliably. Reach for `run-script` only when the structured tools don't cover the question.
|
|
237
|
+
- **Print structured output.** When a `run-script` result is going to be re-consumed by an LLM, prefer JSON or fixed columns over prose. The 64K cap is per-stream — design for it.
|
|
238
|
+
- **Keep transactions narrow.** Open one per logical edit, not one wrapping the whole script. Smaller transactions undo cleanly in Ghidra's history and survive errors better.
|
|
239
|
+
- **Iterate with `edit-script`, not `write-script`.** Once a saved script exists, targeted edits produce reviewable diffs; full overwrites don't.
|
|
240
|
+
- **Read before you edit.** `read-script` first to see the current state and pick `old_string` slices that are unique. Editing blind almost always picks too-short a slice and either misses or hits multiple lines.
|