diff --git a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/AbstractDbgReadCommand.java b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/AbstractDbgReadCommand.java index 2de9131ac1..f7d59c7b38 100644 --- a/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/AbstractDbgReadCommand.java +++ b/Ghidra/Debug/Debugger-agent-dbgeng/src/main/java/agent/dbgeng/manager/cmd/AbstractDbgReadCommand.java @@ -45,6 +45,9 @@ public abstract class AbstractDbgReadCommand extends AbstractDbgCommand pending) { + if (readLen == 0) { + return ULongSpanSet.of(); + } return ULongSpanSet.of(ULongSpan.extent(addr, readLen)); } } diff --git a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DisassemblyInject.java b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DisassemblyInject.java index 39b59b1519..918e2a657b 100644 --- a/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DisassemblyInject.java +++ b/Ghidra/Debug/Debugger/src/main/java/ghidra/app/plugin/core/debug/platform/dbgeng/DbgengX64DisassemblyInject.java @@ -23,7 +23,8 @@ import java.util.concurrent.*; import java.util.stream.Collectors; import ghidra.app.plugin.core.debug.disassemble.TraceDisassembleCommand; -import ghidra.app.plugin.core.debug.workflow.*; +import ghidra.app.plugin.core.debug.workflow.DisassemblyInject; +import ghidra.app.plugin.core.debug.workflow.DisassemblyInjectInfo; import ghidra.app.services.DebuggerModelService; import ghidra.app.services.TraceRecorder; import ghidra.app.util.bin.ByteProvider; @@ -61,14 +62,18 @@ public class DbgengX64DisassemblyInject implements DisassemblyInject { TraceRecorder recorder = modelService == null ? null : modelService.getRecorder(trace); Collection modules = trace.getModuleManager().getModulesAt(snap, first.getMinAddress()); + Msg.debug(this, "Disassembling in modules: " + + modules.stream().map(TraceModule::getName).collect(Collectors.joining(","))); Set modes = modules.stream() .map(m -> modeForModule(recorder, trace, snap, m)) .filter(m -> m != Mode.UNK) .collect(Collectors.toSet()); + Msg.debug(this, "Disassembling in mode(s): " + modes); if (modes.size() != 1) { return; } Mode mode = modes.iterator().next(); + Register longModeReg = language.getRegister("longMode"); Register addrsizeReg = language.getRegister("addrsize"); Register opsizeReg = language.getRegister("opsize"); ProgramContextImpl context = new ProgramContextImpl(language); @@ -76,29 +81,38 @@ public class DbgengX64DisassemblyInject implements DisassemblyInject { RegisterValue ctxVal = context.getDisassemblyContext(first.getMinAddress()); if (mode == Mode.X64) { command.setInitialContext(ctxVal + .assign(longModeReg, BigInteger.ONE) .assign(addrsizeReg, BigInteger.TWO) - .assign(opsizeReg, BigInteger.TWO)); + .assign(opsizeReg, BigInteger.ONE)); } else if (mode == Mode.X86) { command.setInitialContext(ctxVal + .assign(longModeReg, BigInteger.ZERO) .assign(addrsizeReg, BigInteger.ONE) .assign(opsizeReg, BigInteger.ONE)); } // Shouldn't ever get anything else. } + private T waitOn(CompletableFuture future) + throws InterruptedException, ExecutionException, TimeoutException { + // Just don't hang the Ghidra task thread indefinitely. + return future.get(1000, TimeUnit.MILLISECONDS); + } + protected Mode modeForModule(TraceRecorder recorder, Trace trace, long snap, TraceModule module) { if (recorder != null && recorder.getSnap() == snap) { AddressSet set = new AddressSet(); set.add(module.getBase(), module.getBase()); // Recorder should read page try { - // This is on its own task thread, so whatever. - // Just don't hang it indefinitely. - recorder.readMemoryBlocks(set, TaskMonitor.DUMMY).get(1000, TimeUnit.MILLISECONDS); + waitOn(recorder.readMemoryBlocks(set, TaskMonitor.DUMMY)); + waitOn(recorder.getTarget().getModel().flushEvents()); + waitOn(recorder.flushTransactions()); + trace.flushEvents(); } catch (InterruptedException | ExecutionException | TimeoutException e) { - Msg.error("Could not read module header from target", e); + Msg.error(this, "Could not read module header from target", e); // Try to parse whatever's there. If 0s, it'll come UNK. } } diff --git a/Ghidra/Processors/x86/certification.manifest b/Ghidra/Processors/x86/certification.manifest index 3f8ddffd31..2fd5eee7e2 100644 --- a/Ghidra/Processors/x86/certification.manifest +++ b/Ghidra/Processors/x86/certification.manifest @@ -34,6 +34,7 @@ data/languages/x86-16.gdis||GHIDRA||||END| data/languages/x86-16.pspec||GHIDRA||||END| data/languages/x86-32-golang.cspec||GHIDRA||||END| data/languages/x86-32-golang.register.info||GHIDRA||||END| +data/languages/x86-64-compat32.pspec||GHIDRA||||END| data/languages/x86-64-gcc.cspec||GHIDRA||||END| data/languages/x86-64-golang.cspec||GHIDRA||||END| data/languages/x86-64-golang.register.info||GHIDRA||||END| diff --git a/Ghidra/Processors/x86/data/languages/x86-64-compat32.pspec b/Ghidra/Processors/x86/data/languages/x86-64-compat32.pspec new file mode 100644 index 0000000000..51ba63c8e2 --- /dev/null +++ b/Ghidra/Processors/x86/data/languages/x86-64-compat32.pspec @@ -0,0 +1,159 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Ghidra/Processors/x86/data/languages/x86-64.pspec b/Ghidra/Processors/x86/data/languages/x86-64.pspec index 315344dc99..08cefc96c7 100644 --- a/Ghidra/Processors/x86/data/languages/x86-64.pspec +++ b/Ghidra/Processors/x86/data/languages/x86-64.pspec @@ -9,7 +9,6 @@ - diff --git a/Ghidra/Processors/x86/data/languages/x86.ldefs b/Ghidra/Processors/x86/data/languages/x86.ldefs index d643d5fc88..1961485c4f 100644 --- a/Ghidra/Processors/x86/data/languages/x86.ldefs +++ b/Ghidra/Processors/x86/data/languages/x86.ldefs @@ -63,7 +63,7 @@ - + - - + + + Intel/AMD 64-bit x86 in 32-bit compatibility mode (long mode off) + + + +