mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
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:
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user