diff options
| author | blasty <blasty@local> | 2026-07-10 16:01:54 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-10 16:01:54 +0200 |
| commit | ead2125f041649024ede36d0b4eb8e4c4c466e32 (patch) | |
| tree | 6853b40e97295c0e066096d13e9a036bed8a93dd /idatui | |
| parent | pane: auto-start the ida-pro-mcp supervisor if it's down (diff) | |
| download | ida-tui-ead2125f041649024ede36d0b4eb8e4c4c466e32.tar.gz ida-tui-ead2125f041649024ede36d0b4eb8e4c4c466e32.tar.xz ida-tui-ead2125f041649024ede36d0b4eb8e4c4c466e32.zip | |
app: drop the Header (keep the Footer); rpc: function-scope xrefs_from
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.
Diffstat (limited to 'idatui')
| -rw-r--r-- | idatui/app.py | 3 | ||||
| -rw-r--r-- | idatui/rpc.py | 21 |
2 files changed, 20 insertions, 4 deletions
diff --git a/idatui/app.py b/idatui/app.py index ebf928c..086785c 100644 --- a/idatui/app.py +++ b/idatui/app.py @@ -36,7 +36,7 @@ from textual.screen import ModalScreen from textual.scroll_view import ScrollView from textual.strip import Strip from textual.widgets import ( - DataTable, Footer, Header, Input, OptionList, Static, TextArea, + DataTable, Footer, Input, OptionList, Static, TextArea, ) from textual.widgets.option_list import Option @@ -1763,7 +1763,6 @@ class IdaTui(App): # -- layout ------------------------------------------------------------ # def compose(self) -> ComposeResult: - yield Header(show_clock=True) with Horizontal(id="panes"): fp = FunctionsPanel(id="left") fp.display = False # overlay-first: reveal the docked pane with Ctrl+B diff --git a/idatui/rpc.py b/idatui/rpc.py index 73e10d2..426b337 100644 --- a/idatui/rpc.py +++ b/idatui/rpc.py @@ -52,7 +52,8 @@ METHODS = { "pseudocode": "{target?} -> full decompiled body", "disassembly": "{target?,max?=2000} -> {total,lines:[{ea,text}]}", "xrefs_to": "{target,limit?=200} -> [{frm,to,type,fn_addr,fn_name}]", - "xrefs_from": "{target,limit?=200} -> same shape", + "xrefs_from": "{target,limit?=200} -> callees/refs; function-scoped for a " + "function (decomp refs), address-scoped for a 0xADDR", "resolve": "{name} -> {ea}", "keys": "{keys:[str],settle?,timeout?} raw key injection (supports 'wait:<ms>')", "text": "{text,delay_ms?,settle?} type a literal string into the focused input", @@ -319,8 +320,24 @@ def xrefs_to(app, target, limit: int = 200) -> list[dict[str, Any]]: def xrefs_from(app, target, limit: int = 200) -> list[dict[str, Any]]: + """References *out of* the target. For a function (a bare name / its entry ea) + this is whole-body — the callees, string and data refs from the decompiler + (the server's xrefs_from is address-scoped, so it only sees the entry + instruction). For an explicit mid-function 0xADDR it stays address-scoped.""" ea = _target_ea(app, target) - return _xref_dicts(app.program.xrefs_from(ea), limit) if ea is not None else [] + if ea is None: + return [] + fn = app.program.function_of(ea) + if fn is not None and fn.addr == ea: # function target -> decomp outgoing refs + out = [] + for r in app.program.decompile(ea).refs[:limit]: + tf = app.program.function_of(r.addr) + is_func = bool(tf and tf.addr == r.addr) + out.append({"to": r.addr, "name": r.name or (tf.name if tf else None), + "string": r.string, "is_func": is_func, + "type": "code" if is_func else "data"}) + return out + return _xref_dicts(app.program.xrefs_from(ea), limit) def resolve(app, name) -> dict[str, Any]: |
