ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

第3讲:描述符——USB设备的身份证体系

第3讲:描述符——USB设备的身份证体系

USB 教程合集 - 总目录

本讲目标

学完这一讲,你应该能够理解 USB 描述符为什么分成多个层级,知道每一层描述符负责什么,并且能够拿到一段设备描述符后,尝试逐个字段解释它的含义。

一、为什么 USB 设备需要描述符?

上一讲我们说过,USB 通信是 Host 主导的问答过程。

电脑通过 USB 线连接一个设备后,并不能直接知道它是键盘、鼠标、U 盘,还是一个自定义的单片机设备。

那么,电脑是怎么知道的?

答案就是:描述符(Descriptor)。

你可以把描述符理解成设备递交给电脑的一份资料。电脑通过读取这些资料,了解设备的基本信息、功能组织方式,以及后续应该通过哪些端点进行通信。

但这里有个问题:一个设备可能有多个功能,例如一个 USB 设备既是键盘,又是鼠标,还提供一个虚拟串口。如果所有信息都塞进同一个描述符,不仅难以管理,也不利于操作系统分别加载驱动。

因此,USB 使用了分层的描述符体系。

二、描述符是一棵树

可以先记住下面这张结构图:

Device Descriptor(设备描述符) | └── Configuration Descriptor(配置描述符) | ├── Interface Descriptor(接口描述符) | | | ├── 类专用描述符(可选) | └── Endpoint Descriptor(端点描述符) | └── Interface Descriptor(另一个接口) | └── Endpoint Descriptor

这里需要注意:配置描述符后面并不是只跟一个接口。一个配置可以包含多个接口,每个接口也可能包含多个端点。

下面分别看看这些描述符的作用。

2.1 设备描述符:先告诉电脑你是谁

设备描述符(Device Descriptor)描述整个 USB 设备的基本信息,例如:

其中,VID 和 PID 经常出现在设备管理器和 USB 抓包工具中。

2.2 配置描述符:设备有哪些工作配置?

配置描述符(Configuration Descriptor)描述一种设备配置,包含配置值、接口数量以及整个配置描述符集合的总长度等信息。

大多数简单 USB 设备只有一个配置,但协议允许设备提供多个配置。

这里的“配置”不是简单的应用软件配置文件,而是 USB 设备向 Host 提供的一组接口和端点组织方式。

2.3 接口描述符:这个接口负责什么功能?

接口描述符(Interface Descriptor)描述一个接口的基本信息,包括:

例如,HID 接口通常会声明 HID 类相关信息。CDC 设备则可能通过多个接口共同实现虚拟串口功能。

操作系统经常根据接口信息决定如何匹配驱动,而不是只看整个设备的 VID/PID。

2.4 端点描述符:具体从哪里传输数据?

端点描述符(Endpoint Descriptor)描述一个端点的地址、方向、传输类型、最大包长,以及相应的间隔字段。

例如,一个设备可能有:

Endpoint 0x81:IN 方向 Endpoint 0x01:OUT 方向

这里的0x81和0x01是示意值,不代表某个真实设备。

端点地址的最高位用于表示方向:最高位为 1 表示 IN,为 0 表示 OUT;低四位表示端点编号。

IN 和 OUT 的方向始终以 Host 为参照。

端点的详细含义,我们在第4讲中继续讨论。

三、VID 和 PID 到底是什么?

VID 是 Vendor ID,即厂商标识;PID 是 Product ID,即产品标识。

可以简单理解为:

但它们并不是 USB 设备功能的全部描述。即使两个设备使用不同的 VID/PID,它们也可能都属于 HID 键盘;反过来,同一个产品也可能通过不同接口提供多种功能。

正式产品使用 VID/PID 时,需要遵守相应的分配和授权规则,不能随意冒用其他厂商的标识。

四、如何读懂一段设备描述符?

假设我们看到下面这段数据:

bLength 18 bDescriptorType 01h bcdUSB 0200h bMaxPacketSize0 64 idVendor 0x1234 idProduct 0x5678 bNumConfigurations 1

这是一段简化的示意信息,并不是完整的设备描述符,也不代表真实厂商。

逐项理解:

需要注意,USB 描述符中的多字节数值通常使用小端序存储。例如,原始字节34 12对应的数值是0x1234。

如果抓包工具已经把原始数据解析成字段,就可以直接阅读解析结果;如果拿到的是十六进制原始数据,则需要结合字段长度、字段顺序和字节序进行分析。

五、为什么电脑会分多次读取描述符?

配置描述符后面还可能包含接口描述符、端点描述符和类专用描述符,因此整个配置集合的长度并不是固定的。

Host 通常可以先读取配置描述符开头的 9 字节,从wTotalLength得知整个配置描述符集合的长度,然后再读取完整内容。

所以,如果你在抓包中发现电脑先读取一小段配置描述符,随后又读取更长的一段,这通常是正常的枚举过程,不一定是设备发生了异常。

六、本讲小结

本讲只需要记住一个核心结构:

设备描述符描述整个设备,配置描述符组织接口,接口描述符描述功能,端点描述符描述数据通道。

不要急着记住所有字段。拿到一段真实设备的描述符时,先找到它属于哪一层,再逐个解释字段,会容易得多。

留给下一讲的问题

电脑已经知道设备有哪些端点,那么端点究竟是什么?为什么键盘、U 盘和摄像头使用的传输方式不一样?

下一讲,我们来认识端点、管道与 USB 四种传输类型。


RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进