如何在 DriverKit 中将我的 dex 与 USB 设备匹配?
我正在编写一个驱动程序包扩展,其目标是阻止 USB 设备,例如闪存驱动器。作为起点,我选择了 https://developer.apple 的示例项目。 com/documentation/driverkit/communicating_ Between_a_driverkit_extension_and_a_client_app?language=objc
为了不禁用键盘或者鼠标,首先我尝试将我的 dext 与单个具体 USB 驱动器相匹配,我在注册表中找到了其供应商 ID(注意十六进制到十进制的转换)。问题是,当插入闪存驱动器时,系统与我的 dext 不匹配,并继续使用系统 1。
怎么了?为此需要配置配置文件吗?是否可以通过这种方式匹配任何设备?
驱动程序的权利文件:
<?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.usb</key>
<array>
<dict>
<key>idVendor</key>
<integer>9128</integer>
</dict>
</array>
</dict>
</plist>
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>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>IOKitPersonalities</key>
<dict>
<key>DeviceControlDriver</key>
<dict>
<key>idVendor</key>
<integer>9128</integer>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleIdentifierKernel</key>
<string>com.apple.kpi.iokit</string>
<key>IOClass</key>
<string>IOUserService</string>
<key>IOProviderClass</key>
<string>IOUSBHostDevice</string>
<key>IOUserClass</key>
<string>DeviceControlDriver</string>
<key>IOUserServerName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>UserClientProperties</key>
<dict>
<key>IOClass</key>
<string>IOUserUserClient</string>
<key>IOUserClass</key>
<string>DeviceControlDriver</string>
</dict>
</dict>
</dict>
<key>OSBundleUsageDescription</key>
<string></string>
</dict>
</plist>
I am writing a driverkit extension whose goal is to block USB devices, such as flash drives. As a starting point, I chose example project at https://developer.apple.com/documentation/driverkit/communicating_between_a_driverkit_extension_and_a_client_app?language=objc
In effort not to disable a keyboard or a mouse, firstly I am trying to match my dext with a single concrete USB drive, whose vendorId I found in the registry (being aware of hexa to decimal conversions). The problem is that when the flash drive is plugged in, the system doesn't match my dext and continues with the system one.
What's wrong? Is a provisioning profile required for this? Is it even possible to match any device this way?
Driver's entitlement file:
<?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.usb</key>
<array>
<dict>
<key>idVendor</key>
<integer>9128</integer>
</dict>
</array>
</dict>
</plist>
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>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>$(PRODUCT_BUNDLE_PACKAGE_TYPE)</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleVersion</key>
<string>1</string>
<key>IOKitPersonalities</key>
<dict>
<key>DeviceControlDriver</key>
<dict>
<key>idVendor</key>
<integer>9128</integer>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleIdentifierKernel</key>
<string>com.apple.kpi.iokit</string>
<key>IOClass</key>
<string>IOUserService</string>
<key>IOProviderClass</key>
<string>IOUSBHostDevice</string>
<key>IOUserClass</key>
<string>DeviceControlDriver</string>
<key>IOUserServerName</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>UserClientProperties</key>
<dict>
<key>IOClass</key>
<string>IOUserUserClient</string>
<key>IOUserClass</key>
<string>DeviceControlDriver</string>
</dict>
</dict>
</dict>
<key>OSBundleUsageDescription</key>
<string></string>
</dict>
</plist>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里有几个子问题,我将尝试单独解决它们:
macOS 上的 USB 设备匹配遵循非常特定的规则。如果您不遵循 Apple 的此文档中概述的匹配模式之一,匹配通常会失败。
您正在尝试单独匹配
idVendor
;这不起作用,您需要匹配idVendor + idProduct
或列出的其他模式之一。如果您希望分发您的驱动程序,或者甚至在启用 SIP 的情况下在本地运行它,您将需要一个配置文件。请注意,Apple 通常仅针对特定请求的供应商 ID 颁发权利;如果您的需求超出此范围,您需要直接与 Apple 联系。
对于没有有效代码签名的本地测试,可以禁用SIP;您仍然需要在签名中包含有效的嵌入权利,但您可以使用与权利不匹配的配置文件。
请注意,这效果有限,因为在早期系统启动期间不会考虑匹配第 3 方 kext 和 DriverKit 扩展 。这意味着任何可由 Apple 驱动程序声明且在 macOS 启动时已连接的设备将始终与 Apple 自己的驱动程序匹配,而不是您的驱动程序。
对于 USB,您可以通过使用 强制重新枚举来在一定程度上解决此问题
USBDeviceReEnumerate
函数。请注意,这模拟了硬拔出,因此对于已安装的存储设备,您应该首先彻底卸载。There are a few sub-questions here, and I'll try to address them individually:
Matching USB devices on macOS follows very specific rules. If you do not follow one of the matching patterns outlined in this documentation from Apple, matching will generally fail.
You're attempting to match on
idVendor
alone; this will not work, you will need to match on eitheridVendor + idProduct
or one of the other patterns listed.If you wish to distribute your driver, or even run it locally with SIP enabled, you will require a provisioning profile. Note that Apple generally issues entitlements for specific requested vendor IDs only; if your needs go beyond that you'll need to get in touch with Apple directly.
For local testing without valid code signing, you can disable SIP; you will still require valid embedded entitlements in the signature, but you can use a provisioning profile which doesn't match the entitlements.
Note that this will be of somewhat limited effectiveness, as 3rd party kexts and DriverKit extensions are not considered for matching during early system boot. This means that any devices which can be claimed by Apple's drivers and which are already connected at the time macOS starts up will always match Apple's own drivers, not yours.
For USB, you can to some extent work around this by forcing re-enumeration using the
USBDeviceReEnumerate
function. Note that this simulates a hard unplug, so for mounted storage devices, you should unmount cleanly first, for example.