Merge remote-tracking branch 'origin/GP-3895_d-millar_dbgeng_exe_name'

(#5817)
This commit is contained in:
Ryan Kurtz 2023-10-03 11:34:13 -04:00
commit 19e32acd90
13 changed files with 96 additions and 24 deletions

View File

@ -110,5 +110,7 @@ public interface DebugSystemObjects {
void setImplicitThreadDataOffset(long systemOffset); void setImplicitThreadDataOffset(long systemOffset);
void setImplicitProcessDataOffset(long systemOffset); void setImplicitProcessDataOffset(long systemOffset);
String getCurrentProcessExecutableName();
} }

View File

@ -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.ULONGLONG;
import com.sun.jna.platform.win32.WinDef.ULONGLONGByReference; import com.sun.jna.platform.win32.WinDef.ULONGLONGByReference;
import com.sun.jna.platform.win32.WinNT.HRESULT; import com.sun.jna.platform.win32.WinNT.HRESULT;
import com.sun.jna.Native;
import com.sun.jna.platform.win32.COM.COMUtils; import com.sun.jna.platform.win32.COM.COMUtils;
import agent.dbgeng.dbgeng.COMUtilsExtra; import agent.dbgeng.dbgeng.COMUtilsExtra;
@ -261,6 +262,18 @@ public class DebugSystemObjectsImpl1 implements DebugSystemObjectsInternal {
return pulSysOffset.getValue().longValue(); 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 @Override
public DebugSessionId getEventSystem() { public DebugSessionId getEventSystem() {
throw new UnsupportedOperationException("Not supported by this interface"); throw new UnsupportedOperationException("Not supported by this interface");

View File

@ -103,4 +103,6 @@ public interface IDebugSystemObjects extends IUnknown {
HRESULT GetCurrentProcessDataOffset(ULONGLONGByReference SysOffset); HRESULT GetCurrentProcessDataOffset(ULONGLONGByReference SysOffset);
HRESULT GetCurrentProcessExecutableName(byte[] Buffer, ULONG BufferSize, ULONGByReference ExeSize);
} }

View File

@ -17,11 +17,13 @@ package agent.dbgeng.jna.dbgeng.sysobj;
import com.sun.jna.Pointer; import com.sun.jna.Pointer;
import com.sun.jna.Structure; 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 com.sun.jna.platform.win32.WinNT.HRESULT;
import agent.dbgeng.jna.dbgeng.UnknownWithUtils; import agent.dbgeng.jna.dbgeng.UnknownWithUtils;
import agent.dbgeng.jna.dbgeng.sysobj.IDebugSystemObjects2.VTIndices2;
public class WrapIDebugSystemObjects extends UnknownWithUtils implements IDebugSystemObjects { public class WrapIDebugSystemObjects extends UnknownWithUtils implements IDebugSystemObjects {
public static class ByReference extends WrapIDebugSystemObjects 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); 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);
}
} }

View File

@ -241,4 +241,14 @@ public interface DbgProcess extends DbgMemoryOperations {
*/ */
Long getOffset(); Long getOffset();
/**
* Get the executable's name
*/
String getExecutableName();
/**
* Set the executable's name
*/
void setExecutableName(String name);
} }

View File

