Bus Hound 使用指南

Bushound是一款使用起来非常方便快捷的总线数据抓取工具,在我们的测试过成当中,经常会使用它来抓取数据及传输状态用于分析。在这里以usb数据传输为例,大概介绍一下Bushound的使用方法,以及一些典型异常情况的分析。

一、BusHound界面介绍

/uploads/article/20190912/390ed67d8c2889f5791dc24673c43e70.png

打开BusHound之后,显示的是这样的界面。当前所显示的界面为顶端界面选项当中的Capture窗口,这个窗口用于显示所有抓取到的数据。点击Stop时会停止数据抓取,这时点击Run,会清空当前数据并开始抓取数据。

/uploads/article/20190912/3f104b9ad478ff7c076512e145fb56f7.png

这些是想要显示的内容,这些内容可以在Settings窗口下面的Columns to Display设置

扫描二维码关注公众号,回复: 11592674 查看本文章

/uploads/article/20190912/b276bb9a21f64830537c30db9060e030.png

选项当中有对应显示内容的解释,在这里就不一个个细说了。

在数据抓取时,不管有没有勾选相应内容,Bushound都会抓取所有Columns to Display当中选项的数据,只是不显示出来而已。如果在抓取完之后想要看相关数据的话,只需要将对应的选项勾选上即可。

在Settings当中可以设置需要显示的内容。

/uploads/article/20190912/d9dcf3c844237f1a91dc0d57249d54dd.png

这些选项内容如果在抓取数据的时候没有勾选,那么Bushound是不会抓取的。

在Limits栏中可以设置预留给Bushond抓取数据的缓存空间

/uploads/article/20190912/1eb383ed9f740f7cc9922bcf14fd2222.png

Capture Capacity表示缓存的总数据量,Max Record Length表示抓取一个数据包时缓存的数据的量(一条命令\一个状态\一次数据传输,都算一个数据包)。这个在需要的时候可以尽可能设置的大一些,这样抓取的数据比较全面,当数据缓存满了之后,若没有勾选下面的自动停止,则会清除掉所有数据,自动重新开始抓取。

/uploads/article/20190912/3af21049e1c7d07ed7337da6f0dc4c9c.png

在这个栏目里可以选择什么时候需要自动停止bushound的数据抓取。

/uploads/article/20190912/1fd156559bd4a5d72de4f6243dc88f83.png

Save窗口就是常见的数据保存

/uploads/article/20190912/c6e87221a62d926d050b8d1d9a7d20d5.png

Device窗口,用于选择需要抓取的设备及协议层。当勾选到对应的设备那一项时,显示的是经过解析的SCSI协议,设备再上一层是原始的SCSI协议数据。

二、基本协议解析介绍

抓取最简单的的命令时,只需要像上图一样勾选相应设备前面的选项即可,这时抓到的数据主要由 CMD OUT IN组成

/uploads/article/20190912/463dd10cd01653f1518ca73eb3a8f47b.png

(这里我将Max Record length设为16)

CMD表示发送的命令,IN 和 OUT表示数据的读取和发送,关于CMD的含义,这里给出一个列表

/uploads/article/20190912/6cc861d1ba02731e3bea953598783d22.png

这分列表从参考文档SCSI_Commands_Reference_Manual截取出来的,详细相关命令信息也可以从里面查找。

当在Device窗口中勾选了设备的上一层选项时,这时抓到的是SCSI的原始数据

/uploads/article/20190912/727040a950878897874bac86b12a5743.png

/uploads/article/20190912/e567794273e802c94e32673063cb1835.png

可以看到数据明显多了很多,而且眼花缭乱..

我们一点点来解析一下

首先看第一行

/uploads/article/20190912/531b05c3e47a7d2dc1d079dda70b6745.png

这个就是2Ah写命令的原型,Byte[0:3]为小端数据 0x43425355,这个标志在叫做CBW,表示一次命令传输的开始,由Host下发。

Byte[4:7]为CBW Tag,用于给这一个数据包做一个标识。

Byte[8:11]表示命令之后将要传输的数据长度,这里为0x1000即时4096Bytes。

Byte[12]当中的Bit[7]用于表示传输方向,1为读取,0为发送(其他的暂时还没去看)。

Byte[13]表示操作的设备的Lun号,一个设备可以被分为多个分区,即多个Lun,这里用于表示命令是发送给设备的哪一个Lun的。

