
Quokka: A Fast and Accurate Binary Exporter
immagine generata da DALL-E
Quokka è un esportatore di binari: dal disassembly di un programma genera un file di export che può essere utilizzato senza il disassembler. Attualmente supporta IDA Pro, Ghidra e Binary Ninja come backend di disassembly.
L'obiettivo principale di Quokka è consentire di manipolare completamente il binario senza mai aprire un disassembler dopo l'esportazione iniziale. Inoltre, astrae l'API del disassembler per esporre un'interfaccia pulita agli utenti.
Quokka è fortemente ispirato da BinExport, l'esportatore di binari usato da BinDiff.
IDA Pro Ghidra Binary Ninja
│ │ │
IDA Plugin (C++) Ghidra Plugin (Java) BinaryNinja Plugin (Python)
│ │ │
└────────────── quokka.proto ─────────────────┘
(protobuf schema)
│
.quokka files
│
Python bindings (quokka.Program)
├── Capstone backend (primary)
└── Pypcode backend (optional)
Il plugin viene compilato nella CI ed è disponibile nel registry.
Dovrebbe essere possibile installarlo direttamente tramite PIP usando un comando di questo tipo:
$ pip install quokka-project
Nota: il plugin IDA non è necessario per leggere un file generato da Quokka. Viene
utilizzato solo per generarli.
Quokka è compatibile con IDA 9.1+.
Quokka è pubblicato nel repository dei plugin Hex-Rays e può essere installato con
hcli:
user@host:~$ hcli plugin install quokka
Il plugin viene anche compilato nella CI ed è disponibile nella scheda Releases.
Per scaricare il plugin, prendi il file chiamato quokka_plugin.so (o l'archivio
quokka-ida<version>.zip per la tua versione di IDA) e copialo nella tua
directory plugins di IDA.
Quokka supporta anche l'esportazione da Ghidra (>= 12.0.3) tramite
un'estensione dedicata. Produce gli stessi file protobuf .quokka che la
libreria Python può caricare.
Per istruzioni di build, installazione e dettagli d'uso vedi il README dell'estensione Ghidra.
Quokka supporta anche l'esportazione da Binary Ninja tramite un plugin Python.
Produce gli stessi file protobuf .quokka che la libreria Python può caricare.
Per istruzioni di installazione e dettagli d'uso vedi il README dell'estensione BinaryNinja.
Il primo metodo manuale per esportare un binario è usare il plugin all'interno di IDA Pro.
La scorciatoia predefinita in IDA è Alt+A. Apre la seguente finestra di dialogo:

