【问题标题】:Codeless kext to force a specific driver (CDC-ACM)强制使用特定驱动程序的无代码 kext (CDC-ACM)
【发布时间】:2016-02-02 04:21:12
【问题描述】:

我想知道是否有一种方法可以在 OS X 上以通用方式使用 USB 调制解调器(华为 E1550 种类),例如通用 USB 调制解调器。问题是操作系统不会将其识别为合法的 CDC ACM 设备(它是,但它没有宣传是这样的)。

在 Linux 上,加密狗被自动识别为 USB 串行设备。

我不想在我的任何机器上安装 ZTE 和华为供应商驱动程序是有原因的:这些人编写的东西几乎不能正常工作(我上次使用 ZTE 驱动程序的经历涉及向我的日志发送垃圾邮件、占用 RAM,而我无法禁用它),他们的驱动程序不向前兼容,他们忽略了将它们与较新的操作系统版本同步,并且他们通常打算将这些驱动程序与运营商膨胀软件一起分发。

Apple 的开发人员文档以模糊的方式写道,可以编写无代码 kext 以强制匹配设备上的特定驱动程序,或阻止为匹配设备加载通用驱动程序。事实上,大多数对无代码 kext 的搜索都会产生诸如“如何防止我的串行加密狗被识别为调制解调器?”之类的问题,而我想要的却完全相反!

到目前为止,我编写这样一个无代码 kext 的尝试以失败告终 - kextutil 告诉 kext 已成功加载,但它不存在,AppleCDCACM.kext 也是如此(它具有我想要使用的 IOClass)。

JFYI,从 Linux 收集的 lsusb 信息:

Bus 004 Device 005: ID 12d1:1001 华为技术有限公司 E169/E620/E800 HSDPA Modem 设备描述符: b长度 18 bDescriptorType 1 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 idVendor 0x12d1 华为技术有限公司 idProduct 0x1001 E169/E620/E800 HSDPA 调制解调器 bcdDevice 0.00 iManufacturer 2 华为技术 iProduct 1 华为手机 iSerial 0 bNumConfigurations 1 配置描述符: b长度 9 bDescriptorType 2 w总长度 85 bNumInterfaces 3 b配置值 1 iConfiguration 3 高通配置 bm属性 0xe0 自供电 远程唤醒 最大功率 500mA 接口描述符: b长度 9 bDescriptorType 4 b接口编号 0 b备用设置 0 bNumEndpoints 3 bInterfaceClass 255 供应商特定类 bInterfaceSubClass 255 供应商特定子类 bInterfaceProtocol 255 供应商特定协议 接口 0 端点描述符: b长度 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bm属性 3 传输类型中断 同步类型 无 使用类型数据 wMaxPacketSize 0x0040 1x 64 字节 b 间隔 5 端点描述符: b长度 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bm属性 2 传输类型散装 同步类型 无 使用类型数据 wMaxPacketSize 0x0200 1x 512 字节 b 间隔 32 端点描述符: b长度 7 bDescriptorType 5 bEndpointAddress 0x01 EP 1 OUT bm属性 2 传输类型散装 同步类型 无 使用类型数据 wMaxPacketSize 0x0200 1x 512 字节 b 间隔 32 接口描述符: b长度 9 bDescriptorType 4 b接口编号 1 b备用设置 0 bNumEndpoints 2 bInterfaceClass 255 供应商特定类 bInterfaceSubClass 255 供应商特定子类 bInterfaceProtocol 255 供应商特定协议 接口 0 端点描述符: b长度 7 bDescriptorType 5 bEndpointAddress 0x83 EP 3 IN bm属性 2 传输类型散装 同步类型 无 使用类型数据 wMaxPacketSize 0x0200 1x 512 字节 b 间隔 32 端点描述符: b长度 7 bDescriptorType 5 bEndpointAddress 0x02 EP 2 OUT bm属性 2 传输类型散装 同步类型 无 使用类型数据 wMaxPacketSize 0x0200 1x 512 字节 b 间隔 32 接口描述符: b长度 9 bDescriptorType 4 b接口编号 2 b备用设置 0 bNumEndpoints 2 bInterfaceClass 255 供应商特定类 bInterfaceSubClass 255 供应商特定子类 bInterfaceProtocol 255 供应商特定协议 接口 0 端点描述符: b长度 7 bDescriptorType 5 bEndpointAddress 0x84 EP 4 IN bm属性 2 传输类型散装 同步类型 无 使用类型数据 wMaxPacketSize 0x0200 1x 512 字节 b 间隔 32 端点描述符: b长度 7 bDescriptorType 5 bEndpointAddress 0x03 EP 3 OUT bm属性 2 传输类型散装 同步类型 无 使用类型数据 wMaxPacketSize 0x0200 1x 512 字节 b 间隔 32 设备限定符(用于其他设备速度): b长度 10 bDescriptorType 6 bcdUSB 2.00 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 64 bNumConfigurations 1 无法获取调试描述符:资源暂时不可用 设备状态:0x0001 自供电

