feat: Add decompiler configuration options
Add toggleCCode, toggleSyntaxTree and setSimplificationStyle controls to the Java plugin. These allow controlling decompiler output format between C code (default) and raw decompiler output with syntax trees. Example usage: decompile_function_by_address(port=8192, address='0x1000', cCode=True) decompile_function_by_address(port=8192, address='0x1000', syntaxTree=True)
This commit is contained in:
parent
bd56f5b6cc
commit
4fe3c16d25
24
CHANGELOG.md
24
CHANGELOG.md
@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Added
|
||||
- Added decompiler output controls to customize analysis results:
|
||||
- Choose between clean C-like pseudocode (default) or raw decompiler output
|
||||
- Toggle syntax tree visibility for detailed analysis
|
||||
- Select different simplification styles for alternate views
|
||||
- Useful for comparing different decompilation approaches or focusing on specific aspects of the code
|
||||
|
||||
Example showing how to get raw decompiler output with syntax tree:
|
||||
```xml
|
||||
<use_mcp_tool>
|
||||
<server_name>ghydra</server_name>
|
||||
<tool_name>decompile_function_by_address</tool_name>
|
||||
<arguments>
|
||||
{
|
||||
"address": "0x1000",
|
||||
"cCode": false,
|
||||
"syntaxTree": true
|
||||
}
|
||||
</arguments>
|
||||
</use_mcp_tool>
|
||||
```
|
||||
|
||||
## [1.4.0] - 2025-04-08
|
||||
|
||||
### Added
|
||||
|
||||
@ -333,9 +333,24 @@ def list_classes(port: int = DEFAULT_GHIDRA_PORT, offset: int = 0, limit: int =
|
||||
return safe_get(port, "classes", {"offset": offset, "limit": limit})
|
||||
|
||||
@mcp.tool()
|
||||
def get_function(port: int = DEFAULT_GHIDRA_PORT, name: str = "") -> dict:
|
||||
"""Get decompiled code for a specific function"""
|
||||
response = safe_get(port, f"functions/{quote(name)}", {})
|
||||
def get_function(port: int = DEFAULT_GHIDRA_PORT, name: str = "", cCode: bool = True, syntaxTree: bool = False, simplificationStyle: str = "normalize") -> dict:
|
||||
"""Get decompiled code for a specific function
|
||||
|
||||
Args:
|
||||
port: Ghidra instance port (default: 8192)
|
||||
name: Name of the function to decompile
|
||||
cCode: Whether to output C code (default: True)
|
||||
syntaxTree: Whether to include syntax tree (default: False)
|
||||
simplificationStyle: Decompiler analysis style (default: "normalize")
|
||||
|
||||
Returns:
|
||||
Dict containing function details including decompiled code
|
||||
"""
|
||||
response = safe_get(port, f"functions/{quote(name)}", {
|
||||
"cCode": str(cCode).lower(),
|
||||
"syntaxTree": str(syntaxTree).lower(),
|
||||
"simplificationStyle": simplificationStyle
|
||||
})
|
||||
|
||||
# Check if the response is a string (old format) or already a dict with proper structure
|
||||
if isinstance(response, dict) and "success" in response:
|
||||
@ -524,17 +539,25 @@ def get_current_function(port: int = DEFAULT_GHIDRA_PORT) -> dict: # Return dict
|
||||
return safe_get(port, "get_current_function")
|
||||
|
||||
@mcp.tool()
|
||||
def decompile_function_by_address(port: int = DEFAULT_GHIDRA_PORT, address: str = "") -> dict:
|
||||
def decompile_function_by_address(port: int = DEFAULT_GHIDRA_PORT, address: str = "", cCode: bool = True, syntaxTree: bool = False, simplificationStyle: str = "normalize") -> dict:
|
||||
"""Decompile a function at a specific memory address
|
||||
|
||||
Args:
|
||||
port: Ghidra instance port (default: 8192)
|
||||
address: Memory address of the function (hex string)
|
||||
cCode: Whether to output C code (default: True)
|
||||
syntaxTree: Whether to include syntax tree (default: False)
|
||||
simplificationStyle: Decompiler analysis style (default: "normalize")
|
||||
|
||||
Returns:
|
||||
Dict containing the decompiled pseudocode in the 'result.decompilation' field
|
||||
"""
|
||||
response = safe_get(port, "decompile_function", {"address": address})
|
||||
response = safe_get(port, "decompile_function", {
|
||||
"address": address,
|
||||
"cCode": str(cCode).lower(),
|
||||
"syntaxTree": str(syntaxTree).lower(),
|
||||
"simplificationStyle": simplificationStyle
|
||||
})
|
||||
|
||||
# Check if the response is a string (old format) or already a dict with proper structure
|
||||
if isinstance(response, dict) and "success" in response:
|
||||
|
||||
@ -438,6 +438,9 @@ public class GhydraMCPPlugin extends Plugin implements ApplicationLevelPlugin {
|
||||
if ("GET".equals(exchange.getRequestMethod())) {
|
||||
Map<String, String> qparams = parseQueryParams(exchange);
|
||||
String address = qparams.get("address");
|
||||
boolean cCode = Boolean.parseBoolean(qparams.getOrDefault("cCode", "true"));
|
||||
boolean syntaxTree = Boolean.parseBoolean(qparams.getOrDefault("syntaxTree", "false"));
|
||||
String simplificationStyle = qparams.getOrDefault("simplificationStyle", "normalize");
|
||||
|
||||
if (address == null || address.isEmpty()) {
|
||||
sendErrorResponse(exchange, 400, "Address parameter is required");
|
||||
@ -472,6 +475,11 @@ public class GhydraMCPPlugin extends Plugin implements ApplicationLevelPlugin {
|
||||
|
||||
DecompInterface decomp = new DecompInterface();
|
||||
try {
|
||||
// Set decompilation options from parameters
|
||||
decomp.toggleCCode(cCode);
|
||||
decomp.setSimplificationStyle(simplificationStyle);
|
||||
decomp.toggleSyntaxTree(syntaxTree);
|
||||
|
||||
if (!decomp.openProgram(program)) {
|
||||
sendErrorResponse(exchange, 500, "Failed to initialize decompiler");
|
||||
return;
|
||||
@ -1105,6 +1113,11 @@ public class GhydraMCPPlugin extends Plugin implements ApplicationLevelPlugin {
|
||||
|
||||
DecompInterface decomp = new DecompInterface();
|
||||
try {
|
||||
// Default to C code output and no syntax tree for better readability
|
||||
decomp.toggleCCode(true);
|
||||
decomp.setSimplificationStyle("normalize");
|
||||
decomp.toggleSyntaxTree(false);
|
||||
|
||||
if (!decomp.openProgram(program)) {
|
||||
resultObj.addProperty("decompilation_error", "Failed to initialize decompiler");
|
||||
} else {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user