您的位置:首页 > 其它

从调试数据分析USB通信协议——USB键盘鼠标【HID类设备】(四)

2017-11-03 23:42 716 查看

从调试数据分析USB通信协议——USB键盘鼠标【HID类设备】(四)

平时我们在使用USB设备的时候,除了U盘使用的比较多以外,USB人体输入学设备,更是必不可少的存在,如鼠标,键盘。这里小编我也来简述一下HID[Human
Input Device]设备。设备描述符、配置描述符这些陈词滥调,小编就不说了,这里说一下HID描述符,和HID用来定义返回数据格式的报告描述符,上面通过对U盘的学习我们已经知道,针对它有一套SCSI协议[它起初就是用来针对扫描仪,软驱,硬盘的,现在USB协议索性在上面包了一层,继续使用现成的东西],而对于鼠标键盘,由于传输的数据比较少,因此,我们只需要通过一个描述符自定义一种格式来向操作系统发送数据报告,至于,我们要按什么格式传输什么内容上去,这正是这个报告描述符需要去定义的内容,有了前面的基础,这里小编我就一切从简了。


 




























下面是HID键盘的报告描述符范例:

 












为了进一步研究HID类USB设备,小编我又抓取了USB键盘在插入电脑时的数据包信息如下【鼠标的话信息量太大,报告数据太多,不利于分析】,这里有一点小编我要提的是,带报告描述符的数据包是比较大的,Bus
Hound的最大抓取包字节一般默认为32,需要做些修改,如下图所示,小编将其上调至100字节:


                                       .        
 



Bus Hound 6.01 capture on Windows Vista (x64). Complements of www.perisoft.net

 

Device  Phase  Data                                                Description       Cmd.Phase.Ofs(rep)

------  -----  --------------------------------------------------  ----------------  ------------------

//尝试获取设备描述符 

  14.0  CTL    80 06 00 01  00 00 12 00                            GET DESCRIPTOR           1.1.0  

//(1)USB协议版本采用的是BCD编码,此处为0x0110(低字节在前,即1.10).(2)端点0最大包长为8(0x08)字节.(3)厂商ID为0x1c4f.(4)产品ID为0x0026.(5)设备版本号为0x0110,若采用的是BCD编码,即为1.10.(6)厂商字符串索引,产品字符串索引依次为1,2,无产品序列号索引

(7)该设备可能的配置只有1种配置       

  14.0  IN     12 01 10 01  00 00 00 08  4f 1c 26 00  10 01 01 02  ........O.&.....         1.2.0        

               00 01                                               ..                       1.2.16   

//尝试获取配置描述符
        

  14.0  CTL    80 06 00 02  00 00 09 00                            GET DESCRIPTOR           2.1.0  

//(1)配置描述符的集合总长度为0x003b,即59字节长度,若不对Bus
Hound记录的最大包长度做调整,获取完整配置描述符的时候数据就会不全.

(2)该配置支持2个接口.(3)该配置的值为1.(4)没有描述该配置的字符串,即索引值取0.

(5)设备的属性为0xa0,即表示设备是总线供电的,且支持远程唤醒.(6)设备所需的电流为0x31*2=98mA        

  14.0  IN     09 02 3b 00  02 01 00 a0  31                        ..;.....1                2.2.0  

//再一次获取完整的描述符集合信息          

  14.0  CTL    80 06 00 02  00 00 3b 00                            GET DESCRIPTOR           3.1.0  

