Skip to content

Latest commit

 

History

History
132 lines (96 loc) · 4.08 KB

KDK.md

File metadata and controls

132 lines (96 loc) · 4.08 KB

KDK

Apple Silicon supports kernel debugging, but there are some limitations.

Limitations:

  • No known way to switch between kernel variants (e.g. .development, etc.)
  • Active debugging is not supported, but you can still trigger an NMI with the power button.

Two-Machine Debugging Setup

This is somewhat straightforward and follows the general guide outlined in the ReadMe.pdf file contained inside the KDK. The complications arise once you're inside the debugger.

Note: SIP needs to be disabled to set NVRAM boot arguments

There are multiple ways to get a connection between your host and target machine, but the cheapest option is to purchase a "Thunderbolt 3 (USB-C) to Thunderbolt 2 Adapter" and "Thunderbolt to Gigabit Ethernet Adapter". Then connect an ethernet cable between the target and host (can use a USB-C to ethernet adapter on the host end). A regular ethernet to USB-C adapter on the target will not work.

Once both machines are connected, find the name of the networking interface in ifconfig and set the boot-args accordingly:

$ sudo nvram boot-args="debug=0x44 kdp_match_name=enX wdt=-1"

Reboot and record the address of the target on using ifconfig (on the interface used for debugging) then trigger a panic on the target machine. On the host machine run lldb and kdp-remote with the address of the target machine:

$ lldb
(lldb) kdp-remote 169.254.XXX.XXX

Once you are done with debugging, clear the boot-args with

sudo nvram -d boot-args

Bugs

If on any memory read or x (x is an alias for memory read) you are getting

error: kdp read memory failed

Your lldb is broken. Known broken versions include:

  • lldb-1200.0.41 (Apple Swift version 5.3.1 (swiftlang-1200.0.41 clang-1200.0.32.8))

This is due to a bug where lldb attempts to correct the base address to use iOS semantics. The heap on iOS is 0xFFFFFFE0xxxxxxxx whereas on ASi it's 0xFFFFFE0xxxxxxxx (notice the missing F).

This is apparent if you open a coredump and inspect an address:

(lldb) x/x 0xffffe00010204000
error: core file does not contain 0xffffffe010204000

To workaround this issue on a broken lldb use p to evaluate expressions, e.g.:

p *(uint32_t*) 0xfffffe0010204000

This will not use memory read and will therefore work as intended. As well, amend all scripts in the KDK distribution that use the iOS address with the ASi one:

if name == 'VM_MIN_KERNEL_ADDRESS':
    if self.arch == 'x86_64':
        return unsigned(0xFFFFFF8000000000)
    elif self.arch.startswith('arm64'):
-        return unsigned(0xffffffe000000000)
+        return unsigned(0xfffffe000000000)
    else:
        return unsigned(0x80000000)

Crash Server Setup

You can alternatively debug the system by writing coredumps to a remote server and inspect them afterwards. Note that coredumps are typically very large uncompressed (e.g.: 700mb+) so ensure that there is adequate space on the server before continuing.

Connect both machines using the same setup in Two-Machine Debugging Setup and record the IP address of the server running kdumpd. Then, on the panicking machine, set the boot-args as follows:

$ $ sudo nvram boot-args="debug=0xc44 kdp_match_name=enX wdt=-1 _panicd_ip=169.254.XXX.XXX"

On the server, create a location for the coredumps and start kdumpd:

$ sudo mkdir /PanicDumps
$ sudo chown root:wheel /PanicDumps
$ sudo chmod 1777 /PanicDumps

You can either start the daemon:

$ sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.kdumpd.plist

Or you can run it in the foreground:

$ kdumpd -w /PanicDumps

Once the panicking machine panics, the coredump will be written gzipped to /PanicDumps. gunzip it and then load it in lldb with

$ lldb /System/Library/Kernels/kernel.release.t8101 --core core-xnu-XXX

See bugs before continuing.

Once done creating crash dumps, stop the daemon or kill the foreground kdumpd process and wipe the boot-args with sudo nvram -d boot-args.