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
scapy
ortshark
. - 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-decoders
Install Python dependencies (optional):
pip install -r requirements.txt
matplotlib
: 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.txt
python extract_hid_data.py <input.pcap> -o output.txt
Requires 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] file
Modes (--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] file
Modes (--mode
):
0
: Do not draw movement- Combine with
--clicks
to 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
)0
disables 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 ofclick
field 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] file
Modes (--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
)0
disables 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
--offset
to 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,
simulate
mode 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
replay
mode, 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
q
at any time to stop immediately
- A keyboard capture might contain important text that is later deleted/overwritten
simulate
will only provide the final output- Use
raw
to see every keypress explicitly orreplay
with a delay to see the behaviour in real time
- In
replay
mode,<Shift+ArrowKey>
does not select text on Windows 10 due to a bug in thekeyboard
library- 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.txt
and
tshark -r <pcap-file> -Y 'usb.capdata' -T fields -e usb.capdata > usbdata.txt
Get 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