Decoders and visualizers for USB Human Interface Devices (HIDs) — keyboard, mouse, and tablet — including tools to extract raw HID data from PCAP files.
📄 HID Spec: USB HID 1.11
- PCAP extraction — extract raw HID data using
scapyortshark. - Keyboard decoder — translate scan codes into keystrokes
- Mouse decoder — draw mouse movement and clicks
- Tablet decoder — draw tablet pen strokes
Clone the repo:
git clone https://github.com/Nissen96/USB-HID-decoders.git
cd USB-HID-decodersInstall Python dependencies (optional):
pip install -r requirements.txtmatplotlib: Required for mouse/tablet visualizationsscapy: Needed forextract_hid_data.py(not required if using bash version).keyboard: Enables replay mode and keyboard shortcuts during mouse/tablet animations (must be run as root on Linux, unsupported in WSL).
Extract the HID data from a PCAP with one of the two helper scripts:
./extract_hid_data.sh <input.pcap>Requires tshark, the command line version of Wireshark. Simplest and most reliable.
One-liner to extract HID data from Bluetooth Attribute Protocol (btatt):
tshark -r <pcap-file> -Y "btatt.value && frame.len == 20" -T fields -e "btatt.value" > usbdata.txtpython extract_hid_data.py <input.pcap> -o output.txtRequires the Python library scapy. Tries to recover device name and info if possible, but less reliable for now.
Convert HID scan codes to readable keystrokes.
python keyboard_decode.py [--offset N] [--mode {raw,simulate,replay}]
[--env {txt,cmd}] [--delay MS] [--no-reserved]
[-o OUTPUT] fileModes (--mode):
raw: Print each keypress (with modifiers) on a separate linesimulate(default): Simulate typed text on a US-keyboardreplay: Replays keystrokes in active window (⚠️ unsafe for untrusted input)--delay <DELAY>to set delay in miliseconds between keystrokes (default:50)
Environment (--env) (simulate mode only):
txt(default): Multiline editor behavior- Arrow keys are interpreted as cursor movement and simulated
<ENTER>will insert a line break at the cursor position
cmd: Interactive shell/browser behavior- Keys like
<TAB>,<ENTER>,<UP>, and<DOWN>are considered action keys <ENTER>starts a new line, but other actions are written out explicitly
- Keys like
Data Format:
Normal keyboard HID data has a modifier byte (e.g. SHIFT, CTRL, etc.), a reserved null byte, and then up to six keycode bytes (in case of multiple keys pressed):
| Modifier | Reserved | Keycode 1 | ... | Keycode 6 |
Format options:
--offset: Index of modifier byte in case of added prefix bytes (default:0)--no-reserved: Use if the reserved byte is missing (e.g. USBPcap outputs)
Visualize mouse movements and clicks.
python mouse_decode.py [--offset N] [--mode 0-2] [--clicks] [--speed SPEED]
[--bit-lengths {8,12,16}...] [--absolute] fileModes (--mode):
0: Do not draw movement- Combine with
--clicksto show button clicks only
- Combine with
1(default): Draw movement when buttons are held2: Draw all movements
Colors indicate the mouse button(s) pressed when clicking/moving (left/middle/right). Movement while no buttons are held is colored gray in mode 2.
Animation:
--speed: Set animation speed 0-10 (default:0)0disables animation and shows finished drawing
Keyboard controls during animation (very helpful for onscreen keyboard usage or drawing/writing in the same spot multiple times):
SPACE: Pause/resumsec: Clear screen and continueq: Quit
Requires Python library keyboard
Data Format:
Mouse data can come in many formats but has consecutive fields for click, x, and y.
The fields are each either 8, 12, or 16 bits, and should in total be divisible by 16.
Format options:
--offset: Index ofclickfield in each data line (default:0)--bit-lengths: Bit lengths of fields[click, x, y](default:8 8 8)--absolute: Interpret coordinates as absolute instead of the default relative cumulative
Visualize tablet/pen input (pressure ignored).
python tablet_decode.py [--offset N] [--mode 0-2]
[--speed SPEED] fileModes (--mode):
1(default): Draw only when pen is clicked2: Draw all movements
Colors indicate the mouse button(s) pressed when clicking/moving (left and/or right). Movement while no buttons are held is colored gray in mode 2.
Animation:
--speed: Set animation speed 0-10 (default:0)0disables animation and shows finished drawing
Keyboard controls during animation:
SPACE: Pause/resumsec: Clear screen and continueq: Quit
Requires Python library keyboard
- The decoders often work out of the box, but you might need to analyze some data lines manually to figure out the format options
- All scripts support an
--offsetto the real data when data lines are prefixed with extra bytes - Mouse decoder supports different bit lengths for the three data fields
- All scripts support an
- For animation, enable keyboard interaction by installing Python library
keyboard - For keyboard decoding,
simulatemode typically produces the expected final output- Handles most scan codes, arrow keys,
Shift, etc. - Key combos (e.g.
<Ctrl+c>,<Alt+TAB>,<Shift+LEFT>) and some special keys (e.g.<ESC>) are written explicitly.
- Handles most scan codes, arrow keys,
- Be careful with
replaymode, this will repeat all keypresses typed during the capture- This includes any commands, shortcuts, etc. - can be useful for e.g. a Vim capture
- Inspect output from raw/simulated mode before running replay
- Set the computer's keyboard layout to the same as the expected layout used during capture
- Press
qat any time to stop immediately
- A keyboard capture might contain important text that is later deleted/overwritten
simulatewill only provide the final output- Use
rawto see every keypress explicitly orreplaywith a delay to see the behaviour in real time
- In
replaymode,<Shift+ArrowKey>does not select text on Windows 10 due to a bug in thekeyboardlibrary- As a workaround, the program will stop and wait for you to perform those keypresses manually.
- Check out the samples folder to see usage from various CTFs
USB HID data can be extracted from a packet capture with tshark, the CLI of Wireshark.
In Wireshark, the relevant data is stored in the field usb.capdata (Leftover Capture Data) or usbhid.data (HID Data).
These can be extracted separately with
tshark -r <pcap-file> -Y 'usbhid.data' -T fields -e usbhid.data > usbdata.txtand
tshark -r <pcap-file> -Y 'usb.capdata' -T fields -e usb.capdata > usbdata.txtGet data from a specific device by adding a filter for its address, e.g.
-Y 'usb.src == "1.3.1"'The bash script provided in the repo is a one-liner to extract HID data from all USB devices and store in separate files, named after device address:
tshark -r <pcap-file> -Y "usb.capdata || usbhid.data" -T fields -e usb.src -e usb.capdata -e usbhid.data | # Extract usb.src, usb.capdata, and usbhid.data from all packets with HID data
sort -s -k1,1 | # Sort on first field only (usb.src)
awk '{ printf "%s", (NR==1 ? $1 : pre!=$1 ? "\n" $1 : "") " " $2; pre=$1 }' | # Group data by usb.src
awk '{ for (i=2; i<=NF; i++) print $i > "usbdata-" $1 ".txt" }' # For each group, store data in usbdata-<usb.src>.txt