GP-3142: fix for read registers

GP-3142: adding Populate to schema
GP-3142: adding session id to the records
GP-3142: post-review id->record
GP-3142: post-review id->record
GP-3142: post-review adds to interface
GP-3142: post-review try-finally (missed two)
GP-3142: post-review try-finally (missed one)
GP-3142: post-review try-finally; clearer reset logic
GP-3142: post-review better use of TargetMethod.Export
GP-3142: minor fixes
GP-3142: first pass at dbgeng kernel mods
GP-3142: temp holdGP-3142: mods to differentiate system and engine idsGP-3142: fixes for bad system/engine differentationGP-3142: fixes for bad pid/tid <0 testGP-3142: fixes for selection logicGP-3142: attempting to mininize work done, esp. by expensive callsGP-3142: fix for stack framesGP-3142: minor bug fix for sys threadsGP-3142: better register/stack reads for non-system threadsGP-3142: warningsGP-3142: post-squash and rebaseGP-3142: missed a few RefreshBehavior candidatesGP-3142: miscellaneous fixesGP-3142: minimize workloadGP-3142: display fixes; refresh==true for resolved process/threadGP-3142: added re-populate methodsGP-3142: better kernel/user code re-useGP-3142: re-fix for fact that thread 0 belongs to process 0
This commit is contained in:
d-millar
2023-03-21 10:54:40 -04:00
parent 18bf2fbe30
commit 9690254616
56 changed files with 1469 additions and 494 deletions

View File

