无代码kext强制特定驱动程序(CDC-ACM)

时间:2015-11-02 10:00:25

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

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

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

有理由我不想在我的任何机器上使用中兴和华为供应商的驱动程序:这些人写的东西几乎不起作用(我上次与中兴通讯驱动程序的经历涉及垃圾邮件我的日志,占用内存,我无法为了禁用它们,它们的驱动程序不是向前兼容的,它们忽略了将它们与更新的操作系统版本同步,并且它们通常打算使用运营商英国媒体报道来分发这些驱动程序。

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

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

JFYI,从Linux收集的lsusb信息:

Bus 004 Device 005: ID 12d1:1001 Huawei Technologies Co., Ltd. E169/E620/E800 HSDPA Modem
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x12d1 Huawei Technologies Co., Ltd.
  idProduct          0x1001 E169/E620/E800 HSDPA Modem
  bcdDevice            0.00
  iManufacturer           2 HUAWEI Technology
  iProduct                1 HUAWEI Mobile
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           85
    bNumInterfaces          3
    bConfigurationValue     1
    iConfiguration          3 Qualcomm Configuration
    bmAttributes         0xe0
      Self Powered
      Remote Wakeup
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               5
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval              32
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval              32
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval              32
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval              32
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        2
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass    255 Vendor Specific Subclass
      bInterfaceProtocol    255 Vendor Specific Protocol
      iInterface              0 
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x84  EP 4 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval              32
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x03  EP 3 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval              32
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  bNumConfigurations      1
can't get debug descriptor: Resource temporarily unavailable
Device Status:     0x0001
  Self Powered

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

以下是ioreg看到它的方式:

   | |   |       | | +-o HUAWEI Mobile@1d110000  
    | |   |       | |   +-o AppleUSBHostLegacyClient  
    | |   |       | |   +-o AppleUSBHostCompositeDevice  
    | |   |       | |   +-o IOUSBHostInterface@0  
    | |   |       | |   |   {
    | |   |       | |   |     "USBPortType" = 0
    | |   |       | |   |     "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
    | |   |       | |   |     "bcdDevice" = 0
    | |   |       | |   |     "USBSpeed" = 3
    | |   |       | |   |     "idProduct" = 4097
    | |   |       | |   |     "bConfigurationValue" = 1
    | |   |       | |   |     "bInterfaceSubClass" = 255
    | |   |       | |   |     "locationID" = 487653376
    | |   |       | |   |     "IOGeneralInterest" = "IOCommand is not serializable"
    | |   |       | |   |     "IOClassNameOverride" = "IOUSBInterface"
    | |   |       | |   |     "AppleUSBAlternateServiceRegistryID" = 4294969542
    | |   |       | |   |     "idVendor" = 4817
    | |   |       | |   |     "bInterfaceProtocol" = 255
    | |   |       | |   |     "bAlternateSetting" = 0
    | |   |       | |   |     "bInterfaceNumber" = 0
    | |   |       | |   |     "bInterfaceClass" = 255
    | |   |       | |   |   }
    | |   |       | |   |   
    | |   |       | |   +-o IOUSBHostInterface@1  
    | |   |       | |   |   {
    | |   |       | |   |     "USBPortType" = 0
    | |   |       | |   |     "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
    | |   |       | |   |     "bcdDevice" = 0
    | |   |       | |   |     "USBSpeed" = 3
    | |   |       | |   |     "idProduct" = 4097
    | |   |       | |   |     "bConfigurationValue" = 1
    | |   |       | |   |     "bInterfaceSubClass" = 255
    | |   |       | |   |     "locationID" = 487653376
    | |   |       | |   |     "IOGeneralInterest" = "IOCommand is not serializable"
    | |   |       | |   |     "IOClassNameOverride" = "IOUSBInterface"
    | |   |       | |   |     "AppleUSBAlternateServiceRegistryID" = 4294969544
    | |   |       | |   |     "idVendor" = 4817
    | |   |       | |   |     "bInterfaceProtocol" = 255
    | |   |       | |   |     "bAlternateSetting" = 0
    | |   |       | |   |     "bInterfaceNumber" = 1
    | |   |       | |   |     "bInterfaceClass" = 255
    | |   |       | |   |   }
    | |   |       | |   |   
    | |   |       | |   +-o IOUSBHostInterface@2  
    | |   |       | |       {
    | |   |       | |         "USBPortType" = 0
    | |   |       | |         "IOCFPlugInTypes" = {"2d9786c6-9ef3-11d4-ad51-000a27052861"="IOUSBFamily.kext/Contents/PlugIns/IOUSBLib.bundle"}
    | |   |       | |         "bcdDevice" = 0
    | |   |       | |         "USBSpeed" = 3
    | |   |       | |         "idProduct" = 4097
    | |   |       | |         "bConfigurationValue" = 1
    | |   |       | |         "bInterfaceSubClass" = 255
    | |   |       | |         "locationID" = 487653376
    | |   |       | |         "IOGeneralInterest" = "IOCommand is not serializable"
    | |   |       | |         "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>

任何指针?

1 个答案:

答案 0 :(得分:3)

所以,我无法保证您的项目成功 - 我不知道您的调制解调器是否可以使用标准的CDC驱动程序。但我希望能帮助你找到答案。这有五个部分:

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

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

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

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

    驱动程序类和软件包ID

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

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

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

    分别在OSX上。这些中的每一个似乎都假设他们可以完全控制USB接口 - 似乎大多数设备将控制和数据端点分成两个独立的接口。在你的情况下,你只有一个。从技术上讲,通过使用不同的匹配类别,多个驱动程序可以匹配服务。但我无法保证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上,必须对所有密钥(包括无代码密钥)进行签名。在10.9上,如果它们位于/System/Library/Extensions,则它们可以是无符号的;如果设置了内核选项kext-dev-mode=1,则在10.10中它们可以是无符号的。您需要为Apple的Developer Id证书添加特殊的kext签名,以便签署关键字。

    加载和调试

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

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

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

    最后的想法

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