将无代码的KEXT迁移到无代码的DEXT [英] Migrating a codeless KEXT to a codeless DEXT

查看:92
本文介绍了将无代码的KEXT迁移到无代码的DEXT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将无代码的KEXT迁移到无代码的DEXT.我观看了 WWDC 视频并阅读了 Apple Developer 网站上的许多信息.我遇到的困难不是找到要做什么,而是如何开始.一个很好的示例项目教程会有所帮助.

I am migrating a codeless KEXT to a codeless DEXT. I have watched the WWDC video and read much of the information on the Apple Developer site. The difficulty I am having is finding not what to do but how to get started. A nice tutorial with an example project would help.

在我的无代码KEXT中,对于4个单独的设备,我对每个设备都有IOUSBDevice和IOUSBInterface的IOKitPersonalities.KEXT允许我将设备与我的驱动程序"进行匹配.因此Apple HID驱动程序不会抓住它们.我希望在无代码的DEXT中执行相同或相似的操作.

In my codeless KEXT, for 4 separate devices I have IOKitPersonalities for IOUSBDevice and IOUSBInterface for each device. The KEXT allowed me to match my devices to my "driver" so the Apple HID driver wouldn't grab them. I wish to do the same or something similar in the codeless DEXT.

到目前为止,我已经在应用程序中创建了一个名为MyUsbDriver的DriverKit目标(用于DriverKit.framework),并添加了USBDriverKit.framework.这将MyUsbDriver文件夹添加到我的项目中,其中包含文件MyUsbDriver.cpp,MyUsbDriver.iig,Info.plist和MyUsbDriver.entitlements.这是我的问题:

So far, I have created a DriverKit target (for a DriverKit.framework) called MyUsbDriver in an app and added a USBDriverKit.framework. That added a folder MyUsbDriver to my project with files MyUsbDriver.cpp, MyUsbDriver.iig, Info.plist and MyUsbDriver.entitlements. Here are my questions:

  1. 对于USB来说,IOService的默认子类似乎可以-与KEXT中的IOClass相同.是真的吗?

  1. It looks like the default subclass of IOService is OK for USB - that is the same as the IOClass from the KEXT. Is that true?

DEXT世界中的IOUSBHostInterface是否等于KEXT世界中的IOUSBInterface?

Is IOUSBHostInterface in DEXT-world equivalent to IOUSBInterface in KEXT-world?

IOUSBHostDevice是否等于IOUSBDevice?

Is IOUSBHostDevice equivalent to IOUSBDevice?

对于无代码DEXT,我需要对.cpp或.iig做任何事情吗?我的大部分工作不是要在plist和授权文件中完成吗?

Do I need to do anything to the .cpp or .iig for codeless DEXT? Isn't most of my work to be done in the plist and entitlements files?

我的MyUsbDriver目标的框架和库中是否需要USBDriverKit.framework?

Do I need the USBDriverKit.framework in my Frameworks and Libraries of MyUsbDriver target?

在哪里可以找到如何完成此迁移的不错示例?

Where can I find a decent example of how to complete this migration?

任何帮助将不胜感激.

更新:

使用示例和答案中的其他链接,我可以将一些东西汇总在一起.我确实有一个"Doh"瞬间:我最初的测试项目类型是Command Line Tool,但我再也无法嵌入DEXT.我几乎只是手工编辑了pbxproj文件.但是,在查看Scott Knight最初的USBApp示例时,我意识到他使用的项目类型是App.事后看来,这是有道理的,但在当时令人困惑.

Using the example and other links in the answer I was able to get something together. I did have a "Doh" moment: My initial test project type was Command Line Tool and I could never get the DEXT to embed. I almost just hand-edited the pbxproj file. However, in looking at the original example USBApp from Scott Knight, I realized the project type he was using was App, In hindsight, that makes sense but at the time was confounding.

这是到目前为止我要在我们已弃用的设备之一上匹配的info.plist:

Here is the info.plist I have so far to match on one of our deprecated devices:

<?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>MyUsbDrver</key>
        <dict>
            <key>CFBundleIdentifier</key>
            <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
            <key>CFBundleIdentifierKernel</key>
            <string>com.apple.kpi.iokit</string>
            <key>IOClass</key>
            <string>IOUserService</string>
            <key>IOMatchCategory</key>
            <string>com.apple.null.driver</string>
            <key>IOProviderClass</key>
            <string>IOUsbHostInterface</string>
            <key>IOResourceMatch</key>
            <string>IOKit</string>
            <key>IOUserClass</key>
            <string>MyUsbDrver</string>
            <key>IOUserServerName</key>
            <string>Home.MyUsbDrver</string>
            <key>bConfigurationValue</key>
            <integer>1</integer>
            <key>bInterfaceNumber</key>
            <integer>0</integer>
            <key>idProduct</key>
            <integer>2</integer>
            <key>idVendor</key>
            <integer>5843</integer>
        </dict>
    </dict>
    <key>OSBundleUsageDescription</key>
    <string>Codless DEXT to match on IOKit.</string>
