使用Libusb 1.0.25效仿USBHID流量

发布于 2025-01-17 19:04:16 字数 6647 浏览 4 评论 0原文

我目前正在尝试使用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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

两个我 2025-01-24 19:04:16

要执行配置部分,您必须使用:

urb中断是通过>> 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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文