macOS kernel debugging
TL;DR: Run a development kernel (DEVELOPMENT or KASAN) on the target, attach LLDB from a second host over the KDP (Kernel Debug Protocol) transport, and use the matching kernel-debug-kit symbols. On Apple Silicon you typically debug via USB/Thunderbolt with a second Mac and
kdpserver.
What it is
The supported workflow for live kernel debugging on macOS uses two machines:
- Target: boots a non-RELEASE kernel (DEVELOPMENT, DEBUG, or KASAN), with
boot-argsenabling KDP and (on Intel) a debug-stub. - Host: runs LLDB with the Apple-shipped
lldbmacrosPython helpers from the Kernel Debug Kit (KDK) matching the target’s build. Connection transports: - KDP over Ethernet (classic, Intel) —
debug=0x144 kdp_match_name=en0. - KDP over serial / IP for Apple Silicon — typically
kmutil/kdpserverover a USB-C debug cable using DCSD or the Apple Silicon debug probe.
Preconditions / where it applies
- You have physical access to the target Mac and can disable SIP / set
nvram boot-args(requires SIP off for most kernel-debug flags). - A matching KDK is installed on the host — version skew silently breaks symbol resolution.
- Relevant for kernel exploit dev, kext reverse engineering, and analysing crash dumps from
panic.ips. See iokit-attack-surface and apple-mitigations.
Technique
Setup outline (Intel target shown — Apple Silicon differs in transport but not in tooling):
- Install matching KDK on host (download from Apple Developer site under “More Downloads”).
- On target: install the same KDK so the dev kernel is available, then:
1 2 3 4 5
sudo cp /Library/Developer/KDKs/KDK_*.kdk/System/Library/Kernels/kernel.development \ /System/Library/Kernels/ sudo kmutil install --volume-root / --update-all sudo nvram boot-args="debug=0x141 -v kcsuffix=development pmuflags=1" sudo reboot
- On host, after the target panics or you trigger an NMI (power+Cmd+Ctrl+Option+Shift+. or
dtrace -w -n "BEGIN { breakpoint(); }"):1 2 3 4 5
lldb (lldb) kdp-remote 192.168.1.42 (lldb) showalltasks # macro from lldbmacros (lldb) showallthreads (lldb) showbinaryinfo <addr>
- Symbols and macros: LLDB auto-loads
lldbmacrosfrom the KDK.showallclasses,zprint,showmcache,showioservicetreeare essential for IOKit and zone analysis. - Core dumps: panics produce
/cores/*.core(ifkern.coredumpis on) pluspanic.ips. Open in LLDB withlldb -c <core> /Library/Developer/KDKs/.../kernel.development.
For early-boot or PPL-related panics on Apple Silicon, use Apple’s DCSD/Astris cable + a second host running Xcode’s kdpserver; this is the only way to break into pre-userland code.
Detection and defence
- N/A as an attack — this is researcher tradecraft. But the state required (SIP off, dev kernel, debug
boot-args) is itself a red flag if seen on a production endpoint: defenders alert oncsrutil disable, non-standardboot-args, orkernel.developmentin/System/Library/Kernels/. - For exploit-mitigation research, prefer KASAN kernels — they surface heap bugs immediately. See apple-mitigations for what is enforced even with debug kernels.
References
- Apple — Debugging the kernel with LLDB — official setup.
- Apple Developer Downloads — Kernel Debug Kits — version-matched kernels and symbols.
- Patrick Wardle / Objective-See — kernel debugging notes — practical writeups across versions.