Kernelcache Analysis
The kernelcache contains the XNU kernel + all kernel extensions. This is the binary you will reverse engineer the most.
Obtaining the Kernelcache
From an IPSW File
# Download IPSW
# From ipsw.me β select device + iOS version
# IPSW is a ZIP file
unzip iPhone_X_15.4_IPSW.ipsw -d ipsw_extracted/
# Kernelcache file:
ls ipsw_extracted/kernelcache.*
# β kernelcache.release.iphone10 (or similar)
From a Jailbroken Device
# Copy directly
scp root@DEVICE_IP:/System/Library/Caches/com.apple.kernelcaches/kernelcache ./
# Or use img4tool on the device
Decompress / Decrypt
IM4P Format (iOS 10+)
# Install pyimg4
pip3 install pyimg4
# Extract from IM4P container
python3 -m pyimg4 im4p extract \
-i kernelcache.release.iphone10 \
-o kernelcache.macho
# Or use img4tool
img4tool -e -o kernelcache.macho kernelcache.release.iphone10
LZFSE Compression
# If output is still compressed:
# Install lzfse
brew install lzfse
# Decompress
lzfse -decode -i kernelcache.compressed -o kernelcache.macho
# Verify
file kernelcache.macho
# β Mach-O 64-bit arm64e fileset
Loading into IDA Pro
1. File β Open β kernelcache.macho
2. Processor type: ARM Little-endian
3. Wait for auto-analysis (15-60 minutes depending on machine)
4. Apply symbols from KDK:
File β Load file β DWARF file
β Select kernel.release.*.dSYM from KDK
β Full function names + type information
5. If MH_FILESET (iOS 12+):
IDA auto-detects fileset entries
β Each kext is a separate module
β Navigate: View β Open subviews β Segments
Loading into Ghidra
1. File β Import File β kernelcache.macho
2. Language: AARCH64:LE:64:AppleSilicon
3. Options: select "Load all entries" for fileset
4. Analyze: Analysis β Auto Analyze
5. Wait for analysis to complete (can take a long time)
Finding Important Symbols
If You Have KDK Symbols
Search directly by name:
- allproc
- kernel_task
- rootvnode
- pmap_image4_trust_caches
- zone_array (list of all zones)
If No Symbols (Stripped Kernelcache)
Use patchfinder techniques:
1. Find strings β trace xrefs:
"allproc" string β function referencing it β global variable
2. Find known instruction patterns:
MRS X0, TPIDR_EL1 β typically in current_thread()
3. Find the syscall table:
Search for known syscall handler addresses
β Table structure reveals all handlers
4. Find IOKit class names:
"__ZN" prefix β C++ mangled names
Search "IOSurfaceRootUserClient" β class vtable
Automated Patchfinding
# Example: find allproc
# Pattern: function loads address from ADRP+ADD, then reads linked list
# Or use existing tools:
# - iBoot/kernelcache patchfinder (many open-source implementations)
# - Kernel Patchfinder in Dopamine source code
Binary Diffing Workflow
1. Download 2 IPSW files (e.g., iOS 16.5 and 16.5.1)
2. Extract + decompress both kernelcaches
3. Load into IDA β create 2 IDB files
4. Use Diaphora/BinDiff to compare:
- "Changed" functions β security patches
- "Added" functions β new features/mitigations
- "Removed" functions β deprecated code
5. Focus on "Changed" β read diff β identify the vulnerability fixed
6. Research: old version has the bug β potential exploit target