【问题标题】:How to interpret "0000290000000000" sent by my keyboard as USB payload?如何将我的键盘发送的“0000290000000000”解释为 USB 有效负载?
【发布时间】:2022-01-04 16:54:52
【问题描述】:

我正在尝试通过分析 Wireshark 在我的键盘上嗅探的输出来了解 USB 协议。例如,考虑这个框架:

Frame 29335: 72 bytes on wire (576 bits), 72 bytes captured (576 bits) on interface usbmon1, id 0
    Interface id: 0 (usbmon1)
    Encapsulation type: USB packets with Linux header and padding (115)
    Arrival Time: Jan  4, 2022 17:44:50.003878000 CET
    [Time shift for this packet: 0.000000000 seconds]
    Epoch Time: 1641314690.003878000 seconds
    [Time delta from previous captured frame: 0.205081000 seconds]
    [Time delta from previous displayed frame: 3.343982000 seconds]
    [Time since reference or first frame: 342.817999000 seconds]
    Frame Number: 29335
    Frame Length: 72 bytes (576 bits)
    Capture Length: 72 bytes (576 bits)
    [Frame is marked: False]
    [Frame is ignored: False]
    [Protocols in frame: usb]
USB URB
    [Source: 1.5.1]
    [Destination: host]
    URB id: 0xffff8cbe330fba80
    URB type: URB_COMPLETE ('C')
    URB transfer type: URB_INTERRUPT (0x01)
    Endpoint: 0x81, Direction: IN
    Device: 5
    URB bus id: 1
    Device setup request: not relevant ('-')
    Data: present (0)
    URB sec: 1641314690
    URB usec: 3878
    URB status: Success (0)
    URB length [bytes]: 8
    Data length [bytes]: 8
    [Request in: 29167]
    [Time from request: 3.343946000 seconds]
    [bInterfaceClass: Unknown (0xffff)]
    Unused Setup Header
    Interval: 16
    Start frame: 0
    Copy of Transfer Flags: 0x00000204, No transfer DMA map, Dir IN
    Number of ISO descriptors: 0
Leftover Capture Data: 0000290000000000

这里是相关的 lsusb 输出:

> sudo lsusb -s 001:005 -vvvvv

Bus 001 Device 005: ID 046d:c312 Logitech, Inc. DeLuxe 250 Keyboard
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0         8
  idVendor           0x046d Logitech, Inc.
  idProduct          0xc312 DeLuxe 250 Keyboard
  bcdDevice            1.01
  iManufacturer           1 LITEON Technology
  iProduct                2 USB Multimedia Keyboard
  iSerial                 0 
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength       0x0022
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0 
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower               70mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0 
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      65
         Report Descriptors: 
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              24
can't get debug descriptor: Resource temporarily unavailable
Device Status:     0x0000
  (Bus Powered)

“29”根据我按下的键而有所不同。如何将其映射回特定键?是否需要更多上下文来解释这个框架?

【问题讨论】:

  • 您是否在 x86-64 CPU 架构上进行测试?
  • @user123 是的。这些有效载荷的解释是否会因此而有所不同?
  • 我不这么认为,但 USB 控制器可能不同。在 x86-64 上,您会发现 xHC,而在 ARM 上,与硬件的标准化接口较少,因此每个主板都有自己的芯片组需要支持。它可以改变数据的解释,但我不确定具体如何。可以肯定的是,使用 xHC 而不是使用主板制造商为 ARM 制造的随机芯片组更容易解释事情是如何工作的。
  • 但是,我在这里和那里阅读,xHCI 似乎也用于许多 ARM 计算机。

标签: usb wireshark


【解决方案1】:

USB 有效负载代表扫描码(参见此处:https://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html)。解释需要更多的上下文。

可扩展主机控制器接口 (xHCI) 定义了一个寄存器级接口以与现代系统上的 USB 交互 (https://www.intel.com/content/dam/www/public/us/en/documents/technical-specifications/extensible-host-controler-interface-usb-xhci.pdf)。正如我在这里和那里所读到的,大多数计算机(包括 ARM 计算机)都支持 xHCI 作为其 USB 主机控制器。通常,它将采用称为 xHC(英特尔术语)的 PCI-Express 设备的形式。

PCI 设备是 MMIO 和 DMA。要与 PCI 设备交互,您可以在 ACPI 表(更具体地说,MCFG)指定的常规位置写入 RAM。当您在这些常规位置写入 RAM 时,它将写入 PCI 设备的寄存器,而不是允许控制设备。 PCI 设备也可以直接在 RAM 中读/写。

xHC 具有中断传输环。软件(操作系统)会将 TD 放置在键盘中断端点的中断传输环上的适当深度。如 xHCI 规范中所述(如上链接):

如果将多个中断 TD 发布到中断端点传输环,则 xHC 每个 ESIT 消耗的 TD 不应超过一个。

基本上,您使用值对 ESIT 进行编程。 ESIT 值告诉 xHC 不要太频繁地消耗 TD。这将允许在特定时间间隔触发传输。正确的时间间隔在 USB 设备返回的 USB 描述符中指定。

每次传输发生时,软件 (OS) 都会读取值并确定按下的键是否有任何变化。键盘是人机接口设备 (HID),被指定为 USB 标准 (https://wiki.osdev.org/USB_Human_Interface_Devices) 的一部分。

当被要求传输数据时,USB 键盘 (HID) 返回 8 个字节(如您的示例所示)。如 osdev.org 所述:

该报告必须由软件使用中断传输每间隔毫秒请求一次,并且间隔在 USB 键盘的中断 IN 描述符中定义。 USB 键盘报告的大小可能高达 8 个字节,尽管并非所有这些字节都被使用,并且只使用前三个或四个字节来实现正确的实现是可以的(这就是我的做法。)只是为了完成,但是,我将描述键盘的完整报告机制。请注意,下面定义的报告结构仅适用于引导协议。

也许阅读 osdev.org 的 HID 文章,这会给你带来很长的路要走。因此,USB 有效负载可以被解释为在键盘的 USB 描述符中指定的以毫秒为单位的时间间隔过后,键盘发送的数据。每次有新数据进来时,新数据就是每次 ESIT 左右 xHC 查询时在键盘上按下的键。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-09
    • 2016-11-23
    相关资源
    最近更新 更多