Binaryen - WebAssembly Compiler & Optimizer Toolchain Cheatsheet
Binaryen - WebAssembly Compiler & Optimizer Toolchain Cheatsheet
Binaryen è una libreria di infrastruttura del compilatore e della toolchain per WebAssembly, scritta in C++. Il suo strumento principale, wasm-opt, carica un modulo wasm in una rappresentazione intermedia ed esegue pass di ottimizzazione e trasformazione — la stessa macchinaria che le toolchain come Emscripten usano per ridurre e velocizzare wasm. Per i reverse engineer, il disassembler di Binaryen (wasm-dis) e i suoi pass di analisi/trasformazione (inclusa le semplificazioni adiacenti alla de-offuscazione) lo rendono un utile complemento a WABT.
Installazione
| Piattaforma | Comando |
|---|---|
| macOS (Homebrew) | brew install binaryen |
| Debian/Ubuntu | sudo apt install binaryen |
| Arch Linux | sudo pacman -S binaryen |
| npm | npm install -g binaryen (binding JS) |
| Dal sorgente | compila con CMake dal repository WebAssembly/binaryen |
| Verifica | wasm-opt --version |
Strumenti Principali
| Strumento | Fa |
|---|---|
wasm-opt | Carica, ottimizza/trasforma e ri-emetti un modulo |
wasm-dis | Disassembla .wasm → testo |
wasm-as | Assembla testo → .wasm |
wasm-metadce | Dead-code-eliminate attraverso modulo + JS |
wasm-ctor-eval | Valuta i costruttori al momento della compilazione |
wasm-reduce | Rimpicciolisci un modulo preservando un comportamento (riprouzione bug) |
wasm-shell | Esegui la shell del test spec |
Ottimizzazione di un Modulo
# Ottimizza per dimensione e velocità
wasm-opt -O3 module.wasm -o module.opt.wasm
# Ottimizza aggressivamente per dimensione
wasm-opt -Oz module.wasm -o module.small.wasm
| Flag | Effetto |
|---|---|
-O / -O1..-O4 | Ottimizzazione crescente per velocità |
-Os | Ottimizza per dimensione |
-Oz | Ottimizza aggressivamente per dimensione |
--enable-FEATURE | Abilita una proposta wasm (simd, thread, …) |
-o FILE | File di output |
Esecuzione dei Pass Individuali
wasm-opt espone molti pass nominati che puoi eseguire selettivamente — utile per RE (semplificazione del codice offuscato) così come per la compilazione.
# Elenca tutti i pass disponibili
wasm-opt --help | grep -A2 "passes:"
# Esegui pass specifici (ad es. semplificazione + rimozione non utilizzati)
wasm-opt module.wasm --precompute --simplify-locals \
--remove-unused-names --vacuum -o clean.wasm
| Pass (esempi) | Scopo |
|---|---|
--precompute | Piega le espressioni costanti |
--simplify-locals | Riduci l”utilizzo locale ridondante |
--vacuum | Rimuovi il codice ovviamente morto |
--remove-unused-module-elements | Rimuovi funzioni/globali non utilizzate |
--flatten / --rereloop | Ristruttura il flusso di controllo |
Disassembla / Assembla
# Disassembla nella forma di testo di Binaryen
wasm-dis module.wasm -o module.wat
# Assembla indietro
wasm-as module.wat -o module.wasm
Uso RE: Semplifica Poi Leggi
Un trucco pratico di reversing è eseguire i pass di semplificazione di Binaryen per ripulire il rumore del compilatore/offuscatore, quindi leggere il risultato.
# Semplifica un modulo complicato, quindi decompila con WABT
wasm-opt target.wasm --precompute --simplify-locals --vacuum -o simpler.wasm
wasm-decompile simpler.wasm -o simpler.dcmp
Minimizzazione di una Riprouzione (wasm-reduce)
# Rimpicciolisci un modulo mentre uno script riporta ancora il comportamento di interesse
wasm-reduce big.wasm --command "node check.js" -o small.wasm
Ottimo per isolare il minimo wasm che attiva un bug o un comportamento specifico.
Binaryen vs Strumenti Correlati
| Strumento | Focus |
|---|---|
| Binaryen | Ottimizza/trasforma/analizza wasm (a livello di compilatore) |
| WABT | Converte/ispeziona/convalida/decompila |
| diswasm | Decompiler pseudocodice |
| wasm-tools | Manipolazione Rust di basso livello |
Per RE: usa Binaryen per semplificare, WABT/diswasm per leggere, e wasm-tools per convalidare/mutare.