Firmware Probing
The console-probe tool is a generic embedded console scanner built for reverse-engineering firmware command interfaces. It auto-detects the prompt format, parses help output, enters submenus, and optionally brute-forces candidate command names. It was developed for the Winegard firmware but works with any prompt-based serial console.
How console-probe works
Section titled “How console-probe works”The discovery process follows a structured sequence:
-
Prompt detection. The tool sends empty lines (carriage returns) and analyzes the response to identify the prompt string. On the Carryout G2, this detects
TRK>as the root prompt. -
Error string detection. A known-bad command is sent to capture the error response pattern. This lets the tool distinguish between “command recognized” and “command unknown” for subsequent probing.
-
Help parsing. The tool sends the help command (default:
?) and parses the response to extract known commands, their parameters, and descriptions. It identifies which commands are submenus (they change the prompt when entered). -
Submenu discovery. For each discovered submenu, the tool enters it, queries help, and records the available commands. The prompt changes (e.g.,
TRK>toMOT>) confirming successful submenu entry. -
Brute-force probing (optional). With
--deep, the tool sends candidate command names from a wordlist and checks whether each one produces a valid response (as opposed to the error string). This catches commands not listed in help output.
Basic usage
Section titled “Basic usage”Discover commands via help only
Section titled “Discover commands via help only”The fastest mode — queries ? at each menu level, no brute-force:
console-probe --port /dev/ttyUSB2 --baud 115200 --discover-onlyThis enters every discovered submenu, queries help, and prints the command inventory. Add --json to save a structured report:
console-probe --port /dev/ttyUSB2 --baud 115200 --discover-only --json /tmp/discover.jsonDeep probe with wordlist
Section titled “Deep probe with wordlist”Full discovery plus brute-force probing of all submenus:
console-probe --port /dev/ttyUSB2 --baud 115200 --deep --wordlist scripts/wordlists/winegard.txtThe wordlist file contains one candidate command per line. The bundled winegard.txt includes terms extracted from firmware strings and documentation.
Probe a single submenu
Section titled “Probe a single submenu”Target a specific submenu without scanning all of them:
console-probe --port /dev/ttyUSB2 --baud 115200 --submenu dvbCLI options reference
Section titled “CLI options reference”Connection options
Section titled “Connection options”| Option | Default | Description |
|---|---|---|
--port | /dev/ttyUSB0 | Serial port |
--baud | 115200 | Baud rate |
--line-ending | cr | Line ending to send (cr, lf, crlf) |
Discovery overrides
Section titled “Discovery overrides”| Option | Default | Description |
|---|---|---|
--prompt | auto-detect | Override the root prompt string |
--error | auto-detect | Override the error response string |
--help-cmd | ? | Command to request help |
--exit-cmd | q | Command to exit submenus |
Probing options
Section titled “Probing options”| Option | Default | Description |
|---|---|---|
--discover-only | off | Help-only mode, no brute-force |
--deep | off | Probe all discovered submenus |
--submenu NAME | none | Probe a single named submenu |
--timeout | 0.5 | Per-command timeout in seconds |
--blocklist | reboot,stow,def,q,Q | Commands to never send |
--wordlist FILE | none | Extra candidate words file (repeatable) |
Output options
Section titled “Output options”| Option | Default | Description |
|---|---|---|
--json FILE | none | Write results as JSON to file |
The JSON report
Section titled “The JSON report”When --json is specified, the tool writes a structured report with format version 2. The report contains:
{ "format_version": 2, "device": { "port": "/dev/ttyUSB2", "baud": 115200, "root_prompt": "TRK>", "error_string": "type '?' for help" }, "menus": { "TRK": { "help": [ {"name": "mot", "params": "", "description": "enter motor control submenu"}, {"name": "dvb", "params": "", "description": "enter DVB tuner submenu"} ], "probe_hits": [], "undiscovered": [] }, "MOT": { "help": [...], "probe_hits": [["a", "Angle[0] = 180.00 Angle[1] = 45.00"]], "undiscovered": [["xyz", "some unexpected response"]] } }}Key sections in each menu:
help— Commands discovered via the?command, with parameter syntax and descriptions.probe_hits— Commands that produced a valid (non-error) response during brute-force probing.undiscovered— Commands found by probing that were not in the help output. These are the interesting findings — hidden or undocumented commands.
Practical tips
Section titled “Practical tips”Blocklist safety
Section titled “Blocklist safety”The default blocklist (reboot,stow,def,q,Q) prevents the probe from sending commands that would disrupt the session. The reboot command restarts the firmware. The stow command folds the dish flat (dangerous if you’ve modified the feed). The def command restores factory defaults. And q exits the shell entirely on the G2 root menu (kills UART, requires power cycle).
Add more commands to the blocklist if needed:
console-probe --port /dev/ttyUSB2 --baud 115200 --deep \ --blocklist "reboot,stow,def,q,Q,scan,kill"NVS submenu false positives
Section titled “NVS submenu false positives”The NVS submenu treats any unrecognized input as a sequential index read (no error string). This means every candidate command “succeeds” during brute-force probing, producing false positives. The results are harmless (read-only) but noisy. The --discover-only mode avoids this issue since it only queries help.
Using with non-Winegard devices
Section titled “Using with non-Winegard devices”The tool is not Winegard-specific. It works with any serial console that has:
- A recognizable prompt string (auto-detected or specified with
--prompt) - A consistent error response for unknown commands (auto-detected or
--error) - A help command that lists available commands (configurable with
--help-cmd)
# U-Boot bootloader exampleconsole-probe --port /dev/ttyUSB0 --baud 115200 \ --prompt "U-Boot>" --error "Unknown command" --help-cmd "help"Package structure
Section titled “Package structure”The console-probe package is organized as:
profile.py -- DeviceProfile + HelpEntry dataclassesserial_io.py -- Prompt-aware serial I/Odiscovery.py -- Auto-discovery, help parsing, submenu probing, candidate generationreport.py -- JSON report writer (format_version 2)cli.py -- argparse CLI entry pointInstall and run:
uv syncuv run console-probe --help