From 41b3710d5b6f9be24430fd55c46c83f9ae3b8d83 Mon Sep 17 00:00:00 2001 From: blasty Date: Fri, 7 Aug 2026 23:16:30 +0200 Subject: Ctrl+F: search the whole database, by text or by bytes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `/` only ever searched the lines of the view you were in. This adds the search you actually need on a binary: over the entire database, either through the rendered disassembly or through the image. * **text** matches the line as displayed, whitespace-normalised, so `call cs:` finds `call cs:getenv_ptr` (IDA's column padding is not something anyone types). Smartcase; `regex` available over RPC. * **bytes** is IDA's own `find_bytes`, so the pattern language people already know works unchanged: hex pairs, `?` wildcards for a whole byte or one nibble (`48 8? ?? 24`), quoted literals (`"Hello", 0`). Commas, no separators (`488B05C3`) and ragged spacing all normalise. **Which mode you meant is guessed, and the guess is biased on purpose.** `dead`, `add`, `cafe` and `ff` are valid hex AND ordinary things to search for, so a bare hex-looking word stays TEXT; nobody types `48 8b ?? c3` meaning prose. `hex:`/`text:` prefixes and F2 override it. The subtle case is a *typo* in a byte pattern. `48 zz c3` first fell through to a text search and reported "no match" — indistinguishable from "those bytes are not in this binary", which is the most misleading answer a search can give. Now any query whose tokens are all byte-sized is treated as bytes, and a bad token is refused BY NAME. IDA does the same thing quietly (find_bytes answers a malformed pattern with zero hits and no error), so the validation lives in Program.search, not just in the UI. Enter searches, then Enter opens the highlighted hit; the title says which it will do, because a database-wide scan is far too slow to run on every keystroke like the other palettes. Navigation goes to the item head — a byte match can start mid-instruction — and the status names the exact address. Also: the `find` RPC verb and `drive find`, which is the one an agent wants (`drive find '48 8b ?? c3'`). idatui/search.py holds the classification and is pure, so the whole question of "what did they mean" is tested offline: tests/test_search.py, 35 checks, 0.1s. Pilot scenario db_search covers the UI end to end. Full suite: 890 passed, 0 failed, 51.3s. --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'README.md') diff --git a/README.md b/README.md index 1092219..bee852d 100644 --- a/README.md +++ b/README.md @@ -100,6 +100,13 @@ a 400 MB binary scrolls like a text file. **Decompiler** — Hex-Rays pseudocode with syntax highlighting, per-line address anchors, and rename/retype/comment that write back. +**Search** (`ctrl+f`) — the whole database, two ways: **text** through the +rendered disassembly (`call cs:`, `xor eax, eax`) and **bytes** with IDA's +pattern language, wildcards included (`48 8b ?? c3`, nibbles like `8?`, quoted +literals). Which one you meant is guessed from the query — a hex-looking *word* +like `dead` stays a text search — and `hex:`/`text:` or F2 override the guess. +Enter searches, then Enter opens the hit. + **Findings export** (`ctrl+e`) — the session as a markdown writeup: your comments grouped by function, the names and prototypes you set, the types you declared. A `.i64` does not record *who* wrote a comment — IDA's own analyzer -- cgit v1.3.1-sl0p