@ -81,7 +81,7 @@ public class DbgListOSProcessesCommand extends AbstractDbgCommand<Map<DebugProce
String[] fields = line.trim().split("\\s+"); String[] fields = line.trim().split("\\s+");
if (fields.length > 3 && fields[2].equals("Cid:")) { if (fields.length > 3 && fields[2].equals("Cid:")) {
Long pid = Long.parseLong(fields[3], 16); 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) { if (offset != null) {
mirror.setOffset(offset); mirror.setOffset(offset);
updatedProcessIds.add(mirror.getId()); updatedProcessIds.add(mirror.getId());

View File

@ -51,16 +51,19 @@ public class DbgListProcessesCommand extends AbstractDbgCommand<Map<DebugProcess
// Need to create the inferior as if we received =thread-group-created // Need to create the inferior as if we received =thread-group-created
DebugSystemObjects so = manager.getSystemObjects(); DebugSystemObjects so = manager.getSystemObjects();
long pid; long pid;
String name;
if (!manager.isKernelMode()) { if (!manager.isKernelMode()) {
Msg.warn(this, "Resync: Was missing group: i" + id); Msg.warn(this, "Resync: Was missing group: i" + id);
so.setCurrentProcessId(id); so.setCurrentProcessId(id);
pid = so.getCurrentProcessSystemId(); pid = so.getCurrentProcessSystemId();
name = so.getCurrentProcessExecutableName();
} }
else { else {
id = new DebugSystemProcessRecord(id.value()); id = new DebugSystemProcessRecord(id.value());
pid = -1; pid = -1;
name = so.getCurrentProcessExecutableName();;
} }
DbgProcessImpl proc = manager.getProcessComputeIfAbsent(id, pid, true); DbgProcessImpl proc = manager.getProcessComputeIfAbsent(id, pid, name, true);
Long offset = so.getCurrentProcessDataOffset(); Long offset = so.getCurrentProcessDataOffset();
proc.setOffset(offset); proc.setOffset(offset);
} }

View File

@ -317,13 +317,13 @@ public class DbgManagerImpl implements DbgManager {
} }
} }
public DbgProcessImpl getProcessComputeIfAbsent(DebugProcessId id, long pid, boolean fire) { public DbgProcessImpl getProcessComputeIfAbsent(DebugProcessId id, long pid, String name, boolean fire) {
synchronized (processes) { synchronized (processes) {
if (processes.containsKey(id)) { if (processes.containsKey(id)) {
DbgProcessImpl existingProc = processes.get(id); DbgProcessImpl existingProc = processes.get(id);
return existingProc; return existingProc;
} }
DbgProcessImpl process = new DbgProcessImpl(this, id, pid); DbgProcessImpl process = new DbgProcessImpl(this, id, pid, name);
process.add(); process.add();
if (fire) { if (fire) {
getEventListeners().fire.processAdded(process, DbgCause.Causes.UNCLAIMED); getEventListeners().fire.processAdded(process, DbgCause.Causes.UNCLAIMED);
@ -1738,7 +1738,8 @@ public class DbgManagerImpl implements DbgManager {
return null; return null;
} else { } else {
int pid = so.getCurrentProcessSystemId(); int pid = so.getCurrentProcessSystemId();
return getProcessComputeIfAbsent(id, pid, true); String name = so.getCurrentProcessExecutableName();
return getProcessComputeIfAbsent(id, pid, name, true);
} }
} }
@ -1758,14 +1759,15 @@ public class DbgManagerImpl implements DbgManager {
DebugSystemObjects so = getSystemObjects(); DebugSystemObjects so = getSystemObjects();
currentSession = eventSession = getSessionComputeIfAbsent(esid, true); currentSession = eventSession = getSessionComputeIfAbsent(esid, true);
if (kernelMode) { if (kernelMode) {
DbgProcessImpl cp = getProcessComputeIfAbsent(new DebugSystemProcessRecord(epid.value()), -1, true); DbgProcessImpl cp = getProcessComputeIfAbsent(new DebugSystemProcessRecord(epid.value()), -1, null, true);
cp.setOffset(so.getCurrentProcessDataOffset()); cp.setOffset(so.getCurrentProcessDataOffset());
cp.setExecutableName(so.getCurrentProcessExecutableName());
currentProcess = eventProcess = cp; currentProcess = eventProcess = cp;
if (currentProcess.getId().isSystem()) { if (currentProcess.getId().isSystem()) {
execute(new DbgResolveProcessCommand(this, currentProcess)).thenAccept(proc -> { execute(new DbgResolveProcessCommand(this, currentProcess)).thenAccept(proc -> {
currentProcess = eventProcess = proc; currentProcess = eventProcess = proc;
// As you now have both pid & offset, update the id==pid version // 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) { if (mirror != null) {
mirror.setOffset(currentProcess.getOffset()); mirror.setOffset(currentProcess.getOffset());
currentProcess = eventProcess = mirror; currentProcess = eventProcess = mirror;
@ -1790,7 +1792,7 @@ public class DbgManagerImpl implements DbgManager {
} }
} else { } else {
currentProcess = currentProcess =
eventProcess = getProcessComputeIfAbsent(epid, so.getCurrentProcessSystemId(), true); eventProcess = getProcessComputeIfAbsent(epid, so.getCurrentProcessSystemId(), so.getCurrentProcessExecutableName(), true);
currentThread = eventThread = getThreadComputeIfAbsent(etid, (DbgProcessImpl) eventProcess, currentThread = eventThread = getThreadComputeIfAbsent(etid, (DbgProcessImpl) eventProcess,
so.getCurrentThreadSystemId(), false); so.getCurrentThreadSystemId(), false);
getEventListeners().fire.threadSelected(eventThread, null, Causes.UNCLAIMED); getEventListeners().fire.threadSelected(eventThread, null, Causes.UNCLAIMED);

View File

@ -52,6 +52,7 @@ public class DbgProcessImpl implements DbgProcess {
private Long pid; private Long pid;
private Long exitCode; private Long exitCode;
private Long offset; private Long offset;
private String name;
/** /**
* Construct a new inferior * Construct a new inferior
@ -59,6 +60,13 @@ public class DbgProcessImpl implements DbgProcess {
* @param manager the manager creating the process * @param manager the manager creating the process
* @param id the dbgeng-assigned process ID * @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) { public DbgProcessImpl(DbgManagerImpl manager, DebugProcessId id, long pid) {
this.manager = manager; this.manager = manager;
this.id = id; this.id = id;
@ -392,4 +400,14 @@ public class DbgProcessImpl implements DbgProcess {
this.pid = pid; this.pid = pid;
} }
@Override
public String getExecutableName() {
return name;
}
@Override
public void setExecutableName(String name) {
this.name = name;
}
} }

View File

@ -75,7 +75,7 @@ public interface DbgModelTargetProcess extends //
String index = PathUtils.parseIndex(getName()); String index = PathUtils.parseIndex(getName());
Long pid = Long.decode(index); Long pid = Long.decode(index);
DebugProcessId id = new DebugProcessRecord(pid); DebugProcessId id = new DebugProcessRecord(pid);
return manager.getProcessComputeIfAbsent(id, pid, fire); return manager.getProcessComputeIfAbsent(id, pid, null, fire);
} }
catch (IllegalArgumentException e) { catch (IllegalArgumentException e) {
return manager.getCurrentProcess(); return manager.getCurrentProcess();

View File

@ -49,26 +49,32 @@ import ghidra.dbg.util.PathUtils;
name = "Debug", name = "Debug",
type = DbgModelTargetDebugContainerImpl.class, type = DbgModelTargetDebugContainerImpl.class,
required = true, required = true,
fixed = true), fixed = true
),
@TargetAttributeType( @TargetAttributeType(
name = "Memory", name = "Memory",
type = DbgModelTargetMemoryContainerImpl.class, type = DbgModelTargetMemoryContainerImpl.class,
required = true, required = true,
fixed = true), fixed = true
),
@TargetAttributeType( @TargetAttributeType(
name = "Modules", name = "Modules",
type = DbgModelTargetModuleContainerImpl.class, type = DbgModelTargetModuleContainerImpl.class,
required = true, required = true,
fixed = true), fixed = true
),
@TargetAttributeType( @TargetAttributeType(
name = "Threads", name = "Threads",
type = DbgModelTargetThreadContainerImpl.class, type = DbgModelTargetThreadContainerImpl.class,
required = true, required = true,
fixed = true), fixed = true
),
@TargetAttributeType( @TargetAttributeType(
name = DbgModelTargetProcessImpl.EXIT_CODE_ATTRIBUTE_NAME, name = DbgModelTargetProcessImpl.EXIT_CODE_ATTRIBUTE_NAME,
type = Long.class), type = Long.class
@TargetAttributeType(type = Void.class) }) ),
@TargetAttributeType(type = Void.class) }
)
public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl
implements DbgModelTargetProcess { implements DbgModelTargetProcess {
@ -122,8 +128,8 @@ public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl
SUPPORTED_STEP_KINDS_ATTRIBUTE_NAME, DbgModelTargetThreadImpl.SUPPORTED_KINDS // SUPPORTED_STEP_KINDS_ATTRIBUTE_NAME, DbgModelTargetThreadImpl.SUPPORTED_KINDS //
), "Initialized"); ), "Initialized");
if (getManager().isKernelMode()) { if (getManager().isKernelMode()) {
TargetExecutionState state = process.getPid() > 0 ? TargetExecutionState state =
TargetExecutionState.INACTIVE : TargetExecutionState.ALIVE; process.getPid() > 0 ? TargetExecutionState.INACTIVE : TargetExecutionState.ALIVE;
setExecutionState(state, "Initialized"); setExecutionState(state, "Initialized");
} }
else { else {
@ -139,14 +145,15 @@ public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl
Long pid = process.getPid(); Long pid = process.getPid();
if (getManager().isKernelMode()) { if (getManager().isKernelMode()) {
if (id.isSystem()) { if (id.isSystem()) {
return "["+id.id()+"]"; return "[" + id.id() + "]";
} }
String pidstr = Long.toString(pid, base); String pidstr = Long.toString(pid, base);
if (base == 16) { if (base == 16) {
pidstr = "0x" + pidstr; pidstr = "0x" + pidstr;
} }
Long offset = process.getOffset(); Long offset = process.getOffset();
return offset == null ? "[" + pidstr + "]" : "[" + pidstr + " : " + Long.toHexString(offset) + "]"; return offset == null ? "[" + pidstr + "]"
: "[" + pidstr + " : " + Long.toHexString(offset) + "]";
} }
else { else {
if (pid < 0) { if (pid < 0) {
@ -156,7 +163,9 @@ public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl
if (base == 16) { if (base == 16) {
pidstr = "0x" + pidstr; 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 @Override
public CompletableFuture<Void> resync(RefreshBehavior refreshAttributes, RefreshBehavior refreshElements) { public CompletableFuture<Void> resync(RefreshBehavior refreshAttributes,
RefreshBehavior refreshElements) {
if (memory != null) { if (memory != null) {
memory.requestElements(RefreshBehavior.REFRESH_ALWAYS); memory.requestElements(RefreshBehavior.REFRESH_ALWAYS);
} }

View File

@ -1058,4 +1058,9 @@ public class WrappedDbgModel
client.getSymbols().setCurrentScopeFrameIndex(index); client.getSymbols().setCurrentScopeFrameIndex(index);
} }
@Override
public String getCurrentProcessExecutableName() {
return client.getSystemObjects().getCurrentProcessExecutableName();
}
} }

View File

@ -578,7 +578,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
activate((DbgModelTargetExecutionStateful) obj); activate((DbgModelTargetExecutionStateful) obj);
// OK, this sucks, but not all threads are parented to activated objects // OK, this sucks, but not all threads are parented to activated objects
DbgModelTargetProcess parentProcess = ((DbgModelTargetObject) obj).getParentProcess(); DbgModelTargetProcess parentProcess = ((DbgModelTargetObject) obj).getParentProcess();
if (obj instanceof DbgModelTargetExecutionStateful) { if (parentProcess != null && obj instanceof DbgModelTargetExecutionStateful) {
activate(parentProcess); activate(parentProcess);
} }
} }