diff options
| author | blasty <blasty@local> | 2026-07-23 01:53:36 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-23 01:53:36 +0200 |
| commit | 0aba8653f4b585165d06714be32a0560ec5d5341 (patch) | |
| tree | 6f66c42fb8f0067dd1d94880ade26932293aa342 /tests | |
| parent | perf: derive segment map from file_regions, not survey_binary (hex open ~3400x) (diff) | |
| download | ida-tui-0aba8653f4b585165d06714be32a0560ec5d5341.tar.gz ida-tui-0aba8653f4b585165d06714be32a0560ec5d5341.tar.xz ida-tui-0aba8653f4b585165d06714be32a0560ec5d5341.zip | |
app: 'a' — make string literal in the listing (M4 richness)
IDA's 'A' key. New make_string server tool (ida_bytes.create_strlit, auto-length
to the terminator, undefines items in the way first, returns size + decoded
contents). Program.make_string wraps it; 'a' on a listing head routes through
the existing edit plumbing (EditItemRequested kind=string -> _do_edit_item ->
make_string -> bump_items -> reopen).
Verified: make_string at a .rodata addr creates the literal and IDA auto-names
it (aUsage for 'usage'). New listing_make_string scenario drives it through the
UI; listing suite 15/0. Needs a supervisor restart.
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_scenarios.py | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/tests/test_scenarios.py b/tests/test_scenarios.py index 26e916f..62d86dd 100644 --- a/tests/test_scenarios.py +++ b/tests/test_scenarios.py @@ -1507,6 +1507,55 @@ async def s_listing_name_addr(c: Ctx): c.prog.bump_items() +@scenario("listing_make_string") +async def s_listing_make_string(c: Ctx): + """'a' in the listing makes a string literal at the cursor (IDA's 'A').""" + app = c.app + target = None + for start, end, name in c.prog.sections(): + if start >= end: + continue + lm = c.prog.listing(start) + if lm is None: + continue + lm.ensure(80) + h = next((h for h in lm.window(0, 80) + if h.kind == "data" and "'" in h.text), None) + if h is not None: + target = h.ea + break + if target is None: + c.check("found a string data item to remake", False) + return + A = target + try: + c.prog.undefine(A, size=8) + c.prog.bump_items() + await c.goto_ui(hex(A)) + await c.wait(lambda: app._active == "listing" and app._cur is not None + and app._cur.ea == A, 25) + c.check("target is undefined before 'a'", + c.lst.cur_head() is not None and c.lst.cur_head().kind == "unknown", + f"head={c.lst.cur_head()}") + c.lst.focus() + await c.press("a") + await c.wait(lambda: c.lst.model.index_of_ea(A) >= 0 + and c.lst.model.get(c.lst.model.index_of_ea(A)) is not None + and c.lst.model.get(c.lst.model.index_of_ea(A)).kind == "data" + and "'" in c.lst.model.get(c.lst.model.index_of_ea(A)).text, 25) + hi = c.lst.model.index_of_ea(A) + c.check("'a' creates a string literal at the cursor", + hi >= 0 and c.lst.model.get(hi).kind == "data" + and "'" in c.lst.model.get(hi).text, + f"head={c.lst.model.get(hi) if hi >= 0 else None}") + finally: + try: + c.prog.make_string(A) # restore the original string + except Exception: # noqa: BLE001 + pass + c.prog.bump_items() + + # --------------------------------------------------------------------------- # # Runner # --------------------------------------------------------------------------- # |
