Wairz
An open-source AI assisted firmware analysis tool
Ask AI about Wairz
Powered by Claude Β· Grounded in docs
I know everything about Wairz. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Upload firmware images, unpack them, explore the filesystem, analyze binaries, and conduct security assessments β all powered by AI analysis via Model Context Protocol (MCP).
Connect any MCP-compatible AI agent to Wairz's 60+ analysis tools β Claude Code, Claude Desktop, OpenCode, Codex, Cursor, VS Code + Copilot, Gemini CLI, Windsurf, and more.
Features
- Firmware Unpacking β Automatic extraction of SquashFS, JFFS2, UBIFS, CramFS, ext, and CPIO filesystems via binwalk, with multi-partition support
- RTOS Support β Auto-classifies firmware as
linux | rtos | unknownon unpack (FreeRTOS / Zephyr / baremetal Cortex-M), with manual override. RTOS projects get a dedicated tool category for vector-table parsing, task enumeration, base-address recovery, and memory-map analysis on raw.axf/.elfblobs - File Explorer β Browse extracted filesystems with a virtual tree, view text/binary/hex content, and search across files
- Binary Analysis β Disassemble and decompile binaries using radare2 and Ghidra headless, with cross-reference and taint analysis
- Component Map β Interactive dependency graph showing binaries, libraries, scripts, and their relationships
- Security Assessment β Detect hardcoded credentials, crypto material, setuid binaries, insecure configs, and weak permissions
- SBOM & CVE Scanning β Generate Software Bill of Materials (CycloneDX) and scan components against the NVD for known vulnerabilities
- Firmware Emulation β Boot firmware in QEMU (user-mode for single binaries, system-mode for full OS) in isolated containers, with GDB support
- Fuzzing β AFL++ with QEMU mode for cross-architecture binary fuzzing, with automatic dictionary/corpus generation and crash triage
- Firmware Comparison β Diff filesystem trees, binaries, and decompiled functions across firmware versions
- Live Device UART β Connect to physical devices via a host-side serial bridge for interactive console access
- AI Analysis via MCP β 60+ analysis tools exposed to Claude for autonomous security research
- Findings & Reports β Record security findings with severity ratings and evidence, export as Markdown or PDF
Architecture
Claude Code / Claude Desktop / OpenCode
β
β MCP (stdio)
βΌ
βββββββββββββββββββ ββββββββββββββββββββββββββββββββββββ
β wairz-mcp ββββββΆβ FastAPI Backend β
β (MCP server) β β β
β 60+ tools β β Services: firmware, analysis, β
β β β emulation, fuzzing, sbom, uart β
βββββββββββββββββββ β β
β Ghidra headless Β· QEMU Β· AFL++ β
ββββββββββββ¬ββββββββββββββββββββββββ
β
ββββββββββββββββ ββββββββββββββββΌβββββββββββββββ
β React SPA βββββΆβ PostgreSQL β Redis β
β (Frontend) β β β β
ββββββββββββββββ ββββββββββββββββ΄βββββββββββββββ
Optional:
wairz-uart-bridge.py (host) ββ TCP:9999 ββ Docker backend
Prerequisites
Public Beta
WAIRZ is currently in public beta. You may encounter bugs or rough edges. If you run into any issues, please open an issue on GitHub or reach out at andrew@digitalandrew.io.
WAIRZ supports embedded Linux, FreeRTOS, Zephyr, and baremetal Cortex-M firmware. Auto-detection runs on unpack and can be overridden from the project page. Linux-specific tools (emulation, init-script analysis, SBOM, etc.) are hidden on RTOS projects, and a dedicated RTOS tool category is exposed in their place. See RTOS support for details.
Quick Start
Docker (recommended)
git clone https://github.com/digitalandrew/wairz.git
cd wairz
cp .env.example .env
docker compose up --build
- Frontend: http://localhost:3000
- API docs: http://localhost:8000/docs
Local Development
# Start PostgreSQL and Redis
docker compose up -d postgres redis
# Backend
cd backend
uv sync
uv run alembic upgrade head
uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8000
# Frontend (separate terminal)
cd frontend
npm install
npm run dev
Or use the helper script:
./launch.sh
Connecting AI via MCP
Wairz uses MCP to give AI agents access to firmware analysis tools. After starting the backend, register the MCP server with your preferred client:
Claude Code
claude mcp add wairz -- docker exec -i wairz-backend-1 uv run wairz-mcp --project-id <PROJECT_ID>
Claude Desktop
Add to your Claude Desktop config (~/.config/Claude/claude_desktop_config.json on Linux, ~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
{
"mcpServers": {
"wairz": {
"command": "docker",
"args": [
"exec", "-i", "wairz-backend-1",
"uv", "run", "wairz-mcp",
"--project-id", "<PROJECT_ID>"
]
}
}
}
OpenCode
Add to your opencode.json (project root or ~/.config/opencode/opencode.json):
{
"mcp": {
"wairz": {
"type": "local",
"command": ["docker", "exec", "-i", "wairz-backend-1", "uv", "run", "wairz-mcp", "--project-id", "<PROJECT_ID>"],
"timeout": 30000,
"enabled": true
}
}
}
Note: The
timeoutmust be increased from the default 5000ms because Wairz registers 90+ tools.
Once connected, your AI agent can autonomously explore firmware, analyze binaries, run emulation, fuzz targets, and generate security findings. The MCP server supports dynamic project switching via the switch_project tool β no restart needed to change projects.
Projects with multiple firmware versions
When a project has more than one firmware uploaded (useful for diffing across versions via diff_firmware), the MCP server picks the earliest-uploaded unpacked firmware by default. To target a specific version, add --firmware-id <FIRMWARE_ID> to the launch command, or pass firmware_id to the switch_project MCP tool. Use list_firmware_versions to find IDs.
MCP Tools (60+)
| Category | Tools |
|---|---|
| Project | get_project_info, switch_project, list_projects |
| Filesystem | list_directory, read_file, search_files, file_info, find_files_by_type, get_component_map, get_firmware_metadata, extract_bootloader_env |
| Strings | extract_strings, search_strings, find_crypto_material, find_hardcoded_credentials |
| Binary Analysis | list_functions, disassemble_function, decompile_function, list_imports, list_exports, xrefs_to, xrefs_from, get_binary_info, check_binary_protections, check_all_binary_protections, find_string_refs, resolve_import, find_callers, search_binary_content, get_stack_layout, get_global_layout, trace_dataflow, cross_binary_dataflow |
| Security | check_known_cves, analyze_config_security, check_setuid_binaries, analyze_init_scripts, check_filesystem_permissions, analyze_certificate |
| SBOM | generate_sbom, get_sbom_components, check_component_cves, run_vulnerability_scan |
| Emulation | start_emulation, run_command_in_emulation, stop_emulation, check_emulation_status, get_emulation_logs, enumerate_emulation_services, diagnose_emulation_environment, troubleshoot_emulation, get_crash_dump, run_gdb_command, save_emulation_preset, list_emulation_presets, start_emulation_from_preset |
| Fuzzing | analyze_fuzzing_target, generate_fuzzing_dictionary, generate_seed_corpus, generate_fuzzing_harness, start_fuzzing_campaign, check_fuzzing_status, stop_fuzzing_campaign, triage_fuzzing_crash |
| Comparison | list_firmware_versions, diff_firmware, diff_binary, diff_decompilation |
| UART | uart_connect, uart_send_command, uart_read, uart_send_break, uart_send_raw, uart_disconnect, uart_status, uart_get_transcript |
| Reporting | add_finding, list_findings, update_finding, read_project_instructions, list_project_documents, read_project_document |
| Code | save_code_cleanup |
UART Bridge (Optional)
For live device access via UART, run the bridge on the host machine (USB serial adapters can't easily pass through to Docker):
pip install pyserial
python3 scripts/wairz-uart-bridge.py --bind 0.0.0.0 --port 9999
The bridge is a TCP server β the serial device path and baud rate are specified via the uart_connect MCP tool, not on the command line.
On Linux, allow Docker traffic to reach the bridge and ensure .env is configured correctly:
sudo iptables -I INPUT -p tcp --dport 9999 -j ACCEPT
UART_BRIDGE_HOST in .env must be host.docker.internal (not localhost). Restart the backend after changing .env: docker compose restart backend.
See UART Console docs for full setup details.
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 19, Vite, TypeScript, Tailwind CSS, shadcn/ui |
| Code Viewer | Monaco Editor |
| Component Graph | ReactFlow + Dagre |
| Terminal | xterm.js |
| State Management | Zustand |
| Backend | Python 3.12, FastAPI, SQLAlchemy 2.0 (async), Alembic |
| Database | PostgreSQL 16 |
| Cache | Redis 7 |
| Firmware Extraction | binwalk, sasquatch, jefferson, ubi_reader, cramfs-tools |
| Binary Analysis | radare2 (r2pipe), pyelftools |
| Decompilation | Ghidra 11.3.1 (headless) with custom analysis scripts |
| Emulation | QEMU user-mode + system-mode (ARM, MIPS, MIPSel, AArch64) |
| Fuzzing | AFL++ with QEMU mode |
| SBOM | CycloneDX, NVD API (nvdlib) |
| UART | pyserial (host-side bridge) |
| AI Integration | MCP (Model Context Protocol) |
| Containers | Docker + Docker Compose |
Project Structure
wairz/
βββ backend/
β βββ app/
β β βββ main.py # FastAPI application
β β βββ config.py # Settings (pydantic-settings)
β β βββ database.py # Async SQLAlchemy engine/session
β β βββ mcp_server.py # MCP server with dynamic project switching
β β βββ models/ # SQLAlchemy ORM models
β β βββ schemas/ # Pydantic request/response schemas
β β βββ routers/ # REST API endpoints
β β βββ services/ # Business logic
β β βββ ai/ # MCP tool registry + 60+ tool implementations
β β β βββ tools/ # Organized by category (filesystem, binary, security, etc.)
β β βββ utils/ # Path sandboxing, output truncation
β βββ alembic/ # Database migrations
β βββ pyproject.toml
βββ frontend/
β βββ src/
β β βββ pages/ # Route pages (explorer, emulation, fuzzing, SBOM, etc.)
β β βββ components/ # UI components (file tree, hex viewer, component map, etc.)
β β βββ api/ # API client functions
β β βββ stores/ # Zustand state management
β β βββ types/ # TypeScript type definitions
β βββ package.json
βββ ghidra/
β βββ Dockerfile # Ghidra headless container
β βββ scripts/ # Custom Java analysis scripts
βββ emulation/
β βββ Dockerfile # QEMU container (ARM, MIPS, MIPSel, AArch64)
β βββ scripts/ # Emulation helper scripts
βββ fuzzing/
β βββ Dockerfile # AFL++ container with QEMU mode
βββ scripts/
β βββ wairz-uart-bridge.py # Host-side UART serial bridge
βββ docker-compose.yml
βββ launch.sh # Local development launcher
βββ .env.example
βββ CLAUDE.md
Configuration
All settings are configured via environment variables or .env file:
| Variable | Default | Description |
|---|---|---|
DATABASE_URL | postgresql+asyncpg://wairz:wairz@postgres:5432/wairz | PostgreSQL connection |
REDIS_URL | redis://redis:6379/0 | Redis connection |
STORAGE_ROOT | /data/firmware | Firmware storage directory |
MAX_UPLOAD_SIZE_MB | 500 | Maximum firmware upload size |
MAX_TOOL_OUTPUT_KB | 30 | MCP tool output truncation limit |
GHIDRA_PATH | /opt/ghidra | Ghidra installation path |
GHIDRA_TIMEOUT | 120 | Ghidra decompilation timeout (seconds) |
FUZZING_IMAGE | wairz-fuzzing | Fuzzing container image name |
FUZZING_TIMEOUT_MINUTES | 120 | Max fuzzing campaign duration |
FUZZING_MAX_CAMPAIGNS | 1 | Max concurrent fuzzing campaigns |
UART_BRIDGE_HOST | host.docker.internal | UART bridge hostname |
UART_BRIDGE_PORT | 9999 | UART bridge TCP port |
NVD_API_KEY | (empty) | Optional NVD API key for higher rate limits |
LOG_LEVEL | INFO | Logging level |
Testing Firmware
Good firmware images for testing:
- OpenWrt β Well-structured embedded Linux (MIPS, ARM)
- DD-WRT β Similar to OpenWrt
- DVRF (Damn Vulnerable Router Firmware) β Intentionally vulnerable, great for security testing
