aboutsummaryrefslogtreecommitdiffstats
path: root/idatui/app.py
diff options
context:
space:
mode:
authorblasty <peter@haxx.in>2026-09-25 14:28:45 +0200
committerblasty <peter@haxx.in>2026-09-25 14:28:45 +0200
commit9dea7bc83ff9b3b952a761a2d0f92b75abdd6e7e (patch)
treed0ccd92980a96250596a4aaaebccf21f0cffd74d /idatui/app.py
parentREADME: friendlier rewrite; move IDA connection internals to CONTRIBUTING (diff)
parentFix parsing of pseudocode tags (diff)
downloadida-tui-9dea7bc83ff9b3b952a761a2d0f92b75abdd6e7e.tar.gz
ida-tui-9dea7bc83ff9b3b952a761a2d0f92b75abdd6e7e.tar.xz
ida-tui-9dea7bc83ff9b3b952a761a2d0f92b75abdd6e7e.zip
Merge PR #2 from mrexodia: fix pseudocode/listing tag parsing, ida-nexus 0.13.0
https://github.com/blasty/ida-tui/pull/2 — pseudocode address anchors are now split off only as the trailing /*0x…*/ our decompile tool appends, so a marker-shaped string literal or source comment survives display and cursor columns. The listing span walker asks the kernel (tag_skipcode) how long each colour code is instead of assuming two bytes, so semantic group tags with kind/TID headers stay invisible on kernels that emit them. Bumps ida-nexus to 0.13.0. Verified locally on IDA 9.4 + ida-nexus 0.13.0: full suite 974 passed (955 on main + 19 new pure checks). Old vs new span walker give identical output over 60k bash heads (no 0x36 tags on this kernel); the new walker costs 19.8 vs 12.3 us/line, next to 7.6 us for generate_disasm_line.
Diffstat (limited to 'idatui/app.py')
-rw-r--r--idatui/app.py26
1 files changed, 10 insertions, 16 deletions
diff --git a/idatui/app.py b/idatui/app.py
index 75dc9d1..52f474b 100644
--- a/idatui/app.py
+++ b/idatui/app.py
@@ -51,7 +51,7 @@ from textual.widgets import (
from textual.widgets.option_list import Option
from . import diag, findings, graph, kittygfx, search
-from .domain import Func, Head, ListingModel, Program, Struct
+from .domain import Func, Head, ListingModel, Program, Struct, split_pseudocode_line
from .edit_ctl import EditController
from .errors import IDAConnectionError
from .highlight import CTextArea, highlight_c
@@ -193,12 +193,6 @@ _S_DECOMP_WAIT = Style(color="#7c8b9e", italic=True) # 'decompiling' label
_S_DECOMP_DOTS = Style(color="#626c7a") # trailing ellipsis
_S_LINK = Style(bgcolor="#233044") # split view: rows linked to the other pane's cursor
-# Hex-Rays appends a `/*0xEA*/` address marker to each pseudocode line (we fetch
-# with include_addresses so we have a per-line anchor). Matched here to extract
-# the address and strip the marker from the display.
-_ADDR_MARK_RE = re.compile(r"/\*\s*0x([0-9A-Fa-f]+)\s*\*/")
-_ADDR_MARK_STRIP_RE = re.compile(r"\s*/\*\s*0x[0-9A-Fa-f]+\s*\*/")
-
@dataclass
class BinaryState:
@@ -1786,9 +1780,9 @@ class DecompView(SearchMixin, NavMixin, ColumnCursor, ScrollView, can_focus=True
line_eas: list[int | None] = []
clean: list[str] = []
for ln in text.split("\n"):
- eas = _ADDR_MARK_RE.findall(ln)
- line_eas.append(int(eas[-1], 16) if eas else None)
- clean.append(_ADDR_MARK_STRIP_RE.sub("", ln).rstrip())
+ source, line_ea = split_pseudocode_line(ln)
+ line_eas.append(line_ea)
+ clean.append(source)
seglists = highlight_c("\n".join(clean))
self._strips = [Strip(segs) for segs in seglists]
self._texts = ["".join(seg.text for seg in segs) for segs in seglists]
@@ -8225,7 +8219,7 @@ class IdaTui(App):
lines = (dec.code or "").splitlines()
if not (0 <= line_idx < len(lines)):
return 0
- clean = _ADDR_MARK_STRIP_RE.sub("", lines[line_idx])
+ clean, _ = split_pseudocode_line(lines[line_idx])
m = re.search(rf"\b{re.escape(name)}\b", clean)
return m.start() if m else 0
@@ -8255,7 +8249,8 @@ class IdaTui(App):
best: tuple[int, int] | None = None
best_key: tuple[int, int] | None = None
for i, ln in enumerate(lines):
- m = pat.search(_ADDR_MARK_STRIP_RE.sub("", ln))
+ clean, _ = split_pseudocode_line(ln)
+ m = pat.search(clean)
if not m:
continue
# rank: nearest to the anchor; tie -> the line at/after the anchor.
@@ -8277,10 +8272,9 @@ class IdaTui(App):
return -1
best_idx, best_ea = -1, -1
for i, line in enumerate(dec.code.splitlines()):
- for m in re.findall(r"/\*\s*0x([0-9A-Fa-f]+)\s*\*/", line):
- e = int(m, 16)
- if best_ea < e <= ea:
- best_ea, best_idx = e, i
+ _, e = split_pseudocode_line(line)
+ if e is not None and best_ea < e <= ea:
+ best_ea, best_idx = e, i
return best_idx
@staticmethod