diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java index 8e2d55d58b..d727dec67e 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/debug/flatapi/FlatDebuggerAPI.java @@ -38,6 +38,7 @@ import ghidra.dbg.target.TargetExecutionStateful.TargetExecutionState; import ghidra.dbg.target.TargetLauncher.TargetCmdLineLauncher; import ghidra.dbg.target.TargetSteppable.TargetStepKind; import ghidra.dbg.util.PathUtils; +import ghidra.pcode.exec.trace.TraceSleighUtils; import ghidra.program.flatapi.FlatProgramAPI; import ghidra.program.model.address.*; import ghidra.program.model.lang.*; @@ -1129,6 +1130,28 @@ public interface FlatDebuggerAPI { return readRegister(platform, register); } + /** + * Evaluate a Sleigh expression in the given context + * + * @param coordinates the context + * @param expression the Sleigh expression + * @return the value + */ + default BigInteger evaluate(DebuggerCoordinates coordinates, String expression) { + return TraceSleighUtils.evaluate(expression, coordinates.getTrace(), + coordinates.getViewSnap(), coordinates.getThread(), coordinates.getFrame()); + } + + /** + * Evaluate a Sleigh expression in the current context + * + * @param expression the Sleigh expression + * @return the value + */ + default BigInteger evaluate(String expression) { + return evaluate(getCurrentDebuggerCoordinates(), expression); + } + /** * Get the program counter for the given context * @@ -1260,8 +1283,8 @@ public interface FlatDebuggerAPI { * *
* The success or failure of this method depends on a few factors. First is the user-selected - * control mode for the trace. See {@link #setControlMode(ControlMode)}. In read-only mode, - * this will always fail. When editing traces, a write almost always succeeds. Exceptions would + * control mode for the trace. See {@link #setControlMode(ControlMode)}. In read-only mode, this + * will always fail. When editing traces, a write almost always succeeds. Exceptions would * probably indicate I/O errors. When editing via emulation, a write should almost always * succeed. Second, when editing the target, the state of the target matters. If the trace has * no target, this will always fail. If the target is not accepting commands, e.g., because the @@ -1324,8 +1347,8 @@ public interface FlatDebuggerAPI { * *
* The success or failure of this methods depends on a few factors. First is the user-selected - * control mode for the trace. See {@link #setControlMode(ControlMode)}. In read-only mode, - * this will always fail. When editing traces, a write almost always succeeds. Exceptions would + * control mode for the trace. See {@link #setControlMode(ControlMode)}. In read-only mode, this + * will always fail. When editing traces, a write almost always succeeds. Exceptions would * probably indicate I/O errors. When editing via emulation, a write should only fail if the * register is not accessible to Sleigh, e.g., the context register. Second, when editing the * target, the state of the target matters. If the trace has no target, this will always fail. diff --git a/Ghidra/Features/SystemEmulation/ghidra_scripts/DebuggerEmuExampleScript.java b/Ghidra/Features/SystemEmulation/ghidra_scripts/DebuggerEmuExampleScript.java index e00f8c2299..4abbd1329f 100644 --- a/Ghidra/Features/SystemEmulation/ghidra_scripts/DebuggerEmuExampleScript.java +++ b/Ghidra/Features/SystemEmulation/ghidra_scripts/DebuggerEmuExampleScript.java @@ -33,13 +33,11 @@ import ghidra.app.plugin.core.debug.service.emulation.ProgramEmulationUtils; import ghidra.app.plugin.core.debug.service.emulation.data.DefaultPcodeDebuggerAccess; import ghidra.app.plugin.processors.sleigh.SleighLanguage; import ghidra.app.script.GhidraScript; -import ghidra.app.services.DebuggerTraceManagerService; -import ghidra.app.services.ProgramManager; +import ghidra.debug.flatapi.FlatDebuggerAPI; import ghidra.framework.plugintool.PluginTool; import ghidra.pcode.emu.PcodeThread; import ghidra.pcode.exec.*; import ghidra.pcode.exec.PcodeExecutorStatePiece.Reason; -import ghidra.pcode.exec.trace.TraceSleighUtils; import ghidra.pcode.utils.Utils; import ghidra.program.database.ProgramDB; import ghidra.program.model.address.Address; @@ -54,7 +52,7 @@ import ghidra.trace.model.thread.TraceThread; import ghidra.trace.model.time.TraceSnapshot; import ghidra.trace.model.time.TraceTimeManager; -public class DebuggerEmuExampleScript extends GhidraScript { +public class DebuggerEmuExampleScript extends GhidraScript implements FlatDebuggerAPI { private final static Charset UTF8 = Charset.forName("utf8"); @Override @@ -63,9 +61,6 @@ public class DebuggerEmuExampleScript extends GhidraScript { * First, get all the services and stuff: */ PluginTool tool = state.getTool(); - ProgramManager programManager = tool.getService(ProgramManager.class); - DebuggerTraceManagerService traceManager = - tool.getService(DebuggerTraceManagerService.class); SleighLanguage language = (SleighLanguage) getLanguage(new LanguageID("x86:LE:64:default")); /* @@ -103,7 +98,7 @@ public class DebuggerEmuExampleScript extends GhidraScript { } program.save("Init", monitor); // Display the program in the UI - programManager.openProgram(program); + openProgram(program); } finally { if (program != null) { @@ -121,8 +116,8 @@ public class DebuggerEmuExampleScript extends GhidraScript { try { trace = ProgramEmulationUtils.launchEmulationTrace(program, entry, this); // Display the trace in the UI - traceManager.openTrace(trace); - traceManager.activateTrace(trace); + openTrace(trace); + activateTrace(trace); } finally { if (trace != null) { @@ -131,7 +126,7 @@ public class DebuggerEmuExampleScript extends GhidraScript { } // Get the initial thread TraceThread traceThread = trace.getThreadManager().getAllThreads().iterator().next(); - traceManager.activateThread(traceThread); + activateThread(traceThread); /* * Instead of using the UI's emulator, this script will create its own with a custom @@ -172,8 +167,7 @@ public class DebuggerEmuExampleScript extends GhidraScript { for (int i = 0; i < 10; i++) { println("Executing: " + thread.getCounter()); thread.stepInstruction(); - snapshot = - time.createSnapshot("Stepped to " + thread.getCounter()); + snapshot = time.createSnapshot("Stepped to " + thread.getCounter()); emulator.writeDown(host, snapshot.getKey(), 0); } printerr("We should not have completed 10 steps!"); @@ -182,7 +176,7 @@ public class DebuggerEmuExampleScript extends GhidraScript { println("Terminated via interrupt. Good."); } // Display the final snapshot in the UI - traceManager.activateSnap(snapshot.getKey()); + activateSnap(snapshot.getKey()); /* * Inspect the machine. You can always do this by accessing the state directly, but for @@ -210,7 +204,6 @@ public class DebuggerEmuExampleScript extends GhidraScript { * source (live target, emulated, imported, etc.) It's also built into utilities, making it * easier to use. */ - println("RCX+4 (trace) = " + - TraceSleighUtils.evaluate("RCX+4", trace, snapshot.getKey(), traceThread, 0)); + println("RCX+4 (trace) = " + evaluate("RCX+4")); } }