另类方法制作android通用驱动

绝大多数的Android驱动应该都是基于google的通用驱动改造而来,我们不说复杂的添加很多新模块和新功能的改造,就说简单的改造google的anroid通用驱动来实现适配常见anroid手机。本文中一些名词(inf、数字签名)等不做展开说明,有兴趣请自行了解。

先在前面声明大纲,改造Android驱动只需要两点:

  1. 驱动文件的inf文件中添加该手机对应的硬件id/兼容id
  2. 对更新后的inf和所有的原来的文件重新生成cat文件(安全目录),并数字签名

    驱动常见格式

先看一个从android网站上下载的一个官方驱动usb_driver_r04-windows.zip,解压后内部结构为下图所示:

其中inf文件的内容大致如下:

;

; Android WinUsb driver installation.

;

[Version]

Signature = “$Windows NT$”

Class = AndroidUsbDeviceClass

ClassGuid = {3F966BD9-FA04-4ec5-991C-D326973B5128}

Provider = %ProviderName%

DriverVer = 12/06/2010,4.0.0000.00000

CatalogFile.NTx86 = androidwinusb86.cat

CatalogFile.NTamd64 = androidwinusba64.cat

;

; This section seems to be required for WinUsb driver installation.

; If this section is removed the installer will report an error

; “Required section not found in INF file”.

;

[ClassInstall32]

Addreg = AndroidWinUsbClassReg

[AndroidWinUsbClassReg]

HKR,,,0,%ClassName%

HKR,,Icon,,-1

[Manufacturer]

%ProviderName% = Google, NTx86, NTamd64

[Google.NTx86]

; HTC Dream

%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C01

%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C02&MI_01

%SingleBootLoaderInterface% = USB_Install, USB\VID_0BB4&PID_0FFF

; HTC Magic

%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C03&MI_01

;

;Moto Sholes

%SingleAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB

%CompositeAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB&MI_01

;

;Google NexusOne

%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02

%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02&MI_01

%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_4E11

%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E12&MI_01

%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E22&MI_01

[Google.NTamd64]

; HTC Dream

%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C01

%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C02&MI_01

%SingleBootLoaderInterface% = USB_Install, USB\VID_0BB4&PID_0FFF

; HTC Magic

%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C03&MI_01

;

;Moto Sholes

%SingleAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB

%CompositeAdbInterface% = USB_Install, USB\VID_22B8&PID_41DB&MI_01

;

;Google NexusOne

%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02

%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0D02&MI_01

%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_4E11

%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E12&MI_01

%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_4E22&MI_01

[USB_Install]

Include = winusb.inf

Needs = WINUSB.NT

[USB_Install.Services]

Include = winusb.inf

AddService = WinUSB,0x00000002,WinUSB_ServiceInstall

[WinUSB_ServiceInstall]

DisplayName = %WinUSB_SvcDesc%

ServiceType = 1

StartType = 3

ErrorControl = 1

ServiceBinary = %12%\WinUSB.sys

[USB_Install.Wdf]

KmdfService = WINUSB, WinUSB_Install

[WinUSB_Install]

KmdfLibraryVersion = 1.9

[USB_Install.HW]

AddReg = Dev_AddReg

[Dev_AddReg]

HKR,,DeviceInterfaceGUIDs,0x10000,”{F72FE0D4-CBCB-407d-8814-9ED673D0DD6B}”

[USB_Install.CoInstallers]

AddReg = CoInstallers_AddReg

CopyFiles = CoInstallers_CopyFiles

[CoInstallers_AddReg]

HKR,,CoInstallers32,0x00010000,”WdfCoInstaller01009.dll,WdfCoInstaller”,”WinUSBCoInstaller2.dll”

[CoInstallers_CopyFiles]

WinUSBCoInstaller2.dll

WdfCoInstaller01009.dll

[DestinationDirs]

CoInstallers_CopyFiles=11

[SourceDisksNames]

1 = %DISK_NAME%,,,\i386

2 = %DISK_NAME%,,,\amd64

[SourceDisksFiles.x86]

WinUSBCoInstaller2.dll = 1

WdfCoInstaller01009.dll = 1

[SourceDisksFiles.amd64]

WinUSBCoInstaller2.dll = 2

WdfCoInstaller01009.dll = 2

[Strings]

ProviderName = “Google, Inc.”

SingleAdbInterface = “Android ADB Interface”

CompositeAdbInterface = “Android Composite ADB Interface”

SingleBootLoaderInterface = “Android Bootloader Interface”

WinUSB_SvcDesc = “Android USB Driver”

DISK_NAME = “Android WinUsb installation disk”

ClassName = “Android Phone”
上面这个inf中标为红色的地方就是这个驱动默认支持的所有设备的硬件id。

修改inf文件

市面上的常见通用 驱动文件的修改大多是采用如谷歌原生驱动一样的方式,将想要支持的设备的硬件id加到inf文件,每多要支持一个系列的设备,就得修改一次inf文件并且重新发布驱动。这种方式简单粗暴,并且使用微软的inf2cat.exe能够正常生成安全目录。

还有一种就是小米早期版本的驱动一样,直接使用硬件设备的兼容id,它改动过的inf如下:

[Google.NTx86]

;Xiaomi Mione

%CompositeAdbInterface% = USB_Install, USB\Class_FF&SubClass_42&Prot_01

%SingleAdbInterface% = USB_Install, USB\Class_FF&SubClass_42&Prot_03

[Google.NTamd64]

;Xiaomi Mione

%CompositeAdbInterface% = USB_Install, USB\Class_FF&SubClass_42&Prot_01

%SingleAdbInterface% = USB_Install, USB\Class_FF&SubClass_42&Prot_03
但是在研究中发现,在win7上安装驱动时驱动如果没有正确的cat文件和对cat数字签名,驱动是安装不上或者有警告。小米的驱动同样如此,所以估计这也是后来小米的新驱动一样使用上面添加硬件id列表的方式的原因之一吧。

这里我们使用第二种方式,将inf里多余的硬件id全部删除,然后使用小米的这种方式将android手机通用的兼容id写入进去。

生成CAT文件

安装windows的驱动开发包(我使用的是WinDDK 7600.16385.1),找到里面的bin\selfsign\Inf2Cat.exe,使用命令行Inf2Cat.exe /v /driver:驱动目录 /OS:7_X64,7_X86进行编辑,如果是使用的硬件id,则会正常生成安装目录文件,但如果使用兼容id,则会报以下错误。

这个inf2cat程序经研究是c#语言开发的,于是,祭出神器JetBrains dotPeek 1.1 对它进行反编译,并且导出c#工程,然后改掉其中的判断错误的代码

在bool flag = driverPackageInfo.TestSignability(out errors, out warnings);之后, 将flag强制赋值为true。
并且注释掉AssemblyInfo.cs中的//[assembly: AssemblyKeyFile(“\\DQBLD01\builds2\keys\whos.snk”)],然后重新生成一个inf2cat程序,放在winddk的原目录。这样重新生成cat文件,虽然还是有错误提示,但是不要紧,cat文件正常的生成出来了。

最后对生成出来的cat文件进行数字签名,注意要使用signtool.exe+证书文件的数字签名方法,使用signcode.exe的加密方式对于64位程序似乎系统不太认。

这样,一个通用android驱动就完成了。