WIP Ghidra plugin
This commit is contained in:
parent
b5805d39d4
commit
5638734828
Binary file not shown.
|
@ -11,15 +11,18 @@ import ghidra.program.util.ProgramEvent;
|
|||
import ghidra.util.Msg;
|
||||
import ghidra.framework.model.*;
|
||||
import ghidra.program.model.symbol.*;
|
||||
import ghidra.program.model.listing.Data;
|
||||
import ghidra.program.model.listing.Function;
|
||||
import ghidra.program.util.*;
|
||||
import ghidra.framework.cmd.Command;
|
||||
import ghidra.framework.model.TransactionInfo;
|
||||
|
||||
@PluginInfo(
|
||||
status = PluginStatus.STABLE,
|
||||
packageName = "SymbolLogger",
|
||||
category = PluginCategoryNames.COMMON,
|
||||
shortDescription = "Logs symbol and function renames",
|
||||
description = "A plugin that monitors and logs all symbol and function rename events to the console",
|
||||
description = "A plugin that monitors and logs all symbol and function rename events to the console, including undo/redo context",
|
||||
servicesRequired = {},
|
||||
servicesProvided = {}
|
||||
)
|
||||
|
@ -63,9 +66,44 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the context of the current operation (direct action, undo, or redo)
|
||||
*/
|
||||
private String getOperationContext() {
|
||||
try {
|
||||
Program program = getCurrentProgram();
|
||||
if (program != null) {
|
||||
TransactionInfo currentTransaction = program.getCurrentTransactionInfo();
|
||||
if (currentTransaction != null) {
|
||||
String description = currentTransaction.getDescription();
|
||||
if (description != null) {
|
||||
if (description.startsWith("Undo")) {
|
||||
return "[UNDO] ";
|
||||
} else if (description.startsWith("Redo")) {
|
||||
return "[REDO] ";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// Silently handle any exceptions in context detection
|
||||
}
|
||||
return ""; // Direct user action (no prefix)
|
||||
}
|
||||
|
||||
/**
|
||||
* Enhanced logging method that includes undo/redo context
|
||||
*/
|
||||
private void logWithContext(String message) {
|
||||
String context = getOperationContext();
|
||||
Msg.info(this, context + message);
|
||||
}
|
||||
|
||||
private void handleProgramChange(ProgramChangeRecord record) {
|
||||
ProgramEvent eventType = (ProgramEvent)record.getEventType();
|
||||
|
||||
Msg.info(this, "Event: " + record.toString());
|
||||
|
||||
// Handle symbol rename events
|
||||
if (eventType == ProgramEvent.SYMBOL_RENAMED) {
|
||||
handleSymbolRenamed(record);
|
||||
|
@ -102,6 +140,27 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
else if (eventType == ProgramEvent.FUNCTION_CHANGED) {
|
||||
handleFunctionSignatureChanged(record);
|
||||
}
|
||||
// Handle transaction events for better undo/redo tracking
|
||||
// else if (eventType == ProgramEvent..TRANSACTION_STARTED) {
|
||||
// handleTransactionStarted(record);
|
||||
// }
|
||||
// else if (eventType == ProgramEvent.TRANSACTION_ENDED) {
|
||||
// handleTransactionEnded(record);
|
||||
// }
|
||||
}
|
||||
|
||||
private void handleTransactionStarted(ProgramChangeRecord record) {
|
||||
String context = getOperationContext();
|
||||
if (!context.isEmpty()) {
|
||||
logWithContext("TRANSACTION STARTED");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleTransactionEnded(ProgramChangeRecord record) {
|
||||
String context = getOperationContext();
|
||||
if (!context.isEmpty()) {
|
||||
logWithContext("TRANSACTION ENDED");
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSymbolRenamed(ProgramChangeRecord record) {
|
||||
|
@ -111,7 +170,7 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
String newName = (newValue != null) ? newValue.toString() : "null";
|
||||
String oldName = (oldValue != null) ? oldValue.toString() : "null";
|
||||
|
||||
Msg.info(this, String.format("SYMBOL RENAMED: '%s' -> '%s' at address %s",
|
||||
logWithContext(String.format("SYMBOL RENAMED: '%s' -> '%s' at address %s",
|
||||
oldName, newName, record.getStart()));
|
||||
|
||||
// Try to get additional information about the symbol
|
||||
|
@ -124,14 +183,14 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
for (Symbol symbol : symbols) {
|
||||
if (symbol.getName().equals(newName)) {
|
||||
String symbolType = getSymbolTypeDescription(symbol);
|
||||
Msg.info(this, String.format(" Symbol type: %s, Namespace: %s",
|
||||
logWithContext(String.format(" Symbol type: %s, Namespace: %s",
|
||||
symbolType, symbol.getParentNamespace().getName()));
|
||||
|
||||
// If it's a function, log additional function details
|
||||
if (symbol.getSymbolType() == SymbolType.FUNCTION) {
|
||||
Function function = (Function) symbol.getObject();
|
||||
if (function != null) {
|
||||
Msg.info(this, String.format(" Function signature: %s",
|
||||
logWithContext(String.format(" Function signature: %s",
|
||||
function.getPrototypeString(false, false)));
|
||||
}
|
||||
}
|
||||
|
@ -155,7 +214,7 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
|
||||
// Check for name changes
|
||||
if (!newFunc.getName().equals(oldFunc.getName())) {
|
||||
Msg.info(this, String.format("FUNCTION RENAMED: '%s' -> '%s' at address %s",
|
||||
logWithContext(String.format("FUNCTION RENAMED: '%s' -> '%s' at address %s",
|
||||
oldFunc.getName(), newFunc.getName(), newFunc.getEntryPoint()));
|
||||
}
|
||||
|
||||
|
@ -163,18 +222,18 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
String oldSignature = oldFunc.getPrototypeString(false, false);
|
||||
String newSignature = newFunc.getPrototypeString(false, false);
|
||||
if (!oldSignature.equals(newSignature)) {
|
||||
Msg.info(this, String.format("FUNCTION SIGNATURE CHANGED at address %s:", newFunc.getEntryPoint()));
|
||||
Msg.info(this, String.format(" Old: %s", oldSignature));
|
||||
Msg.info(this, String.format(" New: %s", newSignature));
|
||||
logWithContext(String.format("FUNCTION SIGNATURE CHANGED at address %s:", newFunc.getEntryPoint()));
|
||||
logWithContext(String.format(" Old: %s", oldSignature));
|
||||
logWithContext(String.format(" New: %s", newSignature));
|
||||
|
||||
// Log specific changes
|
||||
logFunctionSignatureDetails(oldFunc, newFunc);
|
||||
}
|
||||
} else if (newValue instanceof Function) {
|
||||
Function function = (Function) newValue;
|
||||
Msg.info(this, String.format("FUNCTION MODIFIED: %s at address %s",
|
||||
logWithContext(String.format("FUNCTION MODIFIED: %s at address %s",
|
||||
function.getName(), function.getEntryPoint()));
|
||||
Msg.info(this, String.format(" Signature: %s", function.getPrototypeString(false, false)));
|
||||
logWithContext(String.format(" Signature: %s", function.getPrototypeString(false, false)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,23 +246,23 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
Object newValue = record.getNewValue();
|
||||
Object oldValue = record.getOldValue();
|
||||
|
||||
Msg.info(this, String.format("DATA TYPE CHANGED at address %s", record.getStart()));
|
||||
logWithContext(String.format("DATA TYPE CHANGED at address %s", record.getStart()));
|
||||
|
||||
if (oldValue != null && newValue != null) {
|
||||
Msg.info(this, String.format(" Old type: %s", oldValue.toString()));
|
||||
Msg.info(this, String.format(" New type: %s", newValue.toString()));
|
||||
logWithContext(String.format(" Old type: %s", oldValue.toString()));
|
||||
logWithContext(String.format(" New type: %s", newValue.toString()));
|
||||
} else if (newValue != null) {
|
||||
Msg.info(this, String.format(" Type set to: %s", newValue.toString()));
|
||||
logWithContext(String.format(" Type set to: %s", newValue.toString()));
|
||||
}
|
||||
|
||||
// Try to get more context about the data type change
|
||||
try {
|
||||
Program program = getCurrentProgram();
|
||||
if (program != null && record.getStart() != null) {
|
||||
ghidra.program.model.data.Data data = program.getListing().getDataAt(record.getStart());
|
||||
Data data = program.getListing().getDataAt(record.getStart());
|
||||
if (data != null) {
|
||||
Msg.info(this, String.format(" Data label: %s", data.getLabel()));
|
||||
Msg.info(this, String.format(" Data type: %s", data.getDataType().getName()));
|
||||
logWithContext(String.format(" Data label: %s", data.getLabel()));
|
||||
logWithContext(String.format(" Data type: %s", data.getDataType().getName()));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -214,18 +273,18 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
private void handleDataTypeAdded(ProgramChangeRecord record) {
|
||||
Object newValue = record.getNewValue();
|
||||
|
||||
Msg.info(this, String.format("DATA TYPE ADDED at address %s", record.getStart()));
|
||||
logWithContext(String.format("DATA TYPE ADDED at address %s", record.getStart()));
|
||||
if (newValue != null) {
|
||||
Msg.info(this, String.format(" Type: %s", newValue.toString()));
|
||||
logWithContext(String.format(" Type: %s", newValue.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleDataTypeRemoved(ProgramChangeRecord record) {
|
||||
Object oldValue = record.getOldValue();
|
||||
|
||||
Msg.info(this, String.format("DATA TYPE REMOVED at address %s", record.getStart()));
|
||||
logWithContext(String.format("DATA TYPE REMOVED at address %s", record.getStart()));
|
||||
if (oldValue != null) {
|
||||
Msg.info(this, String.format(" Removed type: %s", oldValue.toString()));
|
||||
logWithContext(String.format(" Removed type: %s", oldValue.toString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -236,7 +295,7 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
String newName = (newValue != null) ? newValue.toString() : "null";
|
||||
String oldName = (oldValue != null) ? oldValue.toString() : "null";
|
||||
|
||||
Msg.info(this, String.format("DATA TYPE RENAMED: '%s' -> '%s' at address %s",
|
||||
logWithContext(String.format("DATA TYPE RENAMED: '%s' -> '%s' at address %s",
|
||||
oldName, newName, record.getStart()));
|
||||
}
|
||||
|
||||
|
@ -244,7 +303,7 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
try {
|
||||
// Check return type changes
|
||||
if (!oldFunc.getReturnType().equals(newFunc.getReturnType())) {
|
||||
Msg.info(this, String.format(" Return type changed: %s -> %s",
|
||||
logWithContext(String.format(" Return type changed: %s -> %s",
|
||||
oldFunc.getReturnType().getName(), newFunc.getReturnType().getName()));
|
||||
}
|
||||
|
||||
|
@ -252,7 +311,7 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
int oldParamCount = oldFunc.getParameterCount();
|
||||
int newParamCount = newFunc.getParameterCount();
|
||||
if (oldParamCount != newParamCount) {
|
||||
Msg.info(this, String.format(" Parameter count changed: %d -> %d",
|
||||
logWithContext(String.format(" Parameter count changed: %d -> %d",
|
||||
oldParamCount, newParamCount));
|
||||
}
|
||||
|
||||
|
@ -264,28 +323,28 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
ghidra.program.model.listing.Parameter newParam = newFunc.getParameter(i);
|
||||
|
||||
if (!oldParam.getDataType().equals(newParam.getDataType())) {
|
||||
Msg.info(this, String.format(" Parameter %d type changed: %s -> %s",
|
||||
logWithContext(String.format(" Parameter %d type changed: %s -> %s",
|
||||
i, oldParam.getDataType().getName(), newParam.getDataType().getName()));
|
||||
}
|
||||
|
||||
if (!oldParam.getName().equals(newParam.getName())) {
|
||||
Msg.info(this, String.format(" Parameter %d name changed: %s -> %s",
|
||||
logWithContext(String.format(" Parameter %d name changed: %s -> %s",
|
||||
i, oldParam.getName(), newParam.getName()));
|
||||
}
|
||||
} else if (i < newParamCount) {
|
||||
ghidra.program.model.listing.Parameter newParam = newFunc.getParameter(i);
|
||||
Msg.info(this, String.format(" Parameter %d added: %s %s",
|
||||
logWithContext(String.format(" Parameter %d added: %s %s",
|
||||
i, newParam.getDataType().getName(), newParam.getName()));
|
||||
} else {
|
||||
ghidra.program.model.listing.Parameter oldParam = oldFunc.getParameter(i);
|
||||
Msg.info(this, String.format(" Parameter %d removed: %s %s",
|
||||
logWithContext(String.format(" Parameter %d removed: %s %s",
|
||||
i, oldParam.getDataType().getName(), oldParam.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
// Check calling convention changes
|
||||
if (!oldFunc.getCallingConventionName().equals(newFunc.getCallingConventionName())) {
|
||||
Msg.info(this, String.format(" Calling convention changed: %s -> %s",
|
||||
logWithContext(String.format(" Calling convention changed: %s -> %s",
|
||||
oldFunc.getCallingConventionName(), newFunc.getCallingConventionName()));
|
||||
}
|
||||
|
||||
|
@ -299,7 +358,7 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
if (newValue instanceof Symbol) {
|
||||
Symbol symbol = (Symbol) newValue;
|
||||
String symbolType = getSymbolTypeDescription(symbol);
|
||||
Msg.info(this, String.format("SYMBOL ADDED: '%s' (%s) at address %s",
|
||||
logWithContext(String.format("SYMBOL ADDED: '%s' (%s) at address %s",
|
||||
symbol.getName(), symbolType, symbol.getAddress()));
|
||||
}
|
||||
}
|
||||
|
@ -309,7 +368,7 @@ public class SymbolRenameLoggerPlugin extends ProgramPlugin implements DomainObj
|
|||
if (oldValue instanceof Symbol) {
|
||||
Symbol symbol = (Symbol) oldValue;
|
||||
String symbolType = getSymbolTypeDescription(symbol);
|
||||
Msg.info(this, String.format("SYMBOL REMOVED: '%s' (%s) at address %s",
|
||||
logWithContext(String.format("SYMBOL REMOVED: '%s' (%s) at address %s",
|
||||
symbol.getName(), symbolType, symbol.getAddress()));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue