mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Merge remote-tracking branch 'origin/GP-2023_d-millar_opendump_REBASED'
Conflicts: Ghidra/Debug/Debugger-agent-dbgmodel/src/main/resources/agent/dbgmodel/model/impl/dbgmodel_schema.xml
This commit is contained in:
commit
c79bc9e773
40 changed files with 562 additions and 78 deletions
|
@ -224,6 +224,8 @@ public interface DebugDataSpaces {
|
|||
|
||||
DebugMemoryBasicInformation queryVirtual(long offset);
|
||||
|
||||
long virtualToPhysical(long offset);
|
||||
|
||||
/**
|
||||
* A shortcut for iterating over virtual memory regions.
|
||||
*
|
||||
|
@ -276,6 +278,9 @@ public interface DebugDataSpaces {
|
|||
public DebugMemoryBasicInformation next() {
|
||||
DebugMemoryBasicInformation ret = next;
|
||||
next = getNext();
|
||||
if (ret.equals(next)) {
|
||||
next = null;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
};
|
||||
|
|
|
@ -268,4 +268,9 @@ public class DebugDataSpacesImpl1 implements DebugDataSpacesInternal {
|
|||
return read;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long virtualToPhysical(long offset) {
|
||||
throw new UnsupportedOperationException("Not implemented in this interface");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
package agent.dbgeng.impl.dbgeng.dataspaces;
|
||||
|
||||
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.COM.COMUtils;
|
||||
|
||||
|
@ -40,6 +41,9 @@ public class DebugDataSpacesImpl2 extends DebugDataSpacesImpl1 {
|
|||
if (hr.equals(COMUtilsExtra.E_UNEXPECTED)) {
|
||||
return null;
|
||||
}
|
||||
if (hr.equals(COMUtilsExtra.E_NOTIMPLEMENTED)) {
|
||||
return null;
|
||||
}
|
||||
COMUtils.checkRC(hr);
|
||||
|
||||
return new DebugMemoryBasicInformation(pInfo.BaseAddress.longValue(),
|
||||
|
@ -49,4 +53,14 @@ public class DebugDataSpacesImpl2 extends DebugDataSpacesImpl1 {
|
|||
new BitmaskSet<>(PageProtection.class, pInfo.Protect.intValue()),
|
||||
PageType.byValue(pInfo.Type.intValue()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public long virtualToPhysical(long offsetV) {
|
||||
ULONGLONG ullOffset = new ULONGLONG(offsetV);
|
||||
ULONGLONGByReference pulOffset = new ULONGLONGByReference();
|
||||
HRESULT hr = jnaData.VirtualToPhysical(ullOffset, pulOffset);
|
||||
COMUtils.checkRC(hr);
|
||||
|
||||
return pulOffset.getValue().longValue();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@ package agent.dbgeng.jna.dbgeng.dataspaces;
|
|||
|
||||
import com.sun.jna.platform.win32.Guid.IID;
|
||||
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.VTableIndex;
|
||||
|
@ -43,4 +44,6 @@ public interface IDebugDataSpaces2 extends IDebugDataSpaces {
|
|||
}
|
||||
|
||||
HRESULT QueryVirtual(ULONGLONG Offset, MEMORY_BASIC_INFORMATION64.ByReference Info);
|
||||
|
||||
HRESULT VirtualToPhysical(ULONGLONG OffsetVirtual, ULONGLONGByReference OffsetPhysical);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package agent.dbgeng.jna.dbgeng.dataspaces;
|
|||
import com.sun.jna.Pointer;
|
||||
import com.sun.jna.Structure;
|
||||
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.WinNTExtra.MEMORY_BASIC_INFORMATION64;
|
||||
|
@ -39,4 +40,11 @@ public class WrapIDebugDataSpaces2 extends WrapIDebugDataSpaces implements IDebu
|
|||
public HRESULT QueryVirtual(ULONGLONG Offset, MEMORY_BASIC_INFORMATION64.ByReference Info) {
|
||||
return _invokeHR(VTIndices2.QUERY_VIRTUAL, getPointer(), Offset, Info);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HRESULT VirtualToPhysical(ULONGLONG OffsetVirtual, ULONGLONGByReference OffsetPhysical) {
|
||||
return _invokeHR(VTIndices2.VIRTUAL_TO_PHYSICAL, getPointer(), OffsetVirtual,
|
||||
OffsetPhysical);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -371,4 +371,6 @@ public interface DbgManager extends AutoCloseable, DbgBreakpointInsertions {
|
|||
|
||||
DebugEventInformation getLastEventInformation();
|
||||
|
||||
DbgSession getSessionComputeIfAbsent(DebugSessionId debugSessionId, boolean b);
|
||||
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ public class DbgListMappingsCommand extends AbstractDbgCommand<Map<Long, DbgSect
|
|||
Msg.warn(this, "Resync: Was missing thread: " + id);
|
||||
so.setCurrentThreadId(id);
|
||||
int tid = so.getCurrentThreadSystemId();
|
||||
manager.getThreadComputeIfAbsent(id, process, tid);
|
||||
manager.getThreadComputeIfAbsent(id, process, tid, false);
|
||||
}
|
||||
for (DebugThreadId id : new ArrayList<>(cur)) {
|
||||
if (updatedThreadIds.contains(id)) {
|
||||
|
|
|
@ -40,12 +40,16 @@ public class DbgListMemoryRegionsCommand extends AbstractDbgCommand<List<DbgModu
|
|||
@Override
|
||||
public List<DbgModuleMemory> complete(DbgPendingCommand<?> pending) {
|
||||
Map<Long, DbgModuleMemory> memory = manager.getKnownMemoryRegions();
|
||||
if (memoryRegions.isEmpty()) {
|
||||
Msg.error(this, "Switching to !address for memory");
|
||||
manager.setAltMemoryQuery(true);
|
||||
}
|
||||
for (DbgModuleMemory region : memoryRegions) {
|
||||
if (memory.containsValue(region)) {
|
||||
continue; // Do nothing, we're in sync
|
||||
}
|
||||
if (!memory.isEmpty()) {
|
||||
Msg.warn(this, "Resync: Was missing memory: " + region.getId());
|
||||
Msg.warn(this, "Resync: Was missing memory: " + Long.toHexString(region.getId()));
|
||||
}
|
||||
manager.addMemory(region);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,115 @@
|
|||
/* ###
|
||||
* IP: GHIDRA
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package agent.dbgeng.manager.cmd;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import agent.dbgeng.dbgeng.DebugControl;
|
||||
import agent.dbgeng.dbgeng.DebugDataSpaces.PageState;
|
||||
import agent.dbgeng.manager.DbgEvent;
|
||||
import agent.dbgeng.manager.DbgModuleMemory;
|
||||
import agent.dbgeng.manager.evt.AbstractDbgCompletedCommandEvent;
|
||||
import agent.dbgeng.manager.evt.DbgConsoleOutputEvent;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.manager.impl.DbgModuleMemoryImpl;
|
||||
import ghidra.util.Msg;
|
||||
|
||||
public class DbgListMemoryRegionsCommandAlt extends AbstractDbgCommand<List<DbgModuleMemory>> {
|
||||
|
||||
private List<DbgModuleMemory> memoryRegions = new ArrayList<>();
|
||||
|
||||
public DbgListMemoryRegionsCommandAlt(DbgManagerImpl manager) {
|
||||
super(manager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handle(DbgEvent<?> evt, DbgPendingCommand<?> pending) {
|
||||
if (evt instanceof AbstractDbgCompletedCommandEvent && pending.getCommand().equals(this)) {
|
||||
return true;
|
||||
}
|
||||
else if (evt instanceof DbgConsoleOutputEvent) {
|
||||
pending.steal(evt);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DbgModuleMemory> complete(DbgPendingCommand<?> pending) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (DbgConsoleOutputEvent out : pending.findAllOf(DbgConsoleOutputEvent.class)) {
|
||||
builder.append(out.getOutput());
|
||||
}
|
||||
parse(builder.toString());
|
||||
|
||||
Map<Long, DbgModuleMemory> memory = manager.getKnownMemoryRegions();
|
||||
for (DbgModuleMemory region : memoryRegions) {
|
||||
if (memory.containsValue(region)) {
|
||||
continue; // Do nothing, we're in sync
|
||||
}
|
||||
if (!memory.isEmpty()) {
|
||||
Msg.warn(this, "Resync: Was missing memory: " + Long.toHexString(region.getId()));
|
||||
}
|
||||
manager.addMemory(region);
|
||||
}
|
||||
List<Long> toRemove = new ArrayList<>();
|
||||
for (Entry<Long, DbgModuleMemory> entry : memory.entrySet()) {
|
||||
if (memoryRegions.contains(entry.getValue())) {
|
||||
continue; // Do nothing, we're in sync
|
||||
}
|
||||
toRemove.add(entry.getKey());
|
||||
}
|
||||
for (Long key : toRemove) {
|
||||
manager.removeMemory(key);
|
||||
}
|
||||
return memoryRegions;
|
||||
}
|
||||
|
||||
private void parse(String result) {
|
||||
String[] lines = result.split("\n");
|
||||
for (String line : lines) {
|
||||
if (line.startsWith("Mapping")) {
|
||||
continue;
|
||||
}
|
||||
String[] fields = line.trim().split("\\s+");
|
||||
if (fields.length < 4) {
|
||||
continue;
|
||||
}
|
||||
String start = fields[0].replaceAll("`", "");
|
||||
String end = fields[1].replaceAll("`", "");
|
||||
long startVal, endVal;
|
||||
try {
|
||||
startVal = Long.parseUnsignedLong(start, 16);
|
||||
endVal = Long.parseUnsignedLong(end, 16);
|
||||
}
|
||||
catch (Exception e) {
|
||||
continue;
|
||||
}
|
||||
String name = fields[3];
|
||||
ArrayList<String> protect = new ArrayList<String>();
|
||||
DbgModuleMemoryImpl region = new DbgModuleMemoryImpl(start, startVal, endVal, startVal,
|
||||
protect, protect, PageState.COMMIT, name, true, true, true);
|
||||
memoryRegions.add(region);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke() {
|
||||
DebugControl control = manager.getControl();
|
||||
control.execute("!address");
|
||||
}
|
||||
|
||||
}
|
|
@ -48,7 +48,7 @@ public class DbgListProcessesCommand extends AbstractDbgCommand<Map<DebugProcess
|
|||
DebugSystemObjects so = manager.getSystemObjects();
|
||||
so.setCurrentProcessId(id);
|
||||
int pid = so.getCurrentProcessSystemId();
|
||||
manager.getProcessComputeIfAbsent(id, pid);
|
||||
manager.getProcessComputeIfAbsent(id, pid, true);
|
||||
}
|
||||
for (DebugProcessId id : new ArrayList<>(cur)) {
|
||||
if (updatedProcessIds.contains(id)) {
|
||||
|
|
|
@ -45,7 +45,7 @@ public class DbgListSessionsCommand extends AbstractDbgCommand<Map<DebugSessionI
|
|||
}
|
||||
// Need to create the inferior as if we received =thread-group-created
|
||||
Msg.warn(this, "Resync: Was missing group: i" + id);
|
||||
manager.getSessionComputeIfAbsent(id);
|
||||
manager.getSessionComputeIfAbsent(id, true);
|
||||
}
|
||||
for (DebugSessionId id : new ArrayList<>(cur)) {
|
||||
if (updatedSessionIds.contains(id)) {
|
||||
|
|
|
@ -46,7 +46,7 @@ public class DbgListThreadsCommand extends AbstractDbgCommand<Map<DebugThreadId,
|
|||
DebugSystemObjects so = manager.getSystemObjects();
|
||||
so.setCurrentThreadId(id);
|
||||
int tid = so.getCurrentThreadSystemId();
|
||||
manager.getThreadComputeIfAbsent(id, process, tid);
|
||||
manager.getThreadComputeIfAbsent(id, process, tid, false);
|
||||
}
|
||||
for (DebugThreadId id : new ArrayList<>(cur)) {
|
||||
if (updatedThreadIds.contains(id)) {
|
||||
|
|
|
@ -19,6 +19,7 @@ import java.nio.ByteBuffer;
|
|||
|
||||
import com.google.common.collect.*;
|
||||
|
||||
import agent.dbgeng.dbgeng.DebugDataSpaces;
|
||||
import agent.dbgeng.manager.DbgThread;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
|
||||
|
@ -49,6 +50,7 @@ public class DbgReadMemoryCommand extends AbstractDbgCommand<RangeSet<Long>> {
|
|||
|
||||
@Override
|
||||
public void invoke() {
|
||||
readLen = manager.getDataSpaces().readVirtual(addr, buf, len);
|
||||
DebugDataSpaces dataSpaces = manager.getDataSpaces();
|
||||
readLen = dataSpaces.readVirtual(addr, buf, len);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,6 +116,7 @@ public class DbgManagerImpl implements DbgManager {
|
|||
private DbgThread eventThread;
|
||||
private volatile boolean waiting = false;
|
||||
private boolean kernelMode = false;
|
||||
private boolean altMemoryQuery = false;
|
||||
private boolean ignoreEventThread = false;
|
||||
private CompletableFuture<String> continuation;
|
||||
private long processCount = 0;
|
||||
|
@ -139,11 +140,16 @@ public class DbgManagerImpl implements DbgManager {
|
|||
}
|
||||
|
||||
public DbgThreadImpl getThreadComputeIfAbsent(DebugThreadId id, DbgProcessImpl process,
|
||||
int tid) {
|
||||
int tid, boolean fire) {
|
||||
synchronized (threads) {
|
||||
if (!threads.containsKey(id)) {
|
||||
DbgThreadImpl thread = new DbgThreadImpl(this, process, id, tid);
|
||||
thread.add();
|
||||
if (fire) {
|
||||
Causes cause = DbgCause.Causes.UNCLAIMED;
|
||||
getEventListeners().fire.threadCreated(thread, cause);
|
||||
getEventListeners().fire.threadSelected(thread, null, cause);
|
||||
}
|
||||
}
|
||||
return threads.get(id);
|
||||
}
|
||||
|
@ -208,11 +214,14 @@ public class DbgManagerImpl implements DbgManager {
|
|||
}
|
||||
}
|
||||
|
||||
public DbgProcessImpl getProcessComputeIfAbsent(DebugProcessId id, int pid) {
|
||||
public DbgProcessImpl getProcessComputeIfAbsent(DebugProcessId id, int pid, boolean fire) {
|
||||
synchronized (processes) {
|
||||
if (!processes.containsKey(id)) {
|
||||
DbgProcessImpl process = new DbgProcessImpl(this, id, pid);
|
||||
process.add();
|
||||
if (fire) {
|
||||
getEventListeners().fire.processAdded(process, DbgCause.Causes.UNCLAIMED);
|
||||
}
|
||||
}
|
||||
return processes.get(id);
|
||||
}
|
||||
|
@ -245,11 +254,14 @@ public class DbgManagerImpl implements DbgManager {
|
|||
}
|
||||
}
|
||||
|
||||
public DbgSessionImpl getSessionComputeIfAbsent(DebugSessionId id) {
|
||||
public DbgSessionImpl getSessionComputeIfAbsent(DebugSessionId id, boolean fire) {
|
||||
synchronized (sessions) {
|
||||
if (!sessions.containsKey(id) && id.id >= 0) {
|
||||
DbgSessionImpl session = new DbgSessionImpl(this, id);
|
||||
session.add();
|
||||
if (fire) {
|
||||
getEventListeners().fire.sessionAdded(session, DbgCause.Causes.UNCLAIMED);
|
||||
}
|
||||
}
|
||||
return sessions.get(id);
|
||||
}
|
||||
|
@ -635,11 +647,11 @@ public class DbgManagerImpl implements DbgManager {
|
|||
lastEventInformation = control.getLastEventInformation();
|
||||
lastEventInformation.setSession(esid);
|
||||
lastEventInformation.setExecutingProcessorType(execType);
|
||||
currentSession = eventSession = getSessionComputeIfAbsent(esid);
|
||||
currentSession = eventSession = getSessionComputeIfAbsent(esid, true);
|
||||
currentProcess =
|
||||
eventProcess = getProcessComputeIfAbsent(epid, so.getCurrentProcessSystemId());
|
||||
eventProcess = getProcessComputeIfAbsent(epid, so.getCurrentProcessSystemId(), true);
|
||||
currentThread = eventThread = getThreadComputeIfAbsent(etid, (DbgProcessImpl) eventProcess,
|
||||
so.getCurrentThreadSystemId());
|
||||
so.getCurrentThreadSystemId(), false);
|
||||
if (eventThread != null) {
|
||||
((DbgThreadImpl) eventThread).setInfo(lastEventInformation);
|
||||
}
|
||||
|
@ -714,9 +726,9 @@ public class DbgManagerImpl implements DbgManager {
|
|||
DebugThreadId eventId = updateState();
|
||||
DbgProcessImpl process = getCurrentProcess();
|
||||
int tid = so.getCurrentThreadSystemId();
|
||||
DbgThreadImpl thread = getThreadComputeIfAbsent(eventId, process, tid);
|
||||
DbgThreadImpl thread = getThreadComputeIfAbsent(eventId, process, tid, true);
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.threadCreated(thread, DbgCause.Causes.UNCLAIMED);
|
||||
//getEventListeners().fire.threadCreated(thread, DbgCause.Causes.UNCLAIMED);
|
||||
getEventListeners().fire.threadSelected(thread, null, evt.getCause());
|
||||
|
||||
String key = Integer.toHexString(eventId.id);
|
||||
|
@ -789,7 +801,7 @@ public class DbgManagerImpl implements DbgManager {
|
|||
DebugProcessId id = so.getProcessIdByHandle(handle);
|
||||
//so.setCurrentProcessId(id);
|
||||
int pid = so.getCurrentProcessSystemId();
|
||||
DbgProcessImpl proc = getProcessComputeIfAbsent(id, pid);
|
||||
DbgProcessImpl proc = getProcessComputeIfAbsent(id, pid, true);
|
||||
getEventListeners().fire.eventSelected(evt, evt.getCause());
|
||||
getEventListeners().fire.processAdded(proc, evt.getCause());
|
||||
getEventListeners().fire.processSelected(proc, evt.getCause());
|
||||
|
@ -797,9 +809,9 @@ public class DbgManagerImpl implements DbgManager {
|
|||
handle = info.initialThreadInfo.handle;
|
||||
DebugThreadId idt = so.getThreadIdByHandle(handle);
|
||||
int tid = so.getCurrentThreadSystemId();
|
||||
DbgThreadImpl thread = getThreadComputeIfAbsent(idt, proc, tid);
|
||||
getEventListeners().fire.threadCreated(thread, evt.getCause());
|
||||
getEventListeners().fire.threadSelected(thread, null, evt.getCause());
|
||||
getThreadComputeIfAbsent(idt, proc, tid, true);
|
||||
//getEventListeners().fire.threadCreated(thread, evt.getCause());
|
||||
//getEventListeners().fire.threadSelected(thread, null, evt.getCause());
|
||||
|
||||
//proc.moduleLoaded(info.moduleInfo);
|
||||
//getEventListeners().fire.moduleLoaded(proc, info.moduleInfo, evt.getCause());
|
||||
|
@ -1606,6 +1618,14 @@ public class DbgManagerImpl implements DbgManager {
|
|||
this.kernelMode = kernelMode;
|
||||
}
|
||||
|
||||
public boolean useAltMemoryQuery() {
|
||||
return altMemoryQuery;
|
||||
}
|
||||
|
||||
public void setAltMemoryQuery(boolean altMemoryQuery) {
|
||||
this.altMemoryQuery = altMemoryQuery;
|
||||
}
|
||||
|
||||
public void setContinuation(CompletableFuture<String> continuation) {
|
||||
this.continuation = continuation;
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ public class DbgSessionImpl implements DbgSession {
|
|||
*/
|
||||
public void add() {
|
||||
manager.sessions.put(id, this);
|
||||
manager.getEventListeners().fire.sessionAdded(this, DbgCause.Causes.UNCLAIMED);
|
||||
//manager.getEventListeners().fire.sessionAdded(this, DbgCause.Causes.UNCLAIMED);
|
||||
//manager.addSession(this, cause);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,4 +44,6 @@ public abstract class AbstractDbgModel extends AbstractDebuggerObjectModel {
|
|||
|
||||
public abstract void deleteModelObject(Object object);
|
||||
|
||||
public abstract boolean isSuppressDescent();
|
||||
|
||||
}
|
||||
|
|
|
@ -53,6 +53,10 @@ public interface DbgModelTargetProcess extends //
|
|||
public void threadStateChangedSpecific(DbgThread thread, DbgState state);
|
||||
|
||||
public default DbgProcess getProcess() {
|
||||
return getProcess(true);
|
||||
}
|
||||
|
||||
public default DbgProcess getProcess(boolean fire) {
|
||||
DbgManagerImpl manager = getManager();
|
||||
DebugSystemObjects so = manager.getSystemObjects();
|
||||
try {
|
||||
|
@ -62,7 +66,7 @@ public interface DbgModelTargetProcess extends //
|
|||
if (id == null) {
|
||||
id = so.getCurrentProcessId();
|
||||
}
|
||||
return manager.getProcessComputeIfAbsent(id, pid);
|
||||
return manager.getProcessComputeIfAbsent(id, pid, fire);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
return manager.getCurrentProcess();
|
||||
|
|
|
@ -44,12 +44,16 @@ public interface DbgModelTargetSession extends //
|
|||
DbgModelTargetProcessContainer getProcesses();
|
||||
|
||||
public default DbgSession getSession() {
|
||||
return getSession(true);
|
||||
}
|
||||
|
||||
public default DbgSession getSession(boolean fire) {
|
||||
DbgManagerImpl manager = getManager();
|
||||
try {
|
||||
String index = PathUtils.parseIndex(getName());
|
||||
Integer sid = Integer.decode(index);
|
||||
DebugSessionId id = new DebugSessionId(sid);
|
||||
return manager.getSessionComputeIfAbsent(id);
|
||||
return manager.getSessionComputeIfAbsent(id, fire);
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
return manager.getCurrentSession();
|
||||
|
|
|
@ -35,6 +35,10 @@ public interface DbgModelTargetThread extends //
|
|||
DbgModelSelectableObject {
|
||||
|
||||
public default DbgThread getThread() {
|
||||
return getThread(false);
|
||||
}
|
||||
|
||||
public default DbgThread getThread(boolean fire) {
|
||||
DbgManagerImpl manager = getManager();
|
||||
DebugSystemObjects so = manager.getSystemObjects();
|
||||
try {
|
||||
|
@ -46,7 +50,7 @@ public interface DbgModelTargetThread extends //
|
|||
}
|
||||
DbgModelTargetProcess parentProcess = getParentProcess();
|
||||
DbgProcessImpl process = (DbgProcessImpl) parentProcess.getProcess();
|
||||
DbgThreadImpl thread = manager.getThreadComputeIfAbsent(id, process, tid);
|
||||
DbgThreadImpl thread = manager.getThreadComputeIfAbsent(id, process, tid, fire);
|
||||
return thread;
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
|
|
|
@ -25,8 +25,7 @@ import org.apache.commons.lang3.exception.ExceptionUtils;
|
|||
|
||||
import agent.dbgeng.dbgeng.DebugSessionId;
|
||||
import agent.dbgeng.manager.DbgManager;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.manager.impl.DbgSessionImpl;
|
||||
import agent.dbgeng.manager.DbgSession;
|
||||
import agent.dbgeng.model.AbstractDbgModel;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import ghidra.async.AsyncUtils;
|
||||
|
@ -61,14 +60,14 @@ public class DbgModelImpl extends AbstractDbgModel implements DebuggerObjectMode
|
|||
protected final CompletableFuture<DbgModelTargetRootImpl> completedRoot;
|
||||
|
||||
protected Map<Object, TargetObject> objectMap = new HashMap<>();
|
||||
private boolean suppressDescent = false;
|
||||
|
||||
public DbgModelImpl() {
|
||||
this.dbg = DbgManager.newInstance();
|
||||
//System.out.println(XmlSchemaContext.serialize(SCHEMA_CTX));
|
||||
this.root = new DbgModelTargetRootImpl(this, ROOT_SCHEMA);
|
||||
this.completedRoot = CompletableFuture.completedFuture(root);
|
||||
DbgSessionImpl s = new DbgSessionImpl((DbgManagerImpl) dbg, new DebugSessionId(0));
|
||||
s.add();
|
||||
DbgSession s = dbg.getSessionComputeIfAbsent(new DebugSessionId(0), true);
|
||||
DbgModelTargetSessionContainer sessions = root.sessions;
|
||||
this.session = (DbgModelTargetSessionImpl) sessions.getTargetSession(s);
|
||||
addModelRoot(root);
|
||||
|
@ -121,8 +120,8 @@ public class DbgModelImpl extends AbstractDbgModel implements DebuggerObjectMode
|
|||
}
|
||||
|
||||
@Override
|
||||
public DbgManagerImpl getManager() {
|
||||
return (DbgManagerImpl) dbg;
|
||||
public DbgManager getManager() {
|
||||
return dbg;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -180,4 +179,13 @@ public class DbgModelImpl extends AbstractDbgModel implements DebuggerObjectMode
|
|||
return ExceptionUtils.rethrow(ex);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuppressDescent() {
|
||||
return suppressDescent;
|
||||
}
|
||||
|
||||
public void setSuppressDescent(boolean suppressDescent) {
|
||||
this.suppressDescent = suppressDescent;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.stream.Collectors;
|
|||
import agent.dbgeng.manager.DbgEventFilter;
|
||||
import agent.dbgeng.manager.cmd.DbgListEventFiltersCommand;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.manager.impl.DbgProcessImpl;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
|
@ -53,7 +54,9 @@ public class DbgModelTargetEventContainerImpl extends DbgModelTargetObjectImpl
|
|||
@Override
|
||||
public CompletableFuture<Void> requestElements(boolean refresh) {
|
||||
DbgModelTargetProcess targetProcess = getParentProcess();
|
||||
if (!refresh || !targetProcess.getProcess().equals(getManager().getCurrentProcess())) {
|
||||
DbgProcessImpl currentProcess = getManager().getCurrentProcess();
|
||||
if (!refresh ||
|
||||
(currentProcess != null && !currentProcess.equals(targetProcess.getProcess()))) {
|
||||
return AsyncUtils.NIL;
|
||||
}
|
||||
return listEventFilters().thenAccept(byName -> {
|
||||
|
|
|
@ -23,6 +23,7 @@ import java.util.stream.Collectors;
|
|||
import agent.dbgeng.manager.DbgExceptionFilter;
|
||||
import agent.dbgeng.manager.cmd.DbgListExceptionFiltersCommand;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.manager.impl.DbgProcessImpl;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.dbg.target.TargetObject;
|
||||
|
@ -53,7 +54,9 @@ public class DbgModelTargetExceptionContainerImpl extends DbgModelTargetObjectIm
|
|||
@Override
|
||||
public CompletableFuture<Void> requestElements(boolean refresh) {
|
||||
DbgModelTargetProcess targetProcess = getParentProcess();
|
||||
if (!refresh || !targetProcess.getProcess().equals(getManager().getCurrentProcess())) {
|
||||
DbgProcessImpl currentProcess = getManager().getCurrentProcess();
|
||||
if (!refresh ||
|
||||
(currentProcess != null && !currentProcess.equals(targetProcess.getProcess()))) {
|
||||
return AsyncUtils.NIL;
|
||||
}
|
||||
return listExceptionFilters().thenAccept(byName -> {
|
||||
|
|
|
@ -26,6 +26,7 @@ import com.google.common.collect.RangeSet;
|
|||
import agent.dbgeng.manager.DbgModuleMemory;
|
||||
import agent.dbgeng.manager.cmd.*;
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.manager.impl.DbgProcessImpl;
|
||||
import agent.dbgeng.model.iface2.*;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.dbg.error.DebuggerMemoryAccessException;
|
||||
|
@ -53,13 +54,17 @@ public class DbgModelTargetMemoryContainerImpl extends DbgModelTargetObjectImpl
|
|||
public DbgModelTargetMemoryContainerImpl(DbgModelTargetProcess process) {
|
||||
super(process.getModel(), process, "Memory", "MemoryContainer");
|
||||
this.process = process;
|
||||
requestElements(true);
|
||||
if (!getModel().isSuppressDescent()) {
|
||||
requestElements(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CompletableFuture<Void> requestElements(boolean refresh) {
|
||||
DbgModelTargetProcess targetProcess = getParentProcess();
|
||||
if (!refresh || !targetProcess.getProcess().equals(getManager().getCurrentProcess())) {
|
||||
DbgProcessImpl currentProcess = getManager().getCurrentProcess();
|
||||
if (!refresh ||
|
||||
(currentProcess != null && !currentProcess.equals(targetProcess.getProcess()))) {
|
||||
return AsyncUtils.NIL;
|
||||
}
|
||||
return listMemory().thenAccept(byName -> {
|
||||
|
@ -90,6 +95,9 @@ public class DbgModelTargetMemoryContainerImpl extends DbgModelTargetObjectImpl
|
|||
if (manager.isKernelMode()) {
|
||||
return manager.execute(new DbgListKernelMemoryRegionsCommand(manager));
|
||||
}
|
||||
if (manager.useAltMemoryQuery()) {
|
||||
return manager.execute(new DbgListMemoryRegionsCommandAlt(manager));
|
||||
}
|
||||
return manager.execute(new DbgListMemoryRegionsCommand(manager));
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,9 @@ public class DbgModelTargetModuleContainerImpl extends DbgModelTargetObjectImpl
|
|||
super(process.getModel(), process, "Modules", "ModuleContainer");
|
||||
this.targetProcess = process;
|
||||
this.process = process.process;
|
||||
requestElements(false);
|
||||
if (!getModel().isSuppressDescent()) {
|
||||
requestElements(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -121,7 +121,11 @@ public class DbgModelTargetProcessImpl extends DbgModelTargetObjectImpl
|
|||
return "[kernel]";
|
||||
}
|
||||
|
||||
String pidstr = Long.toString(process.getPid(), base);
|
||||
Long pid = process.getPid();
|
||||
if (pid < 0) {
|
||||
return "[" + process.getId().id + "]";
|
||||
}
|
||||
String pidstr = Long.toString(pid, base);
|
||||
if (base == 16) {
|
||||
pidstr = "0x" + pidstr;
|
||||
}
|
||||
|
|
|
@ -55,10 +55,12 @@ public class DbgModelTargetRegisterContainerImpl extends DbgModelTargetObjectImp
|
|||
super(thread.getModel(), thread, "Registers", "RegisterContainer");
|
||||
this.thread = thread.getThread();
|
||||
|
||||
requestElements(false);
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
TargetRegisterBank.DESCRIPTIONS_ATTRIBUTE_NAME, this //
|
||||
), "Initialized");
|
||||
if (!getModel().isSuppressDescent()) {
|
||||
requestElements(false);
|
||||
changeAttributes(List.of(), List.of(), Map.of( //
|
||||
TargetRegisterBank.DESCRIPTIONS_ATTRIBUTE_NAME, this //
|
||||
), "Initialized");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -48,7 +48,9 @@ public class DbgModelTargetThreadContainerImpl extends DbgModelTargetObjectImpl
|
|||
this.changeAttributes(List.of(), Map.of(BASE_ATTRIBUTE_NAME, 16), "Initialized");
|
||||
|
||||
getManager().addEventsListener(this);
|
||||
requestElements(false);
|
||||
if (!getModel().isSuppressDescent()) {
|
||||
requestElements(false);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -109,7 +109,11 @@ public class DbgModelTargetThreadImpl extends DbgModelTargetObjectImpl
|
|||
if (getManager().isKernelMode()) {
|
||||
return "[PR" + thread.getId().id + "]";
|
||||
}
|
||||
String tidstr = Long.toString(thread.getTid(), base);
|
||||
Long tid = thread.getTid();
|
||||
if (tid < 0) {
|
||||
return "[" + thread.getId().id + "]";
|
||||
}
|
||||
String tidstr = Long.toString(tid, base);
|
||||
if (base == 16) {
|
||||
tidstr = "0x" + tidstr;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package agent.dbgeng.model.impl;
|
|||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
import agent.dbgeng.manager.impl.DbgManagerImpl;
|
||||
import agent.dbgeng.model.iface2.DbgModelTargetConnector;
|
||||
import ghidra.async.AsyncUtils;
|
||||
import ghidra.async.TypeSpec;
|
||||
|
@ -79,7 +80,12 @@ public class DbgModelTargetTraceOrDumpConnectorImpl extends DbgModelTargetObject
|
|||
@Override
|
||||
public CompletableFuture<Void> launch(Map<String, ?> args) {
|
||||
return AsyncUtils.sequence(TypeSpec.VOID).then(seq -> {
|
||||
getManager().openFile(args).handle(seq::nextIgnore);
|
||||
DbgManagerImpl manager = getManager();
|
||||
Boolean qv = (Boolean) args.get("UseQueryVirtual");
|
||||
if (qv != null) {
|
||||
manager.setAltMemoryQuery(!qv);
|
||||
}
|
||||
manager.openFile(args).handle(seq::nextIgnore);
|
||||
}).finish().exceptionally((exc) -> {
|
||||
throw new DebuggerUserException("Launch failed for " + args);
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue