Getting started in macOS security
Has KPP and SEPOS keys
Regular Boot:
BootROM -> LLB -> iBoot -> Kernel
Recovery Boot:
BootROM -> iBSS -> iBEC -> Kernel
64KB
Baked into hardware and cannot be changed
Decrypts loaded data using the GID key and a RSA Check (SHSH)
Can be updated
Decrypts loaded data using the GID key and a RSA Check (SHSH)
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
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
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
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
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
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
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
DER encoded ASN.1 files for 64bit devices
ASN1 IMG4 Info:
graph TB
IM4P["IM4P Sequence"]
IM4P --> F0["0: string 'IM4P'"]
IM4P --> F1["1: string type<br/>(ibot, rdsk, sepi, ...)"]
IM4P --> F2["2: string description<br/>'KernelCacheBuilder-960.40.11'"]
IM4P --> F3["3: octetstring<br/>(encrypted/raw data)"]
IM4P --> F4["4: DER encoded KBAG values<br/>(optional octetstring)"]
F4 --> KBAG["KBAG Sequences"]
KBAG --> K1["Key Data 1<br/>Sequence"]
K1 --> K1_0["0: int: 01"]
K1 --> K1_1["1: octetstring: iv"]
K1 --> K1_2["2: octetstring: key"]
KBAG --> K2["Key Data 2<br/>Sequence"]
K2 --> K2_0["0: int: 02"]
K2 --> K2_1["1: octetstring: iv"]
K2 --> K2_2["2: octetstring: key"]
style IM4P fill:#e3f2fd,stroke:#1976d2,stroke-width:3px
style KBAG fill:#fff3e0,stroke:#f57c00,stroke-width:2px
style K1 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
style K2 fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
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
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
iOS < 10 encrypted kernel cache
Uses KSLR but base address starts at 0x80001000, 0xFFFFFF8002002000, 0xFFFFFF8004004000
Location: /System/Library/Caches/com.apple.kernelcaches/kernelcache
-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:
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/
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
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
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;
}
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)
More information
Contains Policy modules to restrict access
Uses sysctl values for control policy enforcement
Uses Signatures to validate data
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.
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 :
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;
}
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.
Very similar to network packets with headers and encapsulated data
Simple Messages
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:
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;
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:
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; OUR_mach_msg_header_t msg; unsigned int v8;
* ( _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 )
{
...
}
...
WARNING
If you compile a different kernel build than the system runs prepare for everything failing starting with the boot process
sudo cp BUILD/obj/kernel /System/Library/Kernels/kernel
sudo touch /Library/Extensions