
Visualizzatore binario e strumento di triage — superfici di entropia, classi di byte e Hilbert, dot plot e grafi di flusso di controllo su un unico modello condiviso di spazio degli indirizzi.
Strumento di visualizzazione e triage binario: viste interattive collegate (entropia, istogrammi, superfici immagine/dot-plot, grafi di flusso di controllo) su un unico modello condiviso di spazio degli indirizzi.
pipx install binviz && binviz serve
Apri un file e ogni vista osserva lo stesso spazio degli indirizzi. Seleziona un intervallo in una e le altre lo seguono — l'obiettivo è rispondere a "cos'è questa regione" osservandola in più modi contemporaneamente.
binviz model analizza ELF/PE/Mach-O tramite LIEF in regioni, simboli e una mappatura offset↔indirizzo virtuale, materializzando lacune e sovrapposizioni. Input malformati ricadono su un modello grezzo invece di fallire.binviz triage dice come appare il file e perché; nell'interfaccia ogni risultato porta con un clic ai byte da cui è stato derivato.L'interfaccia è composta da cinque aree di lavoro — Panoramica, Byte, Pattern, Codice e Tutto — sulla stessa selezione. Solo analisi statica: i campioni vengono analizzati, mai eseguiti.




Renderizzate dallo stesso codice che l'interfaccia usa per disegnare, direttamente dalla CLI — rigenera con python docs/make_plates.py.
| Un binario statico | Lo stesso programma, impacchettato con UPX |
|---|---|
![]() | ![]() |
| Codice, stringhe e padding si separano in territori visibili. | La struttura collassa in rumore uniforme — la firma dell'impacchettamento. |
![]() | ![]() |
| L'entropia a finestra rimane a bande e bassa. | Piatta e alta, fino allo stub di decompressione. |
| Stride di riga corretto | Stride di riga sbagliato |
|---|---|
![]() | ![]() |
Stessi byte, un numero diverso. Ecco perché esiste il suggeritore di stride: lo stride di riga sbagliato trasforma una fotografia in rumore diagonale, e concludi che non c'è alcuna fotografia.
ARCHITECTURE.md spiega come è assemblato: cosa viene distribuito, il marchio che ogni superficie eredita, le convenzioni che una nuova schermata deve seguire, e i limiti che sono deliberati. SECURITY.md è la postura di sicurezza.
python -m venv .venv
# -c fissa le versioni esatte contro cui la suite è verde; pyproject.toml
# pubblica intervalli, quindi senza di esso ottieni qualunque cosa risolva oggi
.venv/Scripts/pip install -e ".[dev]" -c constraints-dev.txt # POSIX: .venv/bin/pip
# costruisci il corpus di verità di base (usa zig cc dal pacchetto pip ziglang;
# richiede UPX nel PATH, in $UPX, o decompresso in corpus/tools/upx-*/)
make -C corpus # oppure: python corpus/build.py
# le soglie sono misurate, mai hardcoded (vedi ARCHITECTURE.md §2.1)
python corpus/calibrate.py # scrive corpus/calibration.json
pytest # suite funzionale
pytest -m perf -s # obiettivi di prestazione 100 MB
binviz probe corpus/out/hello_O2
binviz model corpus/out/hello_upx
binviz signal corpus/out/hello_upx --name entropy_4096 --png out.png
binviz hist corpus/out/ramp16.bin --n 2 --dtype u16le --png bigram.png
# superfici: -p passa i parametri della superficie
binviz surface corpus/out/hello_static --name hilbert -p mode=byteclass --png h.png
binviz surface corpus/out/rgb_raw.bin --name image -p mode=rgb8 -p width=320 --png i.png
binviz surface corpus/out/repeats.bin --name dotplot -p mode=exact --png d.png
binviz stride corpus/out/bayer_raw.bin --mode bayer_RGGB_RGB_12
# codice
binviz disasm corpus/out/hello_O2 --limit 20
binviz functions corpus/out/hello_static --sort size
binviz cfg corpus/out/hello_O2 --func main --dot main.dot
# il verdetto, e il perché
binviz triage corpus/out/hello_upx
binviz serve # 127.0.0.1:8000
Stampa un URL contenente un token di sessione — aprilo. Ogni rotta /api richiede il token, perché "ascolta solo su localhost" non è una difesa contro una pagina web in un'altra scheda, che raggiunge 127.0.0.1 come qualsiasi altra origine. SECURITY.md contiene il ragionamento.
L'accesso ai file è limitato a --root (predefinito: la directory di lavoro), quindi i percorsi al di fuori di esso vengono rifiutati.
Tutti e quattro hanno un flag e una variabile d'ambiente, e tutti e quattro esistono per impedire a un chiamante locale di consumare più di quanto intendi. I valori predefiniti sono scelti per un laptop; alzali se la tua macchina è più grande.
| Flag | Env | Predefinito | Cosa limita |
|---|---|---|---|
--max-cache BYTES | BINVIZ_MAX_CACHE | 5 GiB | Dimensione totale delle analisi in cache. Oltre questo, le voci meno recentemente usate vengono espulse — mai una in fase di analisi o visualizzazione. |
--max-upload BYTES | BINVIZ_MAX_UPLOAD | 8 GiB | Upload accettato più grande. |
--max-analyses N | — | 4 | Analisi simultanee; oltre questo /api/open restituisce 503. |
--root DIR | — | cwd | Directory da cui il server può leggere i file. |
Le analisi sono memorizzate in cache sotto ~/.cache/binviz (o $BINVIZ_CACHE), indicizzate per hash del contenuto, quindi riaprire un binario è immediato. Alza --max-cache se preferisci conservarne di più; la cache può essere eliminata a mano in qualsiasi momento — il caso peggiore è che la prossima apertura ri-analizzi.
Altri flag: --token per fissare un token tra i riavvii (utile con il proxy di sviluppo Vite, che legge BINVIZ_TOKEN), --port, --cache e --no-auth per la CI. --no-auth stampa un banner che dice cosa hai disattivato; non usarlo su una macchina condivisa.
pip install "binviz[app]"
binviz app # finestra nativa; --browser per il tuo browser
Stesso server, stesso token, stessa limitazione --root di binviz serve — l'unica differenza è ciò che lo visualizza. Senza pywebview installato, binviz app apre il tuo browser.
Stampa l'URL su cui sta servendo, deliberatamente: avvolgere l'interfaccia in una finestra non rimuove il listener di rete, rende solo più facile dimenticare che c'è. Il listener è autenticato in entrambi i casi, e non esiste --no-auth su binviz app.
La finestra espone esattamente una funzione alla pagina — un selettore di file nativo — e nient'altro. Vedi src/binviz/app.py per il motivo per cui quella lista è così breve.
Le release distribuiscono una wheel e nient'altro. Un eseguibile Python congelato non firmato che include capstone e lief ed esiste per analizzare binari impacchettati è esattamente il profilo su cui SmartScreen e le euristiche AV generano falsi positivi — quindi invece di distribuirne uno, il repository contiene ciò che ti serve per costruirlo da solo, aggirando completamente la firma del codice.
pip install pyinstaller # 6.x
python tools/build_ui.py # costruisce web/ e lo prepara nel pacchetto
pyinstaller packaging/binviz.spec # -> dist/binviz/
Aspettati circa 100 MB, dominati da numpy e lief. È un bundle onedir, non un singolo file autoestraente: avvia dist/binviz/binviz.exe (o fai doppio clic) per la finestra desktop, oppure passagli qualsiasi sottocomando — dist/binviz/binviz.exe triage sample.exe — perché la build congelata è l'intera CLI, non solo la finestra.
Il passaggio di preparazione non è opzionale. web/dist vive fuori dal pacchetto Python, quindi saltarlo produce un'app la cui finestra si apre su un JSON 404; la spec rifiuta di costruire piuttosto che lasciare che accada in silenzio.
Su macOS lo stesso comando produce anche dist/Striate.app, marchiato da packaging/icons/icon.icns. Nessuno dei due è stato eseguito su un Mac — vedi ARCHITECTURE.md §5.
--root continua a essere predefinito sulla directory di lavoro, quindi un eseguibile avviato con doppio clic è limitato alla cartella in cui parte — che di solito è la cartella dell'app stessa. Imposta "Avvia in" del collegamento, oppure avvialo con --root DIR.
Un eseguibile avviato con doppio clic richiede una credenziale. Senza argomenti la build congelata esegue binviz app --auth local, che è l'unica differenza rispetto al predefinito della wheel di nessuna schermata di accesso. I due rispondono a domande diverse: binviz app digitato in un terminale è già un atto deliberato di chi possiede la sessione, mentre un doppio clic non stabilisce nulla — è l'unico percorso di avvio senza terminale, senza comando digitato e senza decisione di limitazione dietro. Richiedere la credenziale è il modo in cui la finestra dice ad alta voce ciò che il terminale avrebbe detto. Esegui binviz passwd prima per impostarne una, oppure passa --auth none esplicitamente per saltarla; qualsiasi cosa fornita sulla riga di comando vince comunque.
Per impostazione predefinita non c'è schermata di accesso e nulla da copiare: il server conia un token di sessione e lo inietta nella pagina che serve, quindi aprire http://127.0.0.1:8000/ funziona semplicemente mentre ogni chiamata API è comunque autenticata.
Su una macchina condivisa, attiva la schermata di accesso:
binviz passwd # richiede input; digest scrypt, modalità 0600
binviz serve --auth local
Se salti binviz passwd, il primo accesso rivendica l'installazione — il banner di avvio avvisa di questo, perché chi raggiunge per primo la porta diventa l'account.
Un eseguibile congelato avviato con doppio clic attiva --auth local per sé; vedi Creazione di un'app standalone per il motivo per cui quel predefinito differisce da quello della wheel.
La schermata di accesso non è il confine di sicurezza; il controllo del token su ogni rotta /api lo è. Qualsiasi cosa sulla macchina può saltare il modulo e chiamare l'API direttamente, che è esattamente il motivo per cui il token esiste. Vedi SECURITY.md.
binviz apre file scelti da un attaccante — questo è il lavoro, non un caso limite, e uno strumento di triage in cui l'analisi di malware compromette l'analista è il peggior fallimento possibile. I campioni vengono analizzati, mai eseguiti. Cosa si fa per il resto:
Contro un binario ostile
id in ogni rotta /api/{id}/… deve essere esattamente 64 caratteri esadecimali prima di essere usato per costruire un percorso.Contro un browser ostile — la minaccia che "ascolta solo su localhost" non affronta, perché una pagina in un'altra scheda raggiunge 127.0.0.1 come qualsiasi altra origine:
/api richiede un token. Viene coniato all'avvio e iniettato nella pagina, quindi nulla viene incollato a mano e nessuna rotta rimane aperta.--root, che per impostazione predefinita è la directory di lavoro. I percorsi al di fuori di esso vengono rifiutati.Host e CORS ristretto, quindi l'origine che necessita di accesso è l'unica che lo ottiene.La finestra desktop non rimuove il listener di rete, rende solo più facile dimenticarlo. Quindi non esiste --no-auth su binviz app, e il bridge js_api espone esattamente un metodo — pick_file(), che non accetta argomenti e restituisce un percorso attraverso la stessa limitazione --root. Un test fallisce se mai appare un secondo metodo.
Le credenziali per --auth local sono digest scrypt scritti in modalità 0600; binviz non memorizza password in chiaro.
SECURITY.md contiene il modello di minaccia, il ragionamento dietro ogni controllo, ciò che deliberatamente non è ancora stato fatto, e come segnalare privatamente una vulnerabilità.
MIT — vedi LICENSE.
Il corpus cross-compila campioni ELF con zig cc, quindi nessuna toolchain Linux è necessaria su Windows/macOS — i campioni vengono analizzati, mai eseguiti.