Binaryen - Kit de herramientas compilador y optimizador de WebAssembly
Binaryen - Kit de herramientas compilador y optimizador de WebAssembly
Binaryen es una biblioteca de infraestructura compilador y conjunto de herramientas para WebAssembly, escrita en C++. Su herramienta estrella, wasm-opt, carga un módulo wasm en una representación intermedia y ejecuta pasadas de optimización y transformación sobre ella — el mismo mecanismo que usan conjuntos de herramientas como Emscripten para reducir y acelerar wasm. Para ingenieros inversos, el desasemblador de Binaryen (wasm-dis) y sus pasadas de análisis/transformación (incluyendo simplificaciones adyacentes a desofuscación) lo hacen un complemento útil a WABT.
Instalación
| Plataforma | Comando |
|---|---|
| macOS (Homebrew) | brew install binaryen |
| Debian/Ubuntu | sudo apt install binaryen |
| Arch Linux | sudo pacman -S binaryen |
| npm | npm install -g binaryen (enlaces de JS) |
| Desde fuente | compilar con CMake desde el repositorio de WebAssembly/binaryen |
| Verificar | wasm-opt --version |
Herramientas principales
| Herramienta | Hace |
|---|---|
wasm-opt | Carga, optimiza/transforma y re-emite un módulo |
wasm-dis | Desensambia .wasm → texto |
wasm-as | Ensambla texto → .wasm |
wasm-metadce | Eliminación de código muerto entre módulo + JS |
wasm-ctor-eval | Evalúa constructores en tiempo de compilación |
wasm-reduce | Reduce un módulo mientras preserva un comportamiento (repro de bug) |
wasm-shell | Ejecuta la shell de prueba de especificaciones |
Optimizando un módulo
# Optimiza para tamaño y velocidad
wasm-opt -O3 module.wasm -o module.opt.wasm
# Optimiza agresivamente para tamaño
wasm-opt -Oz module.wasm -o module.small.wasm
| Bandera | Efecto |
|---|---|
-O / -O1..-O4 | Optimización creciente para velocidad |
-Os | Optimiza para tamaño |
-Oz | Optimiza agresivamente para tamaño |
--enable-FEATURE | Habilita una propuesta de wasm (simd, threads, …) |
-o FILE | Archivo de salida |
Ejecutar pasadas individuales
wasm-opt expone muchas pasadas nombradas que puedes ejecutar selectivamente — útil para ingeniería inversa (simplificar código ofuscado) así como compilaciones.
# Lista todas las pasadas disponibles
wasm-opt --help | grep -A2 "passes:"
# Ejecuta pasadas específicas (por ejemplo, simplificar + eliminar no usado)
wasm-opt module.wasm --precompute --simplify-locals \
--remove-unused-names --vacuum -o clean.wasm
| Pasada (ejemplos) | Propósito |
|---|---|
--precompute | Pliega expresiones constantes |
--simplify-locals | Reduce el uso local redundante |
--vacuum | Elimina código obviamente muerto |
--remove-unused-module-elements | Elimina funciones/globales sin usar |
--flatten / --rereloop | Reestructura el flujo de control |
Desensambia / Ensambla
# Desensambia a la forma de texto de Binaryen
wasm-dis module.wasm -o module.wat
# Ensambla de vuelta
wasm-as module.wat -o module.wasm
Uso de ingeniería inversa: Simplificar luego leer
Un truco práctico de reversing es ejecutar las pasadas de simplificación de Binaryen para limpiar el ruido del compilador/ofuscador, luego leer el resultado.
# Simplifica un módulo complicado, luego descompila con WABT
wasm-opt target.wasm --precompute --simplify-locals --vacuum -o simpler.wasm
wasm-decompile simpler.wasm -o simpler.dcmp
Minimizando un repro (wasm-reduce)
# Reduce un módulo mientras un script aún reporta el comportamiento de interés
wasm-reduce big.wasm --command "node check.js" -o small.wasm
Excelente para aislar el wasm mínimo que desencadena un bug o un comportamiento específico.
Binaryen vs herramientas relacionadas
| Herramienta | Enfoque |
|---|---|
| Binaryen | Optimiza/transforma/analiza wasm (calidad de compilador) |
| WABT | Convierte/inspecciona/valida/descompila |
| diswasm | Descompilador de pseudocódigo |
| wasm-tools | Manipulación Rust de bajo nivel |
Para ingeniería inversa: usa Binaryen para simplificar, WABT/diswasm para leer, y wasm-tools para validar/mutar.