我要连接的接口是接口 0(调制解调器)。

ioreg 是这样看的:

 | | | | | +-o 华为手机@1d110000
    | | | | | +-o AppleUSBHostLegacyClient
    | | | | | +-o AppleUSBHostCompositeDevice
    | | | | | +-o IOUSBHostInterface@0
    | | | | | | {
    | | | | | | “USB端口类型”= 0
    | | | | | | "IOCFPlugInTypes" = {​​"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
    | | | | | | "bcdDevice" = 0
    | | | | | | “USB 速度” = 3
    | | | | | | “idProduct” = 4097
    | | | | | | “bConfigurationValue” = 1
    | | | | | | “bInterfaceSubClass” = 255
    | | | | | | “位置 ID”= 487653376
    | | | | | | "IOGeneralInterest" = "IOCommand 不可序列化"
    | | | | | | "IOClassNameOverride" = "IOUSBInterface"
    | | | | | | "AppleUSBAlternateServiceRegistryID" = 4294969542
    | | | | | | “idVendor”= 4817
    | | | | | | "bInterfaceProtocol" = 255
    | | | | | | “bAlternateSetting” = 0
    | | | | | | “bInterfaceNumber” = 0
    | | | | | | “bInterfaceClass” = 255
    | | | | | | }
    | | | | | |
    | | | | | +-o IOUSBHostInterface@1
    | | | | | | {
    | | | | | | “USB端口类型”= 0
    | | | | | | "IOCFPlugInTypes" = {​​"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
    | | | | | | "bcdDevice" = 0
    | | | | | | “USB 速度” = 3
    | | | | | | “idProduct” = 4097
    | | | | | | “bConfigurationValue” = 1
    | | | | | | “bInterfaceSubClass” = 255
    | | | | | | “位置 ID”= 487653376
    | | | | | | "IOGeneralInterest" = "IOCommand 不可序列化"
    | | | | | | "IOClassNameOverride" = "IOUSBInterface"
    | | | | | | "AppleUSBAlternateServiceRegistryID" = 4294969544
    | | | | | | “idVendor”= 4817
    | | | | | | "bInterfaceProtocol" = 255
    | | | | | | “bAlternateSetting” = 0
    | | | | | | “bInterfaceNumber” = 1
    | | | | | | “bInterfaceClass” = 255
    | | | | | | }
    | | | | | |
    | | | | | +-o IOUSBHostInterface@2
    | | | | | {
    | | | | | “USB端口类型”= 0
    | | | | | "IOCFPlugInTypes" = {​​"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
    | | | | | "bcdDevice" = 0
    | | | | | “USB 速度” = 3
    | | | | | “idProduct” = 4097
    | | | | | “bConfigurationValue” = 1
    | | | | | “bInterfaceSubClass” = 255
    | | | | | “位置 ID”= 487653376
    | | | | | "IOGeneralInterest" = "IOCommand 不可序列化"
    | | | | | "IOClassNameOverride" = "IOUSBInterface"
    | | | | | "AppleUSBAlternateServiceRegistryID" = 4294969546
    | | | | | “idVendor”= 4817
    | | | | | "bInterfaceProtocol" = 255
    | | | | | “bAlternateSetting” = 0
    | | | | | “bInterfaceNumber” = 2
    | | | | | “bInterfaceClass” = 255
    | | | | | }
    | | | | |

到目前为止,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>BuildMachineOSBuild</key>
    <string>15C27b</string>
    <key>CFBundleDevelopmentRegion</key>
    <string>English</string>
    <key>CFBundleIdentifier</key>
    <string>name.fedevych.GenericWWAN</string>
    <key>CFBundleInfoDictionaryVersion</key>
    <string>6.0</string>
    <key>CFBundleName</key>
    <string>GenericWWAN</string>
    <key>CFBundlePackageType</key>
    <string>KEXT</string>
    <key>CFBundleShortVersionString</key>
    <string>99.0.0</string>
    <key>CFBundleSignature</key>
    <string>????</string>
    <key>CFBundleSupportedPlatforms</key>
    <array>
        <string>MacOSX</string>
    </array>
    <key>CFBundleVersion</key>
    <string>99.0.0</string>
    <key>IOKitPersonalities</key>
    <dict>
        <key>HUAWEI_0x12d11001_Control</key>
        <dict>
            <key>CFBundleIdentifier</key>
            <string>com.apple.driver.usb.cdc.acm</string>
            <key>IOClass</key>
            <string>AppleUSBACMControl</string>
            <key>IOProviderClass</key>
            <string>IOUSBHostInterface</string>

            <key>idVendor</key>
            <integer>4817</integer>
            <key>idProduct</key>
            <integer>4097</integer>
            <key>bcdDevice</key>
            <integer>0</integer>

            <key>bInterfaceNumber</key>
            <integer>0</integer>
            <key>bConfigurationValue</key>
            <integer>1</integer>

            <key>IOMatchCategory</key>
            <string>com.apple.driver.AppleUSBACMControl</string>
        </dict>
        <key>HUAWEI_0x12d11001_Data</key>
        <dict>
            <key>CFBundleIdentifier</key>
            <string>com.apple.driver.usb.cdc.acm</string>
            <key>IOClass</key>
            <string>AppleUSBACMData</string>
            <key>IOProviderClass</key>
            <string>IOUSBHostInterface</string>

            <key>idVendor</key>
            <integer>4817</integer>
            <key>idProduct</key>
            <integer>4097</integer>
            <key>bcdDevice</key>
            <integer>0</integer>

            <key>bInterfaceNumber</key>
            <integer>0</integer>
            <key>bConfigurationValue</key>
            <integer>1</integer>

        </dict>
    </dict>
    <key>OSBundleLibraries</key>
    <dict/>
</dict>
</plist>

任何指针?

【问题讨论】:

    标签: macos serial-port modem cdc kernel-extension


    【解决方案1】:

    所以,我不能保证您的项目会成功 - 我不知道您的调制解调器是否可以与标准 CDC 驱动程序一起使用。但我希望能帮助你找出答案。这实际上有 5 个部分:

    1. 与相关设备/接口匹配的正确匹配字典。
    2. 为实际驱动程序设置正确的类和包 ID。
    3. 在无代码 kext 的 info.plist 中需要注意的一些额外点
    4. Kext 签名。
    5. 加载/调试。

    I/O 套件 USB 匹配

    Apple 的Q&A QA1076 是该主题的最佳资源。我建议尽可能具体。所以在你的情况下,例如:

    IOProviderClass: IOUSBInterface
    idVendor: 0x12d1
    idProduct: 0x1001
    bInterfaceNumber: 0
    bConfigurationValue: 1
    

    我希望我是对的。插入设备后,您应该能够通过在终端中运行ioreg -c IOUSBInterface 来确认。这将以 OSX 格式显示系统中所有 USB 接口的属性,并且您应该能够为您的调制解调器选择一个并确保这些属性与我给出的匹配。

    驱动程序类和包 ID

    除了匹配条件之外,info.plist 中的 I/O Kit 个性字典还需要指定应创建实例以驱动匹配设备的 (C++) 类,以及包含它的 kext。

    现在的问题是,使用什么驱动程序。我对 CDC-ACM 设备了解不多,但据我所知,它们由一个控件和一个数据接口组成。其驱动因素似乎是

    /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBCDCACMControl.kext
    /System/Library/Extensions/IOUSBFamily.kext/Contents/PlugIns/AppleUSBCDCACMData.kext
    

    分别在 OSX 上。其中每一个似乎都假设他们可以完全控制 USB 接口 - 似乎大多数设备将控制和数据端点拆分为 2 个单独的接口。在你的情况下,你只有一个。从技术上讲,多个驱动程序可以通过使用不同的匹配类别来匹配服务。但我不能保证 CDC-ACM 数据和控制驱动程序会对此感到满意。你可以试试……

    为此,您实际上需要两个具有相同匹配标准的 I/O 套件个性字典,但其中一个应该具有非默认 IOMatchCategory,例如相关的驱动程序包 ID。

    所以试试这样的:

    <key>IOKitPersonalities</key>
    <dict>
        <key>AppleUSBCDCACMControl</key>
        <dict>
            <key>CFBundleIdentifier</key>
            <string>com.apple.driver.AppleUSBCDCACMControl</string>
            <key>IOClass</key>
            <string>AppleUSBCDCACMControl</string>
            <key>IOProviderClass</key>
            <string>IOUSBInterface</string>
            <key>idVendor</key>
            <integer>4817</integer>
            <key>idProduct</key>
            <integer>4097</integer>
            <key>bInterfaceNumber</key>
            <integer>0</integer>
            <key>bConfigurationValue</key>
            <integer>1</integer>
            <key>IOMatchCategory</key>
            <string>com.apple.driver.AppleUSBCDCACMControl</string>
        </dict>
        <key>AppleUSBCDCACMData</key>
        <dict>
            <key>CFBundleIdentifier</key>
            <string>com.apple.driver.AppleUSBCDCACMData</string>
            <key>IOClass</key>
            <string>AppleUSBCDCACMData</string>
            <key>IOProviderClass</key>
            <string>IOUSBInterface</string>
            <key>IOUserClientClass</key>
            <string>AppleUSBCDCACMDataUserClient</string>
            <key>InputBuffers</key>
            <integer>8</integer>
            <key>OutputBuffers</key>
            <integer>16</integer>
            <key>idVendor</key>
            <integer>4817</integer>
            <key>idProduct</key>
            <integer>4097</integer>
            <key>bInterfaceNumber</key>
            <integer>0</integer>
            <key>bConfigurationValue</key>
            <integer>1</integer>
        </dict>
    </dict>
    

    无代码 kext info.plist

    由于您已经有了一个 kextutil 似乎喜欢的 kext,您可能已经做对了:无代码 kexts 必须:

    • 有一个空的OSBundleLibraries 属性。
    • 没有CFBundleExecutable 属性。

    Kext 签名

    在 OSX 10.10 和 10.11 上,所有 kext,包括无代码的,都必须签名。在 10.9 上,如果它们驻留在 /System/Library/Extensions 中,它们可以是未签名的,而在 10.10 上,如果设置了内核选项 kext-dev-mode=1,它们可以是未签名的。您需要在 Apple 的 Developer Id 证书上添加一个特殊的 kext 签名才能对 kexts 进行签名。

    加载和调试

    /System/Library/Extensions(可写到 10.10)或 /Library/Extensions (10.9+) 中的 Kext 将在启动或设备热插拔时自动匹配。也可以使用kextutil 从这些位置之外手动加载它们。

    加载的 kext 二进制文件列在kextstat 的输出中。 Codeless kexts 没有二进制文件,因此不会出现。但是,如果 I/O Kit Personality 的 CFBundleIdentifier 中指定的包含驱动程序代码的包处于活动状态,则会显示它。

    要查看您的特定设备发生的情况,请使用ioreg 命令行工具或 GUI 工具 IORegistryExplorer(来自 Apple 的硬件 I/O 工具包)或 IOJones(开源)。

    最后的想法

    鉴于 CDC-ACM 控制/数据拆分,您可能无法仅使用无代码 kext 来完成工作。您可能需要更深入地了解 Apple 驱动程序的工作方式,并可能在您自己的 kext 中覆盖它们的一些行为,以便它们找到正确的端点。祝你好运!

    【讨论】:

    • 一件事...在 10.11,我看到 /S/L/E/AppleUSBCDC.kext、/S/L/E/AppleUSBACM.kext 和其他 ECM、EEM 甚至 NCM和 WCM(!!!)。另外,我不知道 Apple 的驱动程序是否已经在控制和数据之间分开了,因为 10.11 的消息来源还没有。另外,现在想知道为什么还没有 QMI 或 MBIM,ECM/NCM/WCM 最初打算部署在哪里。
    • 糟糕,我错了。仍然有两个用于控制和数据的类,只是在一个可执行文件中。
    • 啊,抱歉,我的主要 MBP 仍在 10.10.5 上,我没有意识到他们在 10.11 中改变了一些东西。但听起来其他一切仍然存在。祝 2 位驱动程序仅使用一个界面即可!
    • kext加载成功,但设备不匹配。对于 10.9.4 之后的任何内容,都没有日志记录 IOUSBFamily。
    • 添加了 Info.plist。似乎我现在无法匹配设备(甚至没有加载 CDC 驱动程序)。根据 Apple 文档,它们应该匹配(idVendor + idProduct + bcdDevice + bConfigurationValue + bInterfaceNumber)。会不会是类、子类和协议都是 255(因此可能需要其他键,或者我读错了)?
    猜你喜欢
    • 2016-11-11
    • 1970-01-01
    • 2019-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-08
    • 1970-01-01
    • 2017-10-20
    相关资源
    最近更新 更多