USB与BT HID reports描述符实践与抓包分析

文章内容提示

这篇文章主要说明如何获取与查看USB和BLE HoGP HID设备报告描述符,如何根据获取的描述符读懂report。然后说明了可以使用hidrd-convert工具,来如何根据hex报告描述符转化得到C语言格式的描述符,这对于我们编码是有意义的。 其中,还截取了USB 逻辑分析仪,Wireshark等工具来查看input report。

如何看懂HID report descriptor

对于如何看懂HID报告描述符,几乎离不开下面的这两个pdf:

USB HID Usage Table

USB HID Spec

先看文档(USB HID设备)弄明白一些基本概念:

  1. 项目Item的意义
  2. collection与end collection:namespace的意义,相当于将多个usage page
  3. usage page与 usage
  4. Logical Minimum 与 Logical Maximum
  5. Usage Minimum 与 Usage Maximum
  6. input
  7. report size 与 report count

 

个人认为先准备好这份文档,然后结合一些文章来理解比较快速。以下是个人认为的快速理解的步骤:

1. 看这篇(Tutorial about USB HID Report Descriptors)文章,理解一些基本的概念,主要弄明白概念4与5

2. 不要太过于纠结如何从hex转换到方便大家阅读的格式的report

例如下面这个描述符,我们应该直接看注释而,然后可以知道描述的是mouse,然后根据usage page和usage的值在usage table pdf中找到对应的描述,然后根据对基本概念的了解知道如果鼠标的一个按键按下那么会生成怎么样的report即可:

3. 看后面的 “1. 使用usbhid-dump工具获取报告描述符” 章节了解report字节数的构成来源

需要注意的是input是报告给主机(例如PC,Android)的,因此只能算input的,在主机到设备的时候只能算output的

4. 看文章《HID reports》,结合pdf弄明白一个keyboard的report为何是8个字节,在USB interrupt IN中传输的数据是怎么样的。也可以看后面的USB分析仪给出的例子。

5. 了解hex如何对应不同的Tag,看这篇文章

BT中的HoGP, USB HID设备

如何看懂HID reports

蓝牙BLE的HoGP生成的report

Linux下如何查看report

这里需要区分USB HID与BT通过HoGP生成的HID设备,这两种方式生成的HID设备描述符可以使用的工具不一样。

USB HID设备

1. 使用usbhid-dump工具获取报告描述符

在Linux下,如果一个USB HID设备插入后,在dmesg中可以看到具体的信息,然后可以看到其生成的hid input设备号,例如下面这个设备生成了多个hid input设备

 

上面生成了三个HID Input设备,我们选中其中一个用来分析HID report descriptor。选取的一个设备的描述符为:

后面我们将使用这个设备的报告描述符中的reportID=3的item为例,对其report进行监听和分析。下面是对这个reportID对应的collect的摘抄:

可以看到其report size=16, 即16bits,也就是2Bytes,即每个Filed使用2B来表示,而report count=2, 即有两个filed,故每次的输入报告的字节数(这里面只算input,这个例子也只有input)总共为4个Byte。这里面还有一个report ID =3, 因此我们可以知道每次发送report的时候,将会有5个字节,格式为:

reportID + 4B的reportValue

这个在后面的图Wireshark中由体现和说明,也在后面的USB 逻辑分析仪图中由表示,同时在usbhid-dump的示例中也有log,具体可以结合此来分析。

使用调试接口查看BLE HoGP与USB HID的描述符

见文章后面的内容。

监听获取的report

使用usbhid-dump

按下Volume Down:

 

使用hid的调试接口获取报告描述符

不管是对于USB HID还是BLE过来的通过HoGP生成的HID设备,在/sys/kernel/debug/hid下面都有暴露对应的调试接口,从这边我们可以结合hidrd工具来获取他们的HID报告描述符。

这种方式尤其对于BLE HoGP设备非常有用,如果我们身边没有蓝牙转包工具的时候。

首先切换到root用户,然后进入到debug接口目录中:

在这些设备里面有rdesc和event两个文件,这两个文件的前者是report descriptor,dump一个出来作为例子:

第一部分的hex array是hex格式的report descriptor,后面的是解析后的方便人看的风格的report descriptor。

蓝牙与USB HID设备的report descriptor查看方法

其中前面的那一串hex数值,是hex格式的描述符,我们可以使用hidrd-convert来转换。在下面我们将用这个为例子说明。

hidrd-convet的功能不仅仅是将hex array转换成可行性好的spec格式,也可以将其转换成C语言分割,XML格式。

具体看法常见hidid工具的github主页,或者使用hidrd-convert –help说明。

另外,hidrd项目已经有许多年没有更新了,基本功能可用,但是可能会出现问题。在Ubuntu 14.04和16.04下面ld-config配置不正确,所以会导致在运行hidrd相关程序的时候出现找不到库。对此我在项目中提交了issue:library is not found when execute the hid-convert in Ubuntu 14.04 and 16.04 after make install #19, 对于这个问题,可以设置LD_LIBRARY_PATH环境变量来解决。

USB分析仪中的report

如果使用Beagle USB Analyzer来抓包的话,input report会被分析仪解析出来,结果如下:


WireShark转包查看report

Wireshark抓包分析USB需要先安装usbmon模块

然后确定需要分析的USB设备的USB Bus ID:

据此知道其位于USB Bus3上面,因此在打开Wireshark后选择usbmon3,然后就可以抓包了。

和USB分析仪一样,我们选择同样的Volume Down为例,下面是截图,带有Wireshark的分析的说明:


后面的数据便是report data了。格式为ReportID + Input数值Arrary

参考

0. dump hid report in Linux

1. Tutorial about USB HID Report Descriptors

2. DigiMend: Collecting tablet diagnostics

Leave a Reply

Your email address will not be published. Required fields are marked *