//【1】接口描述符0:(1)当前接口编号为0,接口的备用编号也为0.(2)该接口使用1个端点.(3)该接口所使用的类为0x03,子类为0x01,协议为0x01.(4)该接口没有使用字符串来描述.【2】HID描述符[接口0]:(1)协议的版本号为0x0110, 采用的是BCD编码,此处1.10.(2)所适用的国家为0x00?该说你爱国么?咋不填0x21[美国].(3)下级描述符1个,至少1个.(4)下级描述符类型为0x22,表示报告描述符.(5)下级描述符长度为0x0036,即54个字节. 【3】端点描述符[接口0]:(1)该端点为输入端点,且端点地址为0x01.(2)该端点采用的是中断传输.(3)端点所支持的最大包长度为0x0008,即8字节.(4)根据官方协议文档,这里的0x0a是用来设置数据传输到端点的轮询间隔.【4】接口描述符1:(1)当前接口编号为1,接口的备用编号为0.(2)该接口使用1个端点.(3)该接口所使用的类为0x03,子类为0x00,协议为0x00.(4)该接口没有使用字符串来描述.【5】HID描述符[接口1]:(1)协议的版本号为0x0110,
即1.10.(2)所适用的国家为0x00.(3)下级描述符1个.(4)下级描述符类型为0x22,表示报告描述符.(5)下级描述符长度为0x0032,即50个字节. 【6】端点描述符[接口1]:(1)该端点为输入端点,且端点地址为0x02.(2)该端点采用的是中断传输.(3)端点所支持的最大包长度为0x0003,即3字节.(4)根据官方协议文档,这里的0x0a是用来设置数据传输到端点的轮询间隔.

  14.0  IN     09 02 3b 00  02 01 00 a0  31 09 04 00  00 01 03 01  ..;.....1.......         3.2.0        

               01 00 09 21  10 01 00 01  22 36 00 07  05 81 03 08  ...!...."6......         3.2.16       

               00 0a 09 04  01 00 01 03  00 00 00 09  21 10 01 00  ............!...         3.2.32       

               01 22 32 00  07 05 82 03  03 00 0a                  ."2........              3.2.48       

  14.0  CTL    00 09 01 00  00 00 00 00                     SET CONFIG       4.1.0
//00 09 01 00
设置配置值为1,激活第一个种配置

//按语言ID [09 04],即0x0409[美式英语],来获取字符串索引0x02处[产品字符串]的内容,尝试获取以后,获悉总长度为0x1a,即26字节.      

  14.0  CTL    80 06 02 03  09 04 04 00                            GET DESCRIPTOR           5.1.0(2)     

  14.0  IN     1a 03 55 00                                         ..U.                     5.2.0        

//再次获取完整的产品字符串信息,由于采用的是Unicode编码,因此该处获得的产品字符串内容为USB
Keyboard

  14.0  CTL    80 06 02 03  09 04 1a 00                            GET DESCRIPTOR           6.1.0(2)     

  14.0  IN     1a 03 55 00  53 00 42 00  20 00 4b 00  65 00 79 00  ..U.S.B. .K.e.y.         6.2.0        

               62 00 6f 00  61 00 72 00  64 00                     b.o.a.r.d.               6.2.16  

//又获取一次设备描述符、配置描述符,这是因为我插入的这个键盘是复合设备键盘,即该键盘其实是多个USB输入设备组成,可以明显看到如下复合设备中共有两个USB输入设备,那么该复合设备到底是如何组成的呢,可参看文档【USB经典博文\多功能USB设备的结构设计研究
- 接口_总线_驱动
- 电子发烧友网,地址http://www.elecfans.com/emb/jiekou/2009050656625.html】,这是小编找的一篇博文.多的话小编就不解释了,详细的请自己去看这篇博文,小编这里只截取博文中的一张结构图如下图6,显然我们这里第一次是通过公共端点地址0获取了该复合设备的设备描述符,接下来,我们将通过端点地址1和端点地址2分别获取复合设备两个接口的报告描述符等信息。


 

 


  17.0  CTL    80 06 00 01  00 00 12 00                            GET DESCRIPTOR           9.1.0    

//设备描述符的内容同前,没毛病    

  17.0  IN     12 01 10 01  00 00 00 08  4f 1c 26 00  10 01 01 02  ........O.&.....         9.2.0        

               00 01                                               ..                       9.2.16       

  17.0  CTL    80 06 00 02  00 00 09 00                            GET DESCRIPTOR          10.1.0      