从Byte[15]开始,就是之前解析过后的CMD数据了,这里大概说一下重要位置的含义,从这里开始数据为大端数据

Byte[0] OpCode 

Byte[1] SubOpCode

Byte[2:5] Address 以Sector为单位

Byte[7:8] Length 以Sector为单位

需要注意的是,除了OpCode以外,其他位置的含义并不是固定的,只是在进行2Ah和28h数据传输过程中,这是比较典型的含义。

所以现在重新看下这一行命令,其用途就是,一条2A的写命令,地址为0x000057A0,长度为8 Sector

下一条就是这个2Ah写命令的数据传输,下发了4096 Bytes数据

/uploads/article/20190912/d17e3542fddaeb2f5784cd4cb3188d25.png

我这里为了看起来方便,将抓取长度设成32bytes

再下一条

/uploads/article/20190912/cffcae5840a441cac8743040cfc24bae.png

这是一个由Device发送给Host的数据,开头标识为0x53425355,叫做CSW,用于标志一条SCSI命令传输结束,Byte[4:7]为对应的CBW的Tag。

到此为止,一条SCSI命令就算分析完了,后面的依此类推即可。

后面抽时间再介绍异常状态分析吧

三、SCSI命令发送

打开Devices窗口,双击要发送命令的设备

/uploads/article/20190912/ff65868f2d9207e99db3d3ef9a5ac75d.png

这时会弹出发送命令控制窗

/uploads/article/20190912/e89d79e7b9a8cb8802b57f761b5e5ae1.png

我一般不用USB来发送命令,点击标签栏的SCSI / ATAPI

/uploads/article/20190912/bdd1d6be6f1e08519a4255c6984ca03a.png

这里就可以按照自己想要发送的格式来发送命令,也可以发送自己定制的命令。

/uploads/article/20190912/dc8b6568746dc5fa60b507e9e98e9064.png

这里填写要发送的命令的相关信息,就是Opcode,SubOpCode那些,这里的话填的是一个28h读命令,地址为0x00000020,长度为0x20 Sector。

上面的填好之后,要在DataLength那里填写要进行传输的数据量,0x20 Sector即为16384 Bytes,所以填写16384,因为是读数据,所以方向选择Data In

/uploads/article/20190912/e5bf1952c47f76985b0f43b17cadad0e.png

Timeout表示当超过该设定时间,命令还没有完成的话,则视为超时。从这里可以看出SCSI协议实际上并没有规定超时时间,而是人为设定的。

都填好了之后点击run,就会发送出命令了,左下角会显示出发送的命令的状态。

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

例:

Bus Hound抓包分析

Device:17.0  ——  表示ID为17的设备的0号端点

Phase:阶段列

Cmd.phase.ofs:命令数.阶段数.每个阶段中字节的偏移量

CTL:表示8字节的USB控制传输的Setup包

bmRequestType  ——  80:数据方向从USB到PC;标准的请求;USB设备接收

bRequest  ——  06:表示接下来发送的数据时GET_DESCRIPTOR(主控器读取USB描述符)

wValue  ——  00 01:从偏移地址0开始读取设备描述符

wIndex  ——  00 00:一般用于说明端点号或者接口标识

wLength  ——  12 00:下一阶段发送数据的长度为18个字节(小端格式理解)

First  【IN】:数据传输(USB设备到PC)

bLength  ——  12:数据字节长度为18

bDescriptorType  ——  01:设备描述符

bcdUSB  ——  00 02:USB设备2.0协议
bDeviceClass  ——  ef:USB_DEVICE_CLASS_MISCELLANEOUS(杂项)

bDeviceSubClass  ——  02

bDeviceProtocol  ——  01

bMaxPacketSize0  ——  40:最大包长64个字节

idVendor  ——  1Fc9

idProduct  ——  100B

bcdDevice  ——  0100

iManufacturer  ——  01

iProduct ——  02

iSerialNumber  ——  03

bNumConfigurations  ——  01

Second 【IN】

bLength —— 09:该描述符结构体的大小为9个字节

bDescriptorType ——02:配置描述符

wTotalLength  ——29 00:配置返回的所有数据大小为41个字节(其实是指明下一次传输的数据字节大小)

bNumInterfaces  ——01:此配置的接口数量

bConfigurationValue  ——01:此配置所需要的参数值

iConfiguration  ——00:描述该配置的字符串的索引值

bmAttributes  ——C0:供电模式的选择USB_CONFIG_SELF_POWERED(自供电)

