Binaryen - Chaîne d'outils compilateur et optimiseur WebAssembly
Binaryen - Chaîne d’outils compilateur et optimiseur WebAssembly
Binaryen est une bibliothèque d’infrastructure compilateur et chaîne d’outils pour WebAssembly, écrite en C++. Son outil phare, wasm-opt, charge un module wasm dans une représentation intermédiaire et exécute des passes d’optimisation et de transformation — la même machinerie que les chaînes d’outils comme Emscripten utilisent pour réduire et accélérer wasm. Pour les ingénieurs inverses, le désassembleur de Binaryen (wasm-dis) et ses passes d’analyse/transformation (y compris les simplifications adjacentes à la dés-obfuscation) la rendent complémentaire utile à WABT.
Installation
| Plateforme | Commande |
|---|---|
| macOS (Homebrew) | brew install binaryen |
| Debian/Ubuntu | sudo apt install binaryen |
| Arch Linux | sudo pacman -S binaryen |
| npm | npm install -g binaryen (liaisons JS) |
| Depuis la source | construire avec CMake à partir du dépôt WebAssembly/binaryen |
| Vérifier | wasm-opt --version |
Outils principaux
| Outil | Fait |
|---|---|
wasm-opt | Charger, optimiser/transformer et réémettre un module |
wasm-dis | Désassembler .wasm → texte |
wasm-as | Assembler texte → .wasm |
wasm-metadce | Élimination du code mort entre module + JS |
wasm-ctor-eval | Évaluer les constructeurs au moment de la construction |
wasm-reduce | Réduire un module tout en préservant un comportement (dépannage) |
wasm-shell | Exécuter le shell de test de spécification |
Optimisation d’un module
# Optimize for size and speed
wasm-opt -O3 module.wasm -o module.opt.wasm
# Optimize aggressively for size
wasm-opt -Oz module.wasm -o module.small.wasm
| Drapeau | Effet |
|---|---|
-O / -O1..-O4 | Optimisation croissante pour la vitesse |
-Os | Optimiser pour la taille |
-Oz | Optimiser agressivement pour la taille |
--enable-FEATURE | Activer une proposition wasm (simd, threads, …) |
-o FILE | Fichier de sortie |
Exécution de passes individuelles
wasm-opt expose de nombreuses passes nommées que vous pouvez exécuter sélectivement — utile pour l’ingénierie inverse (simplifier le code obfusqué) ainsi que pour les constructions.
# List all available passes
wasm-opt --help | grep -A2 "passes:"
# Run specific passes (e.g. simplify + remove unused)
wasm-opt module.wasm --precompute --simplify-locals \
--remove-unused-names --vacuum -o clean.wasm
| Pass (exemples) | Objectif |
|---|---|
--precompute | Replier les expressions constantes |
--simplify-locals | Réduire l’utilisation de locales redondantes |
--vacuum | Supprimer le code clairement mort |
--remove-unused-module-elements | Supprimer les foncs/globales inutilisées |
--flatten / --rereloop | Restructurer le flux de contrôle |
Désassembler / Assembler
# Disassemble to Binaryen's text form
wasm-dis module.wasm -o module.wat
# Assemble back
wasm-as module.wat -o module.wasm
Utilisation RE : simplifier puis lire
Une astuce pratique d’ingénierie inverse consiste à exécuter les passes de simplification de Binaryen pour nettoyer le bruit du compilateur/obfuscateur, puis lire le résultat.
# Simplify a gnarly module, then decompile with WABT
wasm-opt target.wasm --precompute --simplify-locals --vacuum -o simpler.wasm
wasm-decompile simpler.wasm -o simpler.dcmp
Minimisation d’un repro (wasm-reduce)
# Shrink a module while a script still reports the behavior of interest
wasm-reduce big.wasm --command "node check.js" -o small.wasm
Idéal pour isoler le wasm minimal qui déclenche un bug ou un comportement spécifique.
Binaryen vs outils associés
| Outil | Foyer |
|---|---|
| Binaryen | Optimiser/transformer/analyser wasm (qualité compilateur) |
| WABT | Convertir/inspecter/valider/décompiler |
| diswasm | Décompilateur pseudocode |
| wasm-tools | Manipulation bas niveau Rust |
Pour l’ingénierie inverse : utiliser Binaryen pour simplifier, WABT/diswasm pour lire, et wasm-tools pour valider/muter.