diff options
| author | user <user@clank> | 2026-08-01 17:18:57 +0200 |
|---|---|---|
| committer | user <user@clank> | 2026-08-01 17:18:57 +0200 |
| commit | 14ca7c7e5c56c3fdd059d168957a2b2e3dbe504e (patch) | |
| tree | 7cc8ea9637b7998fc1da3b4e428a1e39537903fa /docs | |
| parent | tests: trace integration over the RPC socket (45 checks) (diff) | |
| download | ida-tui-14ca7c7e5c56c3fdd059d168957a2b2e3dbe504e.tar.gz ida-tui-14ca7c7e5c56c3fdd059d168957a2b2e3dbe504e.tar.xz ida-tui-14ca7c7e5c56c3fdd059d168957a2b2e3dbe504e.zip | |
rpc: make a raw firmware image drivable (load options, define, bulk symbols)
Opening a headerless blob was the one workflow that fell out of the driving
surface entirely, and each gap hid the next:
- `pane spawn` couldn't pass --processor/--base/--ida-args, so the pane came up
"ready" with zero functions (x86 at 0) and the only way through was to
hand-write a project file. It now forwards them to idatui.launch.
- c/p/t/T (code, function, ARM<->Thumb, vector scan) existed as listing
bindings with no verb, so a driver had to guess raw keys -- and raw keys are
swallowed by whatever modal happens to be up. `define {kind,target?}` goes
through the app's own edit worker and reports what IDA actually did.
- every name went through the typed rename prompt: a navigation (listing page +
decompile) plus two prompt round-trips each. A 427-symbol map took tens of
minutes of driving. `rename_many {items|file}` hands IDA's rename tool the
whole list in one call (371 symbols in 3s) and refreshes the caches and the
function table once.
drive gains `define <kind> [target...]` and `syms <file.json>`.
Verified live against a real pane (tests/test_rawimage_rpc.py, 13 checks:
spawn load options, define thumb/func + unknown-kind rejection, rename_many
from a file and inline, with resolve/functions readback).
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/RPC.md | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/docs/RPC.md b/docs/RPC.md index d1290f5..53ec36b 100644 --- a/docs/RPC.md +++ b/docs/RPC.md @@ -94,6 +94,16 @@ predicate so the returned state is final. | `select` | `index?` | in an open modal list (xrefs/symbols) choose the highlighted (or nth) item and activate it. | | `save` | — | Ctrl+S: persist the `.i64`. | | `close` | — | Escape (dismiss a modal). | +| `define` | `kind`, `target?`, `delay_ms?` | goto `target` (if given) then press the listing key for `kind` ∈ `code`(c) / `func`(p) / `undef`(u) / `thumb`(t) / `thumbscan`(T) / `data`(d) / `string`(a). Leaves hex/decomp for the listing first (those bindings are listing-only). The IDA-side outcome is in `status` (e.g. *defined 228 instructions (0x4370–0x45e8) — control flow ends here*) and in `define.status`. | +| `rename_many` | `items:[{addr,name}]` **or** `file:<json>`, `allow_overwrite?=true` | bulk-apply a symbol map in ONE worker call, then refresh the caches + function table. Accepts `addr`/`start`/`ea`/`address` and `name`/`label`, or a plain `{addr: name}` object. Returns `rename_many:{requested,skipped,ok,failed,errors[]}`. | + +**Raw images: `define` + `rename_many` are the workflow.** A firmware blob loads +with no functions and no names. Point `define thumb` / `define func` at the entry +points you know (IDA's auto-analysis then cascades through the call graph), and +apply the whole symbol file with `rename_many`. Do **not** loop `rename` over a +symbol file: each one costs a navigation (listing page + decompile) plus two +prompt round-trips, i.e. tens of minutes for a few hundred symbols, where +`rename_many` is one call and a few seconds. ### Movement (fast — bare keypresses, pump-only settle) | method | params | effect | @@ -111,6 +121,15 @@ to read the pseudocode → `cursor line=.. col=..` onto a token → `rename name ## Notes / gotchas +- **Load options belong to the first open.** `pane spawn --processor/--base/ + --ida-args` (forwarded to `idatui.launch`) only take effect while there is no + `.i64` yet — IDA bakes them into the database. To change them, delete the + `.i64` (or use Ctrl+L in the TUI) and spawn again. +- **`--processor arm` is AArch64**, and Hex-Rays will not decompile a 32-bit + function in a 64-bit database. For 32-bit ARM firmware use + `--processor arm:ARMv7-A` (see `idatui/formats.py: PROCESSORS`, every name + there verified against a real IDA). + - Settle is the shared `_sync.settle`: drain the message pump, wait for threaded workers, then (for ops with a known outcome) poll a predicate. A verb whose predicate can't be derived (e.g. `rename` on an arbitrary token) falls back to |
