Kext 在 macOS 10.12.6 (16G1114) 中不工作

Kext does not work in macOS 10.12.6 (16G1114)

我按照教程做了 here

我可以通过命令查看我的kext:sudo kextload /tmp/MyDriver.kext && kextstat | grep My

控制台:

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

但我在 /var/log/system.loglog stream --predicate 'eventMessage contains "My"'

中找不到任何日志

我试图触发 panic

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

当然,什么也没有发生:|

也许是一些有用的信息:

csrutil status : System Integrity Protection status: disabled.

几分钟后,我的 kext 从 kextstat 中消失了(什么 :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).

编辑

源代码复制自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 包含大量未使用或旧信息。

听起来你在制作 IOKit kext。如果 IOKit kext 没有 class 个来自该 kext 的实例处于活动状态,则系统会自动卸载该 kext。这样就解释了卸载。

没有实例的原因有:

  • 您期望出现的任何 IOKitPersonalities 都没有出现,因为它们没有匹配任何内容,或者因为您的匹配字典无效。 Info.plist 中的 IOKitPersonalities 字典是什么?
  • 创建实例失败。这可能是因为 class 不完整(您的 class 不小心是抽象的,或者您没有获得正确的 OSMetaClass 样板),或者因为 init-probe -attach-start 序列返回错误。

如果 SIP 被禁用,代码签名失败不是问题,事实上,如果缺少正确的签名阻止加载,您的 kext 将不会显示在 kextstat 中。

如果您需要更具体的帮助,您将需要 post 更多代码。