Skip to content

XNU Training

XNU Training

https://github.com/Siguza/ios-resources
https://github.com/alephsecurity/xnu-qemu-arm64
https://theevilbit.github.io/posts/getting_started_in_macos_security/

iOS BootChain

Has KPP and SEPOS keys

Regular Boot:
BootROM -> LLB -> iBoot -> Kernel

Recovery Boot:
BootROM -> iBSS -> iBEC -> Kernel

BootROM

  • 64KB
  • Baked into hardware and cannot be changed
  • Decrypts loaded data using the GID key and a RSA Check (SHSH)

LLB

  • Can be updated
  • Decrypts loaded data using the GID key and a RSA Check (SHSH)

iBoot

  • Can be updated
  • Loads SEPOS and sends it to SEP
  • Loads Kernel Cache and KPP from flash
  • Decrypts loaded data using the GID key and a RSA Check (SHSH)
  • Has 8bit random KASLR

Kernel

  • Part of the firmware
  • Kernel Cache is iOS kernel (based on the XNU kernel) plus preloaded KEXT extensions
  • Implements page biased code signing
  • Uses AppleMobileFileIntegerity Driver to implement certificates and Entitlement Verification

Hardware Encryption

All iDevices after XXXXX have a hardware AES module with hardware keys
- UID Key: used for iOS Data Protection
- GID Key: used for decrypting firmware, kernel, iBoot and others
- SEP Key: only on new iDevices and as its own GID

GID

  • Can not be extracted
  • Shared with every device of the same CPU
  • is deactivated in hardware by iBoot
    • Needs bootloader exploit to dump
  • IV and KEY are random and Wrapped with the GID key
  • For decrypting Firmware this key is needed

Firmware

  • Just Zip files

Location after ITunes Upgrade/Restore:
- /Users/xxxx/Library/iTunes/iPod Software Update/
- /Users/xxxx/Library/iTunes/iPad Software Update/
- /Users/xxxx/Library/iTunes/iPhone Software Update/
- /Users/xxxx/Library/MobileDevice/Software Images/

Latest Version Information

<?xml version="1.0" encoding="UTF-8" standalone="no"?> <plist version="1.0">
	<dict>
		<key>iTunesMacVersion</key>
		<string>12.5.2</string>
		<key>iPodSoftwareVersions</key>
			<dict>
	<key>24</key>
		<dict>
	<key>UpdaterFamilyID</key>
	<integer>24</integer>
	<key>BuildID</key>
	<integer>152207360</integer>
	<key>FirmwareURL</key>
	<string>http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPod/SBML/osx/bundles/061-4306.20080430.Gtr54/
iPod_24.1.1.2.ipsw</string>
	<key>DocumentationURL</key>
	<string>http://appldnld.apple.com.edgesuite.net/content.info.apple.com/iPod/SBML/osx/bundles/061-4306.20080430.Gtr54/
iPodDocumentation_24.1.1.2.ipd</string>
	<key>VisibleBuildID</key>
	<integer>17989632</integer>
 </dict>

Firmware Keys

IPSW Contents:
- Contains Encrypted RootFS
- Contains Encrypted Kernel
- Contains Encrypted RAM Disk
- Contains Encrypted iBEC, IBBS, Baseband Firmware, iBoot, LLB
- Contains Encrypted SEP firmware for 64bit versions

IMG3 Format

  • Tag biased Files for 32 bit devices

Tag Types:
- TYPE: ibot, kernl, lilb, ...
- DATA: Actual Compressed and Encrypted data
- KBAG: AES Key and IV for data encrypted with the GID key
- CERT: Certificate
- SHSH: RSA encrypted SHA1 Hash of file
- SMOD: Security Domain
- SEPO: Security Epoch
- PROD: Production Device
- ECID: Device ID

Decrypt IMG3:
xpwn tool
xpwn tool lite

>>> xpwntool
useage: xpwntool <infile> <outfile> [-t <template> -c <certificate>] [-k <key>] [-iv <key>] [-decrypt] 
>>> xpwntool kernelcache.release.n49 kernelcache.iPhone5,4_9.3.5_13G36.decrypted -k 656211a75d017ad43ef53c8876d6f573ef1257b04905fa747d5a3e998449c1e6 -iv c7725d05be781928899f162d751a8e25

