Debugger Launchers: LLDB

Integration with LLDB is achieved using a plugin for LLDB's Python Scripting Bridge. It is well-suited for debuging user-space targets on a variety of platforms. It is the de facto debugger for macOS. It can be obtained by installing Xcode from the App Store. Though it may require a bit more careful configuration, it can also be obtained from other repositories like brew.

The following launchers based on the LLDB Debugger are included out of the box:

Local

The plain "lldb" 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 lldb 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 LLDB installed on the local system, and it must support Python 3 scripting. 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're using lldb from the Android NDK and do not have Pip, see Setup for Android NDK

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

Beware that LLDB may embed a different Python interpreter than your system's default. If you are still getting import errors, check the version that LLDB 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.

Options

Once running, you are presented with LLDB's command-line interface in Ghidra's Terminal. This is the bona fide LLDB command-line interface, so it has all the functionality you would expect. If you command LLDB from this shell, the plugin will keep Ghidra in sync. The terminal can 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" category. You can use tab completion to enumerate the available commands and LLDB's "help" command to examine their documentation.

Remote

This launcher can target any TCP-based GDB stub that is compatible with a local copy of lldb. Essentially, it just starts lldb 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 LLDB Setup. Your version of LLDB 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

macOS Kernel

This launcher connects to macOS kernels booted in debug-mode using lldb. Essentially, it just starts lldb and then enters

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 LLDB Setup. Before connecting to the target kernel, you must force an NMI on the target to ready the connection. On actual hardware, this is typically achieved by some button sequence, e.g. L/R-Options + Power or Command+Option+Control+Shift+Esc. In a VM, you may have to pause the VM and modify its state. For example, by cd'ing to the VM's container and issuing the command:

Options

Via SSH

This works the same as the GDB via SSH launcher, but runs lldb on a remote system via ssh.

Android

This has the same options as the LLDB via SSH launcher, which are necessary for connecting to the Android debugger, but executes via the normal lldb mechanism.

Setup for Android NDK

If you're using the copy of lldb included with the Android NDK (Native Development Kit), it may not include pip. Notably, this is the case on Windows at the time of writing. Fortunately, you can retrieve the components to install Pip into the NDK from an official Python distribution.

  1. First, figure out the version of Python that is embedded in the NDK's build of LLDB, and get its path. (If you know the path to lldb, you probably already know the path to its Python.) From a Windows Command Prompt or Powershell:
    PS> C:\path\to\android-ndk\...\lldb
    (lldb) script
    >>> import sys
    >>> sys.version
    [copy down the version indicated]
    >>> sys.path
    [look for the paths ending with Lib and DLLs, and copy them down]
    
  2. Now, obtain the same version of Python from the official Python website, and install or unpack it.
  3. Locate your new installation of Python. If you don't already know where it landed, this can be found by examining the Properties of the Python shortcut in your Start Menu.
  4. There should be a Lib\ensurepip directory in the official Python installation. Copy this into the same place in the Android NDK's build of Python.
  5. There are also three native modules that need to be copied from the official Python's DLLs\ directory to the same in the NDK's build. This is to support SSL for downloading packages from PyPI: (Substitue the ??'s appropriately.)
  6. We should now have enough to bootstrap the NDK's Python with Pip. Again at the Windows Command Prompt or Powershell:
    PS> C:\path\to\android-ndk\...\python -m ensurepip
    PS> C:\path\to\android-ndk\...\python -m pip install ...
    
    See the Setup section for the arguments to pass to pip install ....