| Mode | Name | Size | |
|---|---|---|---|
| d--------- | .agents / skills / idatui | 33 | logstatsplain |
| d--------- | .auto | 686 | logstatsplain |
| d--------- | .fastfeedback | 36 | logstatsplain |
| -rw-r--r-- | .gitignore | 361 | logstatsplainblame |
| -rw-r--r-- | README.md | 7071 | logstatsplainblame |
| -rw-r--r-- | TODO | 3497 | logstatsplainblame |
| d--------- | docs | 336 | logstatsplain |
| d--------- | experiments | 833 | logstatsplain |
| -rwxr-xr-x | ida-tui | 830 | logstatsplainblame |
| d--------- | idatui | 1100 | logstatsplain |
| -rw-r--r-- | logo-trans.png | 224298 | logstatsplainblame |
| -rw-r--r-- | logo.ans | 40439 | logstatsplainblame |
| -rw-r--r-- | logo.png | 818833 | logstatsplainblame |
| d--------- | plan | 34 | logstatsplain |
| -rw-r--r-- | pyproject.toml | 1133 | logstatsplainblame |
| -rw-r--r-- | rehearsed-engineer.md | 452 | logstatsplainblame |
| d--------- | tests | 907 | logstatsplain |
| d--------- | tools | 122 | logstatsplain |
| -rw-r--r-- | uv.lock | 59148 | logstatsplainblame |

IDA Pro in a terminal. Listing, decompiler, graph — keyboard-first, mouse-capable.
disasm · pseudocode · cfg · hex · strings · structs · traces · rpc
┌ ida-tui ─────────────────────────────────────────────────────────────────────┐
│ .text:00002490 ; ---------- S U B R O U T I N E ---------- │
│ .text:00002490 main proc near │
│ .text:00002490 endbr64 │
│ .text:00002494 push rbp ; ← cursor │
│ .text:00002495 mov rbp, rsp │
│ .text:00002498 sub rsp, 0B0h ; `o` → 176 │
└──────────────────────────────────────────────────────────────────────────────┘
Status: personal project, actively hacked on. No packaging, no versioning, no support. It assumes a licensed IDA Pro and a venv at
~/ida-venv. Things move and break. Poke around; don't file expectations.
Why
IDA's own UI is excellent and it is a GUI. This is for the times you're in a terminal over SSH, in a tmux pane next to your notes, or driving RE from a script — and still want the listing, Hex-Rays, and a real control-flow graph.
It is not a reimplementation of IDA. It's a frontend: IDA does the analysis, this draws it.
Install
Needs Python ≥ 3.11 and IDA Pro 9.4+ with idalib.
uv sync
That pulls ida-codemode from PyPI, which is how ida-tui talks to IDA. To also attach to databases you have open in the IDA GUI, install its plugin:
uvx --prerelease=allow --from ida-codemode ida-codemode-mcp --install-plugin
Hacking on ida-codemode itself? Point at a checkout instead:
uv add --editable ../ida-codemode
Run
./ida-tui /path/to/binary # attach to a GUI session, or open a managed database
./ida-tui # attach, when exactly one database is registered
ida-tui never owns an IDA process — it takes a lease. A matching database open in the IDA GUI is reused, otherwise Code Mode starts or shares a managed idalib worker. Quitting drops the lease and leaves everyone else alone.
Headerless blobs need a hint, or IDA assumes x86 at address 0 and analyses nothing:
./ida-tui fw.bin --processor arm --base 0x8000000
These apply only when the database is created — an existing IDB already records
them. On ARM, t toggles ARM/Thumb at the cursor, T scans a vector table for
Thumb entry points.
Keys
enter escape |
follow / back |
tab F5 |
listing ↔ pseudocode |
space |
control-flow graph (z zoom, m minimap, J/K walk edges) |
s |
split view — listing and pseudocode, cursor-synced |
g / ? |
goto · search · search back |
x n y ; |
xrefs · rename · retype · comment |
c d p u a |
make code · data · function · undefine · string |
o O B |
cycle this literal's format · reverse · opcode bytes |
\ " ctrl+t |
hex · strings · structs |
ctrl+n ctrl+p |
symbol palette · command palette |
ctrl+s ctrl+l q |
save · reload as… · quit |
F1 |
all of them |
What's in it
Listing — code, data and undefined runs in one continuous view, with IDA's own colours. Line-virtualized: a 400 MB binary scrolls like a text file.
Decompiler (tab) — Hex-Rays pseudocode, highlighted, with per-line address
anchors. Renames, retypes and comments write back.
Graph (space) — basic blocks laid out with a real layered (Sugiyama) algorithm
and routed, colour-coded edges. The boxes hold the same rows as the listing, so
renames and xrefs work inside them.
Split view (s) — listing and pseudocode side by side, cursor-synced. The
focused pane drives; the other highlights the instructions the current C line owns.
Search (ctrl+f) — the whole database, as text through the disassembly or as
bytes with IDA's wildcard patterns (48 8b ?? c3). It guesses which you meant;
hex:/text: overrides.
Structs / types (ctrl+t) — local types as plain C, editable and highlighted.
ctrl+s declares it straight back into the database.
Literal formats (o) — hex → decimal → binary → char → offset, IDA's own key.
Skips the stops that wouldn't change anything, so no press is a silent no-op.
Findings export (ctrl+e) — the session as a markdown writeup: your comments,
names and prototypes, grouped by function. idatui journals its own edits, so the
report is yours, not IDA's analyzer's.
Execution traces — load a Tenet trace and move through time. Both code views paint the execution trail; the dock shows registers and stack as of that instant.
./ida-tui /path/to/binary --trace trace.0.log # ] [ step · } { step over
RPC — drive the live TUI from another process (agent-driven RE, livestreams):
./ida-tui /abs/path/bin --rpc /tmp/ida.sock
python -m idatui.drive pc main # pseudocode of main
python -m idatui.drive rename sub_5BE0 foo # goto + rename
Scripted feature tour, for screen recordings: python tools/demo.py --spawn
Also — hex view (\), strings ("), symbol and command palettes
(ctrl+n/ctrl+p), multi-binary projects, and a splash that renders as a real
image on terminals speaking the kitty graphics protocol.
Tests
python3 tests/run.py --fast # 380 checks, <1s, any python3 — between edits
python3 tests/run.py --list # what runs, and what needs IDA
python3 tests/run.py # 1031 checks, ~50s — before a commit
Every suite declares NEEDS_IDA; --fast runs only the pure ones (stdlib, no
IDA, no database). The rest drive a headless Textual Pilot against a real
database. Iterate on one with --only:
~/ida-venv/bin/python tests/test_scenarios.py targets/echo --only hex,rename
Before optimising or debugging a slow run, read
.fastfeedback/SPEED.md — per-suite timings, the known
flake, and the four ways a test here wastes minutes.
Working on this with an LLM agent
.agents/skills/idatui/SKILL.md is an
Agent Skills skill covering the architecture,
the test loop, and the traps that cost real time here. Compatible harnesses pick it
up automatically; point others at the file. (A user-level skill of the same name
wins, so symlink yours if you keep one.)
—