IMG4 Format

  • DER encoded ASN.1 files for 64bit devices

ASN1 IMG4 Info:

sequence [
	0: string "IM4P"
	1: string type - ibot, rdsk, sepi, ...
	2: string description - 'KernelCacheBuilder-960.40.11'
	3: octetstring - the encrypted/raw data
	4: octetstring - containing DER encoded KBAG values (optional)
	sequence [ 
		sequence [ 
		0: int: 01
		1: octetstring: iv
		2: octetstring: key ]
	sequence [ 
		0: int: 02
		1: octetstring: iv
		2: octetstring: key ]
	] 
]

Decrypt IMG4:
IMG4tool

img4 -image kernelcache.release.n51  kernelcache.iPhone6,1_9.3.5_13G36.decrypted c840e26120adeaa7267c2e0084f9fed83aa650411e6d4aac5e965d4e92179258113b6eed6d5b04010d3f891be70fee31
img4 -extra kernelcache.release.n51 kpp.iPhone6,1_9.3.5_13G36.decrypted    c840e26120adeaa7267c2e0084f9fed83aa650411e6d4aac5e965d4e92179258113b6eed6d5b04010d3f891be70fee31

Filesystem

  • Is encrypted DMG file in iOS < 9
    • key is calculated from ramdisk image and platform key
  • Currently is no longer encrypted

GenPass for Decrypting RootFS

Generate Password Key:

>>> ./genpass -p s5l8960x -r 058-48619-036.dmg.decrypted -f 058-48574-036.dmg
vfdecrypt key: c3ef95a9174ff5a94499f35f276688a6c5bdf1afd6c230a97690eea4707b222c86d58225

Decrypt RootFS:

vfdecrypt -i 058-48574-036.dmg -k c3ef95a9174ff5a94499f35f276688a6c5bdf1afd6c230a97690eea4707b222c86d58225 -o rootfs.iPhone6,1_9.3.5_13G36.dmg

RootFS iOS Layout:

ls -la /Volumes/Genoa13G36.N51OS/
total 24
drwxrwxr-t 14 stefanesser staff 748 20 Aug 06:26 .
drwxr-xr-x@ 6 root wheel 204 29 Nov 21:14 ..
d-wx-wx-wt 2 stefanesser staff 68 20 Aug 06:26 .Trashes
---------- 1 stefanesser staff 0 26 Mär 2016 .file
drwx------ 2 stefanesser staff 238 20 Aug 06:29 .fseventsd
drwxrwxr-x 87 stefanesser staff 2958 20 Aug 06:08 Applications
drwxrwxr-x 2 stefanesser staff 68 26 Mär 2016 Developer
drwxrwxr-x 14 stefanesser staff 612 20 Aug 06:08 Library
drwxr-xr-x 3 stefanesser staff 102 26 Mär 2016 System
drwxr-xr-x 2 stefanesser staff 136 20 Aug 06:08 bin
drwxrwxr-t 2 stefanesser staff 68 26 Mär 2016 cores
dr-xr-xr-x 2 stefanesser staff 68 26 Mär 2016 dev
lrwxr-xr-x 1 stefanesser staff 11 20 Aug 06:08 etc -> private/etc
drwxr-xr-x 4 stefanesser staff 136 20 Aug 06:00 private
drwxr-xr-x 2 stefanesser staff 442 20 Aug 06:08 sbin
lrwxr-xr-x 1 stefanesser staff 15 20 Aug 06:08 tmp -> private/var/tmp
drwxr-xr-x 8 stefanesser staff 272 20 Aug 06:00 usr
lrwxr-xr-x 1 stefanesser staff 11 20 Aug 06:08 var -> private/var

Kernel Cache

  • iOS < 10 encrypted kernel cache
  • Uses KSLR but base address starts at 0x80001000, 0xFFFFFF8002002000, 0xFFFFFF8004004000

Location: /System/Library/Caches/com.apple.kernelcaches/kernelcache

XNU Kernel

Kernel Arguments

  • -v: verbose boot
  • debug: kernel debugging
  • kext-dev-mode: kernel extension developer mode
  • -zc: zone logging in corruption mode
  • zrecs: how many records to log
  • zlog: name of zone to log
  • dataconstro: if kernel const data is made RO
  • wpkernel: if kernel memory is write protected

