Iaito SHA256 Samples Database
=============================

Iaito keeps a local database that maps the SHA256 of every binary it has seen to
its path on disk. It powers `iaito://sha256/<hash>` deep links (see
[deeplinks.md](deeplinks.md)) and the *Sha256* tab in the New File dialog, and it
lets you look a sample up online (VirusTotal by default).

The implementation lives in `src/common/SamplesDB.{h,cpp}`.


On-disk layout
--------------

The database lives under Iaito's application data directory
(`QStandardPaths::AppDataLocation`, e.g. `~/.local/share/radareorg/iaito/samples/`
on Linux).

To scale to large collections without a single huge index file, entries are
sharded git/rainbow-table style across two hash-prefix directory levels. The
leaf is a plain text bucket file holding one `"<sha256> <absolute-path>"` entry
per line:

```
samples/<h0:2>/<h2:4>/<h0:4>

samples/53/a9/53a9   ->   53a9c0557a948069...172161625 /samples/a.out
                          53a9ffeede...                 /samples/b.bin
```

- The two directory levels are the first two and next two hex characters of the
  hash, giving up to 65536 buckets so no single directory grows unbounded.
- The leaf bucket file is named after the 4-character prefix and contains all
  entries sharing it, hash and absolute path separated by a single space.
- Lookups read just one bucket file; the whole database is only walked when the
  *Sha256* tab lists every entry.

When the same hash is registered again with a different path, the latest path
wins (one path per hash).


Hashing
-------

`SamplesDB::sha256File()` computes the digest with radare2's `r_muta` SHA256
session API, reading the file in fixed-size blocks. Memory stays bounded
regardless of file size, so even multi-gigabyte files hash safely without being
loaded into memory at once.


Populating the database
-----------------------

- **Automatically** — every file you open in Iaito is registered (sha256 -> path)
  once it finishes loading, from `MainWindow::finalizeOpen()`. Hashing runs on a
  background thread so the UI stays responsive on large files. Live debug
  sessions and non-file targets (`malloc://`, `dbg://`, ...) are skipped, as are
  paths that no longer exist.
- **Manually** — the *Sha256* tab in the New File dialog lets you:
  - **Scan folder…** — recursively register every file under a chosen directory
    (runs in the background).
  - **Filter** — the input field filters the list by file name or hash as you
    type.
  - **On disk** — a column shows whether each registered file still exists.
  - **Open** — open the selected sample (also on double-click).
  - **Lookup** — open the configured lookup URL for the selected hash.
  - **Delete** — remove the selected entry from the database (the file is left
    untouched).
  - **Right-click** — *Copy path*, *Copy hash*, *Open containing folder*,
    *Open in lookup URL*, *Remove from database*.


Online lookup URL
-----------------

The *Lookup* button and the *Open in lookup URL* context action open a base URL
with the selected file's SHA256 appended. The base URL defaults to VirusTotal:

```
https://www.virustotal.com/gui/file/<sha256>
```

It is configurable in *Settings -> Samples* (stored as `sha256.lookupBaseUrl`),
where a *Reset* button restores the VirusTotal default. This lets you point the
lookup at any service that resolves a file by its SHA256.


Deep link resolution
---------------------

`iaito://sha256/<hash>` looks the hash up in the database and opens the mapped
file if it still exists, applying any `addr`/`view`/`size` parameters. If the
hash is unknown, Iaito shows a dialog explaining how to register it. Downloading
unknown samples is intentionally out of scope.
