Skip to main content

IPSW Analysis

The ipsw utility is a Go-based program that is used to download and parse IPSWs.

IPSW Information

To obtain basic information of the IPSW file.

% ipsw info iPhone16,1_17.4.1_21E237_Restore.ipsw 

IPSW Info
===========
Version = 17.4.1
BuildVersion = 21E237
OS Type = Production
FileSystem = 096-17468-306.dmg
SystemOS = 096-18212-320.dmg
AppOS = 096-18675-364.dmg
RestoreRamDisk = [096-18353-363.dmg 096-18574-362.dmg]

Devices
-------
iPhone 15 Pro
> iPhone16,1_D83AP_21E237
- TimeStamp: 08 Mar 2024 23:06:41 PST
- KernelCache: kernelcache.release.iphone16
- CPU: A17 Pro (), ID: t8130
- BootLoaders
* iBEC.d83.RELEASE.im4p
* iBoot.d83.RELEASE.im4p
* iBSS.d83.RELEASE.im4p
* LLB.d83.RELEASE.im4p
* sep-firmware.d83.RELEASE.im4p

Extract IPSW

Technically, the IPSW file is a simple zip file, and you can extract it with the unzip command. That will extract all files. However, the ipsw command is a bit more sophisticated in that it can extract only the portions of the file that you are interested in, such as the kernelcache.

unzip

% unzip -qq iPhone11,8_17.3_21D50_Restore.ipsw 

% ls
087-40680-057.dmg
087-40842-056.dmg
087-40854-056.dmg
087-41317-057.dmg
087-41420-057.dmg
BuildManifest.plist
Firmware
Restore.plist
RestoreVersion.plist
SystemVersion.plist
kernelcache.release.iphone11b

% tree
.
├── 096-17468-306.dmg
├── 096-18212-320.dmg
├── 096-18353-363.dmg
├── 096-18574-362.dmg
├── 096-18675-364.dmg
├── BuildManifest.plist
. . . (truncated)

To get a better understanding of the file/directory structure inside the IPSW, refer to the Archive Structure section on the IPSW File Format web page:

https://www.theiphonewiki.com/wiki/IPSW_File_Format

Extract Kernel Cache

The Kernel Cache, included within Apple's iOS IPSW (iPhone Software) files, is a critical component for both the operating system's functionality and security research. It contains the compiled version of the iOS kernel, which is the core of the operating system, managing security, application execution, and hardware interaction. For security researchers, analyzing the kernel cache is paramount to understanding iOS's security mechanisms, discovering vulnerabilities, and developing both mitigations and exploits.

Understanding the Kernel Cache

The kernel cache is specifically designed to optimize boot times and system performance. By precompiling the kernel and essential drivers into a single cache file, iOS devices can boot more quickly compared to dynamically loading these components. However, this compiled nature that Apple applies to the kernel cache add layers of complexity to security research.

Prior to iOS 10, Apple also encrypted the kernel cache to prevent researchers from being able to analyze a critical component of the iOS software. Since then, they have been shipping the kernel cache files as unencrypted making analysis much easier. While there is likely no valid reason to analyze software that is that old, it is important to remember the encrypted part if for some reason you are required to go back to these versions.

While the kernel cache file is no longer encrypted, it is compressed using the modern “LZ” compression tool. This requires an LZ capable tool to decompress the file. However, using the IPSW tool will extract and decompress the kernel cache file in one step.

The unencrypted kernel cache is provided in the IPSW file that is released. You can also grab cache files from a device if that device is jailbroken. We will assume it is not jailbroken here.

% ipsw extract -k iPhone16,1_17.4.1_21E237_Restore.ipsw
• Extracting kernelcache
• Created 21E237__iPhone16,1/kernelcache.release.iPhone16,1

Once the kernel cache is extracted, obtain the version of XNU that is in use:

% ipsw kernel version kernelcache.release.iPhone16,1 
Darwin Kernel Version 23.4.0: Fri Mar 8 23:31:42 PST 2024; root:xnu-10063.102.14~67/RELEASE_ARM64_T8122

Note: There is usually a delay in open-sourcing the latest version of XNU. For instance, this shows version 10063.102.14~67, while the open-source GitHub has 10063.101.15. So, you may not be able to review the code of the absolute latest iOS version (as we did in this example).

View Kernel Extensions (KEXTs)

To view a listing of the kernel extensions:

% ipsw kernel kexts 21E237__iPhone16,1/kernelcache.release.iPhone16,1 
• Kexts count=272
0x7fffffffffffffff: com.apple.driver.AppleBSDKextStarterTMPFS (1)
0x7fffffffffffffff: com.apple.driver.AppleBSDKextStarterVPN (3)
. . . (truncated)

The extensions are included in the extracted kernel cache, and can be analyzed in Ghidra or other disassemblers.

Extract Dynamic Libraries (DYLIBs) Shared Cache

Similar to the kernel, Apple includes the core set of DYLIBs as a cache file so that the iOS device can access these core libraries quicker than having to load them when they are called. There are many things you may need to do with the DYLIB shared cache. For instance, I wrote an iOS Tweak that captures all TLS keys that an application uses to communicate with back-end servers. To make this work, I had to extract the DYLIB cache to obtain the appropriate offsets to make the tweak work with every iOS version currently supported.

Get a list of the DYLIBs:

% ipsw dyld info -l dyld_shared_cache_arm64e

To extract a DYLIB:

% ipsw dyld extract dyld_shared_cache_arm64e libcoretls.dylib 
• Created libcoretls.dylib

% ls -lh libcoretls.dylib
-rwxr-xr-x 1 steve staff 816K Apr 9 18:39 libcoretls.dylib

In this example, I extracted the libcoretls.dylib from the mulitple cache files we extracted earlier.