diff options
| author | blasty <blasty@local> | 2026-07-26 15:04:51 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-26 15:04:51 +0200 |
| commit | 2c2124aff2f4ed6df23512603b6e1ecdcd4b699b (patch) | |
| tree | 2b2c2afe69e7f33e87ccb58e3bc466a94a4e689e /tools | |
| parent | arm: switch ARM/Thumb decoding with `t` (diff) | |
| download | ida-tui-2c2124aff2f4ed6df23512603b6e1ecdcd4b699b.tar.gz ida-tui-2c2124aff2f4ed6df23512603b6e1ecdcd4b699b.tar.xz ida-tui-2c2124aff2f4ed6df23512603b6e1ecdcd4b699b.zip | |
arm: offer 32-bit ARM at load, and fix `p` on carved code
Reported as "after c a few times and p at the entry point, Tab just flashes and
nothing decompiles". Three separate things, found by following it down:
**1. `p` failed on hand-carved code.** ida_funcs.add_func(ea) asks IDA to find
the function's end and on carved code it often can't — a run ending in a tail
call, or whose last instruction isn't recognised as a return, fails with no
reason given. add_func(ea, end) with an explicit end succeeds. define_func_run
tries IDA's way first, then falls back to the end of the contiguous instruction
run, and says which it used.
**2. The database was 64-bit, so Hex-Rays refused it regardless.** Bare `-parm`
gives an AArch64 database. Ask Hex-Rays for the failure object rather than
reading None as "dunno" and it says exactly what's wrong: "only 64-bit functions
can be decompiled in the current database". So the disassembly looked right and
F5 could never work.
That is decided at LOAD and cannot be corrected — inf_set_app_bitness(32)
afterwards makes the decompiler INTERR 50735. The fix is at the load dialog:
arm:ARMv7-A (most firmware), arm:ARMv7-M / arm:ARMv6-M (Cortex-M, Thumb only)
and arm:ARMv5TE now sit alongside 64-bit `arm`, labelled with their bitness.
With arm:ARMv7-A, experiments/fibonacci.bin decompiles:
void __fastcall __noreturn sub_0(int a1) { int v2; v2 = sub_E3C(a1, 0); ... }
— and IDA's own auto-analysis finds 54 Thumb functions on load, versus none as
plain `arm`.
**3. `t` was silently building an undecompilable state.** It forced the SEGMENT
to 32-bit in a 64-bit database, which produces correct-looking disassembly that
F5 will never touch. It now says so and names the fix (Ctrl+L, arm:ARMv7-A)
rather than leaving you to discover it.
tools/verify_procs.py now reports each processor's resulting bitness, since that
is the reason the variants exist — and it compares against the base module name,
because a variant reports "ARM".
tests: test_thumb_ui.py +5 (13 total) — a 64-bit database warns and names the
fix, a 32-bit one finds functions by itself, Tab decompiles a Thumb function and
the result reads like C. test_formats.py +2 (34) pinning that a 32-bit variant is
offered and the ARM labels state their bitness. 209/0 scenarios, 26/0 blob, 30/0
project UI.
Diffstat (limited to 'tools')
| -rw-r--r-- | tools/verify_procs.py | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/tools/verify_procs.py b/tools/verify_procs.py index 8012931..323bf1f 100644 --- a/tools/verify_procs.py +++ b/tools/verify_procs.py @@ -48,9 +48,18 @@ def main() -> int: if rc == 0: ida_auto.auto_wait() got = ida_ida.inf_get_procname() + # "arm:ARMv7-A" selects a VARIANT: inf_get_procname() reports the base + # module ("ARM"), so compare that and check the bitness separately — + # the variant is only worth offering if it actually changes something. + base = name.split(":", 1)[0] + bits = "" + if rc == 0: + import ida_ida + bits = f" bitness={ida_ida.inf_get_app_bitness()}" + ok = rc == 0 and got.lower() == base.lower() + print(f" {'ok ' if ok else 'BAD '} {name:<14} rc={rc} -> {got!r}{bits} {desc}") + if rc == 0: idapro.close_database(save=False) - ok = rc == 0 and got.lower() == name.lower() - print(f" {'ok ' if ok else 'BAD '} {name:<12} rc={rc} -> {got!r} {desc}") if not ok: bad.append((name, rc, got)) |