//获取键盘内第一个子设备的配置描述符:(1)配置描述符的集合总长度为0x0022,即34字节长度.(2)该配置支持1个接口.(3)该配置的值为1.(4)没有描述该配置的字符串,即索引值取0.(5)设备的属性为0xa0,即表示设备是总线供电的,且支持远程唤醒.(6)设备所需的电流为0x31*2=98mA    

  17.0  IN     09 02 22 00  01 01 00 a0  31                        ..".....1               10.2.0        

  17.0  CTL    80 06 00 02  00 00 22 00                            GET DESCRIPTOR          11.1.0

//【1】接口描述符:(1)当前接口编号为0,接口的备用编号也为0.(2)该接口使用1个端点.(3)该接口所使用的类为0x03,子类为0x01,协议为0x01.(4)该接口没有使用字符串来描述.【2】HID描述符:(1)协议的版本号为0x0110, 采用的是BCD编码,此处1.10.(2)所适用的国家为0x00.(3)下级描述符1个.(4)下级描述符类型为0x22,表示报告描述符.(5)下级描述符长度为0x0036,即54个字节. 【3】端点描述符:(1)该端点为输入端点,且端点地址为0x01.(2)该端点采用的是中断传输.(3)端点所支持的最大包长度为0x0008,即8字节.(4)根据官方协议文档,这里的0x0a是用来设置数据传输到端点的轮询间隔.      

  17.0  IN     09 02 22 00  01 01 00 a0  31 09 04 00  00 01 03 01  ..".....1.......        11.2.0        

               01 00 09 21  10 01 00 01  22 36 00 07  05 81 03 08  ...!...."6......        11.2.16       

               00 0a                                               ..                      11.2.32       

  17.0  CTL    00 09 01 00  00 00 00 00                   SET CONFIG        12.1.0    //00 09 01 00
设置配置值为1,激活第一个种配置    

  17.0  CTL    21 0a 00 00  00 00 00 00                            SET IDLE                13.1.0

//[81 06]表示是主机向设备的接口请求数据,而不是像前面一样的向设备请求数据[80],wValue的第一个字节索引值为0,第二个字节0x22表示描述符的类型为报告描述符,wIndex为0x0000,表示向接口0请求数据,长度为0x0076,即118个字节,由于实际的报告描述符并没有这么长,因此是能有多少返回多少吧.    

  17.0  CTL    81 06 00 22  00 00 76 00                            GET DESCRIPTOR          14.1.0       

//关于如下的报告描述符这里我不多BB,小编我使用USBlyzer软件进行了一波分析,请各位读者大人对照下图去理解就行,我只想说一句,就是这里我们选择的是复合设备中的第一个USB子输入设备[即HID
Keyboard Device] .很明显,从下图中我们可以看到在描述符中通过用途页和用途指示了从Num Lock到Scroll
Lock三个键盘灯的输出开关信号,及8个特殊按键按下与否的输入信号,和6个普通按键的缓冲数组,如果对于这块还有不理解的,请回去看看前面对于报告描述符详解的部分.


 

  17.0  IN     05 01 09 06  a1 01 05 08  19 01 29 03  15 00 25 01  ..........)...%.        14.2.0        

               75 01 95 03  91 02 95 05  91 01 05 07  19 e0 29 e7  u.............).        14.2.16       

               95 08 81 02  75 08 95 01  81 01 19 00  29 91 26 ff  ....u.......).&.        14.2.32       

               00 95 06 81  00 c0                                  ......                  14.2.48   

 //再获取一次设备描述符,这里获取的是复合设备中第二个子设备的描述符,设备描述符的内容依然同前,没毛病    

  18.0  CTL    80 06 00 01  00 00 12 00                            GET DESCRIPTOR          15.1.0        

  18.0  IN     12 01 10 01  00 00 00 08  4f 1c 26 00  10 01 01 02  ........O.&.....        15.2.0        

               00 01                                               ..                      15.2.16  

