2016-05-11 82 views
2

我試圖從Wacom Inkling逆向工程通過審查通過USB字節的HID握手

羅爾·楊森提取實時數據已經檢查了包here

// Some kind of handshaking. 
// Values obtained by sniffing the USB connection between SketchManager and the device. 
unsigned char usb_data[33]; 
memset (&usb_data, '\0', 33); 
int bytes = 0; 

memcpy (&usb_data, "\x80\x01\x03\x01\x02\x00\x00\x00", 8); 
bytes += libusb_control_transfer (handle, 
            0x21,   // bmRequestType 
            9,   // bRequest 
            0x0380,  // wValue 
            0,   // wIndex 
            usb_data,  // data 
            33,   // wLength 
            0);   // timeout 

memcpy (&usb_data, "\x80\x01\x0a\x01\x01\x0b\x01\x00", 8); 
bytes += libusb_control_transfer (handle, 0x21, 9, 0x0380, 0, usb_data, 33, 0); 

memset (&usb_data, '\0', 33); 
bytes += libusb_control_transfer (handle, 0xa1, 1, 0x0380, 0, usb_data, 33, 0); 

memcpy (&usb_data, "\x80\x01\x0b\x01\x00\x00\x00\x00", 8); 
bytes += libusb_control_transfer (handle, 0x21, 9, 0x0380, 0, usb_data, 33, 0); 

memcpy (&usb_data, "\x80\x01\x02\x01\x01\x00\x00\x00", 8); 
bytes += libusb_control_transfer (handle, 0x21, 9, 0x0380, 0, usb_data, 33, 0); 

memcpy (&usb_data, "\x80\x01\x0a\x01\x01\x02\x01\x00", 8); 
bytes += libusb_control_transfer (handle, 0x21, 9, 0x0380, 0, usb_data, 33, 0); 

memset (&usb_data, '\0', 33); 
bytes += libusb_control_transfer (handle, 0xa1, 1, 0x0380, 0, usb_data, 33, 0); 

