使用Libusb 1.0.25效仿USBHID流量
我目前正在尝试使用libusb模拟发送到HID设备的流量。使用Wireshark和USBPCAP嗅探流量。我通过请求描述符和设置配置等模拟了第一个数据包,但是在这一点上,根据日志,主机发送设置的空闲请求,获取描述符HID报告,最后一堆设置报告。 libusb中的哪些功能与这些数据包相对应? afaik设置报告基本上是主机将某种设置传输到设备。我认为我可以复制数据包数据并发送自己的报告完全相同吗?还有一种方法可以准确查看数据在设置报告数据包中的作用吗?我需要知道如何正确设置它。
这是我要模拟的数据包:
1 0.000000 host 2.41.0 USB 36 GET DESCRIPTOR Request DEVICE
2 0.000174 2.41.0 host USB 46 GET DESCRIPTOR Response DEVICE
3 0.000208 host 2.41.0 USB 36 GET DESCRIPTOR Request CONFIGURATION
4 0.000291 2.41.0 host USB 37 GET DESCRIPTOR Response CONFIGURATION
5 0.000304 host 2.41.0 USB 36 GET DESCRIPTOR Request CONFIGURATION
6 0.000395 2.41.0 host USB 62 GET DESCRIPTOR Response CONFIGURATION
7 0.000411 host 2.41.0 USB 36 SET CONFIGURATION Request
8 0.001150 2.41.0 host USB 28 SET CONFIGURATION Response
9 0.001167 host 2.41.0 USBHID 36 SET_IDLE Request
10 0.001239 2.41.0 host USBHID 28 SET_IDLE Response
11 0.001386 host 2.41.0 USBHID 36 GET DESCRIPTOR Request HID Report
12 0.001462 2.41.0 host USBHID 104 GET DESCRIPTOR Response HID Report
13 0.002620 host 2.41.1 USB 27 URB_INTERRUPT in
14 0.002645 host 2.41.1 USB 27 URB_INTERRUPT in
15 6.085037 2.41.1 host USB 27 URB_INTERRUPT in
16 6.085090 2.41.1 host USB 27 URB_INTERRUPT in
17 18.467828 host 2.41.0 USBHID 36 SET_IDLE Request
18 18.467993 2.41.0 host USBHID 28 SET_IDLE Response
19 18.468086 host 2.41.1 USB 27 URB_INTERRUPT in
20 18.468114 host 2.41.1 USB 27 URB_INTERRUPT in
21 18.468385 host 2.41.0 USB 36 GET DESCRIPTOR Request STRING
22 18.468537 2.41.0 host USB 86 GET DESCRIPTOR Response STRING
23 18.468595 host 2.41.0 USB 36 GET DESCRIPTOR Request STRING
24 18.468801 2.41.0 host USB 60 GET DESCRIPTOR Response STRING
25 18.475044 host 2.41.0 USBHID 53 SET_REPORT Request
26 18.475273 2.41.0 host USBHID 28 SET_REPORT Response
27 18.475834 host 2.41.0 USBHID 1061 SET_REPORT Request
28 18.476102 2.41.0 host USBHID 28 SET_REPORT Response
29 18.476571 host 2.41.0 USBHID 1061 SET_REPORT Request
30 18.476849 2.41.0 host USBHID 28 SET_REPORT Response
31 18.477280 host 2.41.0 USBHID 1061 SET_REPORT Request
32 18.477565 2.41.0 host USBHID 28 SET_REPORT Response
33 18.478085 host 2.41.0 USBHID 1061 SET_REPORT Request
34 18.478329 2.41.0 host USBHID 28 SET_REPORT Response
35 18.478700 host 2.41.0 USBHID 1061 SET_REPORT Request
我认为我需要声明接口并设置端点。但是我很难理解如何将系统设置为HID类,正确设置中断和轮询等。此时,我有配置描述符,设备描述符和设备手柄可以使用。
#include <stdio.h>
#include "libusb.h"
#include <unistd.h>
#include <time.h>
static void print_devs(libusb_device **devs) //Taken from examples provided with libusb. Not used at this time
{
libusb_device *dev;
int i = 0, j = 0;
uint8_t path[8];
while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(dev, &desc);
if (r < 0) {
fprintf(stderr, "failed to get device descriptor");
return;
}
printf("%04x:%04x (bus %d, device %d)",
desc.idVendor, desc.idProduct,
libusb_get_bus_number(dev), libusb_get_device_address(dev));
r = libusb_get_port_numbers(dev, path, sizeof(path));
if (r > 0) {
printf(" path: %d", path[0]);
for (j = 1; j < r; j++)
printf(".%d", path[j]);
}
printf("\n");
}
}
int port_open (libusb_device* dev, libusb_device_handle** dev_handle){ //Homebrew func. Retries after failed libusb_open
int count = 0;
int err = 0;
printf("Attempting to open port...\n");
while (1){
printf(".\n");
err = libusb_open(dev, &dev_handle); //Attempts to open port
if (err == 0){
break;
}
if(count>TIMEOUT){ //5s without the port opening and it will throw error
printf(libusb_error_name(err));
return -1;
}
count++;
delay(1);
}
return 0;
}
static int target_find(libusb_device *dev){ //Check for device. Libusb already had this but it was done before I saw it.
struct libusb_device_descriptor my_dev;
libusb_get_device_descriptor(dev,&my_dev);
if ((my_dev.idVendor == VENDOR) && (my_dev.idProduct == PRODUCT)){
return 1;
}
return 0;
}
int main(void)
{
int r;
int err = 0;
err = libusb_init(NULL);
if (err != 0) {
printf("LIBUSB ERROR: Could not initialize\n");
return -1;
}
libusb_device **list;
libusb_device *found = NULL;
while(1){ //Finds device and opens port
ssize_t cnt = libusb_get_device_list(NULL, &list);
ssize_t i = 0;
err = 0;
if (cnt < 0){
printf("USB ERROR: Could not fetch device list\n");
return -1;
}
for (i = 0; i < cnt; i++) {
libusb_device *device = list[i];
if (target_find(device)) {
found = device;
break;
}
}
if (found) {
printf("Port found!\n");
struct libusb_device_descriptor desc;
struct libusb_config_descriptor config;
err = libusb_get_device_descriptor(found,&desc);
if (err){
printf(libusb_error_name(err));
return -1;
}
err = libusb_get_config_descriptor(found,0,&config);
if (err){
printf(libusb_error_name(err));
return -1;
}
libusb_device_handle *handle;
err = port_open(found, &handle);
if (err){
printf("\n Timeout ERROR: Could not open port\n");
return -1;
}
break;
}
libusb_free_device_list(list, 1); //Free device list so I can refresh. Unclear if this is needed though.
}
err = libusb_set_configuration(found, 0x1); //Set config 1 for device, should contain 1 interface with two endpoints. I think.
//The rest here I guess???
return 0;
}
I'm currently trying to emulate the traffic sent to/from a HID device using libusb. The traffic is sniffed using wireshark and USBPcap. I emulated the first packets by requesting the descriptors and setting configuration etc. But at this point according to the log, the host sends a set idle request, get descriptor hid report and lastly a bunch of set reports. What functions in libusb corresponds to these packets? AFAIK the set report is basically the host transmitting some sort of settings to the device. I figured I could just copy the packet data and send my own reports exactly the same? Also is there a way to see exactly what the data does in the set report packets? I need to know how to properly set this up.
This is the packets i'm trying to emulate:
1 0.000000 host 2.41.0 USB 36 GET DESCRIPTOR Request DEVICE
2 0.000174 2.41.0 host USB 46 GET DESCRIPTOR Response DEVICE
3 0.000208 host 2.41.0 USB 36 GET DESCRIPTOR Request CONFIGURATION
4 0.000291 2.41.0 host USB 37 GET DESCRIPTOR Response CONFIGURATION
5 0.000304 host 2.41.0 USB 36 GET DESCRIPTOR Request CONFIGURATION
6 0.000395 2.41.0 host USB 62 GET DESCRIPTOR Response CONFIGURATION
7 0.000411 host 2.41.0 USB 36 SET CONFIGURATION Request
8 0.001150 2.41.0 host USB 28 SET CONFIGURATION Response
9 0.001167 host 2.41.0 USBHID 36 SET_IDLE Request
10 0.001239 2.41.0 host USBHID 28 SET_IDLE Response
11 0.001386 host 2.41.0 USBHID 36 GET DESCRIPTOR Request HID Report
12 0.001462 2.41.0 host USBHID 104 GET DESCRIPTOR Response HID Report
13 0.002620 host 2.41.1 USB 27 URB_INTERRUPT in
14 0.002645 host 2.41.1 USB 27 URB_INTERRUPT in
15 6.085037 2.41.1 host USB 27 URB_INTERRUPT in
16 6.085090 2.41.1 host USB 27 URB_INTERRUPT in
17 18.467828 host 2.41.0 USBHID 36 SET_IDLE Request
18 18.467993 2.41.0 host USBHID 28 SET_IDLE Response
19 18.468086 host 2.41.1 USB 27 URB_INTERRUPT in
20 18.468114 host 2.41.1 USB 27 URB_INTERRUPT in
21 18.468385 host 2.41.0 USB 36 GET DESCRIPTOR Request STRING
22 18.468537 2.41.0 host USB 86 GET DESCRIPTOR Response STRING
23 18.468595 host 2.41.0 USB 36 GET DESCRIPTOR Request STRING
24 18.468801 2.41.0 host USB 60 GET DESCRIPTOR Response STRING
25 18.475044 host 2.41.0 USBHID 53 SET_REPORT Request
26 18.475273 2.41.0 host USBHID 28 SET_REPORT Response
27 18.475834 host 2.41.0 USBHID 1061 SET_REPORT Request
28 18.476102 2.41.0 host USBHID 28 SET_REPORT Response
29 18.476571 host 2.41.0 USBHID 1061 SET_REPORT Request
30 18.476849 2.41.0 host USBHID 28 SET_REPORT Response
31 18.477280 host 2.41.0 USBHID 1061 SET_REPORT Request
32 18.477565 2.41.0 host USBHID 28 SET_REPORT Response
33 18.478085 host 2.41.0 USBHID 1061 SET_REPORT Request
34 18.478329 2.41.0 host USBHID 28 SET_REPORT Response
35 18.478700 host 2.41.0 USBHID 1061 SET_REPORT Request
I assume that I need to claim the interface and setup the endpoints. But I am having trouble understanding how to setup the system as hid class, setting the interrupts and polling correctly etc. At this point I have the config descriptor, the device descriptor and a device handle to work with.
#include <stdio.h>
#include "libusb.h"
#include <unistd.h>
#include <time.h>
static void print_devs(libusb_device **devs) //Taken from examples provided with libusb. Not used at this time
{
libusb_device *dev;
int i = 0, j = 0;
uint8_t path[8];
while ((dev = devs[i++]) != NULL) {
struct libusb_device_descriptor desc;
int r = libusb_get_device_descriptor(dev, &desc);
if (r < 0) {
fprintf(stderr, "failed to get device descriptor");
return;
}
printf("%04x:%04x (bus %d, device %d)",
desc.idVendor, desc.idProduct,
libusb_get_bus_number(dev), libusb_get_device_address(dev));
r = libusb_get_port_numbers(dev, path, sizeof(path));
if (r > 0) {
printf(" path: %d", path[0]);
for (j = 1; j < r; j++)
printf(".%d", path[j]);
}
printf("\n");
}
}
int port_open (libusb_device* dev, libusb_device_handle** dev_handle){ //Homebrew func. Retries after failed libusb_open
int count = 0;
int err = 0;
printf("Attempting to open port...\n");
while (1){
printf(".\n");
err = libusb_open(dev, &dev_handle); //Attempts to open port
if (err == 0){
break;
}
if(count>TIMEOUT){ //5s without the port opening and it will throw error
printf(libusb_error_name(err));
return -1;
}
count++;
delay(1);
}
return 0;
}
static int target_find(libusb_device *dev){ //Check for device. Libusb already had this but it was done before I saw it.
struct libusb_device_descriptor my_dev;
libusb_get_device_descriptor(dev,&my_dev);
if ((my_dev.idVendor == VENDOR) && (my_dev.idProduct == PRODUCT)){
return 1;
}
return 0;
}
int main(void)
{
int r;
int err = 0;
err = libusb_init(NULL);
if (err != 0) {
printf("LIBUSB ERROR: Could not initialize\n");
return -1;
}
libusb_device **list;
libusb_device *found = NULL;
while(1){ //Finds device and opens port
ssize_t cnt = libusb_get_device_list(NULL, &list);
ssize_t i = 0;
err = 0;
if (cnt < 0){
printf("USB ERROR: Could not fetch device list\n");
return -1;
}
for (i = 0; i < cnt; i++) {
libusb_device *device = list[i];
if (target_find(device)) {
found = device;
break;
}
}
if (found) {
printf("Port found!\n");
struct libusb_device_descriptor desc;
struct libusb_config_descriptor config;
err = libusb_get_device_descriptor(found,&desc);
if (err){
printf(libusb_error_name(err));
return -1;
}
err = libusb_get_config_descriptor(found,0,&config);
if (err){
printf(libusb_error_name(err));
return -1;
}
libusb_device_handle *handle;
err = port_open(found, &handle);
if (err){
printf("\n Timeout ERROR: Could not open port\n");
return -1;
}
break;
}
libusb_free_device_list(list, 1); //Free device list so I can refresh. Unclear if this is needed though.
}
err = libusb_set_configuration(found, 0x1); //Set config 1 for device, should contain 1 interface with two endpoints. I think.
//The rest here I guess???
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
要执行配置部分,您必须使用:
libusb_set_configuration()
: https://libusb.sourceforge.io/api-/api-/api-1.0/group__libus__libusbus_libusb__dev.dev.dev.dev.dev.dev.html#ga785dddea63abcbcbcbcbcbcbcbcab n63a.9bca.9bca.9bca.9bca.9bca.9bca.9bca.9bca.9ba2a aa.9bca.9bca aa.9bca.9bcA.9baurb中断是通过
>> code>>>>>>>> code> libusb_interrupt_trast_transfer_transfer(
) /group__libusb__syncio.html#ga0f171a72904a552fc43e6e6564d108a3" rel="nofollow noreferrer">https://libusb.sourceforge.io/api-1.0/group__libusb__syncio.html#ga0f171a72904a552fc43e6e6564d108a3
To do the configuration portion, you'll have to use:
libusb_set_configuration()
: https://libusb.sourceforge.io/api-1.0/group__libusb__dev.html#ga785ddea63a2b9bcb879a614ca4867bedlibusb_get_configuration()
: https://libusb.sourceforge.io/api-1.0/group__libusb__dev.html#gae921014b888b105471a31d54c77c1c4dThe URB interrupts are done via
libusb_interrupt_transfer()
https://libusb.sourceforge.io/api-1.0/group__libusb__syncio.html#ga0f171a72904a552fc43e6e6564d108a3