我正在尝试在 DriverKit 中编写一个用户空间 PCI 驱动程序,用于教育/研究目的。我找到了一个来自 WorthDoingBadly 的示例其中包含 PCI 设备 dext 的样板代码(我已删除了漏洞利用代码)。
我已将其修改为通过以下方式匹配 Thunderbolt PCI NVMe 设备IOPCIPrimaryMatch
钥匙。我已经能够在禁用 SIP 的情况下编译、签名和加载它systemextensionsctl developer on
.
当我的设备插入电源时就会出现问题Start
我的驱动程序中的函数被调用。我尝试打电话ivars->pciDevice->Open(this, 0);
在设备上,失败并显示0xe00002cd
“(iokit/common)设备未打开”。
同时,我可以在内核日志中看到,当调用我的驱动程序时,内置 NVMe 驱动程序已经在初始化。
如果我跳过呼叫Open
只需致电RegisterService();
,我可以在 IORegistryExplorer.app 中看到,IONVMeController 和我的“PCICrash”都列在 PCI 设备下。
我推测,如果我可以阻止内置 NVMe 驱动程序占用设备,我的驱动程序就可以工作。这有可能吗?
作为参考,我的 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>IOKitPersonalities</key>
<dict>
<key>PCICrash</key>
<dict>
<key>IOClass</key>
<string>IOUserService</string>
<key>IOProviderClass</key>
<string>IOPCIDevice</string>
<key>IOUserClass</key>
<string>PCICrash</string>
<key>IOUserServerName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>IOPCIPrimaryMatch</key>
<string>0x25228086</string>
<key>IOPCITunnelCompatible</key>
<true/>
</dict>
</dict>
</dict>
</plist>
这是驱动程序的 PCICrash.entitlements:
<?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>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.developer.driverkit</key>
<true/>
<key>com.apple.developer.driverkit.transport.pci</key>
<true/>
<key>com.apple.developer.driverkit.transport.pci.bridge</key>
<true/>
<key>com.apple.developer.driverkit.allow-any-userclient-access</key>
<true/>
</dict>
</plist>
这是应用程序的 PCICrashApp.entitlements:
<?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>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
<key>com.apple.developer.system-extension.install</key>
<true/>
</dict>
</plist>
我在 Xcode 中构建而不进行签名(与 WorthDoingBadly 的设置相同),然后运行以下命令:
$ codesign -s - -f --entitlements "PCICrash/PCICrash.entitlements" "[...]/PCICrashApp.app/Contents/Library/SystemExtensions/com.worthdoingbadly.PCICrashApp.PCICrash.dext"
$ codesign -s - -f --entitlements "PCICrashApp/PCICrashApp.entitlements" "[...]/PCICrashApp.app"
$ systemextensionsctl reset
$ [...]/PCICrashApp.app/Contents/MacOS/PCICrashApp
2023-05-08 18:28:17.810 PCICrashApp[3438:81755] requestNeedsUserApproval
2023-05-08 18:28:23.152 PCICrashApp[3438:81755] didFinishWithResult: 0
A view of IORegistryExplorer. It starts out with white text, upon loading the app and registering the extension, it resets the device, and reattaches it using the stock NVMe driver. Maybe this could be explained by a crashing driver.