我試圖重寫使用HID API其中有一個很小的API(here

我要去嘗試只使用hid_write現在這個代碼,但有可能是一個機會,這handsh ake發送feature report ...?

有沒有人可以看看這個字節流,看看發生了什麼?

編輯:它看起來Inkling公開一個FlashDrive和HID接口,所以我猜這個字節碼必須選擇HID接口並告訴它開始發送數據。但是,我可以用更優雅/更易讀的形式對它進行編碼嗎?

編輯:我讓它工作! hid_writehid_send_feature_report工作!

hid_device* handle = hid_open(inklingVendorId, inklingProductId, NULL); 
jassert(handle != nullptr); 

int bytes_written = 
    hid_send_feature_report(handle, (const unsigned char *)"\x80\x01\x03\x01\x02\x00\x00\x00", 8) + 
    hid_send_feature_report(handle, (const unsigned char *)"\x80\x01\x0a\x01\x01\x0b\x01\x00", 8) + 
    hid_send_feature_report(handle, (const unsigned char *)"\x80\x01\x0b\x01\x00\x00\x00\x00", 8) + 
    hid_send_feature_report(handle, (const unsigned char *)"\x80\x01\x02\x01\x01\x00\x00\x00", 8) + 
    hid_send_feature_report(handle, (const unsigned char *)"\x80\x01\x0a\x01\x01\x02\x01\x00", 8); 
jassert(bytes_written == 5*8); 

const int enable_nonblocking = 1, disable_nonblocking = 0; 
jassert(hid_set_nonblocking(handle, disable_nonblocking) != FAIL); // want to block 

while(true) { 
    int bytes_got = hid_read(handle, usb_data, 10); 

...但我仍然想知道發生了什麼。這很不方便。

編輯:的的lsusb輸出(從羅埃爾,我沒有Linux的手):

Bus 003 Device 002: ID 056a:0221 Wacom Co., Ltd 
Device Descriptor: 
    bLength    18 
    bDescriptorType   1 
    bcdUSB    2.00 
    bDeviceClass   0 (Defined at Interface level) 
    bDeviceSubClass   0 
    bDeviceProtocol   0 
    bMaxPacketSize0  64 
    idVendor   0x056a Wacom Co., Ltd 
    idProduct   0x0221 
    bcdDevice   12.56 
    iManufacturer   1 (error) 
    iProduct    2 MSC Device 
    iSerial     5 4833000045C5549C0002DD012DA5549C 
    bNumConfigurations  1 
    Configuration Descriptor: 
    bLength     9 
    bDescriptorType   2 
    wTotalLength   57 
    bNumInterfaces   2 
    bConfigurationValue  1 
    iConfiguration   3 USB/MSC Inkling 
    bmAttributes   0x80 
     (Bus Powered) 
    MaxPower    500mA 
    Interface Descriptor: 
     bLength     9 
     bDescriptorType   4 
     bInterfaceNumber  0 
     bAlternateSetting  0 
     bNumEndpoints   1 
     bInterfaceClass   3 Human Interface Device 
     bInterfaceSubClass  0 No Subclass 
     bInterfaceProtocol  2 Mouse 
     iInterface    0 
     HID Device Descriptor: 
      bLength     9 
      bDescriptorType  33 
      bcdHID    1.01 
      bCountryCode   0 Not supported 
      bNumDescriptors   1 
      bDescriptorType  34 Report 
      wDescriptorLength  215 
      Report Descriptor: (length is 215) 
      Item(Global): Usage Page, data= [ 0x0d ] 13 
          Digitizer 
      Item(Local): Usage, data= [ 0x02 ] 2 
          Pen 
      Item(Main ): Collection, data= [ 0x01 ] 1 
          Application 
      Item(Global): Report ID, data= [ 0x02 ] 2 
      Item(Local): Usage, data= [ 0x02 ] 2 
          Pen 
      Item(Main ): Collection, data= [ 0x00 ] 0 
          Physical 
      Item(Global): Usage Page, data= [ 0x01 ] 1 
          Generic Desktop Controls 
      Item(Local): Usage, data= [ 0x30 ] 48 
          Direction-X 
      Item(Local): Usage, data= [ 0x31 ] 49 
          Direction-Y 
      Item(Global): Logical Minimum, data= [ 0x00 ] 0 
      Item(Global): Logical Maximum, data= [ 0x80 0x07 ] 1920 
      Item(Global): Physical Minimum, data= [ 0x00 ] 0 
      Item(Global): Physical Maximum, data= [ 0x00 0x78 ] 30720 
      Item(Global): Unit, data= [ 0x11 ] 17 
          System: SI Linear, Unit: Centimeter 
      Item(Global): Unit Exponent, data= [ 0x0e ] 14 
          Unit Exponent: 14 
      Item(Global): Report Size, data= [ 0x10 ] 16 
      Item(Global): Report Count, data= [ 0x02 ] 2 
      Item(Main ): Input, data= [ 0x02 ] 2 
          Data Variable Absolute No_Wrap Linear 
          Preferred_State No_Null_Position Non_Volatile Bitfield 
      Item(Global): Usage Page, data= [ 0x0d ] 13 
          Digitizer 
      Item(Local): Usage, data= [ 0x42 ] 66 
          Tip Switch 
      Item(Local): Usage, data= [ 0x45 ] 69 
          Eraser 
      Item(Local): Usage, data= [ 0x44 ] 68 
          Barrel Switch 
      Item(Local): Usage, data= [ 0x32 ] 50 
          In Range 
      Item(Global): Logical Minimum, data= [ 0x00 ] 0 
      Item(Global): Logical Maximum, data= [ 0x01 ] 1 
      Item(Global): Report Size, data= [ 0x01 ] 1 
      Item(Global): Report Count, data= [ 0x04 ] 4 
      Item(Global): Unit, data= [ 0x00 ] 0 
          System: None, Unit: (None) 
      Item(Main ): Input, data= [ 0x02 ] 2 
          Data Variable Absolute No_Wrap Linear 
          Preferred_State No_Null_Position Non_Volatile Bitfield 
      Item(Global): Usage Page, data= [ 0x09 ] 9 
          Buttons 
      Item(Local): Usage Minimum, data= [ 0x01 ] 1 
          Button 1 (Primary) 
      Item(Local): Usage Maximum, data= [ 0x04 ] 4 
          Button 4 
      Item(Global): Logical Minimum, data= [ 0x00 ] 0 
      Item(Global): Logical Maximum, data= [ 0x01 ] 1 
      Item(Global): Report Size, data= [ 0x01 ] 1 
      Item(Global): Report Count, data= [ 0x04 ] 4 
      Item(Main ): Input, data= [ 0x02 ] 2 
          Data Variable Absolute No_Wrap Linear 
          Preferred_State No_Null_Position Non_Volatile Bitfield 
      Item(Global): Usage Page, data= [ 0x0d ] 13 
          Digitizer 
      Item(Local): Usage, data= [ 0x30 ] 48 
          Tip Pressure 
      Item(Global): Logical Minimum, data= [ 0x00 ] 0 
      Item(Global): Logical Maximum, data= [ 0x00 0x04 ] 1024 
      Item(Global): Report Size, data= [ 0x10 ] 16 
      Item(Global): Report Count, data= [ 0x01 ] 1 
      Item(Main ): Input, data= [ 0x02 ] 2 
          Data Variable Absolute No_Wrap Linear 
          Preferred_State No_Null_Position Non_Volatile Bitfield 
      Item(Global): Usage Page, data= [ 0x0d ] 13 
          Digitizer 
      Item(Local): Usage, data= [ 0x3d ] 61 
          X Tilt 
      Item(Local): Usage, data= [ 0x3e ] 62 
          Y Tilt 
      Item(Global): Logical Minimum, data= [ 0x81 ] 129 
      Item(Global): Logical Maximum, data= [ 0x7f ] 127 
      Item(Global): Report Size, data= [ 0x08 ] 8 
      Item(Global): Report Count, data= [ 0x02 ] 2 
      Item(Main ): Input, data= [ 0x02 ] 2 
          Data Variable Absolute No_Wrap Linear 
          Preferred_State No_Null_Position Non_Volatile Bitfield 
      Item(Main ): End Collection, data=none 
      Item(Global): Usage Page, data= [ 0x01 ] 1 
          Generic Desktop Controls 
      Item(Local): Usage, data= [ 0x00 ] 0 
          Undefined 
      Item(Global): Report ID, data= [ 0x04 ] 4 
      Item(Global): Logical Minimum, data= [ 0x00 ] 0 
      Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 
      Item(Global): Report Size, data= [ 0x08 ] 8 
      Item(Global): Report Count, data= [ 0x0c ] 12 
      Item(Main ): Input, data= [ 0x02 ] 2 
          Data Variable Absolute No_Wrap Linear 
          Preferred_State No_Null_Position Non_Volatile Bitfield 
      Item(Global): Usage Page, data= [ 0x01 ] 1 
          Generic Desktop Controls 
      Item(Local): Usage, data= [ 0x00 ] 0 
          Undefined 
      Item(Global): Report ID, data= [ 0x08 ] 8 
      Item(Global): Logical Minimum, data= [ 0x00 ] 0 
      Item(Global): Logical Maximum, data= [ 0xff 0x00 ] 255 
      Item(Global): Report Size, data= [ 0x08 ] 8 
      Item(Global): Report Count, data= [ 0x3b ] 59 
      Item(Main ): Input, data= [ 0x02 ] 2 
          Data Variable Absolute No_Wrap Linear 
          Preferred_State No_Null_Position Non_Volatile Bitfield 
      Item(Local): Usage, data= [ 0x01 ] 1 
          Pointer 
      Item(Global): Report ID, data= [ 0x80 ] 128 
      Item(Global): Report Size, data= [ 0x08 ] 8 
      Item(Global): Report Count, data= [ 0x20 ] 32 
      Item(Main ): Feature, data= [ 0x02 ] 2 
          Data Variable Absolute No_Wrap Linear 
          Preferred_State No_Null_Position Non_Volatile Bitfield 
      Item(Main ): End Collection, data=none 
      Item(Global): Usage Page, data= [ 0x01 ] 1 
          Generic Desktop Controls 
      Item(Local): Usage, data= [ 0x02 ] 2 
          Mouse 
      Item(Main ): Collection, data= [ 0x01 ] 1 
          Application 
      Item(Global): Report ID, data= [ 0x01 ] 1 
      Item(Local): Usage, data= [ 0x01 ] 1 
          Pointer 
      Item(Main ): Collection, data= [ 0x00 ] 0 
          Physical 
      Item(Global): Usage Page, data= [ 0x01 ] 1 
          Generic Desktop Controls 
      Item(Local): Usage, data= [ 0x30 ] 48 
          Direction-X 
      Item(Local): Usage, data= [ 0x31 ] 49 
          Direction-Y 
      Item(Global): Logical Minimum, data= [ 0x00 ] 0 
      Item(Global): Logical Maximum, data= [ 0x80 0x07 ] 1920 
      Item(Global): Physical Minimum, data= [ 0x00 ] 0 
      Item(Global): Physical Maximum, data= [ 0x00 0x78 ] 30720 
      Item(Global): Unit, data= [ 0x11 ] 17 
          System: SI Linear, Unit: Centimeter 
      Item(Global): Unit Exponent, data= [ 0x0e ] 14 
          Unit Exponent: 14 
      Item(Global): Report Size, data= [ 0x10 ] 16 
      Item(Global): Report Count, data= [ 0x02 ] 2 
      Item(Main ): Input, data= [ 0x02 ] 2 
          Data Variable Absolute No_Wrap Linear 
          Preferred_State No_Null_Position Non_Volatile Bitfield 
      Item(Global): Usage Page, data= [ 0x09 ] 9 
          Buttons 
      Item(Local): Usage Minimum, data= [ 0x01 ] 1 
          Button 1 (Primary) 
      Item(Local): Usage Maximum, data= [ 0x03 ] 3 
          Button 3 (Tertiary) 
      Item(Global): Logical Minimum, data= [ 0x00 ] 0 
      Item(Global): Logical Maximum, data= [ 0x01 ] 1 
      Item(Global): Report Size, data= [ 0x01 ] 1 
      Item(Global): Report Count, data= [ 0x03 ] 3 
      Item(Global): Unit, data= [ 0x00 ] 0 
          System: None, Unit: (None) 
      Item(Main ): Input, data= [ 0x02 ] 2 
          Data Variable Absolute No_Wrap Linear 
          Preferred_State No_Null_Position Non_Volatile Bitfield 
      Item(Global): Report Count, data= [ 0x05 ] 5 
      Item(Main ): Input, data= [ 0x01 ] 1 
          Constant Array Absolute No_Wrap Linear 
          Preferred_State No_Null_Position Non_Volatile Bitfield 
      Item(Main ): End Collection, data=none 
      Item(Main ): End Collection, data=none 
     Endpoint Descriptor: 
     bLength     7 
     bDescriptorType   5 
     bEndpointAddress  0x83 EP 3 IN 
     bmAttributes   3 
      Transfer Type   Interrupt 
      Synch Type    None 
      Usage Type    Data 
     wMaxPacketSize  0x0040 1x 64 bytes 
     bInterval    4 
    Interface Descriptor: 
     bLength     9 
     bDescriptorType   4 
     bInterfaceNumber  1 
     bAlternateSetting  0 
     bNumEndpoints   2 
     bInterfaceClass   8 Mass Storage 
     bInterfaceSubClass  6 SCSI 
     bInterfaceProtocol  80 Bulk-Only 
     iInterface    4 USB/MSC Inkling 
     Endpoint Descriptor: 
     bLength     7 
     bDescriptorType   5 
     bEndpointAddress  0x81 EP 1 IN 
     bmAttributes   2 
      Transfer Type   Bulk 
      Synch Type    None 
      Usage Type    Data 
     wMaxPacketSize  0x0200 1x 512 bytes 
     bInterval    0 
     Endpoint Descriptor: 
     bLength     7 
     bDescriptorType   5 
     bEndpointAddress  0x02 EP 2 OUT 
     bmAttributes   2 
      Transfer Type   Bulk 
      Synch Type    None 
      Usage Type    Data 
     wMaxPacketSize  0x0200 1x 512 bytes 
     bInterval    0 
Device Qualifier (for other device speed): 
    bLength    10 
    bDescriptorType   6 
    bcdUSB    2.00 
    bDeviceClass   0 (Defined at Interface level) 
    bDeviceSubClass   0 
    bDeviceProtocol   0 
    bMaxPacketSize0  64 
    bNumConfigurations  2 
Device Status:  0x0000 
    (Bus Powered) 

回答

2

1)確認端倪使用HID USB設備類。嘗試使用lsusb -v並檢查輸出中的bDeviceClassbInterfaceClass字段()USB人機界面設備類可用於描述設備和接口類。當USB設備可包含多個功能時,使用接口類https://en.wikipedia.org/wiki/USB_human_interface_device_class )在說明書中(https://www.wacom.com/~/media/files/store-manuals/inkling-manual-english.pdf)據說它是一個USB閃存驅動器,在這種情況下它使用USB大容量存儲設備類(BULK transfer)

2)如果是USB HID設備類,您可以嘗試獲取特徵報告(如果發現任何類似的網站)http://libusb.6.n5.nabble.com/How-to-get-HID-report-td4628.html

