Documentation
¶
Overview ¶
Package usbdesc decodes USB descriptors — the self-describing data structures a USB device returns during enumeration (the device, configuration, interface, endpoint, HID and string descriptors of USB 2.0 / 3.x). It is the device-fingerprinting and BadUSB-analysis companion to the project's usbhid (HID report decode) and badusb tooling. A captured descriptor blob (from `lsusb -v`, a USB sniffer, or the device itself) identifies the device: its **idVendor / idProduct** (the VID:PID fingerprint), its device and per-interface **class** (HID / Mass Storage / CDC / …), and its endpoints. This is real recon: an unexpected **HID boot-keyboard interface** (class 3 / subclass 1 / protocol 1) is the signature of a BadUSB / rubber- ducky keystroke-injector masquerading as a peripheral, and a **composite device** that mixes, say, a keyboard with mass storage is a classic malicious-USB pattern — both are flagged.
Wrap-vs-native judgement ¶
Native. USB descriptors are fixed, length-prefixed little-endian structures defined by the USB specification: each descriptor is bLength + bDescriptorType + type-specific fields, and a configuration blob is a concatenation walked by bLength. A byte-slice walk + field reads + a class-code lookup; stdlib only, no new go.mod dep.
Verifiable / no confidently-wrong output ¶
The descriptor layouts and the USB-IF base class codes follow the USB specification (and match `lsusb` output) — the structures are deterministic and byte-checkable against spec-built vectors. The Device, Configuration, Interface, Endpoint, Interface-Association, HID and String descriptors are decoded; a class-specific or unknown descriptor type is surfaced by type with its body as raw hex (the class-specific layouts are many and vendor-defined), and a bLength that is zero or overruns the buffer stops the walk rather than guessing.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Descriptor ¶
type Descriptor struct {
Length int `json:"length"`
Type int `json:"type"`
TypeHex string `json:"type_hex"`
TypeName string `json:"type_name"`
// Device (0x01)
USBVersion string `json:"usb_version,omitempty"`
DeviceClass string `json:"device_class,omitempty"`
DeviceSubClass *int `json:"device_subclass,omitempty"`
DeviceProtocol *int `json:"device_protocol,omitempty"`
MaxPacketSize0 *int `json:"max_packet_size_0,omitempty"`
VendorID string `json:"vendor_id,omitempty"`
ProductID string `json:"product_id,omitempty"`
DeviceVersion string `json:"device_version,omitempty"`
NumConfigurations *int `json:"num_configurations,omitempty"`
// Configuration (0x02)
TotalLength *int `json:"total_length,omitempty"`
NumInterfaces *int `json:"num_interfaces,omitempty"`
ConfigValue *int `json:"configuration_value,omitempty"`
Attributes string `json:"attributes,omitempty"`
MaxPowerMA *int `json:"max_power_ma,omitempty"`
// Interface (0x04)
InterfaceNumber *int `json:"interface_number,omitempty"`
AlternateSetting *int `json:"alternate_setting,omitempty"`
NumEndpoints *int `json:"num_endpoints,omitempty"`
InterfaceClass string `json:"interface_class,omitempty"`
InterfaceSubClass *int `json:"interface_subclass,omitempty"`
InterfaceProtocol *int `json:"interface_protocol,omitempty"`
// Endpoint (0x05)
EndpointAddress string `json:"endpoint_address,omitempty"`
EndpointType string `json:"endpoint_type,omitempty"`
EndpointMaxPkt *int `json:"endpoint_max_packet_size,omitempty"`
EndpointInterval *int `json:"endpoint_interval,omitempty"`
// String (0x03)
String string `json:"string,omitempty"`
PayloadHex string `json:"payload_hex,omitempty"`
}
Descriptor is one decoded USB descriptor.
type Result ¶
type Result struct {
Descriptors []Descriptor `json:"descriptors"`
Notes []string `json:"notes,omitempty"`
}
Result is the decoded view of a USB descriptor blob.