How the Kernel Gets these Arguments:

extern char * PE_boot_args(void);

#if !defined(__LP64__) && !defined(__arm__)
extern boolean_t PE_parse_boot_arg(
	const char *arg_string,
	void *arg_ptr) __deprecated;
#endif

extern boolean_t PE_parse_boot_argn(
	const char *arg_string,
	void *arg_ptr,
	int max_arg);

Getting Kernel Arguments from userspace:

sysctl kern.bootargs
kern.bootargs: kext-dev-mode=1 -v

Setting Kernel Arguments:
- Can be set by NVRAM variable boot-args
- Can be added to /Library/Preferences/SystemConfiguration/com.apple.Boot.plist file
- This file is SIP protected

Setting Args by nvram:

sudo nvram boot-args='wpkernel=0 -v’

Setting Args by file:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>Kernel Flags</key>
	<string>-v</string>
</dict>
</plist>

Kernel Extensions (KEXT)

Some are built into the kernel. These are denoted where their is nothing in the linked against column

Listing Kernel Extensions:

$ kextstat
Index Refs Address            Size    Wired   Name                                                (Version) <Linked Against>
	1 98   0xffffff7f807e4000 0x8d80  0x8d80  com.apple.kpi.bsd                                   (13.4.0)
	2 7    0xffffff7f80bee000 0x28c0  0x28c0  com.apple.kpi.dsep                                  (13.4.0)
	3 119  0xffffff7f807ac000 0x1e050 0x1e050 com.apple.kpi.iokit                                 (13.4.0)
	4 125  0xffffff7f807cb000 0xbf40  0xbf40  com.apple.kpi.libkern                               (13.4.0)
	5 110  0xffffff7f807a9000 0x2d10  0x2d10  com.apple.kpi.mach                                  (13.4.0)
	6 48   0xffffff7f807d7000 0x7d90  0x7d90  com.apple.kpi.private                               (13.4.0)
	7 63   0xffffff7f807df000 0x48e0  0x48e0  com.apple.kpi.unsupported                           (13.4.0)
	8 0    0xffffff7f80c3d000 0xb000  0xb000  com.apple.kec.pthread                               (1)        <7 6 5 4 1>
	9 2    0xffffff7f80dad000 0x47000 0x47000 com.apple.kec.corecrypto                            (1.0)      <7 6 5 4 3 1>
   10 20   0xffffff7f80bf4000 0x9000  0x9000  com.apple.iokit.IOACPIFamily                        (1.4)      <7 6 4 3>
   11 31   0xffffff7f808bf000 0x2b000 0x2b000 com.apple.iokit.IOPCIFamily                         (2.9)      <7 6 5 4 3>
   12 2    0xffffff7f820d2000 0x59000 0x59000 com.apple.driver.AppleACPIPlatform                  (2.0)      <11 10 7 6 5 4 3 1>
   13 1    0xffffff7f80df4000 0xb000  0xb000  com.apple.driver.AppleFDEKeyStore                   (28.30)    <9 7 6 5 4 3 1>
   14 1    0xffffff7f810b1000 0xf000  0xf000  com.apple.iokit.IOReportFamily                      (23)       <5 4 3>
   15 12   0xffffff7f807ed000 0x25000 0x25000 com.apple.iokit.IOStorageFamily                     (1.9)      <7 6 5 4 3 1>
   16 0    0xffffff7f811b0000 0x19000 0x19000 com.apple.driver.DiskImages                         (371.1)    <15 7 6 5 4 3 1>
   17 0    0xffffff7f81bc9000 0x14000 0x14000 com.apple.driver.AppleKeyStore                      (2)        <9 7 6 5 4 3 1>
   18 0    0xffffff7f81d66000 0x2b000 0x2b000 com.apple.driver.AppleIntelCPUPowerManagement       (217.92.1) <7 6 5 4 3 1>
   19 0    0xffffff7f80bf1000 0x3000  0x3000  com.apple.security.TMSafetyNet                      (7)        <7 6 5 4 2 1>
   20 2    0xffffff7f80c1c000 0x5000  0x5000  com.apple.kext.AppleMatch                           (1.0.0d1)  <4 1>
   21 1    0xffffff7f80c21000 0x14000 0x14000 com.apple.security.sandbox                          (278.11.1) <20 7 6 5 4 3 2 1>
   22 0    0xffffff7f80c35000 0x7000  0x7000  com.apple.security.quarantine                       (3)        <21 20 7 6 5 4 2 1>
   23 0    0xffffff7f82142000 0x8000  0x8000  com.apple.nke.applicationfirewall                   (153)      <7 6 5 4 3 1>
   24 0    0xffffff7f81d61000 0x3000  0x3000  com.apple.driver.AppleIntelCPUPowerManagementClient (217.92.1) <7 6 5 4 3 1>
   25 0    0xffffff7f820a6000 0x3000  0x3000  com.apple.driver.AppleAPIC                          (1.7)      <4 3>
   26 3    0xffffff7f81043000 0x4000  0x4000  com.apple.iokit.IOSMBusFamily                       (1.1)      <5 4 3>
   27 0    0xffffff7f82131000 0x7000  0x7000  com.apple.driver.AppleACPIEC                        (2.0)      <26 12 10 5 4 3>
