第三部分:USB设备的研究——在Windows中枚举USB设备

阅读量207330

|

发布时间 : 2015-12-23 13:02:56

x
译文声明

本文是翻译文章,文章来源:360安全播报

原文地址:http://nicoleibrahim.com/part-3-usb-device-research-windows-registry-enumerations/

译文仅供参考,具体内容表达以及含义原文为准。

http://p0.qhimg.com/t01bceeff7173cdf8e7.png

你有没有想过为什么Windows要使用不同的驱动程序去配置貌似是同一类型的USB设备?我当然想过。这个问题激发了我研究MSC的兴趣,PTP和MTP在我之前的文章中已经探讨过了。

USB设备会发送一条消息到Windows,然后由系统组件去确定该设备属于什么类型,该如何使用,实际上就是确定这个USB设备有些什么样的功能。在本文中,我们将涵盖不同的设备通信方面的内容,还有Windows在枚举USB设备时的内部工作机制。所提到的信息算是高级概述了,大多数来源于微软的在线开发手册和一些我个人的测试总结。下面的论题将是本文重点:

如何创建驱动栈并如何与USB设备通信。

Windows是如何为一个设备选择一个最佳的驱动程序的。

安装和枚举相关的注册表项

复合设备的枚举。

1.1使用驱动栈枚举和通信

与设备进行通信其实是由几个不同的驱动程序来完成的。这些驱动在设备栈中与一个设备对象相关联,由PnP维护。在PnP设备树中,每一个PnP节点都有它自己的设备栈,一个节点可能代表一个设备、复合设备的一个功能或者与物理设备无关的软设备。

在设备栈中第一个被创建的对象在栈的底部,最后一个被创建的在栈顶。

PDO(物理设备对象:Physical Device Object)是第一个被创建的对象,它由PnP设备树下的功能驱动所创建。下一个被创建的对象是FDO(功能设备对象:Functional Device Object),这是这个栈中主要的驱动。该驱动处理读、写及设备控制请求。也可以在栈中当过滤驱动使用。这些都是由功能驱动所创建,并且辅助FDO执行任务。这些设备被称为Filter Dos(过滤设备对象:Filter Device Object)。一个过滤驱动可以在功能驱动之上(上层驱动),或者也可以运行在功能驱动之下(底层驱动)。还有一点,当一个设备在原始模式时,在设备节点中就没有功能驱动或者过滤驱动了。

当一个设备第一次被安装的时候,INF文件用于确定哪个驱动是功能驱动,哪个是过滤驱动。而这些信息也会存储进注册表中。PnP管理器就用注册表中的这些信息去枚举这个设备的设备栈。下列图片就是一个USB存储设备栈的示例:

t019589f7070b237036.png

在前面提到的堆栈中的所有驱动程序,都是内核驱动。有时候,一个设备可以同时有一个用户模式堆栈,和一个内核模式堆栈。用户模式的驱动常常是基于UMDF(用户模式驱动程序框架:User-Mode Driver Framework)的,DLL表示用户模式的驱动。

1.2Windows是如何为一个USB设备选取最好的驱动程序的呢?

1.2.1设备与Windows之间的通信:获取硬件ID和兼容的ID

当一个设备绑定到一个运行Windows系统的计算机时,USB集线器驱动(USB hub driver)会从已经绑定的设备上查询信息并且会创建一个或多个硬件ID和兼容ID。

硬件ID由“USB”作为前缀,并指向用来处理这个设备的总线驱动,其次是供应商、模型和修订标识符。硬件标识的格式是:

USBVID_1234&PID_5678&REV_0001

供应商、模型和修订标识符是从设备描述响应包(Device Descriptor Response packet)中拖过来的,对应的字段分别是:idProduct,idVendor和bcdDevice,如图2所示:

t0183806f3434a0ee1b.png

兼容ID也是由”USB”作为前缀,指示由集线器驱动负责处理这个设备,随后是分类代码、子类代码和协议代码。格式如下示例:

