A terminal-based RF signal analysis tool for capturing, decoding, and retransmitting automotive keyfob signals. Built in Rust with a real-time TUI powered by ratatui. Protocol decoders are aligned with the ProtoPirate reference.
Supported hardware: KAT uses HackRF One (or compatible) when present for full receive and transmit. For receive-only operation, RTL433 (or any compatible RTL-SDR dongle) is supported: if no HackRF is found, KAT uses the first available RTL-SDR for capture and decode; transmit (Lock/Unlock/Trunk/Panic, Replay) is disabled when using RTL433/RTL-SDR.

Use KAT only on systems and vehicles you own or have explicit, written permission to test. Capturing, decoding, or transmitting keyfob and vehicle-access signals without authorization may be illegal in your jurisdiction (e.g. computer misuse, unauthorized access, or radio regulations). You are solely responsible for ensuring your use complies with all applicable laws. KAT is intended for security research, authorized penetration testing, education, and legitimate testing on your own equipment. The authors and contributors assume no liability for misuse or damage arising from use of this software.
.fob (versioned JSON with vehicle metadata, signal info, optional raw pairs) and .sub (Flipper Zero compatible).fob files with automatic v1/v2 format detection~/.config/KAT/config.ini (auto-created with comments on first run): export path, max captures, research_mode, radio defaults, export format:freq, :lock, :unlock, :replay, :save, :load, :delete, :q / :quit, and moreAt runtime, KAT tries HackRF first; if none is found, it uses the first available RTL433/RTL-SDR for receive-only. If neither is connected, it runs without TX/RX support (no live capture); a startup warning offers to continue or you can connect a device and restart.
macOS:
brew install hackrf
# RTL433/RTL-SDR: no extra system lib required; rtl-sdr-rs uses rusb
Debian / Ubuntu:
sudo apt install libhackrf-dev pkg-config libusb-1.0-0-dev
Fedora:
sudo dnf install hackrf-devel pkg-config libusb1-devel
Arch Linux:
sudo pacman -S hackrf libusb
On Linux, if using RTL433/RTL-SDR, you may need to unload DVB-T kernel modules so the device is not claimed by the kernel (see rtl-sdr-rs).
git clone <repo-url> && cd KAT
cargo build --release
The binary is placed at target/release/kat.
./target/release/kat
KAT starts in an interactive terminal UI. If no HackRF or RTL433/RTL-SDR is detected, a warning appears (“No HackRF or RTL-SDR detected”) and you can press any key to continue without TX/RX support—you can still view, import, and export captures. The header shows the active device (HackRF, RTL-SDR (RX only) when using RTL433/RTL-SDR, or No device) and radio status; when no device is connected, the status is shown in red (DISCONNECTED). When using RTL433/RTL-SDR, transmit actions (Replay, TX Lock/Unlock/Trunk/Panic) show “(no TX)” in the signal menu and display a receive-only message if selected.
| Key | Action |
|---|---|
j / k or Arrow Up / Down |
Navigate captures list |
Enter |
Open signal action menu on selected capture |
Tab |
Open radio settings menu (Frequency, LNA, VGA, AMP) |
r |
Toggle receive mode (start/stop RX) |
: |
Enter VIM-style command mode |
Esc |
Close menu / cancel current action |
q |
Quit (restores terminal) |
:q or :quit |
Quit from command line (same as q; restores terminal) |
Press Enter on a capture to open the action menu. When using RTL-SDR (receive-only), transmit actions show (no TX) and are disabled.
| Action | Description |
|---|---|
| Replay | Re-transmit raw capture (HackRF only; “no TX” with RTL-SDR) |
| TX Lock | Transmit lock command |
| TX Unlock | Transmit unlock command |
| TX Trunk | Transmit trunk release command |
| TX Panic | Transmit panic alarm command |
| Export .fob | Export signal with full vehicle + signal metadata |
| Export .sub | Export in Flipper Zero SubGHz format |
| Delete | Remove capture from the list |
When exporting to .fob, a metadata form collects filename and optional vehicle info:
A1B2C3D4) is shown in the field and appended to the filename so each export has a distinct file.The exported .fob file is a versioned JSON document (v2.0, format kat-fob) containing:
{
"version": "2.0",
"format": "kat-fob",
"signal": {
"protocol": "Kia V3/V4",
"frequency": 433920000,
"frequency_mhz": "433.92MHz",
"modulation": "PWM",
"rf_modulation": "AM/FM",
"encryption": "KeeLoq",
"data_bits": 64,
"data_hex": "...",
"serial": "0x1A2B3C",
"key": "0x...",
"button": 1,
"button_name": "Lock",
"counter": 1234,
"crc_valid": true,
"encoder_capable": true
},
"vehicle": {
"year": 2023,
"make": "Kia",
"model": "Sportage",
"region": "NA",
"command": "Lock",
"notes": ""
},
"capture": {
"timestamp": "2026-02-07T12:00:00Z",
"raw_data_hex": "0x...",
"raw_pair_count": 0,
"raw_pairs": [{"level": true, "duration_us": 400}, {"level": false, "duration_us": 800}]
}
}
Year_Make_Model_Region_Command_8HEX.fob).raw_data_hex, raw_pair_count, and optionally raw_pairs when config include_raw_pairs is true.Transmit commands (:lock, :unlock, :trunk, :panic) require HackRF; with RTL-SDR they report that transmit is not available.
| Command | Description |
|---|---|
:freq <MHz> |
Set receive frequency (e.g. :freq 433.92) |
:lock <ID> |
Transmit lock signal (ID: single, comma list, or range; e.g. 1, 1, 3, 5, 1-5) |
:unlock <ID> |
Transmit unlock signal (same ID formats) |
:trunk <ID> |
Transmit trunk release (same ID formats) |
:panic <ID> |
Transmit panic alarm (same ID formats) |
:replay <ID> |
Replay raw capture(s) by ID in order (same ID formats; HackRF only) |
:save <ID> |
Save capture to file |
:delete <ID> |
Delete capture from list |
:load <file> |
Import capture from .fob or .sub file |
:q or :quit |
Quit application (terminal restored cleanly, same as pressing q) |
On first launch, KAT creates the config directory and a default config file. Captures are in-memory only and are not written to disk unless you export them.
~/.config/KAT/
├── config.ini # Application settings (auto-generated with comments)
└── exports/ # Default export directory for .fob / .sub files
Example config.ini (all keys optional; defaults are used if missing):
[general]
export_directory = ~/.config/KAT/exports
import_directory = ~/.config/KAT/import
max_captures = 100
research_mode = false
[radio]
default_frequency = 433920000
default_lna_gain = 24
default_vga_gain = 20
default_amp = false
[export]
default_format = fob
include_raw_pairs = true
~/.config/KAT/import). Exports are still saved to export_directory.true (default), unknown (unidentified) signals are shown in addition to decoded ones; when false, only successfully decoded signals appear.true, .fob exports include raw level/duration pairs for replay.Protocol behavior and RF modulation (AM/FM) follow the ProtoPirate reference. KAT’s receiver is AM/OOK only; FM protocols may still decode when the signal produces a usable envelope.
| Protocol | Encoding | RF | Encryption | Frequency |
|---|---|---|---|---|
| Kia V0 | PWM | FM | Fixed Code | 433.92 MHz |
| Kia V1 | Manchester | AM | Fixed Code | 315 / 433.92 MHz |
| Kia V2 | Manchester | FM | Fixed Code | 315 / 433.92 MHz |
| Kia V3/V4 | PWM | AM/FM | KeeLoq | 315 / 433.92 MHz |
| Kia V5 | Manchester | FM | Fixed Code | 433.92 MHz |
| Kia V6 | Manchester | FM | AES-128 | 433.92 MHz |
| Kia V7 | Manchester | FM | Fixed Code (CRC8) | 315 / 433.92 MHz |
| Ford V0 | Manchester | FM | Rolling Code | 315 / 433.92 MHz |
| Ford V1 | Manchester | FM | Rolling Code (descramble + CRC16) | 315 / 433.92 MHz |
| Ford V2 | Manchester | FM | Fixed Code (0x7FA7 sync) | 315 / 433.92 MHz |
| Ford V3 | Manchester | FM | Fixed Code (decode-only) | 315 / 433.92 MHz |
| Chrysler V0 (Dodge/Jeep) | PWM | AM | Rolling Code (seed-XOR) | 315 / 433.92 MHz |
| Honda Static | Manchester | FM | Fixed Code | 315 / 433.92 MHz |
| Honda V1 | PWM | AM | Fixed Code | 315 / 433.92 MHz |
| Toyota (Lexus) | PWM / NRZ | AM | KeeLoq (decode-only) | 315 / 433.92 MHz |
| Land Rover V0 | Diff. Manchester | FM | Rolling Code (3-bit check) | 315 / 433.92 MHz |
| Land Rover RKE | PWM | AM | KeeLoq | 315 / 433.92 MHz |
| Fiat V0 | Manchester | FM | Fixed Code | 433.92 MHz |
| Fiat V1 (Magneti Marelli) | Manchester | FM | Rolling Code | 433.92 MHz |
| Mazda V0 | Pair-based | FM | XOR Deobfuscation | 433.92 MHz |
| Mazda Siemens | Manchester | FM | Siemens XOR/interleave | 433.92 MHz |
| Mitsubishi V0 | PWM | FM | Bit Negation + XOR | 868.35 MHz |
| BMW CAS4 | Manchester | AM | CAS4 rolling (decode-only) | 433.92 MHz |
| Porsche Touareg | PWM | AM | Rotation Cipher | 433.92 / 868.35 MHz |
| Porsche Cayenne | PWM | AM | VAG rolling register | 433.92 / 868.35 MHz |
| Subaru | PWM | AM | Rolling Code | 433.92 MHz |
| Suzuki | PWM | AM | Rolling Code | 433.92 MHz |
| VAG (VW/Audi/Seat/Skoda) | Manchester | AM | AUT64/XTEA | 433.92 / 434.42 MHz |
| Scher-Khan | PWM | FM | Magic Code | 433.92 MHz |
| Star Line | PWM | AM | KeeLoq | 433.92 MHz |
| PSA (Peugeot/Citroën) | Manchester | FM | Modified TEA/XOR | 433.92 MHz |
| PSA2 (PSA OLD) | Manchester | AM | TEA | 433.92 MHz |
KeeLoq generic fallback: If no protocol decodes a capture, KAT tries KeeLoq with every keystore manufacturer key (Kia V3/V4 and Star Line bit layouts). On success the protocol is shown as Keeloq (keystore name) (e.g. Keeloq (Alligator), Keeloq (Pandora_PRO)). See docs/keeloq_generic.md.
KAT matches capture metadata (Year / Make /