libusb_get_descriptor使標準 GET_DESCRIPTOR 請求,其中 bmRequestType字段是 0x80。 DT_REPORT 描述符請求必須 指示接收者是一個接口,它要求 bmRequestType是0×81

你有兩個不錯的選擇。報告描述符全部包含在 的配置描述符中,所以您應該能夠整體獲取整個配置描述符並解析它以提取報告 描述符。

另外,libusb_get_descriptor超過 libusb_control_transfer很薄的一層,所以你可以隻手展開:

res = libusb_control_transfer(devh, LIBUSB_ENDPOINT_IN | 
LIBUSB_RECIPIENT_INTERFACE, 
LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8) | 0, 0, buf, 
sizeof(buf), 1000); 

更多鏈接: - http://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/ http://www.beyondlogic.org/usbnutshell/usb1.shtml

---------------------------------------------------------------------------------

libusb_control_transfer執行USB控制傳輸控制傳輸用於命令和狀態操作,看到這個http://libusb.sourceforge.net/api-1.0/group__syncio.htmlhttp://www.beyondlogic.org/usbnutshell/usb4.shtml#Control

USB控制請求USB的一個亞型請求,看到http://www.beyondlogic.org/usbnutshell/usb6.shtml

usb_data似乎是USB發送緩衝區時,始終填充數據字節,則發送libusb_control_transfer即可