USBCLASS_01&SUBCLASS_23&PROT_45

这个分类、子类和协议代码既可以从设备描述符的bDeviceClass、bDeviceSubClass、bDeviceProtocol字段获取也可以从接口描述符的bInterfaceClass、bInterfaceSubClass和bInterfaceProtocol字段获取。

t014ae0088a5884ea22.png

USB.org定义了不同的USB设备的类,所以,供应商便可以使用由操作系统提供的设备驱动。设备描述符由设备自己发送到操作系统,并且其中包含了类(Class)、子类(SubClass)和协议(Protocol)字段。据USB.org所说,这些字段被用于识别一个USB设备提供的功能,协议被用于与该设备通信。

你可以在这里看到完整的设备类型列表http://www.usb.org/developers/defined_class

不过对于我们讨论的话题,下面只列出MSC、PTP和MTP的类:

t0171aa074f4dce9ba7.png

1.2.2 Windows内部

USB集线器驱动告诉即插即用管理器:发现了新的设备。然后即插即用管理器就查询这个设备的所有的硬件ID。

然后,即插即用管理器便传达消息给Windows,指示有一个新的设备被发现,并且需要被安装,同时会发送处理时需要的硬件ID列表。

1.2.3 INF文件:根据硬件ID去搜索匹配的硬件ID或兼容ID,Windows试图在一个驱动包中搜索各种相匹配的INF文件。如果没有找到相匹配的硬件ID,那么它就为这个设备去搜索相匹配的兼容ID。

1.2.4 驱动的排名和安装

如果找到一个或多个相匹配的驱动程序,Windows就会为其中的每一个驱动分配一个等级。至于Windows如何排列每一个驱动的更多信息,你可以阅读[5]。等级最低的驱动程序将会被使用。如果一个设备有多个同等级的驱动,那么Windows就会根据数字签名状态、驱动日期和修订信息去决定应该选择哪个驱动程序。

该驱动通过下面的途径被安装:

1.公共安装程序被注册。一个公共安装程序典型地写附加配置信息到系统注册表中,或者执行一个其它的安装任务如需要一个安装时间信息,而这个信息显然不能由一个INF文件来处理。而它们可以获取一个设备运转时需要的设备参数。

2.Windows从这个INF中的入口处确定设备的安装类型,这个信息被存储到:SYSTEMCurrentControlSetControlClass{ClassGUID}中

3.在驱动和公共安装程序完成后,PnP就获取控制权。PnP管理器为每个驱动调用AddDevice程序,从更底层的过滤驱动开始,然后是功能驱动,最后是最顶层的过滤驱动。然后PnP为每个设备分配资源。

4.如果有指定一个公共安装程序,Windows就为附加安装程序发送代码到公共安装程序。

5.完成这些后,设备就被安装好了且准备就绪。

1.3注册表键

SYSTEMCurrentControlSetControlClass{ClassGUID}####

这个键代表设备安装类型,是为了便于设备安装。而大多数类都是系统相关,不过厂商也可以指定自己的类。当一个设备绑定到系统时,INF文件被用于在安装设备的时候存储信息。一个设备可能会使用多个不同的GUID,其中每一个都可以与驱动栈相关联。每一个GUID都是由系统为每个设备所创建的注册表键值。键值的格式是”####“,在第一个安装好的设备下面依次从0000开始,每增加一个设备,键值就递增。你可以在SYSTEMCurrentControlSetEnumEnumeratorDeviceIDInstanceID找到参考。

SYSTEMCurrentControlSetControlDeviceClasses{DeviceInterfaceClassGUID}SymbolicLinkName

驱动接口类是一个设备输出的途径,也是驱动功能到其他系统组件的途径,包括了其它的驱动以及用户模式下的程序。一个特定设备的驱动会注册一个设备接口类。当一个驱动注册一个设备接口类时,I/O管理器将设备和设备接口类的GUID合并成一个符号链接名,下面就是一个符号链接名的示例:

