diswasm - WebAssembly Decompiler & RE Cheatsheet
diswasm is an open-source decompiler and reverse-engineering tool for WebAssembly (.wasm) binaries. As more application logic ships as wasm — in browsers, edge functions, plugins, and even malware — analysts need to read it. diswasm parses a wasm module, disassembles its functions, recovers structure, and produces higher-level pseudocode from the stack-machine bytecode, making it far easier to understand than raw wasm. It complements the WebAssembly Binary Toolkit (WABT) for a full wasm RE workflow.
Installation
| Method | How |
|---|
| From source | git clone https://github.com/wasmkit/diswasm && cd diswasm |
| Build | follow the repo’s build steps (per language) |
| Companion tools | pair with WABT (wasm2wat) and wasm-tools |
| Verify | run against a known .wasm and inspect output |
Understanding wasm First
| Concept | Meaning |
|---|
| Module | The .wasm unit: functions, memory, tables, globals |
| Stack machine | wasm executes on an operand stack (no registers) |
| WAT | WebAssembly Text format (human-readable .wat) |
| Sections | type, import, function, code, data, export, … |
| Types | i32, i64, f32, f64 (plus reference types) |
Basic Workflow
# 1) Inspect structure with WABT's disassembler
wasm2wat module.wasm -o module.wat
# 2) Decompile to pseudocode with diswasm
diswasm module.wasm > module.pseudo
# 3) Read the recovered functions and control flow
| Step | Tool | Output |
|---|
| Disassemble | wasm2wat (WABT) | .wat text (low-level) |
| Decompile | diswasm | pseudocode (higher-level) |
| Objdump-style | wasm-objdump (WABT) | sections/opcodes |
What diswasm Recovers
| Feature | Helps with |
|---|
| Function boundaries | Where each function starts/ends |
| Control flow | block/loop/if reconstructed as structured code |
| Locals/params | Typed variables per function |
| Memory ops | loads/stores against linear memory |
| Imports/exports | Host functions called / functions exposed |
Reading the Output (Triage)
| Signal | Look for |
|---|
| Imported host functions | JS/host calls (env.*) reveal capabilities |
| String/data section | Embedded constants, URLs, keys |
| Exported functions | The module’s entry points |
| Memory growth / bulk ops | Unpacking or large buffers |
| Indirect calls | Function-table dispatch (obfuscation) |
| Tool | Role |
|---|
| diswasm | Decompile wasm → pseudocode |
WABT (wasm2wat, wasm-objdump) | Disassemble / inspect |
| wasm-tools | Rust low-level manipulation/validation |
Binaryen (wasm-dis) | Compiler-grade analysis/optimization |
| Ghidra + wasm plugin | Full RE environment |
Common Workflows
# Analyze an unknown browser wasm payload
wasm2wat suspicious.wasm -o suspicious.wat # structure
diswasm suspicious.wasm > suspicious.c # readable logic
grep -iE "fetch|eval|XMLHttp|import" suspicious.wat # capabilities
# Compare two versions of a wasm module
diswasm v1.wasm > v1.pseudo; diswasm v2.wasm > v2.pseudo
diff v1.pseudo v2.pseudo
diswasm vs Other Approaches
| Aspect | diswasm | wasm2wat (WABT) | JEB (commercial) |
|---|
| Output level | Pseudocode | Low-level WAT | Pseudo-C decompiler |
| Cost | Free/open-source | Free/open-source | Commercial |
| Best for | Quick readable decompilation | Faithful disassembly | Deep, polished RE |
Resources