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

Resources

  • pyimg4
  • img4tool
  • ipsw.me – IPSW downloads
  • Apple KDK – developer.apple.com β†’ Downloads β†’ search β€œKernel Debug Kit”