另类方法制作android通用驱动
绝大多数的Android驱动应该都是基于google的通用驱动改造而来,我们不说复杂的添加很多新模块和新功能的改造,就说简单的改造google的anroid通用驱动来实现适配常见anroid手机。本文中一些名词(inf、数字签名)等不做展开说明,有兴趣请自行了解。
先在前面声明大纲,改造Android驱动只需要两点:
先看一个从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驱动就完成了。