My Foray Into Mac OS X Kernel Hacking

Last night I watched Julia Evans’ StrangeLoop talk “You can be a kernel hacker!” I was inspired by her straightforward strategies for getting started with kernel hacking.

While Julia’s examples are for Linux, I decided to explore Mac OS X. If my operating system is a tool I should learn to use, I should learn about Mac OS X so I can apply my knowledge in my day to day life. (I might switch to Linux if I feel like I’m missing out on some of Julia’s wizardry!)

I first needed to find out what the Mac OS X kernel was even called. Which led me to this question on superuser. Darwin is the Mac OS X equivalent of the Linux kernel. It was open sourced by Apple in 2006.

Strace all the things

The Mac OS X counterpart to strace is dtrace. This blog post explains some history and why you might want to use dtruss instead. I found dtruss easier to use.

The first command I ran was dtruss kill -9 24419. (After doing ps aux | grep java to see all my running java processes. I usually have lots of java processes running.) It returned lots of output, some of which made sense to me. Kill with the -9 flag indicates that a process should be killed immediately — it is given no chance to clean up after itself. (Kill -9 is equivalent to kill -SIGKILL.)

Some lines in the output obviously made sense:

getpid(0x1, 0x105D42000, 0x49656E69) = 41792 0

kill(0x5F63, 0x9, 0x1) = 0 0

Others were more cryptic:

stat64(“/AppleInternal\0", 0x7FFF59EF8968, 0x0) = -1 Err#2

fcntl(0x3, 0x3D, 0x7FFF59EF6620) = 0 0

mmap(0x105D0B000, 0x2000, 0x5, 0x12, 0x3, 0x1000) = 0x105D0B000 0

And the rest were somewhere in between:

mprotect(0x105D11000, 0x88, 0x1) = 0 0

geteuid(0x7FFF59EF8820, 0x7FFF59EF8658, 0x0) = 0 0

pread(0x3, “\312\376\272\276\0", 0x1000, 0x0) = 4096 0

Read some kernel code

Time to pick a system call and find out one thing about it.

I had some trouble finding the source code for the Darwin kernel. Turns out its name is xnu. I downloaded the latest tarball and used ag to search for classics like chmod and SIGKILL.

The closest things I found to the implementation of chmod was libsyscall/wrappers/unix03/chmod.c. The comments indicate it’s a stub and only for UNIX03. The stub part makes sense because the code is just if statements. I don’t see the logic for how chmod actually works.

To be continued

At this point my brain (and hopefully yours) is overwhelmed with new knowledge about the kernel. I’ll cover some of Julia’s other strategies in subsequent blog posts. Fortunately, Apple has a Kernel Programming Guide with a section on how to add new modules.