//获取键盘内第二个子设备的配置描述符:(1)配置描述符的集合总长度为0x0022,即34字节长度.(2)该配置支持1个接口.(3)该配置的值为1.(4)没有描述该配置的字符串,即索引值取0.(5)设备的属性为0xa0,即表示设备是总线供电的,且支持远程唤醒.(6)设备所需的电流为0x31*2=98mA     

  18.0  CTL    80 06 00 02  00 00 09 00                            GET DESCRIPTOR          16.1.0        

  18.0  IN     09 02 22 00  01 01 00 a0  31                        ..".....1               16.2.0        

  18.0  CTL    80 06 00 02  00 00 22 00                            GET DESCRIPTOR          17.1.0

  //【1】接口描述符:(1)当前接口编号为1,接口的备用编号也为0.(2)该接口使用1个端点.(3)该接口所使用的类为0x03,子类为0x00,协议为0x00.(4)该接口没有使用字符串来描述.【2】HID描述符:(1)协议的版本号为0x0110, 采用的是BCD编码,此处1.10.(2)所适用的国家为0x00.(3)下级描述符1个.(4)下级描述符类型为0x22,表示报告描述符.(5)下级描述符长度为0x0032,即50个字节. 【3】端点描述符:(1)该端点为输入端点,且端点地址为0x02.(2)该端点采用的是中断传输.(3)端点所支持的最大包长度为0x0003,即3字节.(4)根据官方协议文档,这里的0x0a是用来设置数据传输到端点的轮询间隔.        

  18.0  IN     09 02 22 00  01 01 00 a0  31 09 04 01  00 01 03 00  ..".....1.......        17.2.0        

               00 00 09 21  10 01 00 01  22 32 00 07  05 82 03 03  ...!...."2......        17.2.16       

               00 0a                                               ..                      17.2.32       

  18.0  CTL    00 09 01 00  00 00 00 00                      SET CONFIG        18.1.0   //00 09 01 00
设置配置值为1,激活第一个种配置      

  18.0  CTL    21 0a 00 00  01 00 00 00                            SET IDLE                19.1.0        

  18.0  USTS   c0000004                                            stall pid               19.2.0    

//[81 06]表示是主机向设备的接口请求数据,而不是像前面一样的向设备请求数据[80],wValue的第一个字节索引值为0,第二个字节0x22表示描述符的类型为报告描述符,wIndex为0x0001,表示向接口1请求数据,长度为0x0072,即114个字节,由于实际的报告描述符并没有这么长,因此是能有多少返回多少吧.     

  18.0  CTL    81 06 00 22  01 00 72 00                            GET DESCRIPTOR          20.1.0     

//同样使用USBlyzer软件进行一波分析,如下图,这里我们选择的是复合设备中的第二个USB子输入设备.很明显,从下图中我们可以看到在描述符中通过Consumer用途取得了设置音量大小的用途,及从系统控制用途中取得了待机,唤醒等用途.
需要注意的是这里将Consumer用途页和System Control页用途页分成了两种报告来上传,因此分配了两种报告ID.
 

