| Commit message (Collapse) | Author | Age | Files | Lines |
| |
|
|
|
|
|
|
|
|
| |
Manual navigation is snappy; the demo was not, because I authored the pauses
for someone reading every status line. Halved every beat with a 0.25s floor so
the scenes stay distinguishable, and dropped the prompt typing from 45ms to
18ms per character -- still legibly typing, no longer something you wait on.
--speed still scales it either way: 0.5 for a fast cut, 2.0 to slow it back
down for a narrated take.
|
| |
|
|
|
|
|
| |
The app auto-lands on main once the function index is in, so scene_open typed
a goto to a place it was already standing. Every keystroke a driver injects
costs a round trip, so that was pure dead time at the very start of the tour --
the worst place to spend it, since it is the part a recording opens on.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
--spawn needs tmux or zellij and puts the app in a second pane, which is wrong
when the capture is one terminal. --here launches the TUI through the ./ida-tui
launcher with stdio inherited, so it draws on the terminal you ran the demo
from, then drives it over the socket exactly as before and quits it at the end.
Going through the launcher rather than re-deriving the interpreter keeps the
$IDATUI_PYTHON rules in one place.
Two things this mode has to get right:
- Narration would be drawn over the app, so it is collected and replayed after
the alternate screen is gone. The operator still sees the full scene list,
just at the end instead of during.
- The socket is waited for with a deadline that also watches the child, so a
TUI that dies before it ever listens fails in a second instead of hanging
until the timeout. Teardown reaps the process (wait, then terminate, then
kill) and removes the scratch copy on every path.
--here and --spawn are rejected together. Verified: argument handling, the
mutual exclusion, and that the pure suites are unaffected. The end-to-end
--here run is NOT verified here -- it needs a real terminal, which this
environment does not have.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Ten scenes over the RPC layer: goto, listing scroll, pseudocode, the literal
format ring, follow/back, the graph (zoom, minimap, edge walking), split view,
xrefs, a rename and a comment, the strings/symbols/structs/hex browsers, and
search. It drives the semantic verbs, so prompts are typed character by
character and a recording shows the app being used rather than poked.
--spawn opens its own pane on a COPY of the target (binary plus .i64, so the
analysis is not re-paid) and tears it down afterwards; --sock drives a session
you set up yourself, for control over pane size and zoom. Edits are reverted at
the end, including a re-navigate so the last frame does not still show the
demo's rename. --speed scales every pause, --only runs a subset, --list prints
the scenes.
Writing it found a real bug in the RPC hex verb: it waited for `app.is_hex` to
become true, but backslash TOGGLES the hex view, so the call that leaves hex
could never satisfy its predicate and always timed out after 20s. Any driver
could open the hex view and never close it. It now waits for the mode to flip,
the way toggle_view already did.
Verified by running every scene against a live database and asserting the UI
actually moved -- landed on main, decomp reachable, graph reports 280 blocks,
split toggles off, no modal left open, the rename reaches the database and the
revert removes it. 15/15. Full suite still 788 passed, 0 failed.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The artwork is now a proper transparent PNG with soft edges (24% of its pixels
carry partial alpha) instead of opaque art on black with a stray full-width
scan line along the bottom. Cropped to its content and resized 1024 -> 768px,
which halves the file and costs nothing visible; logo-trans.png keeps the
master for future re-renders.
Two things the new art exposed, both wrong before it:
fit() assumed cells were 1:2. This terminal reports 9x22, i.e. 1:2.44. The old
logo was 474x516 -- close enough to the assumption that nobody noticed -- but a
square image at the hardcoded 60x33 would have been visibly stretched. The
graphics query now asks for the cell size too (CSI 16 t rides along in the same
round trip, before the DA1 that already synchronises it) and fit() uses the
answer.
The footprint was a constant. logo_cells() derives it from the artwork and the
measured cell size, so the art can be replaced without anyone remembering to
edit a number.
logo.ans was stale: the block-art fallback for terminals that can't draw an
image was still the OLD artwork, scan line included. tools/make_logo_ans.py
regenerates it from logo.png so the two cannot drift again. It understands
alpha -- a transparent cell emits no colour and lets the terminal background
through, and a cell with only one opaque half uses the matching half block so
the pixel lands on the correct side.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
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.
|