Skip to content
KitploitKITPLOIT
ToolsExploitsBlog
Log in
Submit
ToolsExploitsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

FeedsContactPrivacy© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
usb-rea — Reverse Engineer any USB gadget: capture vendor-app traffic, infer the protocol with evidence, generate an open Python/libusb driver. CLI + MCP server. | Kitploit
Tools/GitHubGitHub/emirmrkaljevic/usb-rea
Packet Sniffing & AnalysisReverse EngineeringScripting & AutomationHardware HackingUtilities & FrameworksHardware & IoT SecurityBinary Analysis
GitHubemirmrkaljevic/usb-rea

usb-rea

Reverse Engineer any USB gadget: capture vendor-app traffic, infer the protocol with evidence, generate an open Python/libusb driver. CLI + MCP server.

View Repository
91 day agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share

usb-rea: Reverse Engineer any USB gadget

ci license usb-rea MCP server

Support my open-source work: get a SkinToScan pack
If you find this useful, you can support me by getting a SkinToScan pack, my other project. It's a one-time purchase that directly funds my open-source work.

Buy Single Picture Check, €4.49 Buy 5 Picture Pack, €19.99 (popular) Buy 15 Picture Pack, €54.99

Concrete result: from captures of the NZXT Kraken X (1e71:170e) fan command, usb-rea recovers 02 4d <channel> 00 <duty> byte for byte, exactly as liquidctl's kraken2.py sends it, and the generated driver emits identical packets for duty values it never saw. Same for the SteelSeries Rival 100 (1038:1702) DPI, polling and RGB tables from rivalcfg. Proof runs in CI: docs/VALIDATION.md. Full walk-through with a CRC8 and a rolling counter: Corsair Hydro Platinum case study. Real Windows USBPcap of an ASUS TUF Gaming LC III LCD: case study.

Have a Windows-only device? Open a device request with a capture and I will run it and publish the result.

usb-rea demo: capture labelled clicks, get the protocol and a working driver

Got a USB device that only ships a Windows vendor app (case LCD, RGB controller, mouse, "smart" lamp)? Click around in the vendor app while usb-rea captures the USB traffic (usbmon on Linux, USBPcap on Windows), diffs the packets per action, infers the protocol, and writes an open-source Python/libusb driver, with every conclusion linked to the exact packets that prove it.

Status: alpha (v0.7.11, on PyPI). Validated on synthetic devices, on protocols documented by liquidctl and rivalcfg, on public Wireshark captures (see docs/VALIDATION.md) and on a real AIO cooler LCD capture a user shared, where it found the same brightness command and image stream format the user had worked out by hand. Your captures are welcome.

Try it in 10 seconds (no hardware needed)

pip install usb-rea
usb-rea demo --device fan
mode         100%  0x5a | counter (+1 per message) | 0x30 | lookup 1→0x11, 2→0x22, 3→0x47 | 0x00 | 0x00 | u16le crc16_modbus(bytes[0:6])
fan          100%  0x5a | counter (+1 per message) | 0x10 | u16be round(value * 1 + 0) | 0x00 | u16le crc16_modbus(bytes[0:6])
color        100%  0x5a | counter (+1 per message) | 0x20 | round(value * 1 + 0) | round(value[1] * 1 + 0) | round(value[2] * 1 + 0) | u16le crc16_modbus(bytes[0:6])
  color only sent while mode 3 (3x; other commands ran in mode 1, 2): the driver sets it first

handshake (3 messages sent once when the app opens the device):
  1. 5a 00 01 00 00 00 0d 1d -> a5 01 ?? ?? ?? ?? ??, sent again 2x later (session reopened)
  2. 5a 00 02 38 b4 e6 52 1e 1e -> a5 02 ?? ??, bytes 3-6 = token from step 1, sent again 2x later (session reopened)
     reply byte 2 = 01 (2x, most common): the steps below
     reply byte 2 = 02 (1x): 5a 00 04 01 00 00 5c 11 -> a5 04 01 ??, 5a 00 03 01 00 00 5d 65 -> a5 03 01 ??
  3. 5a 00 03 01 00 00 5d 65 -> a5 03 01 ??, sent again 1x later (session reopened)

device replies:
mode         6/6  0xa5 | = query byte 2 (0x30) | = query byte 1 | = query byte 3 | 0x00 | sum8(bytes[0:5])
fan          6/6  0xa5 | = query byte 2 (0x10) | = query byte 1 | u16le round(value * 1 + 0) | sum8(bytes[0:5])
color        6/6  0xa5 | = query byte 2 (0x20) | = query byte 1 | 0x00 | 0x00 | sum8(bytes[0:5])
poll 1       7/7  0xa5 | = query byte 2 (0x40) | u16le rpm = raw, seen 800..4011 | u8 temp = raw, seen 35..38 | mode: 0x11 = silent, 0x22 = balanced, 0x47 = turbo | sum8(bytes[0:6])

24 of 24 'seen' observations matched a reply byte (mode, rpm, temp)

It writes a synthetic capture of a fan controller (its vendor app first opens a session with a token the fan hands out, then polls the fan's status, and the markers note what the app's screen showed, seen rpm 1207 temp 37 mode silent), recovers the protocol and the replies, names the readings and the fan's mode, notices that the app only sets a color in mode 3, and writes report.md (every claim linked to Wireshark frame numbers) and a working pyusb driver that encodes values it never saw and decodes what the fan answers.

--device lamp (default) is a simple 8-bit device; --device lcd is a pump cap screen whose app streams a JPEG video while you change the brightness; --device dial shows 32-bit values and packed bitfields:

position     100%  0xa5 | 0x01 | u32le round(value * 1 + 0) | sum8(bytes[0:6])
level        100%  0xa5 | 0x02 | bits[0:4] = round(value * 1 + 0) | 0x00 | sum8(bytes[0:4])
Download Tool