From c0f95615dfeb0cdb4d472bfd28df2233a13174d8 Mon Sep 17 00:00:00 2001 From: d-millar <33498836+d-millar@users.noreply.github.com> Date: Mon, 2 Oct 2023 14:17:44 +0000 Subject: [PATCH] GP-3895: add executable name --- .../dbgeng/dbgeng/DebugSystemObjects.java | 2 ++ .../sysobj/DebugSystemObjectsImpl1.java | 13 +++++++ .../dbgeng/sysobj/IDebugSystemObjects.java | 2 ++ .../sysobj/WrapIDebugSystemObjects.java | 11 ++++-- .../java/agent/dbgeng/manager/DbgProcess.java | 10 ++++++ .../cmd/DbgListOSProcessesCommand.java | 2 +- .../manager/cmd/DbgListProcessesCommand.java | 5 ++- .../dbgeng/manager/impl/DbgManagerImpl.java | 14 ++++---- .../dbgeng/manager/impl/DbgProcessImpl.java | 18 ++++++++++ .../model/iface2/DbgModelTargetProcess.java | 2 +- .../model/impl/DbgModelTargetProcessImpl.java | 34 ++++++++++++------- .../dbgmodel/gadp/impl/WrappedDbgModel.java | 5 +++ .../model/impl/DbgModel2TargetRootImpl.java | 2 +- 13 files changed, 96 insertions(+), 24 deletions(-) diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/dbgeng/DebugSystemObjects.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/dbgeng/DebugSystemObjects.java index dd5b5232bd..c6193c44ed 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/dbgeng/DebugSystemObjects.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/dbgeng/DebugSystemObjects.java @@ -110,5 +110,7 @@ public interface DebugSystemObjects { void setImplicitThreadDataOffset(long systemOffset); void setImplicitProcessDataOffset(long systemOffset); + + String getCurrentProcessExecutableName(); } diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/impl/dbgeng/sysobj/DebugSystemObjectsImpl1.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/impl/dbgeng/sysobj/DebugSystemObjectsImpl1.java index 8577ac0e85..6b3cb01bdf 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/impl/dbgeng/sysobj/DebugSystemObjectsImpl1.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/impl/dbgeng/sysobj/DebugSystemObjectsImpl1.java @@ -24,6 +24,7 @@ import com.sun.jna.platform.win32.WinDef.ULONGByReference; import com.sun.jna.platform.win32.WinDef.ULONGLONG; import com.sun.jna.platform.win32.WinDef.ULONGLONGByReference; import com.sun.jna.platform.win32.WinNT.HRESULT; +import com.sun.jna.Native; import com.sun.jna.platform.win32.COM.COMUtils; import agent.dbgeng.dbgeng.COMUtilsExtra; @@ -261,6 +262,18 @@ public class DebugSystemObjectsImpl1 implements DebugSystemObjectsInternal { return pulSysOffset.getValue().longValue(); } + @Override + public String getCurrentProcessExecutableName() { + ULONGByReference pulPathLength = new ULONGByReference(); + COMUtils.checkRC(jnaSysobj.GetCurrentProcessExecutableName(null, new ULONG(0), pulPathLength)); + byte[] aBuffer = new byte[pulPathLength.getValue().intValue()]; + HRESULT hr = jnaSysobj.GetCurrentProcessExecutableName(aBuffer, pulPathLength.getValue(), null); + if (hr.equals(COMUtilsExtra.E_UNEXPECTED) || hr.equals(COMUtilsExtra.E_NOTIMPLEMENTED)) { + return null; + } + return Native.toString(aBuffer); + } + @Override public DebugSessionId getEventSystem() { throw new UnsupportedOperationException("Not supported by this interface"); diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/jna/dbgeng/sysobj/IDebugSystemObjects.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/jna/dbgeng/sysobj/IDebugSystemObjects.java index bcd5bfd64b..57c4144b60 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/jna/dbgeng/sysobj/IDebugSystemObjects.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/jna/dbgeng/sysobj/IDebugSystemObjects.java @@ -103,4 +103,6 @@ public interface IDebugSystemObjects extends IUnknown { HRESULT GetCurrentProcessDataOffset(ULONGLONGByReference SysOffset); + HRESULT GetCurrentProcessExecutableName(byte[] Buffer, ULONG BufferSize, ULONGByReference ExeSize); + } diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/jna/dbgeng/sysobj/WrapIDebugSystemObjects.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/jna/dbgeng/sysobj/WrapIDebugSystemObjects.java index 7784216623..ce1b153792 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/jna/dbgeng/sysobj/WrapIDebugSystemObjects.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/jna/dbgeng/sysobj/WrapIDebugSystemObjects.java @@ -17,11 +17,13 @@ package agent.dbgeng.jna.dbgeng.sysobj; import com.sun.jna.Pointer; import com.sun.jna.Structure; -import com.sun.jna.platform.win32.WinDef.*; +import com.sun.jna.platform.win32.WinDef.ULONG; +import com.sun.jna.platform.win32.WinDef.ULONGByReference; +import com.sun.jna.platform.win32.WinDef.ULONGLONG; +import com.sun.jna.platform.win32.WinDef.ULONGLONGByReference; import com.sun.jna.platform.win32.WinNT.HRESULT; import agent.dbgeng.jna.dbgeng.UnknownWithUtils; -import agent.dbgeng.jna.dbgeng.sysobj.IDebugSystemObjects2.VTIndices2; public class WrapIDebugSystemObjects extends UnknownWithUtils implements IDebugSystemObjects { public static class ByReference extends WrapIDebugSystemObjects @@ -132,4 +134,9 @@ public class WrapIDebugSystemObjects extends UnknownWithUtils implements IDebugS return _invokeHR(VTIndices.GET_CURRENT_PROCESS_DATA_OFFSET, getPointer(), SysOffset); } + @Override + public HRESULT GetCurrentProcessExecutableName(byte[] Buffer, ULONG BufferSize, ULONGByReference ExeSize) { + return _invokeHR(VTIndices.GET_CURRENT_PROCESS_EXECUTABLE_NAME, getPointer(), Buffer, BufferSize, ExeSize); + } + } diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/DbgProcess.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/DbgProcess.java index eeee2a6942..c962f5c86c 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/DbgProcess.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/DbgProcess.java @@ -241,4 +241,14 @@ public interface DbgProcess extends DbgMemoryOperations { */ Long getOffset(); + /** + * Get the executable's name + */ + String getExecutableName(); + + /** + * Set the executable's name + */ + void setExecutableName(String name); + } diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/DbgListOSProcessesCommand.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/DbgListOSProcessesCommand.java index 9082938b6c..5094cd478c 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/DbgListOSProcessesCommand.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/DbgListOSProcessesCommand.java @@ -81,7 +81,7 @@ public class DbgListOSProcessesCommand extends AbstractDbgCommand 3 && fields[2].equals("Cid:")) { Long pid = Long.parseLong(fields[3], 16); - DbgProcessImpl mirror = manager.getProcessComputeIfAbsent(new DebugProcessRecord(pid), pid, false); + DbgProcessImpl mirror = manager.getProcessComputeIfAbsent(new DebugProcessRecord(pid), pid, null, false); if (offset != null) { mirror.setOffset(offset); updatedProcessIds.add(mirror.getId()); diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/DbgListProcessesCommand.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/DbgListProcessesCommand.java index ce848eb0be..233700bb98 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/DbgListProcessesCommand.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/DbgListProcessesCommand.java @@ -51,16 +51,19 @@ public class DbgListProcessesCommand extends AbstractDbgCommand { currentProcess = eventProcess = proc; // As you now have both pid & offset, update the id==pid version - DbgProcessImpl mirror = getProcessComputeIfAbsent(new DebugProcessRecord(proc.getPid()), proc.getPid(), true); + DbgProcessImpl mirror = getProcessComputeIfAbsent(new DebugProcessRecord(proc.getPid()), proc.getPid(), null, true); if (mirror != null) { mirror.setOffset(currentProcess.getOffset()); currentProcess = eventProcess = mirror; @@ -1789,7 +1791,7 @@ public class DbgManagerImpl implements DbgManager { } } else { currentProcess = - eventProcess = getProcessComputeIfAbsent(epid, so.getCurrentProcessSystemId(), true); + eventProcess = getProcessComputeIfAbsent(epid, so.getCurrentProcessSystemId(), so.getCurrentProcessExecutableName(), true); currentThread = eventThread = getThreadComputeIfAbsent(etid, (DbgProcessImpl) eventProcess, so.getCurrentThreadSystemId(), false); getEventListeners().fire.threadSelected(eventThread, null, Causes.UNCLAIMED); diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/impl/DbgProcessImpl.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/impl/DbgProcessImpl.java index 68baa88578..95677abd9f 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/impl/DbgProcessImpl.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/impl/DbgProcessImpl.java @@ -52,6 +52,7 @@ public class DbgProcessImpl implements DbgProcess { private Long pid; private Long exitCode; private Long offset; + private String name; /** * Construct a new inferior @@ -59,6 +60,13 @@ public class DbgProcessImpl implements DbgProcess { * @param manager the manager creating the process * @param id the dbgeng-assigned process ID */ + public DbgProcessImpl(DbgManagerImpl manager, DebugProcessId id, long pid, String name) { + this.manager = manager; + this.id = id; + this.pid = pid; + this.name = name; + } + public DbgProcessImpl(DbgManagerImpl manager, DebugProcessId id, long pid) { this.manager = manager; this.id = id; @@ -392,4 +400,14 @@ public class DbgProcessImpl implements DbgProcess { this.pid = pid; } + @Override + public String getExecutableName() { + return name; + } + + @Override + public void setExecutableName(String name) { + this.name = name; + } + } diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/iface2/DbgModelTargetProcess.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/iface2/DbgModelTargetProcess.java index e42207db37..bb0b1c66b0 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/iface2/DbgModelTargetProcess.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/iface2/DbgModelTargetProcess.java @@ -75,7 +75,7 @@ public interface DbgModelTargetProcess extends // String index = PathUtils.parseIndex(getName()); Long pid = Long.decode(index); DebugProcessId id = new DebugProcessRecord(pid); - return manager.getProcessComputeIfAbsent(id, pid, fire); + return manager.getProcessComputeIfAbsent(id, pid, null, fire); } catch (IllegalArgumentException e) { return manager.getCurrentProcess(); diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetProcessImpl.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetProcessImpl.java index 9bfc40b1d5..24119e54df 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetProcessImpl.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/model/impl/DbgModelTargetProcessImpl.java @@ -49,26 +49,32 @@ import ghidra.dbg.util.PathUtils; name = "Debug", type = DbgModelTargetDebugContainerImpl.class, required = true, - fixed = true), + fixed = true + ), @TargetAttributeType( name = "Memory", type = DbgModelTargetMemoryContainerImpl.class, required = true, - fixed = true), + fixed = true + ), @TargetAttributeType( name = "Modules", type = DbgModelTargetModuleContainerImpl.class, required = true, - fixed = true), + fixed = true + ), @TargetAttributeType( name = "Threads", type = DbgModelTargetThreadContainerImpl.class, required = true, - fixed = true), + fixed = true + ), @TargetAttributeType( name = DbgModelTargetProcessImpl.EXIT_CODE_ATTRIBUTE_NAME, - type = Long.class), - @TargetAttributeType(type = Void.class) }) + type = Long.class + ), + @TargetAttributeType(type = Void.class) } +) public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl implements DbgModelTargetProcess { @@ -122,8 +128,8 @@ public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl SUPPORTED_STEP_KINDS_ATTRIBUTE_NAME, DbgModelTargetThreadImpl.SUPPORTED_KINDS // ), "Initialized"); if (getManager().isKernelMode()) { - TargetExecutionState state = process.getPid() > 0 ? - TargetExecutionState.INACTIVE : TargetExecutionState.ALIVE; + TargetExecutionState state = + process.getPid() > 0 ? TargetExecutionState.INACTIVE : TargetExecutionState.ALIVE; setExecutionState(state, "Initialized"); } else { @@ -139,14 +145,15 @@ public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl Long pid = process.getPid(); if (getManager().isKernelMode()) { if (id.isSystem()) { - return "["+id.id()+"]"; + return "[" + id.id() + "]"; } String pidstr = Long.toString(pid, base); if (base == 16) { pidstr = "0x" + pidstr; } Long offset = process.getOffset(); - return offset == null ? "[" + pidstr + "]" : "[" + pidstr + " : " + Long.toHexString(offset) + "]"; + return offset == null ? "[" + pidstr + "]" + : "[" + pidstr + " : " + Long.toHexString(offset) + "]"; } else { if (pid < 0) { @@ -156,7 +163,9 @@ public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl if (base == 16) { pidstr = "0x" + pidstr; } - return "[" + id.id() + ":" + pidstr + "]"; + String name = process.getExecutableName(); + return name == null ? "[" + id.id() + ":" + pidstr + "]" + : "[" + id.id() + ":" + pidstr + "]" + " : " + name; } } @@ -284,7 +293,8 @@ public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl } @Override - public CompletableFuture resync(RefreshBehavior refreshAttributes, RefreshBehavior refreshElements) { + public CompletableFuture resync(RefreshBehavior refreshAttributes, + RefreshBehavior refreshElements) { if (memory != null) { memory.requestElements(RefreshBehavior.REFRESH_ALWAYS); } diff --git a/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/gadp/impl/WrappedDbgModel.java b/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/gadp/impl/WrappedDbgModel.java index 733507b4db..04006fbc02 100644 --- a/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/gadp/impl/WrappedDbgModel.java +++ b/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/gadp/impl/WrappedDbgModel.java @@ -1058,4 +1058,9 @@ public class WrappedDbgModel client.getSymbols().setCurrentScopeFrameIndex(index); } + @Override + public String getCurrentProcessExecutableName() { + return client.getSystemObjects().getCurrentProcessExecutableName(); + } + } diff --git a/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/model/impl/DbgModel2TargetRootImpl.java b/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/model/impl/DbgModel2TargetRootImpl.java index 6501ded7d6..e112f1ae96 100644 --- a/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/model/impl/DbgModel2TargetRootImpl.java +++ b/Ghidra/Debug/Debugger-agent-dbgmodel/src/main/java/agent/dbgmodel/model/impl/DbgModel2TargetRootImpl.java @@ -578,7 +578,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot activate((DbgModelTargetExecutionStateful) obj); // OK, this sucks, but not all threads are parented to activated objects DbgModelTargetProcess parentProcess = ((DbgModelTargetObject) obj).getParentProcess(); - if (obj instanceof DbgModelTargetExecutionStateful) { + if (parentProcess != null && obj instanceof DbgModelTargetExecutionStateful) { activate(parentProcess); } }