diff options
| author | blasty <blasty@local> | 2026-08-07 22:55:27 +0200 |
|---|---|---|
| committer | blasty <blasty@local> | 2026-08-07 22:55:27 +0200 |
| commit | 2eb2a0a8cff586fffecfcb068c53b65e8f6f9839 (patch) | |
| tree | 82ccb8e8fa9608c41862a13d04827d7c76ac99ee /docs | |
| parent | SPEED.md: the 85ms keypress, and what settle() still cannot see (diff) | |
| download | ida-tui-2eb2a0a8cff586fffecfcb068c53b65e8f6f9839.tar.gz ida-tui-2eb2a0a8cff586fffecfcb068c53b65e8f6f9839.tar.xz ida-tui-2eb2a0a8cff586fffecfcb068c53b65e8f6f9839.zip | |
Export findings as markdown (Ctrl+E), and the journal that makes it true
The output of an RE session is what you worked out, and it was locked in a
.i64 that only IDA can read. Ctrl+E (or `drive export`, or the `export` RPC
verb) writes it out: your comments grouped by function with the line each
annotates, the names and prototypes you set, the types you declared.
**The hard part was provenance, and it needed a mechanism, not a filter.**
A database does not record WHO wrote a comment or a name. IDA's analyzer
sets `; switch 73 cases` and `; s1` with the same `set_cmt` a person uses,
and the ELF loader sets `elf_gnu_hash_nbuckets` and `File class: 64-bit`
the same way. Four probes, all negative: the FF_COMM flag is identical,
`get_cmt` returns them all, `generate_disasm_line` tags every one of them
COLOR_REGCMT (not COLOR_AUTOCMT), and they survive with auto-comments
switched off. A first cut filtered by shape and produced a report whose
first screen was ELF header trivia and `; jumptable ... case 99`.
So idatui journals its own edits (idatui/journal.py) into a netnode in the
database: it rides along in the .i64, it is still there next session, and
the report is then exactly what was done here -- 2 findings out of a
database carrying 693 other annotations. Recorded at the choke points in
edit_ctl (rename, name-address, comment, retype) and in the struct editor;
flushed on save, on export and on quit, so no edit pays a round trip.
Without a journal (a database worked on in the IDA GUI, or predating this)
the report falls back to filtering by shape -- dummy names, imports, loader
segments, the analyzer's stereotyped switch/jumptable strings -- and says
so in the document rather than claiming authorship it cannot prove.
idatui/findings.py splits gather (needs IDA) from render (does not), so the
formatting, grouping, sorting, escaping and the empty cases are tested
offline: tests/test_findings.py, 32 checks, no worker, 0.1s. The pilot
scenario covers the round trip that matters -- edit through the UI, export,
find it in the file, and reload the journal from the .i64.
Full suite: 842 passed, 0 failed, 51.2s.
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/RPC.md | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/docs/RPC.md b/docs/RPC.md index d13e8cd..4e736f6 100644 --- a/docs/RPC.md +++ b/docs/RPC.md @@ -102,6 +102,7 @@ predicate so the returned state is final. | `xrefs` | — | `x`: open the xref picker. | | `symbols` | `query?` | Ctrl+N palette, optionally pre-typed. | | `structs` | — | Ctrl+T struct editor. | +| `export` | `path?`, `types?=true` | write the session's findings as **markdown** and return `{path, comments, names, types, functions, bytes}`. Not typed through a prompt: the point of this verb is the file it leaves behind, so a driver gets the path back rather than a screenshot. Defaults to `<binary>.findings.md`. See *Findings export* below. | | `search` | `term`, `direction?=1` | `/` (or `?`) incremental search in the active code view. | | `select` | `index?` | in an open modal list (xrefs/symbols) choose the highlighted (or nth) item and activate it. | | `save` | — | Ctrl+S: persist the `.i64`. | @@ -131,6 +132,27 @@ symbol file: each one costs a navigation (listing page + decompile) plus two prompt round-trips, i.e. tens of minutes for a few hundred symbols, where `rename_many` is one call and a few seconds. +### Findings export + +`export` writes what the session **worked out** -- comments, names, prototypes +and the types you declared -- as one markdown document. + +The interesting part is provenance. A `.i64` does not record *who* wrote a +comment or a name: IDA's analyzer sets `; switch 73 cases` and `; s1` with the +same `set_cmt` a person uses, the loader sets `elf_gnu_hash_nbuckets` and +`File class: 64-bit` the same way, and the flags, `get_cmt` and even the colour +tag in `generate_disasm_line` are identical for all of them. So idatui keeps its +own **journal** (`idatui/journal.py`) of every edit it makes, in a netnode +inside the database, and the report is built from that -- exact, and still there +next session. Ask it on a database nobody journalled (worked on in the IDA GUI, +or before this existed) and it falls back to filtering by shape and says so in +the document. + +```sh +python -m idatui.drive export # -> <binary>.findings.md +python -m idatui.drive export /tmp/writeup.md +``` + ### Movement (fast — bare keypresses, pump-only settle) | method | params | effect | |--------|--------|--------| |