這是評論形式的USB控制請求(http://www.beyondlogic.org/usbnutshell/usb6.shtml

memcpy (&usb_data, "\x80\x01\x03\x01\x02\x00\x00\x00", 8); 
bytes += libusb_control_transfer (handle, 
            0x21,   // bmRequestType 
            9,   // bRequest 
            0x0380,  // wValue 
            0,   // wIndex 
            usb_data,  // data 
            33,   // wLength 
            0);   // timeout 

的這是USB控制請求的縮寫形式

memcpy (&usb_data, "\x80\x01\x0a\x01\x01\x0b\x01\x00", 8); 
bytes += libusb_control_transfer (handle, 0x21, 9, 0x0380, 0, usb_data, 33, 0); 

所以像"\x80\x01\x03\x01\x02\x00\x00\x00"的所有字節序列是作爲命令碼用於配置Inkling('握手')並且只有Inkling和Wacom人員明白...

+0

感謝你們,當我在這裏消化這些信息時,我已經更新了我的問題,主要是爲了證實你對lsusb所說的話。 –

+0

更新了答案... –

1

所以這是一個單報告您送USB:

80 01 03 01 02 00 00 00 .... (in total the buffer is 1+32 = 33 bytes) 
^^      Report ID 

這是有關部分從HID描述:

... 
Item(Global): Report ID, data= [ 0x80 ] 128 
Item(Global): Report Size, data= [ 0x08 ] 8 
Item(Global): Report Count, data= [ 0x20 ] 32 
Item(Main ): Feature, data= [ 0x02 ] 2 
       Data Variable Absolute No_Wrap Linear 
       Preferred_State No_Null_Position Non_Volatile Bitfield 

這表示您的報告ID 0x80的數據已經被解釋爲32次一個字節(這是意思取決於我想的驅動程序)。這是一個功能,這意味着它可以通過控制端點上的GET_FEATURE/SET_FEATURE報告配置設備。

有關如何解釋此描述符的更多信息,請參見http://www.usb.org/developers/hidpage/中的HID v1.1規範。