Home

Awesome

ida_kernelcache: An IDA Toolkit for analyzing iOS kernelcaches

<!-- Brandon Azad -->

ida_kernelcache is an IDAPython module for IDA Pro to make working with iOS kernelcaches easier. The module provides functions to:

The main processing function is designed to be run before any manual analysis or reverse engineering. With the default settings, IDA tends to miss a lot of useful information in the kernelcache. These scripts help IDA along by leveraging the known structure of the kernelcache to automatically propagate useful information.

In addition to the stock functionality in the module, ida_kernelcache contains several scripts to make analyzing the iOS kernelcache easier. For example, you can use the scripts to autogenerate C structs used by a function.

Many of the techniques used in ida_kernelcache were developed for and borrowed directly from memctl.

Versions

ida_kernelcache has been tested with IDA Pro 6.95 on kernelcaches for iOS versions 10.1.1, 11.0, 11.2, 11.3.1, and 12.0 beta. Currently only Arm64 kernelcaches from iOS 10 and later are supported.

Getting started

You need to already have a decompressed kernelcache file loaded into IDA. You can find the URL to download a particular IPSW from Apple online, and there are a number of public tools (including memctl) capable of decompressing the kernelcache.

In IDA, select "File" -> "Script file..." from the menu bar, then choose the ida_kernelcache.py script in the main directory. This will load the ida_kernelcache module into the IDAPython interpreter under the names ida_kernelcache and kc. In the IDAPython prompt, type kc.kernelcache_process() and hit Enter to start analyzing the kernelcache. This function performs all the major analyses supported by ida_kernelcache. The function will run for several minutes as IDA identifies and analyzes new functions.

ida_kernelcache will try not to overwrite user names for addresses. This means that if the kernelcache has been manually analyzed prior to initialization with kernelcache_process, the results may not be as thorough because user-specified names may block automatic name propagation. However, there's also no guarantee that ida_kernelcache won't mess up prior analysis, so if you do decide to run kernelcache_process on a kernelcache file which you've already analyzed, make a backup first.

The ida_kernelcache module

ida_kernelcache is meant to be loaded via ida_kernelcache.py; the submodules in the ida_kernelcache directory are not meant to be loaded directly. However, ida_kernelcache exposes the functionality of many of these submodules. Here is what each of them does:

Other scripts

The ida_kernelcache_reload.py script is identical to ida_kernelcache.py, except it forces the ida_kernelcache module and all submodules to be reloaded. It is mostly useful for development.

The scripts directory contains scripts that use ida_kernelcache to perform some sort of analysis. These scripts are too specific to be part of the main ida_kernelcache module, but they are useful when reverse engineering the kernelcache. They include:

Class reconstruction

If you are using the Hex-Rays decompiler, one of the more interesting features of ida_kernelcache is the automatic C++ class reconstruction, which will use the OSMetaClass information and data flow analysis to create IDA structs to represent the classes found in the kernelcache. These representations can dramatically improve the readability of the pseudocode representation. To learn more, see the post Reconstructing C++ classes in the iOS kernelcache using IDA Pro.

The new iOS 12 kernelcache format

With iOS 12, Apple introduced a new kernelcache format on some devices. Among the changes, this new kernelcache's kernel pointers are tagged to link them in a list, presumably to allow iBoot to slide the kernel without the _PrelinkLinkKASLROffsets data in the prelink dictionary. Trying to analyze a stock kernelcache using this format in IDA is difficult due to the missing cross-references. See the article Analyzing the iOS 12 kernelcache's tagged pointers for details.

If you just want to untag the pointers in the kernelcache without performing any additional processing, run kc.tagged_pointers.untag_pointers().

A note on generalizing

Some of this functionality likely applies more broadly than just to Apple kernelcaches (for example, vtable analysis and symbol propagation, or most of the functions in ida_utilities.py). Nonetheless, I've limited the import scope to just the ida_kernelcache module because I have not tested any of this on other types of binaries.

License

ida_kernelcache is released under the MIT license.

Much of the functionality in ida_kernelcache is borrowed from memctl, which is also released under the MIT license. Other sources are noted in the comments in the corresponding files.


Brandon Azad