Le modalità disponibili sono:
Nota: la modalità FULL non è ancora implementata. Solo la modalità LIGHT è attualmente funzionante.
Nota: questo richiede un'installazione IDA funzionante.
$ idat -OQuokkaAuto:true -OQuokkaDecompiled:true -A /path/to/hello.i64
Tutte le opzioni disponibili sono descritte nella pagina Usage.
Nota: idat viene usato al posto di ida per aumentare la velocità di esportazione, poiché
l'interfaccia grafica non è necessaria.
$ analyzeHeadless /tmp/proj Test \
-import /path/to/binary \
-scriptPath ghidra_extension/src/script/ghidra_scripts \
-postScript QuokkaExportHeadless.java \
--out=/path/to/output.quokka --mode=LIGHT
Vedi il README dell'estensione Ghidra per maggiori dettagli.
Nota: l'uso headless dell'API Binary Ninja richiede una licenza commerciale. In assenza di una, usa invece il comando di esportazione all'interno dell'interfaccia di Binary Ninja.
$ python binaryninja_extension/export_headless.py /path/to/binary \
-o /path/to/output.quokka --mode LIGHT
Vedi il README dell'estensione BinaryNinja per maggiori dettagli.
Quokka fornisce uno strumento CLI per esportare automaticamente uno o più file e/o directory (tutti i file eseguibili in ciascuna directory) in parallelo. Supporta sia i backend IDA Pro che Ghidra:
$ quokka-cli --backend ghidra -t 8 dir/
$ quokka-cli --backend ida --ida-path /opt/ida -t 8 dir/
$ quokka-cli -t 8 dir/ # auto-detect backend
$ quokka-cli -o "%p/exports/%f.quokka" binary # custom output directory
$ quokka-cli -b ida -o %F_ida.quokka -t 4 dir/ # Using relative path
$ quokka-cli -t 8 dir1/ dir2/ binary1 binary2 # multiple inputs
Per impostazione predefinita, il file .quokka viene posizionato accanto al binario di input
(ad es. /usr/bin/ls produce /usr/bin/ls.quokka). Usa -o per sovrascrivere questo
comportamento con un percorso letterale o un template espanso per ogni file
(%f = stem, %F = nome file, %p = directory padre, %P = percorso completo,
%e = estensione, %% = % letterale).
Esegui quokka-cli --help per tutte le opzioni. I flag principali includono:
-b, --backend per scegliere il backend del disassembler (ida, ghidra o auto)-i, --ida-path per fornire il percorso della directory di installazione di IDA (la cartella che contiene idat)--ghidra-path per fornire la directory di installazione di Ghidra (sovrascrive GHIDRA_INSTALL_DIR)-o, --output per impostare il percorso di output o il template (predefinito: %F.quokka)-m, per scegliere la modalità di esportazione ( o )import quokka
from quokka.types import Disassembler
# Directly from the binary (auto-detects available backend)
prog = quokka.Program.from_binary("/bin/ls")
# Explicitly choose a backend
prog = quokka.Program.from_binary("/bin/ls", disassembler=Disassembler.GHIDRA)
prog = quokka.Program.from_binary("/bin/ls", disassembler=Disassembler.IDA)
# From the exported file
prog = quokka.Program("ls.quokka", # the exported file
"/bin/ls") # the original binary
# Add new types from C declarations
prog.add_type("struct context { int id; char name[64]; };")
prog.add_type("enum status { OK=0, ERROR=1 };")
# Save the .quokka file
prog.write()
# Or apply changes (including new types) back to the IDA database
prog.commit(database_file="ls.i64", overwrite=True)
Vedi la documentazione completa sulla modifica per i dettagli su rinomina delle funzioni, impostazione dei prototipi e altro.
Il processo di compilazione dipende dalla versione dell'IDA SDK in uso. Queste due modalità sono anche chiamate il nuovo metodo e il vecchio metodo.
L'IDA SDK è stata finalmente resa open source, quindi non è più necessario scaricarla separatamente.
Puoi usare l'opzione cmake -DIDA_VERSION=<major>.<minor> per sincronizzarla automaticamente da github.
user@host:~/quokka$ cmake -B build \ # Where to build
-S . \ # Where are the sources
-DIDA_VERSION=9.2 \ # IDA SDK version
-DCMAKE_BUILD_TYPE:STRING=Release \ # Build Type
user@host:~/quokka$ cmake --build build -- -j
Poiché l'IDA SDK è ancora codice proprietario, devi procurartela da solo e fornire
il suo percorso a cmake tramite l'opzione -DIdaSdk_ROOT_DIR:STRING=path/to/sdk
NOTA: questo funzionerà anche con le versioni più recenti, ma richiede più passaggi da parte degli utenti, poiché dovranno scaricare l'SDK da soli.
user@host:~/quokka$ cmake -B build \ # Where to build
-S . \ # Where are the sources
-DIdaSdk_ROOT_DIR:STRING=path/to/ida_sdk \ # Path to IDA SDK
-DCMAKE_BUILD_TYPE:STRING=Release \ # Build Type
user@host:~/quokka$ cmake --build build --target quokka_plugin -- -j
Per installare il plugin:
user@host:~/quokka$ cmake --install build
In ogni caso, il plugin si troverà anche in build/quokka-install. Puoi
copiarlo nella directory dei plugin utente di IDA.
user@host:~/quokka$ cp build/quokka-install/quokka_plugin.so $HOME/.idapro/plugins/
Per informazioni più dettagliate sulla compilazione, vedi Compilazione
La documentazione è disponibile online su documentazione
Puoi vedere un elenco di domande qui FAQ
Nota: attualmente è implementata solo la modalità LIGHT. La modalità FULL (self-contained) è prevista ma non ancora funzionante.
Quokka offre due modalità per esportare l'analisi di disassembly: la modalità light e la modalità self-contained.
La modalità light si concentra sull'esportazione di sole informazioni essenziali, producendo file veloci e leggeri. In questa modalità non viene esportata alcuna informazione a livello di istruzione o inferiore, quindi il motore Capstone verrà utilizzato a runtime per ottenere il disassembly delle istruzioni.
La modalità self-contained, invece, esporta il disassembly completo, esattamente come lo mostra il disassembler backend. Questo produce file più pesanti, ma non richiede di dipendere da disassembler di terze parti a runtime.
È importante notare che entrambe le modalità offrono la stessa API nei binding Python.
[!WARNING] Dalla modalità self-contained è ancora possibile ottenere l'oggetto istruzione di Capstone, ma attenzione: il disassembly di Capstone potrebbe essere diverso da quello esportato da Quokka (le istruzioni potrebbero essere divise, unite, non supportate, avere mnemonici diversi, ecc.). In generale piattaforme diverse di analisi binaria producono disassembly diversi; tienilo a mente quando mescoli Capstone con la modalità self-contained.
Per una panoramica completa delle differenze tra le due modalità, guarda la tabella qui sotto:
¹ Abilitabile opzionalmente
² Attualmente non supportato
--modelightfull--decompiled per abilitare l'esportazione del codice decompilato (solo IDA)-v, --verbose per abilitare il logging verbose| Modalità Light | Modalità Self-contained |
|---|
| Funzioni | ✅ | ✅ |
| Blocchi di base | ✅ | ✅ |
| Istruzioni | ❌ | ✅ |
| Operandi | ❌ | ✅ |
| Riferimenti dati | ✅ | ✅ |
| Riferimenti incrociati | ✅ | ✅ |
| Sezioni/Layout | ✅ | ✅ |
| Decompilazione | ✅¹ | ✅¹ |
| Coordinate di disegno del CFG | ✅¹² | ✅¹² |