diff options
| author | blasty <blasty@local> | 2026-07-26 00:04:38 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-07-26 00:04:38 +0200 |
| commit | cf8b4645e2744fff455fc09167f91d011a3e620a (patch) | |
| tree | f8480964ec9e531ed98916f3cb6a5d513833a2b6 /tools/verify_procs.py | |
| parent | loading: ask how to load an unrecognised file, like IDA does (diff) | |
| download | ida-tui-cf8b4645e2744fff455fc09167f91d011a3e620a.tar.gz ida-tui-cf8b4645e2744fff455fc09167f91d011a3e620a.tar.xz ida-tui-cf8b4645e2744fff455fc09167f91d011a3e620a.zip | |
formats: verify every offered processor name against a real IDA
The curated list was written from the procs/ directory listing. Two of the
twenty names were wrong, and wrong here is not a soft failure: IDA REFUSES to
open the database (rc=4) with nothing useful said. The load dialog would have
handed people a dead end from inside the UI that exists to rescue them — the
same silent-failure class the dialog was built to kill.
h8 -> h8300 (h8.so is the module FILENAME, not a processor name)
sparc -> sparcb / sparcl (and SPARC has endianness variants, like MIPS/PPC)
Also probed the aliases people reach for first: arm64, aarch64, mips, m68k are
all invalid. 'arm' covers AArch64 (verified: an AArch64 blob analyses to 35
functions under -parm), so those names now live in the human labels, where the
filter still finds them — typing "arm64" finds ARM, "m68k" finds 68k, "mips"
finds both endiannesses.
tools/verify_procs.py does the check: open a scratch blob with -p<name>, read
back inf_get_procname(), compare. Fresh temp dir per name, because once a
database exists IDA ignores the load switches and every name after the first
would "pass". 21/21 verified.
tests: +11 formats, including the verified-set guard (adding a processor without
re-running the script fails on purpose) and checks that the rejected aliases are
NOT offered but ARE still findable by typing them. 32/0 formats, 199/0 scenarios.
Diffstat (limited to 'tools/verify_procs.py')
| -rw-r--r-- | tools/verify_procs.py | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/tools/verify_procs.py b/tools/verify_procs.py new file mode 100644 index 0000000..8012931 --- /dev/null +++ b/tools/verify_procs.py @@ -0,0 +1,64 @@ +#!/usr/bin/env python3 +"""Check every name in ``formats.PROCESSORS`` against a real IDA. + +Run this before adding a processor to the list. + +A wrong ``-p`` name is not a soft failure: IDA refuses to open the database +(rc=4) with nothing useful said, which is the same silent-failure class the load +dialog exists to prevent. Offering a name that doesn't work would hand the user +a dead end from inside the very UI meant to rescue them. + +Two of the first twenty entries were wrong — ``h8`` and ``sparc`` are module +FILENAMES (procs/h8.so, procs/sparc.so), not processor names; the real ones are +``h8300`` and ``sparcb``/``sparcl``. The aliases people reach for first +(``arm64``, ``aarch64``, ``mips``, ``m68k``) are all invalid too, which is why +they appear in the human labels instead, where the filter can still find them. + + /usr/bin/python tools/verify_procs.py # needs idalib, not textual +""" + +from __future__ import annotations + +import os +import sys +import tempfile + +sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) + +from idatui.formats import PROCESSORS # noqa: E402 + + +def main() -> int: + import idapro + idapro.enable_console_messages(False) + import ida_auto + import ida_ida + + blob = bytes(range(256)) * 8 + bad: list[tuple[str, int, str]] = [] + for name, desc in PROCESSORS: + # A fresh directory each time: once a database exists IDA ignores the + # load switches, and every name after the first would "pass". + d = tempfile.mkdtemp() + path = os.path.join(d, "probe.bin") + with open(path, "wb") as f: + f.write(blob) + rc = idapro.open_database(path, run_auto_analysis=False, args=f"-p{name}") + got = "" + if rc == 0: + ida_auto.auto_wait() + got = ida_ida.inf_get_procname() + 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)) + + print(f"\n{len(PROCESSORS) - len(bad)}/{len(PROCESSORS)} verified") + for name, rc, got in bad: + print(f" {name}: rc={rc} procname={got!r}") + return 1 if bad else 0 + + +if __name__ == "__main__": + raise SystemExit(main()) |
