Pkg.WASMDecompiler — API for decompiling WebAssembly (WASM) modules

Overview

The Pkg.WASMDecompiler module contains the API for decompiling WebAssembly modules into readable pseudo-code. It operates on a parsed Pkg.WASM.WASMObject instance (or directly on a .wasm file path) and produces output in the spirit of wabt’s wasm-decompile: a stack-machine to expression-tree reconstruction with operator-precedence-correct parenthesization, named locals, globals and functions from the Name section (with stable pN / vN / gN / fN fallbacks), structured control flow lowered to labelled goto loc_X (with continue recognized for branches back to the enclosing loop), typed memory-access syntax (u8[v0 + 8], i32[v3 + 12]), single-use pure-arithmetic temporary inlining, and inline string literals at pointer-consumer sites (call arguments, assignment right-hand sides, store values, return values) — comparisons and arithmetic keep the numeric form.

Per-statement source-offset tags are emitted via Pkg.WASM.Opcodes.WasmTag_Instruction so the cursor stays on the same logical instruction when toggling between disassembly and decompiler. Tags are also emitted around loc_X label definitions and references (Pkg.WASM.Opcodes.WasmTag_LabelDef, Pkg.WASM.Opcodes.WasmTag_LabelJump) and around function-name references in calls (Pkg.WASM.Opcodes.WasmTag_FuncRef).

The decompiler registers itself as a discoverable plugin (wasm_decompilers), so the bytecode view contributed by Pkg.WASM picks it up automatically and remembers the user’s mode choice across sessions.

Decompiling a WASM Module

The following code example demonstrates how to decompile a whole WebAssembly module:

from Pro.Core import *
from Pkg.WASM import WASMObject
from Pkg.WASMDecompiler import WASMDecompiler

def decompileWASM(fname):
    c = createContainerFromFile(fname)
    if c.isNull():
        return
    obj = WASMObject()
    if not obj.Load(c) or not obj.Initialize():
        return
    dec = WASMDecompiler()
    if not dec.init(obj):
        return
    text, _tags = dec.decompile()
    if text is not None:
        print(text)

Decompiling a Single Function

A function index or symbolic name (from the Name section) can be passed to WASMDecompiler.decompile() to decompile just that function. The returned tags are an Pro.Core.NTTextTags instance and can be applied to a text browser view for navigation:

from Pro.Core import *
from Pkg.WASM import WASMObject
from Pkg.WASMDecompiler import WASMDecompiler

def decompileFunction(fname, name_or_index):
    c = createContainerFromFile(fname)
    if c.isNull():
        return
    obj = WASMObject()
    if not obj.Load(c) or not obj.Initialize():
        return
    dec = WASMDecompiler()
    if not dec.init(obj):
        return
    text, tags = dec.decompile(name_or_index)
    if text is not None:
        print(text)
        print("tag count:", tags.tagCount() if tags is not None else 0)

Decompiling with a Wait Object

Decompilation of large modules can be long-running. A wait object can be passed to make the operation interruptible:

from Pro.Core import *
from Pkg.WASM import WASMObject
from Pkg.WASMDecompiler import WASMDecompiler

def decompileWASMWithWait(fname, wo):
    c = createContainerFromFile(fname)
    if c.isNull():
        return
    obj = WASMObject()
    if not obj.Load(c) or not obj.Initialize():
        return
    dec = WASMDecompiler()
    if not dec.init(obj):
        return
    text, _tags = dec.decompile(wo=wo)
    if text is not None:
        print(text)

Module API

Pkg.WASMDecompiler module API.

Classes:

WASMDecompiler()

WebAssembly module decompiler.

class WASMDecompiler

WebAssembly module decompiler.

Produces readable pseudo-code with expression folding, named locals/globals/functions and resolved branch labels (using offsets relative to each function’s body).

Methods:

decompile([name_or_index, wo])

Decompiles a function or the entire module.

init(file_name_or_obj)

Initializes the decompiler.

resetCache()

Resets any cached decompilation state.

setIndentSize(size)

Sets the indentation size used by the emitter.

decompile(name_or_index: Optional[Union[str, int]] = None, *, wo: Optional[Pro.Core.NTIWait] = None)Tuple[Optional[str], Optional[Pro.Core.NTTextTags]]

Decompiles a function or the entire module.

Tags are emitted around loc_X label definitions (Pkg.WASM.Opcodes.WasmTag_LabelDef) and around the loc_X references inside goto/continue/break statements (Pkg.WASM.Opcodes.WasmTag_LabelJump), so the UI can resolve clicks to the matching label.

Parameters
  • name_or_index (Optional[Union[str, int]]) – Optional function index or symbolic name. If None, decompiles the whole module (imports, globals, memories, tables, data, functions).

  • wo (Optional[NTIWait]) – Optional wait object for long-running operations.

Returns

Returns a tuple (text, tags). The first element is None on failure.

Return type

Tuple[Optional[str], Optional[NTTextTags]]

See also init().

init(file_name_or_obj: Union[str, Pkg.WASM.WASMObject])bool

Initializes the decompiler.

Parameters

file_name_or_obj (Union[str, WASMObject]) – Either a path to a .wasm file or a pre-loaded Pkg.WASM.WASMObject instance.

Returns

Returns True on success.

Return type

bool

See also decompile().

resetCache()None

Resets any cached decompilation state.

setIndentSize(size: int)None

Sets the indentation size used by the emitter.

Parameters

size (int) – Number of spaces per indent level (clamped to a minimum of 1).