Skip to main content

Debugging the XNU Kernel with IDA Pro and Corellium

IDA 7.3 introduces the Remote XNU Debugger. It is designed to communicate with the GDB stub included with popular virtualization tools, namely VMware Fusion (for OSX) and Corellium (for iOS).

The debugger allows you to observe the Darwin kernel as it is running, while at the same time utilizing the full power of IDA’s analysis capabilities. It works equally well on Mac, Windows, and Linux.

This write-up is intended to quickly get you familiar with the debugger, as well as offer some hints to make the experience as smooth as possible.

Getting Started

To get started with debugging iOS, we will perform a simple experiment to patch kernel memory.

The device used in this example is a virtual iPhone XS with iOS 12.1.4, but it should work with any model or iOS version that Corellium supports. Begin by powering on your device and allowing it to boot up. In the Corellium UI, look for the line labelled SSH under Advanced options:

SSH advanced options

Ensure you can connect to the device by running ssh [email protected] uname -v over ssh:

$ ssh [email protected] uname -v
Darwin Kernel Version 18.2.0 ... root:xnu-4903.242.2~1/RELEASE_ARM64_T8020

We will use IDA to patch this version string.

Now launch IDA, and when prompted with the window IDA: Quick start, choose Go to start with an empty database and open Debugger>Attach>Remote XNU Debugger. In the Corellium UI, find the hostname:port used by the kernel GDB stub. It should be specified in the line labelled kernel gdb:

labelled kernel GDB

And set the Hostname and Port fields in IDA’s application setup window:

debug dialog

Now click on Debug options>Set specific options, and for the Configuration dropdown menu, be sure to select Corellium-ARM64:

configuration selection

You can ignore the other config options for now, and click OK.

Click OK again, and wait for IDA to establish a connection to Corellium’s GDB stub (this may take a few seconds). Then select <attach to the process started on target> and wait for IDA to attach. This might take several seconds (we will address this later), but for now, simply wait for IDA to perform the initial setup.

If IDA could detect the kernel, it should appear in the Modules list:

modules list

and the kernel version will be printed to the console:

FFFFFFF007029FD7: detected Darwin Kernel Version 18.2.0 ...

Navigate to this address and use IDAPython to overwrite the string:

navigate to address

idaapi.dbg_write_memory(0xFFFFFFF007029FD7, "IDAPRO".encode('utf-8'))

Resume the OS, and try running the same command as before:

$ ssh [email protected] uname -v
IDAPRO Kernel Version 18.2.0 ... root:xnu-4903.242.2~1/RELEASE_ARM64_T8020

If we could successfully write to kernel memory, IDAPRO should appear in the output.

Debugging the iOS firmware/bootloader is not typically supported unless you have an on-premise Corellium setup.

This content was originally posted on Hex Rays tutorials. Thanks to Ilfak for letting us use it here!