bMaxPower  ——32:设备从总线提取的最大的电流100mA

Third 【IN】(前面数据和第二个IN一样,从32后开始分析)

bLength  ——  09:接口描述符结构体大小

bDescriptorType  —— 04:USB_INTERFACE_DESCRIPTOR_TYPE

bInterfaceNumber  ——  01:该接口的编号

bAlternateSetting   ——   00:备用的接口描述符编号

bNumEndpoints  —— 02:该接口使用的端点数,不包括端点0

bInterfaceClass  ——  03:接口类型为USB_DEVICE_CLASS_HUMAN_INTERFACE(HID)

bInterfaceSubClass  ——  00:接口子类型

bInterfaceProtocol  ——  00:接口遵循的协议

iInterface  ——  04:描述该接口的字符串索引值

HID Class Descriptor

bLength  ——09:该HID描述符的大小

bDescriptorType —— 21:HID_HID_DESCRIPTOR_TYPE

bcdHID  —— 00 01:HID类协议版本号,为1.1

bCountryCode  —— 00:固件的国家地区代码

bNumDescriptors  —— 01:下级描述符的个数

bDescriptorType  —— 22:下级描述符为HID_REPORT_DESCRIPTOR_TYPE(报告描述符)

wDescriptorLength  —— 2C 00:下级描述符的长度

Endpoint HID Interrupt In

bLength  ——  07

bDescriptorType  ——  05:端点描述符

bEndpointAddress  ——  84:HID_EP_IN Address

bmAttributes  ——  03:USB_ENDPOINT_TYPE_INTERRUPT

wMaxPacketSize  ——  04

bInterval  ——  00 20:间隔为16ms

Endpoint HID Interrupt Out

bLength  ——  07

bDescriptorType  ——  05:端点描述符

bEndpointAddress  ——  04:HID_EP_OUT Address

bmAttributes  ——  03:USB_ENDPOINT_TYPE_INTERRUPT

wMaxPacketSize  ——  04

bInterval  ——  00 20:间隔为16ms

CTL:表示8字节的USB控制传输的Setup包

bmRequestType  —— 00:数据方向从PC到USB;标准的请求;USB设备接收

bRequest  ——  09:表示接下来的请求是SET_CONFIGURATION (设置配置)

wValue  ——  00 01:从偏移地址0开始读取设备描述符

wIndex  ——  00 00:一般用于说明端点号或者接口标识

wLength  ——  00 00

CTL:表示8字节的USB控制传输的Setup包

bmRequestType  —— 21:数据方向从PC到USB;Class类的请求;接口接收

bRequest  ——  0a:表示接下来的请求是GET_INTERFACE (获取接口)

wValue  ——  00 00:从偏移地址0开始读取设备描述符

wIndex  ——  01 00:接口标识为01

wLength  ——  00 00

CTL:表示8字节的USB控制传输的Setup包

bmRequestType  —— 81:数据方向从USB到PC;标准请求;接口接收

bRequest  ——  06:表示接下来的请求是获取描述符

wValue  ——  00 22:从偏移地址00 22开始读取描述符

wIndex  ——  01 00:接口标识为01

wLength  ——  6C 00:数据长度为108个字节

Fourth 【IN】——HID Report Descriptor

具体参考usbdesc.c内的设置

分析整个通信过程则可知其传输事务过程如下:

1、Setup事务,传输Setup数据格式包,告诉设备接下要获取USB描述符,但不知道描述符的类型,并指明了接下来的数据传输方向和传输的数据大小

2、IN传输事务,表示设备传输数据到PC,传输中指明了这次传输的数据大小,类型是设备描述符以及其他相关的设备信息

3、Setup事务,改变了读取描述符的偏移地址和传输数据的大小

4、N传输事务,但描述符类型是配置描述符,指明了接口数量、供电模式、最大电流等参数

5、Setup事务,再次获取配置描述符,仅仅改变了获取的传输数据的大小为41个字节,即下一次准备接收41个字节

6、IN事务,返回配置描述符时连并接口、端点描述符都一起返回,向PC指明了这是个HID接口以及其使用的端点数

7、Setup事务,设置配置

8、Setup事务,设置接口闲置状态

9、Setup事务,获取描述符

10、IN事务,设备发送HID报告描述符给PC

猜你喜欢

转载自blog.csdn.net/sinat_26528193/article/details/107686489