diff options
| author | blasty <blasty@local> | 2026-07-24 15:33:17 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-24 15:33:17 +0200 |
| commit | 731bca5c31f3507424a391fecf081be1a6c6717d (patch) | |
| tree | b089dab655490cefe3f59554c0a4845a94e49035 /idatui/domain.py | |
| parent | listing: shift+home jumps to the start of the instruction text (diff) | |
| download | ida-tui-731bca5c31f3507424a391fecf081be1a6c6717d.tar.gz ida-tui-731bca5c31f3507424a391fecf081be1a6c6717d.tar.xz ida-tui-731bca5c31f3507424a391fecf081be1a6c6717d.zip | |
xrefs: show fine-grained kind (call/jump/read/write/offset) in the dialog
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.
Diffstat (limited to 'idatui/domain.py')
| -rw-r--r-- | idatui/domain.py | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/idatui/domain.py b/idatui/domain.py index d7ebf3c..8a127d7 100644 --- a/idatui/domain.py +++ b/idatui/domain.py @@ -127,9 +127,10 @@ class Ref: class Xref: frm: int # the referencing address to: int | None # the referenced address - type: str # "code" | "data" | ... + type: str # coarse: "code" | "data" fn_name: str | None # function containing `frm` fn_addr: int | None + kind: str | None = None # fine: call/jump/flow/read/write/offset/text/info @dataclass(frozen=True) @@ -1260,11 +1261,14 @@ class Program: return _parse_xrefs(payload) def xrefs_to(self, ea: int, limit: int = 2000) -> list[Xref]: - payload = self.client.call( - "xref_query", - queries=[{"addr": hex(ea), "direction": "to", "include_fn": True, - "dedup": True, "count": limit}], - ) + q = [{"addr": hex(ea), "direction": "to", "include_fn": True, + "dedup": True, "count": limit}] + try: + # xref_types adds a fine-grained `kind` (call/read/write/...) for the + # xref dialog; fall back to xref_query (code/data only) if absent. + payload = self.client.call("xref_types", queries=q) + except IDAToolError: + payload = self.client.call("xref_query", queries=q) return _parse_xrefs(payload) # -- address resolution ------------------------------------------------ # @@ -1365,6 +1369,7 @@ def _parse_xrefs(payload) -> list[Xref]: type=d.get("type", "?"), fn_name=fn.get("name"), fn_addr=_as_int(fn["addr"]) if fn.get("addr") else None, + kind=d.get("kind"), )) return out |
