eruption icon indicating copy to clipboard operation
eruption copied to clipboard

Add support for Kone Aimo

Open array-in-a-matrix opened this issue 1 year ago • 9 comments

Introduction I have the still experimental Kone Aimo mouse.

Please describe the bug The eruption GUI does not detect the mouse. Experimental drivers are enabled and the eruption daemon does detect the mouse (however it thinks it is the Kone Aimo Remastered which isn't correct, should I open another issue for this?). I am able to change the profile of the mouse with eruptionctl.

$ eruptionctl devices list   
Dumping Eruption managed devices list

Keyboard devices:
<No supported devices detected>


Mouse devices:
00: ROCCAT Kone Aimo Remastered

Miscellaneous devices:
<No supported devices detected>


To Reproduce Steps to reproduce the behavior: N/A

Expected behavior The GUI should detect mouse and be able to configure it.

Logs

Eruption daemon afaik doesn't log anything related to this and I don't believe it should as this is only a GUI problem from what I can tell.

eruption-gui (click to expand)

 Eruption is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 Eruption is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with Eruption.  If not, see <http://www.gnu.org/licenses/>.

 Copyright (c) 2019-2022, The Eruption Development Team


(eruption-gui:58479): Gtk-CRITICAL **: 03:04:20.595: gtk_cell_area_attribute_connect: assertion 'gtk_cell_area_has_renderer (area, renderer)' failed

(eruption-gui:58479): Gtk-WARNING **: 03:04:20.893: Unable to parse accelerator '<delete>': ignored request to install 1 accelerators

(eruption-gui:58479): Gtk-WARNING **: 03:04:20.901: Failed to set text '<unknown>' from markup due to error parsing markup: Error on line 1 char 26: Element “markup” was closed, but the currently open element is “unknown”

(eruption-gui:58479): Gtk-WARNING **: 03:04:20.901: Failed to set text '<unknown>' from markup due to error parsing markup: Error on line 1 char 26: Element “markup” was closed, but the currently open element is “unknown”

(eruption-gui:58479): Gtk-WARNING **: 03:04:20.901: Failed to set text '<unknown>' from markup due to error parsing markup: Error on line 1 char 26: Element “markup” was closed, but the currently open element is “unknown”

(eruption-gui:58479): Gtk-CRITICAL **: 03:04:20.915: gtk_cell_area_attribute_connect: assertion 'gtk_cell_area_has_renderer (area, renderer)' failed

(eruption-gui:58479): Gtk-CRITICAL **: 03:04:20.915: gtk_cell_area_attribute_connect: assertion 'gtk_cell_area_has_renderer (area, renderer)' failed

(eruption-gui:58479): Gtk-CRITICAL **: 03:04:20.923: gtk_cell_area_attribute_connect: assertion 'gtk_cell_area_has_renderer (area, renderer)' failed

(eruption-gui:58479): Gtk-CRITICAL **: 03:04:20.924: gtk_cell_area_attribute_connect: assertion 'gtk_cell_area_has_renderer (area, renderer)' failed

(eruption-gui:58479): Gtk-CRITICAL **: 03:04:20.929: gtk_cell_area_attribute_connect: assertion 'gtk_cell_area_has_renderer (area, renderer)' failed

(eruption-gui:58479): Gtk-CRITICAL **: 03:04:20.929: gtk_cell_area_attribute_connect: assertion 'gtk_cell_area_has_renderer (area, renderer)' failed

(eruption-gui:58479): Gtk-CRITICAL **: 03:04:20.939: gtk_cell_area_attribute_connect: assertion 'gtk_cell_area_has_renderer (area, renderer)' failed

(eruption-gui:58479): Gtk-CRITICAL **: 03:04:20.939: gtk_cell_area_attribute_connect: assertion 'gtk_cell_area_has_renderer (area, renderer)' failed

(eruption-gui:58479): Gtk-WARNING **: 03:04:21.183: Failed to set text '<unknown>' from markup due to error parsing markup: Error on line 1 char 26: Element “markup” was closed, but the currently open element is “unknown”

(eruption-gui:58479): Gtk-WARNING **: 03:04:21.183: Failed to set text '<unknown>' from markup due to error parsing markup: Error on line 1 char 26: Element “markup” was closed, but the currently open element is “unknown”

(eruption-gui:58479): Gtk-WARNING **: 03:04:21.183: Failed to set text '<unknown>' from markup due to error parsing markup: Error on line 1 char 26: Element “markup” was closed, but the currently open element is “unknown”

Screenshots (optional) image

Please complete the following information:

  • Eruption version [e.g. 0.1.20]:
    • Eruption 0.1.24 (0.1.23.r102.g618d4211) (release build) (compiled eruption-git from the AUR)
  • Your device(s) (sudo lsusb):
    • Bus 001 Device 007: ID 1e7d:2e2c ROCCAT ROCCAT Kone Aimo 16K

Additional context I'm sure the logs I put aren't enough. Not sure what else to add tho.

My system:

Operating System: Arch Linux
Qt Version: 5.15.4
GTK4 Version: 4.6.6-1
Kernel: 5.18.9-zen1-1-zen
Graphics Platform: Wayland

array-in-a-matrix avatar Jul 08 '22 07:07 array-in-a-matrix

@array-in-a-matrix This feature of the GUI is not implemented yet. I will try to find the time to implement it soon!

X3n0m0rph59 avatar Jul 08 '22 07:07 X3n0m0rph59

I will put the pcapng trace here hopefully tomorrow.

array-in-a-matrix avatar Jul 08 '22 07:07 array-in-a-matrix

I wanted to upload it earlier but I didn't have time. Here it is now tho! Swarm_init_and_AIMO_color.zip

array-in-a-matrix avatar Jul 10 '22 06:07 array-in-a-matrix

@array-in-a-matrix Thank you very much for creating the capture file! I will look into it now...

X3n0m0rph59 avatar Jul 10 '22 06:07 X3n0m0rph59

Out of curiosity, how do you reverse engineer the capture file?

array-in-a-matrix avatar Jul 10 '22 06:07 array-in-a-matrix

I am viewing the *.pcapng trace file using the Wireshark GUI, looking for USB and USBHID protocol packets. The Setup Data / Data Fragment fields of USBHID packets are the most relevant. They contain the bytes that get exchanged between the OEM software and the hardware and vice versa. I am trying to spot recurring patterns in the byte sequence and through this extract the underlying protocol.

Each ROCCAT device is different from the others, ROCCAT does not use a unified protocol. Reversing the specific protocol of a USB device can be hard, especially if checksums or some kind of crypto is involved. While reversing the protocol of the ROCCAT Kain 200 for example, I had to implement a CRC8 reversing tool that is able to find the parameters of the CRC checksum (polynom and init values) from a sequence of bytes containing multiple samples of a command.

eruption-debug-tool utils reverse-crc8 "[0x32,0xff,0x00,0x00,0x00,0x00,0xff]" "[0x31,0x59,0xa5,0xff,0x00,0x00,0x00]" "[0x31,0x00,0x00,0xff,0xff,0x00,0x00]"

If I have access to a specific device, I will just poke around and see what happens... I have implemented a debugging tool that can generate diffs of the 'internal state' of a device.

eruption-debug-tool state-diff

It generates a (colored) diff-like output:

Index: 00: ID: 1e7d:343b ROCCAT/ROCCAT Aimo Pad Wide Subdev: 0
Reading data from device...
The following USB HID report IDs have changed bytes:

Changed bytes: [6, 8, 9, 10, 11, 19]
0x01: [0x01, 0x01, 0x16, 0x01, 0x00, 0x00, 0x00=>0xff, 0x00, 0xff=>0x00, 0x00=>0xff, 0x00=>0x09, 0x00=>0x07, 0xfa, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x8c=>0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Changed bytes: [4, 12, 19]
0x02: [0x02, 0x00, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x8c=>0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Changed bytes: [4, 12]
0x06: [0x06, 0x00, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Changed bytes: [3, 12, 19]
0x04: [0x04, 0x00, 0x00, 0xff=>0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x8c=>0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Changed bytes: [12, 19]
0x03: [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x8c=>0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Changed bytes: [3, 12, 19]
0x05: [0x04, 0x00, 0x00, 0xff=>0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x8c=>0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Saving state data...
Done

But most of the time I do not have access to a device that I want to support. This usually requires several round-trips. It is hard to get it right on the first try.

The driver code for devices supported by eruption can be found in eruption/src/hwdevices/*.

X3n0m0rph59 avatar Jul 10 '22 07:07 X3n0m0rph59

Thank you so much for this explanation! Most of it went over my head lol.

array-in-a-matrix avatar Jul 11 '22 22:07 array-in-a-matrix

I am viewing the *.pcapng trace file using the Wireshark GUI, looking for USB and USBHID protocol packets. The Setup Data / Data Fragment fields of USBHID packets are the most relevant. They contain the bytes that get exchanged between the OEM software and the hardware and vice versa. I am trying to spot recurring patterns in the byte sequence and through this extract the underlying protocol.

Each ROCCAT device is different from the others, ROCCAT does not use a unified protocol. Reversing the specific protocol of a USB device can be hard, especially if checksums or some kind of crypto is involved. While reversing the protocol of the ROCCAT Kain 200 for example, I had to implement a CRC8 reversing tool that is able to find the parameters of the CRC checksum (polynom and init values) from a sequence of bytes containing multiple samples of a command.

eruption-debug-tool utils reverse-crc8 "[0x32,0xff,0x00,0x00,0x00,0x00,0xff]" "[0x31,0x59,0xa5,0xff,0x00,0x00,0x00]" "[0x31,0x00,0x00,0xff,0xff,0x00,0x00]"

If I have access to a specific device, I will just poke around and see what happens... I have implemented a debugging tool that can generate diffs of the 'internal state' of a device.

eruption-debug-tool state-diff

It generates a (colored) diff-like output:

Index: 00: ID: 1e7d:343b ROCCAT/ROCCAT Aimo Pad Wide Subdev: 0
Reading data from device...
The following USB HID report IDs have changed bytes:

Changed bytes: [6, 8, 9, 10, 11, 19]
0x01: [0x01, 0x01, 0x16, 0x01, 0x00, 0x00, 0x00=>0xff, 0x00, 0xff=>0x00, 0x00=>0xff, 0x00=>0x09, 0x00=>0x07, 0xfa, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x8c=>0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Changed bytes: [4, 12, 19]
0x02: [0x02, 0x00, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x8c=>0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Changed bytes: [4, 12]
0x06: [0x06, 0x00, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Changed bytes: [3, 12, 19]
0x04: [0x04, 0x00, 0x00, 0xff=>0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x8c=>0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Changed bytes: [12, 19]
0x03: [0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x8c=>0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Changed bytes: [3, 12, 19]
0x05: [0x04, 0x00, 0x00, 0xff=>0xe1, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x09, 0x07, 0xfa=>0xe1, 0x00, 0xe6, 0x8c, 0x00, 0xff, 0x80, 0x8c=>0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x09, 0x07, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, ]

Saving state data...
Done

But most of the time I do not have access to a device that I want to support. This usually requires several round-trips. It is hard to get it right on the first try.

The driver code for devices supported by eruption can be found in eruption/src/hwdevices/*.

X3n0m0rph59, thank you so much for this insights! i find it absolutly amazing, how this is done. sadly, till this point, i fear i'd have to dive deeper in basics of encryption and understanding byte patterns, to experiment those highly respected skills by my own.

allow me to ask, and please excuse reactivating this topic:

in my basic understanding, i'd think that if i e.g capture a communication between the mouse (kone aimo remastered) doing a specific task (reducing the brightness of the leds) on a win machine with e.g. wireshark, that there should be a way to kind of "inject" this recorded packets (or the extracts of the usb hid bits in it) to the mouse on linux (w/o the specific need on this particualr attempt, to understand the pattern behind it?)?

most likely i miss fundamental aspects (sender reciever verification? api things?) but i would be very thankfull if you as somebody understanding this matter, may point me out to reading material or a few keywords maybe, so i could try to go on that journey?

thank you for this great work and your time (-:

tuxaddict avatar Nov 19 '23 09:11 tuxaddict

@tuxaddict Please excuse me for taking so long to respond to your question... Yes, your assumption is absolutely correct! You could replay a pre-recorded byte sequence to most devices and expect it to work. There are some caveats though:

  • The protocol may use some kind of authentication, maybe even to intentionally protect against replay attacks
  • The byte sequence depends on some changing state and needs to adapt

In the aforementioned case of dimming the brightness of the LEDs of a device:

Most devices do not make use of a dedicated brightness value of some sorts, but are setting their perceived brightness solely via the RGB color triple that gets sent to the device.

RGB (255, 0, 0) would be bright red RGB (0, 0, 0) would be black (LEDs off)

where

RGB (128, 0, 0) would be dim red

meaning it has the same tone but would be less bright.

X3n0m0rph59 avatar Nov 30 '23 04:11 X3n0m0rph59