</dict>
</plist>

我不确定IOResourceMatch-值是IOKit,这是我要尝试的方向.

I am not sure about IOResourceMatch - the value is IOKit, which is the direction I am trying to go.

更新第二个:

进度!

我最终不得不手动更改pbxproj文件中的签名规定.禁用SIP,在我的应用程序中设置系统扩展激活/停用,并进行命令行签名.我发现此存储库对于一个不错的激活码Objective-C示例很有帮助- https://github.com/google/santa.git .一切构建和代码签名似乎都成功了.得到有趣的错误

I ended up having to manually change the signing provisions in my pbxproj file. Disabled SIP, set up System Extension activation/deactivation in my app and did command-line signing. I found this repository to be helpful with a decent Objective-C example for the activation code - https://github.com/google/santa.git. Everything builds and code signing seemed to be successful. Getting the fun error

SystemExtension "Home.MyUsbDrver" request did fail: Error Domain=OSSystemExtensionErrorDomain Code=8 "(null)"

更新3:

我检查了我的DEXT和应用程序权利,看来需要更新应用程序权利.这就是我现在要为应用程序准备的内容:

I checked my DEXT and app entitlements, and it looked like the app entitlements needed to be updated. This is what I have now for app:

<?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/>
    <key>com.apple.developer.system-extension.uninstall</key>
    <true/>
</dict>
</plist>

我错过了后两个.清理了我的项目,构建并再次签名.当我尝试从Xcode运行时,仍然出现错误.当我从 Finder 运行我的应用程序时,我得到了系统首选项对话框.在那之后,Xcode的结果仍然相同,现在从Finder运行时只剩下应用程序的闪光.我重新启动-仍然是相同的结果.但是,从终端运行systemextensionsctl -list时,我得到:

I was missing the bottom two. Cleaned my project, built, signed again. When I tried running from Xcode, still got the error. When I ran my app from Finder, I got the system preferences dialog. After that, still the same result from Xcode, and now nothing but a flash of the app when run from Finder. I rebooted - still the same results. However, from terminal when I run systemextensionsctl -list, I get:

3 extension(s)
--- com.apple.system_extension.driver_extension
enabled active  teamID  bundleID (version)  name    [state]
        <REDACTED>  Home.MyUsbDrver (1.0/1) Home.MyUsbDrver [terminated waiting to uninstall on reboot]
*   *   <REDACTED>  Home.MyUsbDrver (1.0/1) Home.MyUsbDrver [activated enabled]
        <REDACTED>  Home.MyUsbDrver (1.0/1) Home.MyUsbDrver [activated waiting to upgrade]

重新启动后,我得到了:

After a reboot I get this:

1 extension(s)
--- com.apple.system_extension.driver_extension
enabled active  teamID  bundleID (version)  name    [state]
*   *   <REDACTED>  Home.MyUsbDrver (1.0/1) Home.MyUsbDrver [activated enabled]

因此,看来我的系统扩展已经安装到位,但是实际上我不确定为什么,因为我刚刚重新启动并没有运行我的应用程序.

So, it looks like my system extension is in place, but I am actually not sure why since I just did a fresh reboot and have not run my app.

更新4:

我发现授权的问题仅仅是文件的格式.我在TextEdit中对其进行了更改,现在可以与我的设备进行通讯了.这就是我最终得到的:

I figured out the problem with my entitlements was just the format of the file. I changed it in TextEdit and I can now communicate with my device. Here is what I ended up with:

<?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.developer.driverkit</key>
    <true/>
    <key>com.apple.developer.driverkit.transport.usb</key>
    <array>
        <dict>
            <key>idVendor</key>
            <integer>VID0</integer>
            <key>idProductArray</key>
            <array>
                <integer>PID0</integer>
                <integer>PID1</integer>
                <integer>PID2</integer>
                <integer>PID3</integer>
                <integer>PID4</integer>
            </array>
        </dict>
    </array>
    <key>com.apple.security.app-sandbox</key>
    <true/>
</dict>
</plist>

推荐答案

我正在竭尽全力反对让同一件事起作用.最后,我设法获得了一个有效的DEXT,该DEXT禁用了Apple HID驱动程序以用于特定的供应商ID/产品ID组合.我们已经获得了供应商ID的DriverKit权利.

I was banging my head hard against getting the same thing to work. In the end I managed to get a working DEXT that disables the Apple HID driver for specific vendor ID/product ID combinations. We have obtained the DriverKit entitlement for our vendor ID.

  1. 看起来IOService的默认子类对于USB是可以的-与KEXT中的IOClass相同.是真的吗?

这对我有用.我尝试完全删除 .iig .cpp 文件,但是与KEXT不同,似乎需要编译一些代码才能使签名正常工作.因此,最后我得到的是 IOService 的空子类.

This worked for me. I tried removing the .iig and .cpp files completely, but unlike KEXTs, it seems that there needs to be some code compiled in order for signing to work properly. So I ended up with just an empty subclass of IOService.

  1. DEXT世界中的IOUSBHostInterface是否等于KEXT世界中的IOUSBInterface?

