Debugger Launchers: Windows Debugger (WinDbg, dbgeng.dll)

Integration with WinDbg is achieved by implementing a console debugger in Python 3 based on dbgeng.dll (via pybag). This DLL represents the Microsoft Windows Debugger engine, and so is best suited for debugging Windows user-space targets. This DLL also backs WinDbg and several other debuggers on Windows. By default, the launcher will search for this DLL in an installation of the Windows Debugging Kits version 10. If it does not find it there, it will probably crash with a message in the Terminal.

The following launchers based on Microsoft's dbgeng.dll are included out of the box:

Local

The plain "dbgeng" defaults to launching the current program as a user-mode process on the local system. If there is no current program, this launcher cannot be used. Clearing the Image option will cause this launcher to fail.

Please note on some system configurations, one of the debugger's dependencies dbghelp.dll may get loaded from the system directory instead of from the WinDbg installation, usually because a security product has pre-loaded it into the Python process. You might work around this by copying the affected DLLs from your WinDbg installation into your Python installation.

Setup

Installing WinDbg is highly recommended. If you wish to forego installing WinDbg, you can use the DLL provided with Windows, which is substantially less capable, by manually pointing this connector to C:\Windows\system32. If you do this, some commands, e.g. .server, will not be available.

If you have access to PyPI, setting up your Python 3 environment is done using Pip. Please note the version specifier for Protobuf.

If you are offline, or would like to use our provided packages, we still use Pip, but with a more complicated invocation:

If you get an import error regarding distutils, it is due to a transitive dependency on a buggy version of capstone. Work around it by installing setuptools.

Options

Once running, you are presented with a command-line interface in Ghidra's Terminal. This CLI accepts your usual WinDbg (kd) commands. You can escape from this CLI and enter a Python 3 REPL by entering ".exit". This is not an actual kd command, but our implementation understands this to mean exit the kd REPL. From the Python 3 REPL, you can access the underlying Python-based API pybag. This is an uncommon need, but may be useful for diagnostics and/or workarounds. To re-enter the kd REPL, enter "repl()". Alternatively, if you are trying to quit, but typed ".exit", just type "quit()" to terminate the session.

Extended Local

The "dbgeng-ext" launcher extends the base dbgeng launcher adding extra options (a la IDebugClient's CreateProcess2).

Options

Attach

This launcher allows the user to attach to a local running process. Options are the same as those for the base dbgeng, except for ProcessId and AttachFlags

Options

Remote

This launcher connects to a remote debugger that has opened a port for remote control.

Options

Process Server

The "dbgeng-svrcx" launcher extends the base dbgeng launcher adding an option for connecting through a remote process server.

Options

Windows Kernel

This version of the dbgeng should be used for kernel-debugging of a remote machine. Options are the same as the base dbgeng, except for the connection-string arguments. For remote debugging, the target machine should be booted with the appropriate options, set using BCDEDIT or the equivalent, such as:

where IP= the address of the machine runing Ghidra.

Options

EXDI

Setup for EXDI connections is fairly complicated and difficult to get correct. The argument string typically should be something like:

The CLSID here should match the CLSID in the exdiConfigData.xml file in the debugger architectural directory. If windbg has been run using EXDI at some point, there will also be an entry in the System Registry for this CLSID. The InprocServer32 subentry for this CLSID in the Registry should point to a copy of ExdiGdbSrv.dll, typically the one in the same directory. This DLL must reside somewhere that the debugger has permission to load from, i.e. not in the WindowsApps directory tree. The exdiConfigData file should be configured for the target you're using. We heavily recommend using displayCommPackets==yes, as many of the tasks take considerable time, and this is the only indicator of progress.

The Kd=Guess parameter causes the underlying engine to scan memory for the kernel's base address, which will probably not be provided by the gdbstub. (Kd=NtBaseAddr is also a valid option, as is eliminating the parameter, but, currently, we have no idea how to point the configuration at a correct value. Using this option will cause the load to spin pointlessly.) If you can, we highly recommend breaking the target near the base address, as the search proceeds down through memory starting at the current program counter. If the difference between the PC and the base address is large, the loading process will punt before useful values are detected. If anyone understand how to extend this search (or knows how to set the base address to sidestep the scan), we would really love some guidance.

TTD (Time-Travel Debugging)

This is an extension to our launcher for the Windows Debugger to support TTD. WinDbg TTD uses event:ticks to denote its times. This corresponds well to Ghidra's snapshot:steps syntax, when we let snapshot be an event and ticks count the number of instruction steps. Upon expanding the "Events" node in the Model tree, we create a snapshot for every TTD event, including thread create/terminate, module load/unload, syscall, and other asynchronous changes. Then, when Ghidra navigates to a schedule of the form snapshot:steps, we command WinDbg to navigate to the corresponding event:ticks instead of using Ghidra's emulator. Conversely, time navigation from the WinDbg CLI will correspondingly navigate Ghidra. Thus, the two are synchronized in time. We also add reverse variants of the Go and Step control commands.

Options

This launcher has basically the same options as the WinDbg launcher, except that arguments are not included and the DLL path must contain TTDReplay.dll and the scripts that implement TTD. These are most easily obtained by installing WinDbg Preview or later.

Setup

Depending on how you acquire WinDbg TTD, you may need to copy the installation to a directory Ghidra is allowed to access. It's best not to try cherry-picking files. Just copy/unpack the entire WinDbg installation. Point the launch dialog to the directory containing dbgeng.dll as usual.

NOTE: It's possible, especially if you have anti-virus software installed, that dbghelp.dll is forcefully loaded into the Python process before our connector package tries to load dbgeng.dll. This can cause dbghelp.dll to be loaded from System32, but dbgeng.dll to be loaded from the WinDbg installation, often leading to DLL compatibility problems. This usually manifests in module load and/or Python import errors. The only real way to be sure is to use a system utility and inspect the DLLs loaded by the python.exe process. You may be able to work around the issue by copying dbghelp.dll (and any other affected WinDbg DLLs) from the WinDbg installation into your Python installation, e.g., C:\Python313\dbghelp.dll.