| Mode | Name | Size | |
|---|---|---|---|
| -rw-r--r-- | .gitignore | 151 | logstatsplainblame |
| -rw-r--r-- | README.md | 5561 | logstatsplainblame |
| -rw-r--r-- | TODO | 3526 | logstatsplainblame |
| d--------- | docs | 176 | logstatsplain |
| d--------- | experiments | 124 | logstatsplain |
| -rwxr-xr-x | ida-tui | 913 | logstatsplainblame |
| d--------- | idatui | 525 | logstatsplain |
| -rw-r--r-- | logo.ans | 24788 | logstatsplainblame |
| d--------- | plan | 34 | logstatsplain |
| -rw-r--r-- | pyproject.toml | 814 | logstatsplainblame |
| -rw-r--r-- | rehearsed-engineer.md | 452 | logstatsplainblame |
| d--------- | server | 43 | logstatsplain |
| d--------- | tests | 45 | logstatsplain |
| -rw-r--r-- | uv.lock | 11747 | logstatsplainblame |
ida-tui
A minimal, keyboard-first (mouse-capable) TUI frontend for IDA Pro, built with Textual and driving idalib (IDA headless).
Opening a binary spawns our own idalib worker — a private subprocess talking a
unix socket (idatui/worker.py + WorkerClient), ~50–100× cheaper per call than
an HTTP transport. It reuses ida-pro-mcp's
tool implementations in-process; the old ida-pro-mcp HTTP server/supervisor path
has been removed.
⚠️ Status: not ready for public consumption
This is a personal, actively-hacked-on project. It is not packaged, polished, or supported for general use. Expect sharp edges:
- Hardcoded paths and assumptions (e.g. a venv at
~/ida-venv, a specific IDA/idalib layout). - No stable API, no versioning promises, no changelog — things move and break.
- Requires a working IDA Pro + idalib install, which you must license and set up yourself.
- Known open bugs (see the backlog below), including no handling of PLT/import stubs.
- Basically undocumented beyond this file and
docs/.
If you found this expecting a finished tool: it isn't one yet. Poke around, but don't file expectations. Use at your own risk.
What it does
- A unified IDA-style listing (continuous disassembly interleaved with data /
undefined heads) as the default code view;
F5/Tabdrops into the decompiler (pseudocode) for the function under the cursor. Both are line-virtualized and page lazily over the worker. - Keyboard navigation: follow (
enter), xrefs (x, tagged call/read/write/ offset), rename (n), retype (y), comment (;), incremental search (/?), history (back), hex view (\), andhome/end/shift+homeline motions. - A functions panel (fuzzy symbol palette on
Ctrl+N), hex viewer, struct editor, and inline make code/data/function/string edits. - An optional unix-socket RPC layer to puppeteer the live TUI from another
process (agent-driven RE / livestreaming). See
docs/RPC.md.
Architecture (three layers, kept separate)
idatui/worker.py+idatui/worker_client.py— the backend.worker.pyopens one DB with idalib (on its main thread) and serves ida-pro-mcp's tool functions over a unix socket;WorkerClientspawns it and is a stdlib-only drop-in client (length-prefixed pickle, calls serialized under a lock). Shared error types + theSessionmodel live inidatui/errors.py.idatui/domain.py— paging/caching over the worker client (FunctionIndex,DisasmModel,ListingModel,decompile, xrefs, resolve). Synchronous, thread-safe. Tools ida-pro-mcp lacks (heads,read_raw,resolve_names,xref_types, …) are injected byserver/patch_server.py, which the worker runs itself on startup.idatui/app.py— the Textual app (virtualizedScrollViews, shared cursor/ search/nav mixins, modals).
The domain + worker-client layers are intentionally stdlib-only (the worker process links idalib); only the TUI layer pulls in Textual + Pygments.
Requirements
- Python ≥ 3.11
- A working IDA Pro with idalib and ida-pro-mcp installed (the worker reuses ida-pro-mcp's tool implementations in-process — no server runs).
- Textual ≥ 8 and Pygments ≥ 2 for the TUI (
pip install -e '.[tui]').
Two python environments are expected: one with textual + idapro for the TUI
(~/ida-venv, override $IDATUI_PYTHON) and one with idapro + ida_pro_mcp
for the worker (auto-detected, override $IDATUI_WORKER_PYTHON).
Running
One command — it spawns a private idalib worker for the binary (which opens + auto-analyzes it in its own process over a unix socket) and drops you into the TUI behind a loading overlay:
./ida-tui /path/to/binary # open a binary and drive it — that's it
It uses ~/ida-venv/bin/python for the TUI (override with $IDATUI_PYTHON) and
resolves binary paths against your real cwd. The binary's directory must be
writable (idalib writes a .i64 there).
Recovering a wedged database: if a worker was hard-killed it leaves unpacked
foo.id0/.id1/.id2/.nam/.tilnext tofoo.i64, and the.i64then refuses to reopen. Delete those stale files (never the.i64) and retry —ida-tuidoes this automatically.
RPC / driving the TUI
Give the TUI --rpc <sock> to expose a unix-socket control channel, then drive
it from another pane:
./ida-tui /abs/path/bin --rpc /tmp/ida.sock
python -m idatui.drive where # ergonomic terse-text helper
python -m idatui.drive pc main # pseudocode of main
python -m idatui.drive rename sub_5BE0 foo # goto + rename
Or let idatui.pane spawn + manage TUI panes in tmux (see the idatui-rpc skill):
python -m idatui.pane spawn --open /abs/path/bin # -> {sock, pane, ready}
python -m idatui.pane list
python -m idatui.pane stop --sock <sock>
See docs/RPC.md for the full protocol.
Tests
A headless Textual Pilot suite lives in tests/; it spawns a worker on the
given binary (default targets/echo):
python tests/test_scenarios.py targets/echo # full UI suite
python tests/test_scenarios.py --only hex,rename
Docs
docs/RPC.md— the RPC protocoldocs/PAGING_FINDINGS.md— idalib tool paging/scale quirksdocs/TEXTUAL_NOTES.md— Textual pitfalls encountereddocs/TUI_DRIVING_BLUEPRINT.md— generalizing the driving layer
