Search code examples
macosiokitkernel-extension

Kext does not work in macOS 10.12.6 (16G1114)


I followed the tutorial here

I can see my kext by command: sudo kextload /tmp/MyDriver.kext && kextstat | grep My

console:

144 0 0xffffff7f832af000 0x2000 0x2000 com.MyCompany.driver.MyDriver (1) 54793E2C-195A-3CE9-9655-9F68562401BF <4 3>

But I cannot find any log either in /var/log/system.log or log stream --predicate 'eventMessage contains "My"'

I tried to trigger a panic.

volatile char *kernel_panic = NULL;
volatile char message = *kernel_panic;

And of course, nothing happens :|

Maybe some useful info:

csrutil status : System Integrity Protection status: disabled.

After a few minute, my kext disappear from kextstat (what :O)

kextutil -nt /tmp/MyDriver.kext

Code Signing Failure: code signature is invalid
/tmp/MyDriver.kext appears to be loadable (including linkage for on-disk libraries).

EDIT

Source code is copied from tutorial

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>CFBundleDevelopmentRegion</key>
    <string>$(DEVELOPMENT_LANGUAGE)</string>
    <key>CFBundleExecutable</key>
    <string>$(EXECUTABLE_NAME)</string>
    <key>CFBundleIdentifier</key>
    <string>com.MyCompany.driver.${PRODUCT_NAME:rfc1034identifier}</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>$(PRODUCT_NAME)</string>
    <key>CFBundlePackageType</key>
    <string>KEXT</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>IOKitPersonalities</key>
    <dict>
        <key>MyDriver</key>
        <dict>
            <key>IOProviderClass</key>
            <string>IOResources</string>
            <key>IOMatchCategory</key>
            <string>com_MyCompany_driver_MyDriver</string>
            <key>IOKitDebug</key>
            <integer>65535</integer>
            <key>IOClass</key>
            <string>com_MyCompany_driver_MyDriver</string>
            <key>CFBundleIdentifier</key>
            <string>com.MyCompany.driver.${PRODUCT_NAME:rfc1034identifier}</string>
        </dict>
    </dict>
    <key>NSHumanReadableCopyright</key>
    <string>Copyright © 2018 bu9. All rights reserved.</string>
    <key>OSBundleLibraries</key>
    <dict>
        <key>com.apple.kpi.iokit</key>
        <string>16.7</string>
        <key>com.apple.kpi.libkern</key>
        <string>16.7</string>
    </dict>
</dict>
</plist>

MyDriver.hpp

/* add your code here */

#include <IOKit/IOService.h>
class com_MyCompany_driver_MyDriver : public IOService
{
    OSDeclareDefaultStructors(com_MyCompany_driver_MyDriver)
public:
    virtual bool init(OSDictionary *dictionary = 0) override;
    virtual void free(void) override;
    virtual IOService *probe(IOService *provider, SInt32 *score) override;
    virtual bool start(IOService *provider) override;
    virtual void stop(IOService *provider) override;
};

MyDriver.cpp

/* add your code here */
#include <IOKit/IOLib.h>
#include "MyDriver.hpp"

// This required macro defines the class's constructors, destructors,
// and several other methods I/O Kit requires.
OSDefineMetaClassAndStructors(com_MyCompany_driver_MyDriver, IOService)

// Define the driver's superclass.
#define super IOService

bool com_MyCompany_driver_MyDriver::init(OSDictionary *dict)
{
    bool result = super::init(dict);
    IOLog("MyDriver::Initializing\n");
    return result;
}

void com_MyCompany_driver_MyDriver::free(void)
{
    IOLog("MyDriver::Freeing\n");
    super::free();
}

IOService *com_MyCompany_driver_MyDriver::probe(IOService *provider,
                                                SInt32 *score)
{
    IOService *result = super::probe(provider, score);
    IOLog("MyDriver::Probing\n");
    return result;
}

bool com_MyCompany_driver_MyDriver::start(IOService *provider)
{
    bool result = super::start(provider);
    IOLog("MyDriver::Starting\n");
    volatile char *kernel_panic = NULL;
volatile char message = *kernel_panic;
    return result;
}

void com_MyCompany_driver_MyDriver::stop(IOService *provider)
{
    IOLog("MyDriver::Stopping\n");
    super::stop(provider);
}

p/s: apple contains a lot of unused or old info.


Solution

  • It sounds like you're making an IOKit kext. IOKit kexts are automatically unloaded by the system if no class instances from that kext are live. So that explains the unloading.

    The reasons why there are no instances are either:

    • Whatever IOKitPersonalities you were expecting to appear have not appeared, because they didn't match anything, or because your matching dictionary is not valid. What's your IOKitPersonalities dictionary from Info.plist?
    • Creating the instance failed. This can be because the class is incomplete (your class is accidentally abstract or you haven't got the correct OSMetaClass boilerplate), or because something along the init-probe-attach-start sequence is returning an error.

    The code signing failure is not a problem if SIP is disabled, and indeed your kext would not show in kextstat if lack of correct signature was preventing it from loading.

    You will need to post more code if you would like some more specific help.