I have a Chinese USB gaming mouse (04d9:a070) which has 4 color modes and 4 light levels. I know for a fact that this mouse is capable for showing at least 5 different color so it must be an RGB led (4 legs). The software is the worst I've ever seen and it's incredibly hard to change the color, brightness and mode so it works and doesn't just turn off. Now I'm planning to make my own control software (for Linux first).

I have started with a simple guide "Reverse Engineering a USB mouse (Updated 3rd May 2017)" at Bytepunk (can't post a link but Google or DuckDuckGo should find that guide)

I have already sniffed most of the things I need. I used USBlyzer on Windows with the awful control software and got a few hex strings and figured out how to change the color, brightness and mode in the hex strings. I pasted the data I discovered here (Pastebin)

Clicking turn on lights from the Windows control software

out: 07 07 01 00 00 00 00 00 <-- Is this a "Commands coming in call"?
out: 07 09 01 02 00 00 00 00 <-- 07 09 01 0X where X is the color
out: 07 0C 01 04 00 00 00 00 <-- 07 0Y 01 0Z where Y is the brightness and Z is the mode 
out: 07 13 04 00 00 00 00 00 <-- Is this a "Commands sent call"?

X - OFF: 0 RED: 1 BLUE: 2 GREEN: 3 PINK: 4
Y - LOW: B MED: 9 HIGH: C 

My problem is that when I try to "write" anything to the device it just hangs and I get a "[Errno2] Entity not found" error and the mouse needs to be replugged in order to make it work again. It doesn't "disconnect" but it stays in lsusb and nothing special shows up in dmesg.

I pasted my modified python script to Pastebin

I also applied a custom udev rule

SUBSYSTEM=="usb", ATTR{idVendor}=="04d9", ATTR{idProduct}=="a070", GROUP:="plugdev", MODE="0666"

I'm new to serial communications and reverse engineering so I don't know what to search for. I think I can post pictures and more data from the USBlyzer in the comments. This is my first post here so I don't have the reputation to give more links.

Greetings, Santeri

1 Answer 1


my understanding of USB is very low at best (even if I do develop some simple USB devices for a living) so read this with major prejudice...

  1. Your driver class and configuration must match the USB (mouse) device

    I do not know how your USB mouse is programmed but interface must be the same (CDC class can have more interfaces) and if not match then the USB will not work properly.

    So you need to know which pipes are used and which are input and output, if they use bulk or interrupt transfers.

    My bet is your mouse will be a HID class with use of only interrupt transfers. But if it is some crazy multimedia ergonomic multi feature sillyness it might be even CDC.

  2. Transfer of data

    Let assume you got HID so the device is communicating by control pipe0 and or interrupt pipes(1,2...).

    Now depending on the mouse firmware it might need a specific order of read/write commands otherwise the firmware will freeze or hang up till timeout.

    For example some commands do not return any data and can be send at any time ...

    Some commands return data in specific pipe and if not read back by host in time the firmware can crash/freeze.

    Another problem the mouse might be configurable and requesting some initialization sequence of codes/commands determining the mouse purpose/specs/whatever. Again if the firmware expects that first, sending any other command can freeze your mouse.

    Also some firmwares expect commands with timing and sending too often or too rarely is wrong in such case.

    Your sniffing data does not take into account any of this. Try to sniff also the other pipes (maybe with time stamps) and log all to something like this:

    Once done you should see what the device is sending back. It is important to see how many bytes an in what pipe. Then you can update your script and after you send your command read appropriate number of bytes back to host so your firmware on the mouse will not freeze up.

  • 1. pretty much solved my problem. I had the wrong bmRequestType value. I'm not sure why but I got an invalid value from USBlyzer. I used Wireshark this time and got the correct value (0x21). Now I'm able to control the LEDs and other settings. Thank you for the explanation! Commented Sep 26, 2017 at 15:42
  • @user1475122 glad to be of help.
    – Spektre
    Commented Sep 26, 2017 at 17:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.