...

Finding the location of the Kernel Extrications:

kextutil -t -n -b com.apple.driver.AppleIntelCPUPowerManagementClient
/System/Library/Extensions/AppleIntelCPUPowerManagementClient.kext appears to be loadable (including linkage for on-disk libraries).

Most System Kernel Extensions are stored in /System/Library/Extensions/. While Third Party Kernel Extensions are stored in /Library/Extensions/

Kernel Programming Interface

Example of Kernel Extensions:
com.apple.kpi.bsd: bsd APIs
com.apple.kpi.dsep: Mandatory Access Control (MAC)
com.apple.kpi.iokit: I/O Kit APIs
com.apple.kpi.libkern: kernel runtime library
com.apple.kpi.mach: Mach APIs
com.apple.kpi.private: private APIs just for Apple
com.apple.kpi.unsupported: unsupported / deprecated APIs

Making a Kernel Extension

  1. Using Xcode Make a new Project
  2. Choose Template OS X -> System Plug-in -> Generic Kernel Extension
  3. Add the com.apple.kpi.libkern lib to the project
  4. Set *.kext file to uid=root, gid=wheel
  5. Set all directories only writable by root:wheel
  6. Set all files to 644
  7. Only mach-o binary has +x

Fixing File Permissions:

sudo cp -R My\ First\ Kernel\ Extension.kext /tmp
sudo chown -R root:wheel My\ First\ Kernel\ Extension.kext/
sudo chmod 775 My\ First\ Kernel\ Extension.kext/
sudo chmod 644 My\ First\ Kernel\ Extension.kext/*.*
sudo chmod +x My\ First\ Kernel\ Extension.kext/*.kext

Kernel Extension must be signed or need to add kext-dev-mode=1 to the boot arguments

Running a Kernel Extension:

sudo kextload My\ First\ Kernel\ Extension.kext
sudo kextunload My\ First\ Kernel\ Extension.kext

Jailbreaking

The old way was to use the task_for_pid and patch it so that it was pid=0. This is not possible on iOS 10+

The new way is to register a new kernel_task to a special port. This was changed in iOS 10.3 where only the kernel can set kernel tasks.

Getting a Kernel Task:

int main(int argc, char **argv, char **envp, char **apple)
{
	kern_return_t res;
	task_t kerneltask;
	pid_t kernelpid = 0;

	int uid = getuid();

	if (uid != 0) {
		fprintf(stderr, "[-] error: %s must be run as the root user.\n", argv[0]);
		_exit(1);
	}

	res = task_for_pid(mach_task_self(), kernelpid, &kerneltask);

	if (res != KERN_SUCCESS) {
		res = host_get_special_port(mach_host_self(), HOST_LOCAL_NODE, 4, &kerneltask);
	}

	if (res != KERN_SUCCESS) {
		fprintf(stderr, "[-] error: unable to get kernel task.\n");
		_exit(1);
	}

Reading Kernel Memory:

restlen = len;
while (restlen > 0) {
	unsigned long toread = restlen > 2048 ? 2048 : restlen;
	size = 0;
	res = vm_read_overwrite(kerneltask, start + already_read, toread, 
							buffer + already_read, &size);
	if (res != KERN_SUCCESS || size != toread) {
		fprintf(stderr, "[-] error: failed to read %u bytes from %p "
		"(got only %u bytes back).\n", toread, start + already_read, size);
		_exit(1);
	}
	restlen -= toread;
	already_read += toread;
}

Writing Kernel Memory:

restlen = len;
while (restlen > 0) {
	unsigned long towrite = restlen > 2048 ? 2048 : restlen;
	size = 0;
	res = vm_write(kerneltask, start + already_written, 
					buffer + already_written, towrite);
	if (res != KERN_SUCCESS) {
		fprintf(stderr, "[-] error: failed to write %u bytes at %p.\n", 
				towrite, start + already_written);
		_exit(1);
	}
	restlen -= towrite;
	already_written += towrite;
}

System Integrity Protection (SIP)

  • Biased on OSX sandboxing

Restrictions:
- load only signed kernel extensions
- disallow debugging of restricted apps
- disallow use of kernel debugger
- disallow modifications of protected areas on filesystem
- restricts use of dtrace
- disallow arbitrary modifications of nvram
- … other related restrictions (like disallowing unload of launchd services)

Kernel Mandatory Access Control

More information
- Contains Policy modules to restrict access
- Uses sysctl values for control policy enforcement
- Uses Signatures to validate data

Kernel Panic

  • Means their is some bug in the code that reached an unexpected input or state.
  • Reports are written to /Library/Logs/DiagnosticReports
    • Can use the Kernel Debug Kit to debug the Panics

Using LLDB with a Kernal Panic:

sudo lldb -c /PanicDumps/core-xnu-2782.1.97-192.168.96.220-2bfbd764 /…/kernels/kernel
(lldb) target create “/…/kernels/kernel” --core "/PanicDumps/core-xnu-2782.1.97-192.168.96.220-2bfbd764"
warning: 'kernel' contains a debug script. To run this script in this debug session:
command script import “/…/kernels/kernel.dSYM/Contents/Resources/Python/kernel.py”
To run all discovered debug scripts in this session:
settings set target.load-script-from-symbol-file true
Kernel UUID: 89E10306-BC78-3A3B-955C-7C4922577E61
Load Address: 0xffffff802d200000
Kernel slid 0x2d000000 in memory.
Loaded kernel file /Users/sesser/Desktop/kernels/kernel
Loading 89 kext modules warning: Can't find binary/dSYM for com.apple.kec.pthread (DB4D4632-FD2B-3FAE-86D3-3432DCDB7FA9)
.warning: Can't find binary/dSYM for com.apple.kec.Libm (76E44753-B3B7-3424-96E5-6FC673973819)
.warning: Can't find binary/dSYM for com.apple.kec.corecrypto (0CB1D8BD-9EB7-3A02-8274-BCBB852B55B4)
.warning: Can't find binary/dSYM for com.apple.iokit.IOACPIFamily (70E2B65E-A91A-3522-A1A0-79FD63EABB4C)
.warning: Can't find binary/dSYM for com.apple.iokit.IOPCIFamily (766FC23F-452C-3B74-951C-598BB17BCF06)
…
. done.
Core file '/PanicDumps/core-xnu-2782.1.97-192.168.96.220-2bfbd764' (x86_64) was loaded.
Process 0 stopped
* thread #1: tid = 0x0000, 0xffffff802d422e87 kernel`Debugger(message=<unavailable>) + 695 at model_dep.c:888, stop reason = signal SIGSTOP
frame #0: 0xffffff802d422e87 kernel`Debugger(message=<unavailable>) + 695 at model_dep.c:888
(lldb) command script import "kernels/kernel.dSYM/Contents/Resources/Python/kernel.py"
Loading kernel debugging from kernels/kernel.dSYM/Contents/Resources/Python/kernel.py
LLDB version lldb-320.4.156
settings set target.process.python-os-plugin-path "kernels/kernel.dSYM/Contents/Resources/Python/lldbmacros/core/operating_system.py"
command script import "kernels/kernel.dSYM/Contents/Resources/Python/lldbmacros/xnu.py"
xnu debug macros loaded successfully. Run showlldbtypesummaries to enable type summaries.
(lldb) kdp-remote 192.168.96.220
Version: Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64; UUID=89E10306-
BC78-3A3B-955C-7C4922577E61; stext=0xffffff8029000000
Kernel UUID: 89E10306-BC78-3A3B-955C-7C4922577E61
Load Address: 0xffffff8029000000
Kernel slid 0x28e00000 in memory.
Loaded kernel file kernels/kernel
Loading 89 kext modules warning: Can't find binary/dSYM for com.apple.kec.pthread (DB4D4632-FD2B-3FAE-86D3-3432DCDB7FA9)
.warning: Can't find binary/dSYM for com.apple.kec.Libm (76E44753-B3B7-3424-96E5-6FC673973819)
...
. done.

Kernel Authorization

Making a Anti Debugging solution:

#include <mach/mach_types.h>
#include <sys/unistd.h>
#include <sys/types.h>
#include <sys/kauth.h>
#include <sys/vnode.h>
#include <sys/proc.h>

kern_return_t denydebugging_start(kmod_info_t * ki, void *d);
kern_return_t denydebugging_stop(kmod_info_t *ki, void *d);

proc_t current_proc();

static int kauth_deny_debugging(kauth_cred_t credential, void *idata, kauth_action_t action,
								uintptr_t arg0, uintptr_t arg1, uintptr_t arg2, uintptr_t arg3){
	int result;
	result = KAUTH_RESULT_DEFER;
	
	switch (action) {
		case KAUTH_PROCESS_CANTRACE:
			proc_t  targetProc;
			int *   errPtr;
			pid_t   pid;
			char buffer[128];
			
			targetProc = (proc_t) arg0;
			errPtr     = (int *) arg1;
			pid        = proc_pid(targetProc);
			
			memset(buffer, 0, sizeof(buffer));
			
			proc_name(pid, buffer, sizeof(buffer));
			
			if (strcmp(buffer, "evil") == 0) {
				*errPtr = EPERM;
				result = KAUTH_RESULT_DENY;
				printf("Denied debugging access to evil\n");
				proc_signal(proc_ppid(current_proc()), SIGKILL);
			}
			break;
		default:
			// do nothing
			break;
	}
	
	return result;
}

static kauth_listener_t kal;

kern_return_t denydebugging_start(kmod_info_t * ki, void *d)
{
	kal = kauth_listen_scope(KAUTH_SCOPE_PROCESS, &kauth_deny_debugging, NULL);
	return KERN_SUCCESS;
}

kern_return_t denydebugging_stop(kmod_info_t *ki, void *d)
{
	kauth_unlisten_scope(kal);
	return KERN_SUCCESS;
}

Mach Ports

  • Communication through Mach ports are done through messages

Getting a Mach port allows the program to make IPC calls.
- kern_return_t mach_port_allocate(ipc_space_t task, mach_port_right_t right, mach_port_name_t *name)
- mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &myport);

Rights:
MACH_PORT_RIGHT_SEND: Right holder can send a message to this port.
MACH_PORT_RIGHT_RECEIVE: Right holder can retrieve messages from this port (a port can only have one receiver).
MACH_PORT_RIGHT_SEND_ONCE: Right holder can send only one message (usually used for reply ports contained in messages).
MACH_PORT_RIGHT_PORT_SET: Collection of receive rights for multiple ports.
MACH_PORT_RIGHT_DEAD_NAME: Not really a right. Send rights become dead when receiver is destroyed. Send once rights become dead when after one message.

Mach Messages

  • Very similar to network packets with headers and encapsulated data
  • Simple Messages
    • Contains plain data
  • Complex Messages
    • Contains out-of-line data or ports

Simple Message Header:
- msgh_bits: describe the message features
- msgh_size: is size of message
- msgh_remote_port: msgh_local_port - communication ports
- msgh_voucher_port: optional voucher port for message
- msgh_id: port specific ID of message

Sending and Receiving messages:

mach_msg_return_t mach_msg(mach_msg_header_t *msg, mach_msg_option_t option, mach_msg_size_t send_size, mach_msg_size_t rcv_size, mach_port_t rcv_name, mach_msg_timeout_t timeout, mach_port_t notify)

mach_msg_overwrite(mach_msg_header_t *msg, mach_msg_option_t option, mach_msg_size_t send_size, mach_msg_size_t rcv_limit, mach_port_t rcv_name, mach_msg_timeout_t timeout, mach_port_t notify, mach_msg_header_t *rcv_msg, mach_msg_size_t rcv_scatter_size)

Sending a Custom Mach Message:

/* we need that because we indent to also receive messages */
mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &myport);

