Skip to main content
Glama
GhidraUtils.java3.98 kB
package com.lauriewired.util; import ghidra.app.services.ProgramManager; import ghidra.framework.plugintool.PluginTool; import ghidra.program.model.data.DataType; import ghidra.program.model.data.DataTypeManager; import ghidra.program.model.address.Address; import ghidra.program.model.listing.Program; import ghidra.util.Msg; import javax.swing.*; import java.lang.reflect.InvocationTargetException; import java.util.*; import java.util.concurrent.atomic.AtomicBoolean; import ghidra.app.services.DataTypeManagerService; import static ghidra.program.util.GhidraProgramUtilities.getCurrentProgram; import ghidra.util.data.DataTypeParser; import ghidra.util.data.DataTypeParser.AllowedDataTypes; /** * Utility class for Ghidra-related operations. * Provides methods to interact with the current program, resolve data types, * and set comments at specific addresses. */ public final class GhidraUtils { /** * Gets the current program from the specified plugin tool. * * @param tool the plugin tool * @return the current program, or null if not available */ public static Program getCurrentProgram(PluginTool tool) { ProgramManager pm = tool.getService(ProgramManager.class); return pm != null ? pm.getCurrentProgram() : null; } /** * Resolves a data type by name, handling common types and pointer types * * @param tool The plugin tool to use for services * @param dtm The data type manager * @param typeName The type name to resolve * @return The resolved DataType, or null if not found */ public static DataType resolveDataType(PluginTool tool, DataTypeManager dtm, String typeName) { DataTypeManagerService dtms = tool.getService(DataTypeManagerService.class); DataTypeManager[] managers = dtms.getDataTypeManagers(); DataType dt = null; List<DataTypeManager> managerList = new ArrayList<>(); for (DataTypeManager manager : managers) { if (manager != dtm) managerList.add(manager); } managerList.addFirst(dtm); DataTypeParser parser = null; for (DataTypeManager manager : managerList) { try { parser = new DataTypeParser(manager, null, null, AllowedDataTypes.ALL); dt = parser.parse(typeName); if (dt != null) { return dt; // Found a successful parse, return } } catch (Exception e) { // Continue to next manager if this one fails } } // Fallback to int if we couldn't find it Msg.warn(GhidraUtils.class, "Unknown type: " + typeName + ", defaulting to int"); return dtm.getDataType("/int"); } /** * Sets a comment at the specified address in the current program. * * @param tool the plugin tool * @param addressStr the address as a string * @param comment the comment to set * @param commentType the type of comment (e.g., CodeUnit.PLATE_COMMENT) * @param transactionName the name of the transaction for logging * @return true if successful, false otherwise */ public static boolean setCommentAtAddress(PluginTool tool, String addressStr, String comment, int commentType, String transactionName) { Program program = getCurrentProgram(tool); if (program == null) return false; if (addressStr == null || addressStr.isEmpty() || comment == null) return false; AtomicBoolean success = new AtomicBoolean(false); try { SwingUtilities.invokeAndWait(() -> { int tx = program.startTransaction(transactionName); try { Address addr = program.getAddressFactory().getAddress(addressStr); program.getListing().setComment(addr, commentType, comment); success.set(true); } catch (Exception e) { Msg.error(GhidraUtils.class, "Error setting " + transactionName.toLowerCase(), e); } finally { program.endTransaction(tx, success.get()); } }); } catch (InterruptedException | InvocationTargetException e) { Msg.error(GhidraUtils.class, "Failed to execute " + transactionName.toLowerCase() + " on Swing thread", e); } return success.get(); } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/harry-cysic/GhidraMCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server