@@ -16,17 +16,52 @@
package agent.dbgmodel.gadp.impl;
import java.nio.ByteBuffer;
import java.util.*;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.sun.jna.platform.win32.WinDef.ULONGLONG;
import com.sun.jna.platform.win32.COM.COMException;
import agent.dbgeng.dbgeng.*;
import agent.dbgeng.dbgeng.DebugAdvanced;
import agent.dbgeng.dbgeng.DebugClient;
import agent.dbgeng.dbgeng.DebugControl;
import agent.dbgeng.dbgeng.DebugDataSpaces;
import agent.dbgeng.dbgeng.DebugEventCallbacks;
import agent.dbgeng.dbgeng.DebugInputCallbacks;
import agent.dbgeng.dbgeng.DebugModule;
import agent.dbgeng.dbgeng.DebugModuleInfo;
import agent.dbgeng.dbgeng.DebugOutputCallbacks;
import agent.dbgeng.dbgeng.DebugProcessId;
import agent.dbgeng.dbgeng.DebugProcessRecord;
import agent.dbgeng.dbgeng.DebugRegisters;
import agent.dbgeng.dbgeng.DebugRunningProcess;
import agent.dbgeng.dbgeng.DebugRunningProcess.Description;
import agent.dbgeng.dbgeng.DebugRunningProcess.Description.ProcessDescriptionFlags;
import agent.dbgeng.dbgeng.DebugValue.*;
import agent.dbgeng.dbgeng.DebugServerId;
import agent.dbgeng.dbgeng.DebugSessionId;
import agent.dbgeng.dbgeng.DebugSymbolEntry;
import agent.dbgeng.dbgeng.DebugSymbolId;
import agent.dbgeng.dbgeng.DebugSymbolName;
import agent.dbgeng.dbgeng.DebugSymbols;
import agent.dbgeng.dbgeng.DebugSystemObjects;
import agent.dbgeng.dbgeng.DebugThreadId;
import agent.dbgeng.dbgeng.DebugValue;
import agent.dbgeng.dbgeng.DebugValue.DebugInt16Value;
import agent.dbgeng.dbgeng.DebugValue.DebugInt32Value;
import agent.dbgeng.dbgeng.DebugValue.DebugInt64Value;
import agent.dbgeng.dbgeng.DebugValue.DebugValueType;
import agent.dbgmodel.dbgmodel.bridge.HostDataModelAccess;
import agent.dbgmodel.dbgmodel.debughost.*;
import agent.dbgmodel.dbgmodel.debughost.DebugHost;
import agent.dbgmodel.dbgmodel.debughost.DebugHostContext;
import agent.dbgmodel.dbgmodel.debughost.DebugHostMemory1;
import agent.dbgmodel.dbgmodel.debughost.DebugHostModule1;
import agent.dbgmodel.dbgmodel.debughost.DebugHostSymbol1;
import agent.dbgmodel.dbgmodel.debughost.DebugHostSymbolEnumerator;
import agent.dbgmodel.dbgmodel.debughost.DebugHostSymbols;
import agent.dbgmodel.dbgmodel.main.ModelObject;
import agent.dbgmodel.impl.dbgmodel.DebugRunningProcessImpl;
import agent.dbgmodel.impl.dbgmodel.bridge.HDMAUtil;
@@ -592,7 +627,7 @@ public class WrappedDbgModel
public void setCurrentThreadId(DebugThreadId dti) {
DebugSystemObjects so = client.getSystemObjects();
DebugThreadId currentThreadId = so.getCurrentThreadId();
if (dti.id != currentThreadId.id) {
if (!dti.id().equals(currentThreadId.id())) {
so.setCurrentThreadId(dti);
}
/*
@@ -919,7 +954,7 @@ public class WrappedDbgModel
}
int pid = Integer.decode(id);
if (pid == 0) {
return new DebugProcessId(-1);
return new DebugProcessRecord(-1);
}
DebugProcessId dpi = client.getSystemObjects().getProcessIdBySystemId(pid);
addObj(dpi, id);

View File

@@ -164,30 +164,26 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
@Override
public void processSelected(DbgProcess process, DbgCause cause) {
objectSelected(process);
if (getManager().isKernelMode()) {
processActivated(process);
if (process != null) {
objectSelected(process);
}
}
@Override
public void threadSelected(DbgThread thread, DbgStackFrame frame, DbgCause cause) {
objectSelected(thread);
if (getManager().isKernelMode() && thread != null) {
processActivated(thread.getProcess());
threadActivated(thread);
}
if (frame != null) {
objectSelected(frame);
if (thread != null) {
objectSelected(thread);
if (frame != null) {
objectSelected(frame);
}
}
}
public void objectSelected(Object object) {
List<String> objPath = findObject(object);
TargetObject obj = getModel().getModelObject(objPath);
if (obj instanceof DbgModelSelectableObject) {
setFocus((DbgModelSelectableObject) obj);
}
model.fetchModelObject(objPath, RefreshBehavior.REFRESH_WHEN_ABSENT).thenAccept(obj ->
update(obj)
);
}
@Override
@@ -217,21 +213,6 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
});
}
public void processActivated(DbgProcess proc) {
List<String> objPath = findObject(proc);
DbgModelTargetExecutionStateful stateful = (DbgModelTargetExecutionStateful) getModel().getModelObject(objPath);
if (stateful == null) {
return;
}
TargetExecutionState state = stateful.getExecutionState();
if (state.equals(TargetExecutionState.INACTIVE)) {
stateful.changeAttributes(List.of(), Map.of( //
TargetExecutionStateful.STATE_ATTRIBUTE_NAME, TargetExecutionState.ALIVE //
), "Selected");
stateful.fetchAttributes(RefreshBehavior.REFRESH_ALWAYS);
}
}
@Override
public void threadCreated(DbgThread thread, DbgCause cause) {
getObject(thread).thenAccept(obj -> {
@@ -253,21 +234,6 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
});
}
public void threadActivated(DbgThread thread) {
List<String> objPath = findObject(thread);
DbgModelTargetExecutionStateful stateful = (DbgModelTargetExecutionStateful) getModel().getModelObject(objPath);
if (stateful == null) {
return;
}
TargetExecutionState state = stateful.getExecutionState();
if (state.equals(TargetExecutionState.INACTIVE)) {
stateful.changeAttributes(List.of(), Map.of( //
TargetExecutionStateful.STATE_ATTRIBUTE_NAME, TargetExecutionState.ALIVE //
), "Selected");
stateful.fetchAttributes(RefreshBehavior.REFRESH_ALWAYS);
}
}
@Override
public void moduleLoaded(DbgProcess proc, DebugModuleInfo info, DbgCause cause) {
getObjectRevisited(proc, List.of("Modules"), info).thenAccept(obj -> {
@@ -340,7 +306,7 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
xpath.addAll(ext);
// NB: fetchModelObject may have to be called with false
return AsyncUtils.sequence(TypeSpec.cls(DbgModelTargetObject.class)).then(seq -> {
getModel().fetchModelObject(xpath, false).handle(seq::next);
getModel().fetchModelObject(xpath, RefreshBehavior.REFRESH_NEVER).handle(seq::next);
}, TypeSpec.cls(TargetObject.class)).then((pobj, seq) -> {
if (pobj == null) {
seq.exit();
@@ -564,11 +530,11 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
DebugSystemObjects so = getManager().getSystemObjects();
List<String> objpath = new ArrayList<>();
DebugSessionId sid = so.getCurrentSystemId();
String skey = sid.id < 0 ? PathUtils.makeKey("0x0")
: PathUtils.makeKey("0x" + Integer.toHexString(sid.id));
String skey = sid.value() < 0 ? PathUtils.makeKey("0x0")
: PathUtils.makeKey("0x" + sid.id());
if (obj instanceof DbgSession) {
DbgSession session = (DbgSession) obj;
skey = PathUtils.makeKey("0x" + Long.toHexString(session.getId().id));
skey = PathUtils.makeKey("0x" + session.getId().id());
}
if (obj instanceof DbgSession || obj instanceof String) {
objpath = List.of("Sessions", skey);
@@ -615,6 +581,30 @@ public class DbgModel2TargetRootImpl extends DbgModel2DefaultTargetModelRoot
return objpath;
}
private void update(TargetObject obj) {
if (obj instanceof DbgModelSelectableObject) {
setFocus((DbgModelSelectableObject) obj);
}
if (obj instanceof DbgModelTargetExecutionStateful) {
activate((DbgModelTargetExecutionStateful) obj);
// OK, this sucks, but not all threads are parented to activated objects
DbgModelTargetProcess parentProcess = ((DbgModelTargetObject) obj).getParentProcess();
if (obj instanceof DbgModelTargetExecutionStateful) {
activate(parentProcess);
}
}
}
private void activate(DbgModelTargetExecutionStateful stateful) {
TargetExecutionState state = stateful.getExecutionState();
if (state.equals(TargetExecutionState.INACTIVE)) {
stateful.changeAttributes(List.of(), Map.of( //
TargetExecutionStateful.STATE_ATTRIBUTE_NAME, TargetExecutionState.ALIVE //
), "Selected");
stateful.fetchAttributes(RefreshBehavior.REFRESH_ALWAYS);
}
}
private TargetEventType getEventType(DbgState state, DbgCause cause, DbgReason reason) {
switch (state) {
case RUNNING:

View File

@@ -83,7 +83,7 @@ public class DbgModelSetContextMWETest extends AbstractGhidraHeadlessIntegration
private void dumpRegsViaDX() {
DebugThreadId id = so.getCurrentThreadId();
if (id.id == -1) {
if (id.value() == -1) {
return;
}
@@ -102,7 +102,7 @@ public class DbgModelSetContextMWETest extends AbstractGhidraHeadlessIntegration
private void dumpFrame0ViaDX() {
DebugThreadId id = so.getCurrentThreadId();
if (id.id == -1) {
if (id.value() == -1) {
return;
}
@@ -135,44 +135,44 @@ public class DbgModelSetContextMWETest extends AbstractGhidraHeadlessIntegration
private void dumpFrame0ViaK() {
DebugThreadId id = so.getCurrentThreadId();
if (id.id == -1) {
if (id.value() == -1) {
return;
}
try {
DebugStackInformation stackInfo = control.getStackTrace(0, 0, 0);
if (stackInfo.getNumberOfFrames() == 0) {
Msg.info(this, "t" + id.id + ".Stack is empty?");
Msg.info(this, "t" + id.id() + ".Stack is empty?");
}
else {
DEBUG_STACK_FRAME frame = stackInfo.getFrame(0);
Msg.info(this,
String.format("t%d.Frame[0].io=%08x", id.id,
String.format("t%d.Frame[0].io=%08x", id.id(),
frame.InstructionOffset.longValue()));
}
}
catch (Exception e) {
Msg.info(this, "Could not read t" + id.id + ".Frame[0].io: " + e);
Msg.info(this, "Could not read t" + id.id() + ".Frame[0].io: " + e);
}
}
private void dumpPCViaRegsAPI() {
DebugThreadId id = so.getCurrentThreadId();
if (id.id == -1) {
if (id.value() == -1) {
return;
}
try {
Msg.info(this, String.format("t%d.rip=%s", id.id,
Msg.info(this, String.format("t%d.rip=%s", id.id(),
registers.getValueByName("rip")));
}
catch (Exception e) {
Msg.info(this, "Could not read t" + id.id + ".RIP: " + e);
Msg.info(this, "Could not read t" + id.id() + ".RIP: " + e);
}
try {
Msg.info(this, String.format("t%d.eip=%s", id.id,
Msg.info(this, String.format("t%d.eip=%s", id.id(),
registers.getValueByName("eip")));
}
catch (Exception e) {
Msg.info(this, "Could not read t" + id.id + ".EIP: " + e);
Msg.info(this, "Could not read t" + id.id() + ".EIP: " + e);
}
}