##?#USBSTOR#Disk&Ven_Toshiba&Prod_External_USB_HDD&Rev_#2010041434D5&0#{53f56307-b6bf-11d0-94f2-00a0c91efb8b}
链接符号名的子键有一个名为”DeviceInstance“的入口。它的值就像下面这种格式:

EnumeratorDeviceIDInstanceID

SYSTEMCurrentControlSetEnumEnumerator

这个键由PnP管理器创建。这个键下有当前系统中的每一个设备实例的子键。子键中有一些信息比如设备描述、硬件ID、兼容ID和资源需求。这个enumerator就代表是一个设备的驱动栈中的一个对象的功能驱动。在Windows发布XP的时候,USB设备的Enumerator包括了USB、STORAGE和其它设备中的USBSTOR。

1.4多功能及混合设备

一些设备具有多个接口,可允许每一个接口去实现不同的功能。在Windows中,这些设备和单一功能的设备有些许不同的地方。在这个查询了这个设备的硬件ID和搜索玩INF文件后,如果在使用的INF文件中找到了相匹配的驱动,那么通用的父驱动程序就不会起作用。然而,如果没有找到匹配的驱动,USBCOMPOSITE的一个兼容ID就会被使用,如果支持,那么这个USB通用父驱动程序:Generic Parent Driver(Usbccgp.sys)就会被使用。

这个通用父驱动必须知道它应该管哪一个接口。这使得该设备可以使用微软提供的驱动去支持它自己的接口。如果有接口在Windows本地没有相应的驱动,那么供应商就必须提供一个驱动和INF文件。

在之前的文章中,我探讨了Windows为啥不能正确地枚举黑莓设备。这是因为黑莓供应商指定的软件必须在连接的时候先安装,它可以访问在软件安装过程中提供的驱动程序和INF文件。如果没有了这些,那么Windows的通用父驱动没有了必要的信息去正确地枚举这个设备了。

在注册表中,每一个被枚举出来的接口貌似都是一个独立的设备,但是Windows却是把一个所谓的单独的设备当成一个接口组件进行管理的。

已经枚举出来的设备接口的硬件ID被加在MI_XX后面。相关的入口被注册表的键和值,而这个键和值就是用来处理该接口的特定功能的。

即将到来……

在下一篇文章中,我计划涵盖我的研究中的基础技能,包括详细的安装环境及使用方法,以及下面这些测试:

https://p1.ssl.qhimg.com/t01888930cdec442b43.png

资源

1.http://msdn.microsoft.com/en-us/library/windows/hardware/hh439632%28v=vs.85%29.aspx

2.http://msdn.microsoft.com/en-us/library/windows/hardware/ff728852%28v=vs.85%29.aspx

3.http://msdn.microsoft.com/en-us/library/windows/hardware/ff553356%28v=vs.85%29.aspx

4.http://msdn.microsoft.com/en-us/library/windows/hardware/ff728853%28v=vs.85%29.aspx

5.http://msdn.microsoft.com/en-us/library/windows/hardware/ff686700%28v=vs.85%29.aspx

6.http://msdn.microsoft.com/en-us/library/windows/hardware/ff549491%28v=vs.85%29.aspx

7.http://msdn.microsoft.com/en-us/library/windows/hardware/ff549460%28v=vs.85%29.aspx

8.http://msdn.microsoft.com/en-us/library/windows/hardware/ff546173%28v=vs.85%29.aspx

9.http://msdn.microsoft.com/en-us/library/windows/hardware/ff537109%28v=vs.85%29.aspx

10.http://msdn.microsoft.com/en-us/library/windows/hardware/ff539234%28v=vs.85%29.aspx

本文翻译自360安全播报 原文链接。如若转载请注明出处。
分享到:微信
+10赞
收藏
ToBin
分享到:微信

发表评论

内容需知
合作单位
  • 安全客
  • 安全客
Copyright © 北京奇虎科技有限公司 三六零数字安全科技集团有限公司 安全客 All Rights Reserved 京ICP备08010314号-66