Re-routing System Calls

© Amit Singh. All Rights Reserved.Written in Early 2003

Why?

Re-routing (intercepting, modifying the arguments or results of, blocking, ...) system calls can be a powerful tool for doing "interesting" things with an operating system. It is more challenging (and therefore more fun, perhaps) on systems whose source is not available, such as Solaris, because the published APIs only tell you what goes in and what comes out - what happens within is not always known, or easy to find.

I once created a system call audit mechanism for Linux and later on used similar techniques while creating a virtualized version of the Solaris operating system. Darwin's source is available for most people to see, so it is possible to study how its system calls are implemented. Moreover, most of the calls are derived from BSD, so those familiar with FreeBSD, for example, should find it familiar.

Example

The sample code provided below implements a very simple Mac OS X kernel extension that essentially does the following:

The extension contains an implementation of open that copies the string representing the pathname of the file being opened from user space to kernel space, and prints a message containing the arguments passed to open. Thereafter, the function simply calls the original open through the saved reference.

Note that the messages printed by the kernel extension are logged in /var/log/system.log. All invocations of the open system call would result in a message being logged. Thus, you can simply do a tail -f /var/log/system.log and run something like cat /etc/resolv.conf to see the extension working.

Disclaimer

Please understand that loading unsupported kernel extensions into your operating system kernel is an inherently risky thing to do, and could result in a catastrophic data loss. The following code is unsupported. If you wish to download, compile, run or experiment with it, you must do so at your own risk.

Download