From 57b09047881d4bb42b2b98e4bb0739d5bc5e5af8 Mon Sep 17 00:00:00 2001 From: blasty Date: Sat, 25 Jul 2026 23:49:14 +0200 Subject: loading: say how to read a headerless blob (processor, base) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A raw firmware dump has no format to detect, so IDA fell back to x86 at address 0. It doesn't fail — it opens, analyses, and finds nothing. An AArch64 image loaded this way gave 0 functions; told the truth it gives 35. ida-tui fw.bin --processor arm --base 0x8000000 and per binary in a project, which is what a multi-image firmware actually needs: {"path": "app.bin", "processor": "arm", "base": "0x8000000"} idapro.open_database() already accepted IDA command-line switches; nothing was passing any. Plumbed BinaryRef -> WorkerPool -> WorkerClient -> worker argv, plus a load_args for the single-binary path that has no project ref. base is written the way people say it (0x8000000, int or string, any base). IDA's -b is in PARAGRAPHS — -b1000 loads at 0x10000 — so BinaryRef.load_args converts, and a base that isn't 16-byte aligned is refused rather than silently landing 16x off. ida_args passes anything else through. Two bugs found by testing the whole path rather than the happy one: * Project.load() whitelisted path/label when normalising entries, so the load options were dropped the first time a project was reopened — set a processor, come back tomorrow, it's gone. * Re-passing the switches to an EXISTING database makes IDA refuse the open (rc != 0, no functions). The .i64 already records how the image was loaded, so the worker skips them once a database exists. My first guard checked splitext(path) + ".i64" and never fired, because IDA names it ".i64" — keeping the extension. It checks both spellings now. Verified on a real AArch64 blob: fresh load 35 functions based at 0x8002440, reopen 35 again, and the CLI rejects an unaligned or non-numeric --base. tests: +6 project (options recorded, paragraph conversion, file round-trip, add() takes them, an ELF passes nothing, hex-string base). 39/0 project, 195/0 scenarios, 30/0 project UI, 36/0 index, 27/0 pool. --- README.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'README.md') diff --git a/README.md b/README.md index eb9f05b..8fc59fd 100644 --- a/README.md +++ b/README.md @@ -90,6 +90,19 @@ It uses `~/ida-venv/bin/python` for the TUI (override with `$IDATUI_PYTHON`) and resolves binary paths against your real cwd. The binary's directory must be writable (idalib writes a `.i64` there). +Headerless blobs need to be told what they are — a raw firmware dump has no +format to detect, and IDA falls back to x86 at address 0, which analyses to +nothing: + +```sh +./ida-tui fw.bin --processor arm --base 0x8000000 +``` + +`--base` is a real address (IDA's own `-b` is in paragraphs; the conversion is +done for you). In a project the options are recorded per binary, which is what a +multi-image firmware wants. They apply to the first open only — after that the +`.i64` records how the image was loaded. See `docs/PROJECTS.md`. + > Recovering a wedged database: if a worker was hard-killed it leaves unpacked > `foo.id0/.id1/.id2/.nam/.til` next to `foo.i64`, and the `.i64` then refuses to > reopen. Delete those stale files (never the `.i64`) and retry — `ida-tui` does -- cgit v1.3.1-sl0p