memset(&msg, 0, sizeof(msg));
strcpy(msg.body, "This is the message...\n");

msg.header.msgh_remote_port = myport; /* port to send to */
msg.header.msgh_local_port = MACH_PORT_NULL;
msg.header.msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_MAKE_SEND, 0);

msg.header.msgh_size = sizeof(msg);
ret = mach_msg(&msg.header, MACH_SEND_MSG, msg.header.msgh_size, 0, 0, 0, 0);

Receiving a Mach Message:

// Zero buffer
memset(&msgin, 0, sizeof(msgin));

ret = mach_msg(&msgin.header, MACH_RCV_MSG, 0, 5000, myport, 0, 0);

Receiving a Mach Message from Clock Service:

kern_return_t host_get_clock_service(host_t host, clock_id_t clock_id, clock_serv_t *clock_serv){
	kern_return_t lr; // esi@1
	OUR_mach_msg_header_t msg; // [sp+20h] [bp-38h]@1
	unsigned int v8; // [sp+44h] [bp-14h]@17

	*(_DWORD *)msg.body = *(_DWORD *)&NDR_record_ptr->mig_vers;
	*(_DWORD *)&msg.body[4] = *(_DWORD *)(&NDR_record_ptr->mig_vers + 4);
	*(_DWORD *)&msg.body[8] = clock_id;
	msg.msgh_bits = 0x1513;
	msg.msgh_remote_port = host;
	msg.msgh_local_port = mig_get_reply_port();
	msg.msgh_id = 206;
	kr = mach_msg(&msg, 3, 0x24u, 0x30u, msg.msgh_local_port, 0, 0);
	if ( (unsigned int)(kr - 0x10000002) < 2 )
	{
	...
	}
	...

Building The XNU Kernel

WARNING: If you compile a different kernel build than the system runs prepare for everything failing starting with the boot process

Building XNU for OS X 10.13 High Sierra

#Make sure that Xcode is installed and license is accepted
sudo xcodebuild -license

#install firehose from lib dispatch
git clone https://github.com/Proteas/install_firehose_lib

#download source code of dtrace, AvailabilityVersion and xnu
curl -O https://opensource.apple.com/tarballs/dtrace/dtrace-262.tar.gz
curl -O https://opensource.apple.com/tarballs/AvailabilityVersions/AvailabilityVersions-32.tar.gz
curl -O https://opensource.apple.com/tarballs/xnu/xnu-4570.1.46.tar.gz

#build and install CTF tools from dtrace
tar zxf dtrace-262.tar.gz
cd dtrace-262
mkdir -p obj sym dst
xcodebuild install -target ctfconvert -target ctfdump -target ctfmerge ARCHS="x86_64" SRCROOT=$PWD OBJROOT=$PWD/obj SYMROOT=$PWD/sym DSTROOT=$PWD/dst
sudo ditto $PWD/dst/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/local/ /usr/local/
cd ..

#Install AvailabilityVersions
tar zxf AvailabilityVersions-32.tar.gz
cd AvailabilityVersions-32
mkdir -p dst
make install SRCROOT=$PWD DSTROOT=$PWD/dst
sudo ditto $PWD/dst/usr/local/ `xcrun -sdk macosx -show-sdk-path`/usr/local/
cd ..

#build XNU
tar zxf xnu-4570.1.46.tar.gz
cd xnu-4570.1.46
make SDKROOT=macosx ARCH_CONFIGS=X86_64 KERNEL_CONFIGS=RELEASE
#Debug Mode
#make SDKROOT=macosx ARCH_CONFIGS=X86_64 KERNEL_CONFIGS=DEBUG all
#Activate Kernel debuging
#sudo nvram boot-args=‘debug=0x444 _panicd_ip=1.2.3.4’

Changing the Kernels

sudo cp BUILD/obj/kernel /System/Library/Kernels/kernel
sudo touch /Library/Extensions