From 321a7ae0fcac527c24551b157c8fb26af6ffbf5e Mon Sep 17 00:00:00 2001 From: blasty Date: Fri, 10 Jul 2026 16:01:54 +0200 Subject: app: drop the Header (keep the Footer); rpc: function-scope xrefs_from MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- idatui/rpc.py | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'idatui/rpc.py') 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:')", "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]: -- cgit v1.3.1-sl0p