Debugging the XNU Kernel with IDA Pro and Corellium

Learn about IDA 7.3's Remote XNU Debugger. This guide explains how to debug the Darwin kernel using IDA's analysis features while the kernel runs on virtual machines. Works on Mac, Windows, and Linux.

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 labeled SSH under Advanced options:

Screenshot of the Corellium platform; left side judicious rule, Generic Android, and advanced options. Right side is an image of an Android home screen.

Ensure you can connect to the device by running ssh root@ uname -v over ssh:

$ ssh root@ 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 labeled kernel gdb:

 Screenshot of the Corellium platform; left side judicious rule, connect via VPN. The right side is an image of an iPhone 14 Pro Max home screen.

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

Debug Application setup: XNU Kernel on iMac.

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

Configuration; Corellium-ARM64

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:

XNU Kernel 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:

IDAPython to overwrite the string

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

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

$ ssh root@ 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!