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/
<?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>
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
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 bootdebug
: kernel debuggingkext-dev-mode
: kernel extension developer mode-zc
: zone logging in corruption modezrecs
: how many records to logzlog
: name of zone to logdataconstro
: if kernel const data is made ROwpkernel
: 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¶
- Using Xcode Make a new Project
- Choose Template OS X -> System Plug-in -> Generic Kernel Extension
- Add the
com.apple.kpi.libkern
lib to the project - Set *.kext file to uid=root, gid=wheel
- Set all directories only writable by root:wheel
- Set all files to 644
- 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