如果你想自己去编写一个报告描述符,可以使用官方提供的HID报告描述符生成工具来生成,这里小编我也下载了这个工具。


 

  18.0  IN     05 0c 09 01  a1 01 85 01  19 00 2a 3c  02 15 00 26  ..........*<...&        20.2.0        

               3c 02 95 01  75 10 81 00  c0 05 01 09  80 a1 01 85  <...u...........        20.2.16       

               02 19 81 29  83 25 01 75  01 95 03 81  02 95 05 81  ...).%.u........        20.2.32       

               01 c0                                               ..                      20.2.48   

    

  17.0  CTL    21 09 00 02  00 00 01 00                            SET REPORT              21.1.0        

  17.0  OUT    01                                                  .                       21.2.0        

  17.1  IN     00 00 00 00  00 00 00 00                            ........                22.1.0        

   8.0  CTL    a3 00 00 00  01 00 04 00                            GET STATUS              23.1.0        

   8.0  CTL    a3 00 00 00  02 00 04 00                            GET STATUS              24.1.0        

   8.0  IN     07 05 00 00                                         ....                    23.2.0        

   8.0  CTL    00 01 01 00  00 00 00 00                            CLEAR FEATURE           25.1.0        

   8.0  IN     00 01 00 00                                         ....                    24.2.0        

   8.0  CTL    23 01 02 00  01 00 00 00                            CLEAR FEATURE           26.1.0        

   8.1  IN     02                                                  .                       27.1.0        

   8.0  CTL    a3 00 00 00  01 00 04 00                            GET STATUS              28.1.0        

   8.0  IN     07 05 04 00                                         ....                    28.2.0        

   8.0  CTL    23 01 12 00  01 00 00 00                            CLEAR FEATURE           29.1.0        

   8.0  CTL    a3 00 00 00  01 00 04 00                            GET STATUS              30.1.0        

   8.0  IN     03 05 00 00                                         ....                    30.2.0        

  14.0  CTL    80 06 00 02  00 00 09 00                            GET DESCRIPTOR          31.1.0        

  14.0  IN     09 02 3b 00  02 01 00 a0  31                        ..;.....1               31.2.0        

  14.0  CTL    80 06 00 02  00 00 3b 00                            GET DESCRIPTOR          32.1.0        

  14.0  IN     09 02 3b 00  02 01 00 a0  31 09 04 00  00 01 03 01  ..;.....1.......        32.2.0        

               01 00 09 21  10 01 00 01  22 36 00 07  05 81 03 08  ...!...."6......        32.2.16       

               00 0a 09 04  01 00 01 03  00 00 00 09  21 10 01 00  ............!...        32.2.32       

               01 22 32 00  07 05 82 03  03 00 0a                  ."2........             32.2.48       

   8.0  CTL    a3 00 00 00  01 00 04 00                            GET STATUS              33.1.0(10)    

   8.0  IN     03 05 00 00                                         ....                    33.2.0        

   8.0  CTL    23 03 02 00  01 00 00 00                            SET FEATURE             43.1.0        

 

USB的上位机设计

关于上位机的程序设计,小编这里比较熟悉的是VC的环境,推荐一本书【圈圈教你玩USB.pdf】,该书从165页开始介绍了在VC++
6.0环境下,如何编写一个自定义HID设备的上位机程序,至于其他情况,其实一般情况下使用底层的一些USB转换芯片,厂商都会提供对应的上层驱动库,所以应用的话,一般不用担心这些,主要还是要了解USB通信这一部分,其实对于操作系统而言,USB协议中利用端点进行点对点通信的这种模式,更类似于管道通信的一种硬件抽象模型。

 

 这里小编我将相关的资料资源下载链接放在下面:



1.圈圈教你玩usb,一本介绍usb不错的书:http://download.csdn.net/download/tanjiaqi2554/10049482

2.usb协议和文件系统用的一些分析软件:http://download.csdn.net/download/tanjiaqi2554/10049478
3.pc用usb摄像头点亮软件:http://download.csdn.net/download/tanjiaqi2554/10049469
4.USBlyzer,一款不错的usb设备类分析软件:http://download.csdn.net/download/tanjiaqi2554/10049464
5.介绍伽马在摄像和显示中存在的原因和意义:http://download.csdn.net/download/tanjiaqi2554/10049457
6.FAT文件系统介绍文档和官方协议:http://download.csdn.net/download/tanjiaqi2554/10049444
7.使用wireshark和bushound抓取的usb设备数据包:http://download.csdn.net/download/tanjiaqi2554/10049454
8.USB协议官方文档:http://download.csdn.net/download/tanjiaqi2554/10049441

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