我相信.我使用了 IOUSBHostInterface ,并且在KEXT中使用了 IOUSBInterface .

I believe so. I used IOUSBHostInterface and we had IOUSBInterface in our KEXT.

  1. IOUSBHostDevice是否等于IOUSBDevice?

我不知道,但是我相信.

I don't know, but I believe so.

  1. 对于无代码 DEXT,我是否需要对 .cpp 或 .iig 执行任何操作?我的大部分工作不是要在plist和授权文件中完成吗?

我不需要更改 .cpp .iig 文件中的任何内容.您可能希望在释放它之前删除 .cpp 文件中的 os_log(OS_LOG_DEFAULT,"Hello World"); 行.但是在调试时,告诉我DEXT是否实际上正在加载对我很有用.您可以运行 log stream --source |grep'HELLO'在终端中查找日志.

I did not need to change anything in the .cpp and .iig files. You might want to delete the os_log(OS_LOG_DEFAULT, "Hello World"); line in the .cpp file before you release it. But while debugging, it was useful for me to tell whether the DEXT was actually loading or not. You can run log stream --source | grep 'HELLO' in a terminal to look for the log.

  1. 我的MyUsbDriver目标的框架和库中是否需要USBDriverKit.framework?

我的DEXT链接到 DriverKit.framework .我不知道是否需要.

My DEXT links against DriverKit.framework. I don't know if it's needed or not.

  1. 在哪里可以找到有关如何完成此迁移的不错的示例?

也许这些可以帮助您

在开发DriverKit扩展(dext)期间,请执行以下操作:

During development of a DriverKit extension (dext), do the following:

  • Disable system integrity protection (SIP): https://apple.stackexchange.com/a/208481/21491. (Reboot in recovery mode, run csrutil disable). Remember to enable it again!

通过运行 systemextensionsctl开发人员

确保没有安装旧的无代码KEXT.(从/Library/Extensions 和/或/System/Library/Extensions 中删除它.请确保随后重新启动)

Make sure you don't have your old codeless KEXT installed. (Delete it from /Library/Extensions and/or /System/Library/Extensions. Make sure to reboot afterwards)

  • 您可能需要一个包含DriverKit权利的手动配置文件.我认为我的问题是我获得了企业开发人员团队而不是公共开发团队的DriverKit权利.

  • You might need a manual provisioning profile that contains the DriverKit entitlements. I think my problem was that I got the DriverKit entitlement on an enterprise developer team instead of a team for public development.

加载扩展程序的应用需要使用系统扩展程序"权利,但不需要手动提供个人资料.

The app that loads the extension needs the "System Extension" entitlement, but does not need a manual provisining profile.

当心系统偏好设置"中的愚蠢错误.您需要同意在每次加载dext时加载它.但是,如果安全性和隐私"窗格已经打开,它不会显示同意按钮.您需要重新启动系统偏好设置"才能显示它.我一直在使用命令 pkill -9系统偏好设置";慷慨地从终端打开/System/Library/PreferencePanes/Security.prefPane 可以解决此问题.

Be ware of a stupid bug in System Preferences. You need to consent to loading the dext every time it gets loaded. However, if the "Security & Privacy" pane is already open, it will not show the button to give the consent. You need to restart System Preferences for it to show up. I've been using the command pkill -9 "System Preferences"; open /System/Library/PreferencePanes/Security.prefPane from Terminal generously to workaround this.

您可以使用 systemextensionsctl 卸载dext或重置系统状态.但是,这实际上并不会更改驱动程序匹配项,因此您需要重新启动.慷慨.我之所以使用此终端命令是因为我很懒: osascript -e'告诉应用程序系统事件"重新启动".

You can use systemextensionsctl to uninstall the dext or reset the system state. However, this does not actually change the driver matching, so you need to reboot. Generously. I used this Terminal command because I'm lazy: osascript -e 'tell app "System Events" to restart'.

您可以使用 ioreg 来检查设备是否与扩展名匹配:ioreg -lirc IOUSBHostInterface.

You can use ioreg to check whether devices are being matched to the extension or not: ioreg -lirc IOUSBHostInterface.

使扩展生效的关键是将 IOProviderClass 设置为在Info.plist文件中使用 IOUSBHostInterface 而不是 IOResources .(为了参考,KEXT使用 IOUSBInterface ,它是苹果已弃用)

The key to getting the extension to work is to set the IOProviderClass to IOUSBHostInterface instead of IOResources in the Info.plist file. (For reference, the KEXT uses IOUSBInterface which is one of the classes that Apple has deprecated)

您可能希望每次对DEXT进行更改时都在 Info.plist 中更改版本,以确保您实际上使用的是正确的版本.( systemextensionsctl 将显示其已加载的版本).

You might want to bump the version in Info.plist every time you make changes to your DEXT to make sure that you are actually using the correct one. (systemextensionsctl will show the version it has loaded).

这篇关于将无代码的KEXT迁移到无代码的DEXT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