Sunday, 3 June 2012

First contact


I started my first kernel module on mac os x just for fun. Pretty easy actually because xcode give you a nice template to start with as always. Just build it out of the box and copy your ext file to eg /tmp change the permission into root:wheel and chmod with 644. However there's one pitfall with the generated plist. The OSBundle key isn't proper filled in. Something the Apple guys forgot. Nevertheless the best thing is copy an existing plist from a another module and adapt with your executable name and references.  I took the /System/Library/Extensions/webdav_fs.kext and changed the fields in bold below. But in fact you just need the libkern and the mach bundles references for this simple project so you can add them in the xcode editor too if you like.

The beauty is that the kernel modules can be loaded and unloaded on the fly with following commands:

kextload <kext name>
kextunload <kext name>

Printf results can be viewed in the /var/log/kernel.log


Jun  3 21:32:30 Guy-Van-Overtveldts-iMac kernel[0]: kernel1_start: kernel module started ....
Jun  3 21:32:39 Guy-Van-Overtveldts-iMac kernel[0]: kernel1_stop: kernel module stopped ....



See below the two most important files:

kernel1.c


#include <mach/mach_types.h>
#include <libkern/libkern.h>

kern_return_t kernel1_start(kmod_info_t * ki, void *d);
kern_return_t kernel1_stop(kmod_info_t *ki, void *d);

kern_return_t kernel1_start(kmod_info_t * ki, void *d)
{
    printf("%s: kernel module started ....\n",__FUNCTION__);
    return KERN_SUCCESS;
}

kern_return_t kernel1_stop(kmod_info_t *ki, void *d)
{
    printf("%s: kernel module stopped ....\n",__FUNCTION__);
    return KERN_SUCCESS;
}


Info.plist


<?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>BuildMachineOSBuild</key>
        <string>11E29</string>
        <key>CFBundleDevelopmentRegion</key>
        <string>English</string>
        <key>CFBundleExecutable</key>
        <string>kernel1</string>
        <key>CFBundleIdentifier</key>
        <string>guy.kernel1</string>
        <key>CFBundleInfoDictionaryVersion</key>
        <string>6.0</string>
        <key>CFBundleName</key>
        <string>kernel1</string>
        <key>CFBundlePackageType</key>
        <string>KEXT</string>
        <key>CFBundleShortVersionString</key>
        <string>1.9.0</string>
        <key>CFBundleSignature</key>
        <string>????</string>
        <key>CFBundleVersion</key>
        <string>1.9.0</string>
        <key>DTCompiler</key>
        <string></string>
        <key>DTPlatformBuild</key>
        <string>11E29</string>
        <key>DTPlatformVersion</key>
        <string>GM</string>
        <key>DTSDKBuild</key>
        <string>11E29</string>
        <key>DTSDKName</key>
        <string></string>
        <key>DTXcode</key>
        <string>0410</string>
        <key>DTXcodeBuild</key>
        <string>11E29</string>
        <key>OSBundleAllowUserLoad</key>
        <true/>
        <key>OSBundleLibraries</key>
        <dict>
                <key>com.apple.kpi.libkern</key>
                <string>9.0.0</string>
                <key>com.apple.kpi.mach</key>
                <string>9.0.0</string>
        </dict>
</dict>
</plist>