Aller au contenu

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

PlateformeCommande
macOS (Homebrew)brew install binaryen
Debian/Ubuntusudo apt install binaryen
Arch Linuxsudo pacman -S binaryen
npmnpm install -g binaryen (liaisons JS)
Depuis la sourceconstruire avec CMake à partir du dépôt WebAssembly/binaryen
Vérifierwasm-opt --version

Outils principaux

OutilFait
wasm-optCharger, optimiser/transformer et réémettre un module
wasm-disDésassembler .wasm → texte
wasm-asAssembler texte → .wasm
wasm-metadceÉlimination du code mort entre module + JS
wasm-ctor-evalÉvaluer les constructeurs au moment de la construction
wasm-reduceRéduire un module tout en préservant un comportement (dépannage)
wasm-shellExé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
DrapeauEffet
-O / -O1..-O4Optimisation croissante pour la vitesse
-OsOptimiser pour la taille
-OzOptimiser agressivement pour la taille
--enable-FEATUREActiver une proposition wasm (simd, threads, …)
-o FILEFichier 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
--precomputeReplier les expressions constantes
--simplify-localsRéduire l’utilisation de locales redondantes
--vacuumSupprimer le code clairement mort
--remove-unused-module-elementsSupprimer les foncs/globales inutilisées
--flatten / --rereloopRestructurer 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

OutilFoyer
BinaryenOptimiser/transformer/analyser wasm (qualité compilateur)
WABTConvertir/inspecter/valider/décompiler
diswasmDécompilateur pseudocode
wasm-toolsManipulation bas niveau Rust

Pour l’ingénierie inverse : utiliser Binaryen pour simplifier, WABT/diswasm pour lire, et wasm-tools pour valider/muter.

Ressources