| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
ida-pro-mcp's xref_query only classifies xrefs as code/data (xr.iscode). Add an
injected `xref_types` tool (server/patch_server.py) that mirrors xref_query's
query/envelope shape but derives a fine `kind` from the IDA xref type:
call/jump/flow for code (fl_CF/CN/JF/JN/F), read/write/offset/text/info for data
(dr_R/W/O/T/I). The worker self-injects it on startup like the other custom tools.
* domain: Xref gains a `kind` field; _parse_xrefs reads it; xrefs_to() now calls
xref_types (falling back to xref_query if absent). xrefs_from is unchanged.
* app: the `x` dialog shows the kind as an aligned column after the address
(`000034F4 read sub_34F0+0x4`).
* rpc: the structured xrefs_to read carries `kind` too.
Verified live over the worker/RPC harness on targets/echo: sub_2C00 callers ->
call; __progname -> offset (GOT), read (sub_34F0), write (sub_3500); stdout ->
read/offset.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Full IDA-style unification. The function-bounded DisasmView is gone from the UI:
navigation opens ONE continuous segment listing (functions+data+undefined
interleaved) at the target; F5/Tab decompiles the function under the cursor and
back. The listing gained the opcode column (Head.raw, 'o' toggle) so rendering
matches disasm.
Routing: _do_navigate/_open_function/_open_entry target the listing;
_show_active drops disasm; _active in {listing,decomp,hex}; _pref=listing.
Decomp is a per-function toggle with a listing fallback on failure. Edits
reload in place (_reload_active_code); bump_names() drops the listing cache so
renames refresh. Listing 'n' is symbol-aware. ListingModel gains
cached_line/lines shims; Head.label. DisasmView removed from compose/handlers;
rpc updated. DisasmModel kept (domain/test_domain).
Tests migrated (c.dis->ListingView; open(decomp) F5s; xref/search re-pointed).
Per-scenario green across view_toggle/rename/follow_xrefs/xref_labels/decomp_*/
search/mouse/startup/continuous_view (30/1, 1 cold-decompile flake).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The real disassembly-listing view. ListingView is a line-virtualized
ScrollView (reusing ColumnCursor/SearchMixin/NavMixin) backed by
ListingModel, rendering code, data (db/dw/dd, strings, jump tables) and
undefined bytes interleaved with per-kind styling. Non-function regions now
open in it instead of the M0 DisasmModel stopgap.
Integration (IdaTui): a new `listing` active mode. _open_entry routes region
entries to ListingView; _show_active/compose add it; follow/xrefs/comment and
the c/p/u edit verbs handle it (define_func upgrades a region straight to the
function view); backslash reaches hex and returns via _code_mode (so leaving
hex from a region lands back on the listing, not a func view); Tab explains
there's no pseudocode for a region. rpc._active_widget learns `listing`.
Server fix (the important one): the `heads` walker now steps by get_item_end
instead of next_head. next_head SKIPS undefined bytes, so after undefining a
function its start address wasn't even a listing line and the cursor snapped to
the next defined item; stepping by item-end renders undefined bytes as `db ?`
lines (IDA-accurate) and makes navigation land exactly on any address —
essential for "go to unmarked bytes and hit c". Needs a supervisor restart.
Tests: region_define rewritten to assert the ListingView path + segment-wide
listing + p-upgrade; new listing_view scenario (data-segment listing renders
data heads, cursor reports head ea, backslash->hex->back). Pilot 115 pass / 1
pre-existing flaky (filter); rpc_smoke 29/0; test_domain 27/0.
|
| |
|
|
| |
spawn-hang + bare KeyError)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
toggle_view's settle predicate (lambda: app._active != before) never
fired when tabbing toward pseudocode on a function Hex-Rays can't
decompile: App._apply_decomp snaps the view back to disasm, so _active
returns to its prior value -> full 20s settle timeout (x2 in _show_decomp,
~40s for drive pc). Recognize the decomp-failed fallback as settled.
Also harden two amplifiers surfaced by the same case:
- rpcclient: the CLI socket had no read timeout and would block forever
on any server slowness; add a bounded settimeout (IDATUI_RPC_TIMEOUT,
default 90s) with a clear error.
- domain.decompile: pass a bounded 15s timeout and cache failures, so a
failing decompile can't sit at the 30s client default or be re-run by
transport retries.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
The clock/title Header added noise (and made screen() non-deterministic);
remove it from the app itself — the Footer stays. Layout shifts up a row;
scenario suite still 101 green.
xrefs_from on a function was near-useless: the server's xrefs_from is
address-scoped, so passing the entry ea only returned the fall-through
from the first instruction. For a function target it now returns
whole-body references from the decompiler (callees + string/data refs:
{to,name,string,is_func,type}); an explicit 0xADDR stays address-scoped.
Verified live: xrefs_from main now lists setlocale/getopt_long/sub_* etc.
rpc_smoke: 25 green.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
cursor_on {word,line?,occurrence?} places the cursor on a token, verified
with the app's own tokenizer (so 'main' won't match inside 'domain');
rename/retype/follow gain an optional word= that runs it first — the
ergonomic way to edit a named symbol without a manual view+cursor dance.
Single-driver gate: the socket now serves one client at a time; a second
concurrent connection is refused with 'busy' (no multi-driver support yet,
by request). Sequential connections are unaffected.
screen gains format=text|html|svg (html/svg are colored — for an
out-of-band web viewer). rpc_smoke: 24 green.
|
| |
|
|
|
|
|
|
|
|
|
| |
Spawn-and-drive needs to know when the freshly-launched TUI is usable:
ping/state now carry {ready,functions,complete} (cheap; no health call)
and ping adds the module name. Add a graceful 'quit' verb (acks, then
exits on a short delay so the reply still flushes) and a self-documenting
'methods' table. Program-dependent verbs are refused with a clear
'not ready' instead of exploding in a worker while still loading.
rpc_smoke covers readiness, methods and quit (21 green).
|
| |
|
|
|
|
|
|
|
|
|
|
| |
Introspection (offloaded to a thread so a big fetch can't freeze the
render): pseudocode (full body), disassembly (bounded), xrefs_to/from
(structured), resolve (name->ea). These let an agent reason about a
function and the call graph without scraping screen().
Semantic: select (choose the highlighted/nth item in the open xrefs or
symbol-palette list and activate it — the natural follow-up to xrefs/
symbols), search (/ or ? incremental in the active code view), save
(Ctrl+S). rpc_smoke exercises all of them end-to-end (18 green).
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Layer high-level verbs over the raw injection: goto/open, rename, comment,
retype, follow, back, toggle_view, hex, xrefs, symbols, structs, close,
plus fast move/cursor. Editing/goto verbs type through the real prompts
with a per-char delay (default 35ms) so viewers see it typed; movement
uses bare keypresses with a pump-only settle to stay snappy. Each verb
settles on an op-specific predicate where one exists (goto lands on the
target, follow grows the nav stack, toggle flips _active, modals open),
so the returned state is never stale.
rpc_smoke now drives the semantic path end-to-end (rename round-trip via
the prompt-fill seam), 11 green.
|
|
|
Run the TUI with --rpc <sock> and it renders normally while an asyncio
listener on the same loop lets another process drive it. Handlers touch
the UI directly (same loop, no thread hop), so every injected key has the
identical on-screen effect a keyboard would — the point for livestreaming.
Newline-delimited JSON. v1 methods: keys/text (raw injection, via the same
_press_keys the pilot uses; text can interleave wait:<ms> for a typed-out
look), state/view/screen/functions (introspection; screen() is a full
plain-text render of exactly what the viewer sees). No auth by design —
the socket is 0600, local only.
tests/rpc_smoke.py drives it end-to-end over a real socket (7 green).
|