Debugger Launchers: GDB

Integration with GDB is achieved using a Python-based plugin for GDB. It is well-suited for debuging Linux user-space targets, many embedded systems, and sometimes Windows user-space targets. Please note you may need to obtain a properly-configured build of GDB for your target. If you are working with an embedded system, it is probably safest to install the "multiarch" build of GDB from your package manager.

The following launchers based on GDB (GNU Debugger) are included out of the box:

Local

The plain "gdb" launch script defaults to launching the current program as a user-mode process on the local system. If there is no current program, or if you clear the Image option, this launcher will only start gdb and get it connected to a Ghidra trace. You may then manually start or connect to your target. Note that this may also require manual mapping of your program database(s) to the target memory.

Setup

You must have GDB installed on the local system, and it must embed the Python 3 interpreter. 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:

Beware that GDB may embed a different Python interpreter than your system's default. If you are still getting import errors, check the version that GDB embeds:

Note the version and ensure that you are invoking Pip with that version. Supposing sys.version indicates 3.10, you should invoke Pip using python3.10 -m pip.

Warning: Modern Linux distributions are beginning to adopt PEP 668, which prevents installation of Python packages outside of a virtual environment (venv) even for non-root user accounts. Unfortunately, gdb does not seem to honor the currently activated venv, and so such configurations are not officially supported. You may be able to work around this by modifying the PYTHONPATH lines of the launcher script, but your mileage may vary. For now, we recommend using the --break-system-packages argument with Pip.

Options

Once running, you are presented with GDB's command-line interface in Ghidra's Terminal. This is the bona fide GDB command-line interface, so it has all the functionality you would expect. If you command GDB from this shell, the plugin will keep Ghidra in sync. The terminal can also be used to interact with the target application when it is running. The plugin provides an additional set of commands for managing the connection to Ghidra, as well as controlling trace synchronization. These are all in the "ghidra" command prefix. You can use tab completion to enumerate the available commands and GDB's "help" command to examine their documentation.

Via SSH

This works the same as the GDB launcher, but runs gdb on a remote system via ssh. In contrast to the previous system, which used an SSH library for Java, this launcher uses the ssh command on the local system. Thus, it should have broader compatibility with remote systems, and it should use the same configuration files as you are accustomed to. That said, we developed it using OpenSSH, so your experience will be best if your copy understands the same command-line arguments.

Setup

You must install GDB and an SSH server onto the target host. Your local SSH client must support remote port forwarding (-R option) and terminal allocation (-t option), and the remote server must be configured to permit them.

You will need to manually install the required Python packages on the target host, comprising our plugin for GDB and its dependencies. Copy all of the Python packages from Ghidra/Debug/Debugger-rmi-trace/pypkg/dist/ and Ghidra/Debug/Debugger-agent-gdb/pypkg/dist/ to the remote system. It is easiest to put them all in one directory, e.g., ~/ghidra-pypgk/. Then install them:

Please see Setup for notes about embedded Python interpreter versions.

Options

gdbserver via SSH

This works similarly to the GDB via SSH launcher, but instead of tunneling the Trace RMI connection, tunnels the RSP (gdbserver) connection. There is actually a fairly elegant method of doing this straight from within gdb, which is exactly what this launcher does:

This has some advantages compared to running gdb on the remote target:

  1. GDB may not be available on the remote target.
  2. There is no need to install our plugin for GDB on the target.

But, it also has some drawbacks:

  1. gdbserver must be installed on the remote system, and the local gdb must be compatible with it.
  2. It may be slightly more annoying to map modules from the remote system, because of the way GDB reports these modules.
  3. The memory map may be absent. Though this is overcome by creating an entry for the entire address space, if the map is of interest to your analysis, it may not be available.

Setup

You must have GDB installed on the local system and a compatible version of gdbserver installed on the target system. You must have an SSH server installed on the target system. It may be worth testing your setup manually (outside of Ghidra) to ensure everything is configured correctly. On the local system, follow the steps given in Setup. There are no additional Python requirements on the target system.

Options

QEMU

These launchers orchestrate a QEMU user- or system-mode target and connect to it using our Python plugin for GDB. Ghidra will inspect the current program and attempt to map its language to the appropriate QEMU command, but due to subtle errors and/or outright failure, the default value for the QEMU command option often requires careful inspection.

There are two separate scripts for QEMU, one for user mode and one for system mode. Note that QEMU does not support user-mode emulation on Windows, so that script is not available on Windows hosts.

Setup

You must acquire versions of QEMU and GDB that support the target architecture. Aside from the copy of QEMU required, setup is the same whether for user or system mode. As for GDB, on many distributions of Linux, you can install gdb-multiarch. Follow the steps given in Setup.

Options

Wine

This launchers runs wine in a gdb session on Linux and directs it to a target Windows executable. There are other ways to rig a Windows target in GDB on Linux, but this is the method we have chosen. This may prevent GDB from processing the object file, because it is a PE file, and most copies of GDB for UNIX will support only ELF. Nevertheless, Ghidra should recognize the target and map it, giving you symbols and debug info in the front end, even if not in the GDB CLI.

Setup

In addition to the steps given in Setup, you must install Wine on your system. Prepare for configuration by locating the actual wine executable. These are often in some library directory and named "wine32" or "wine64." To find them, either examine the file list of the installed package, or dissect the wrapper wine script, usually on your path:

The locations are usually given in variables at the top of the script, e.g., "/usr/lib/wine/wine64". One is for 64-bit Windows targets and another is for 32-bit Windows targets. Unlike native Windows, Wine does not (yet) implement WoW64 (Windows on Windows 64). Instead, the 32-bit target is loaded using a 32-bit copy of Wine, and so is serviced by Linux's 32-bit system calls. NOTE: Careful attention must be given to select the correct wine executable for the target program's architecture! Even though the wine executable is smart enough to correct this mistake, it results in calls to exec, which confuse this launcher. If GDB complains that it cannot place breakpoints because of memory access, it is probably because of this mistake.

The launcher loads some additional support packages in our plugin for GDB, e.g., to scan the memory map for PE files and amend the module list. Thus, Ghidra can display both Windows and Linux modules, and map them to its program databases accordingly, despite GDB's inability to process PE files. There are perhaps other configurations of GDB for Linux that can process ELFs as well as PEs loaded by Wine, but they do not seem to be readily available in any popular package repositories.

Options

Remote

This launcher can target any TCP-based GDB stub that is compatible with a local copy of gdb. Essentially, it just starts gdb and then enters

into it. It is best to test this command outside of Ghidra to be sure everything is compatible before using this launcher. This launcher does not require an image, nor does it create your target. Thus, it can be used without a current program.

Setup

On your local system, follow the steps given in Setup. Your version of GDB must be compatible with the stub (e.g., gdbserver) on the target system. There are no additional requirements on the target system.

NOTE: The target program image must match that imported in Ghidra, or else things may not map or synchronize correctly.

Options

rr

This launcher runs rr in a gdb session on Linux for replaying rr-generated traces.

Options

Other options are the same as in GDB.