Ghidra Wasm plugin with disassembly and decompilation support
Java
410
234 commits
updated Dec 15, 2025
Module to load WebAssembly files into Ghidra, supporting disassembly and decompilation.

The easiest way to install the plugin is as a Ghidra extension. Grab a
release that is
compatible with your version of Ghidra - for example, if you're using Ghidra
12.0, download the file beginning with ghidra_12.0_PUBLIC. You don't need
to unzip the file: simply launch Ghidra, go to "File -> Install Extensions",
select the + icon, and select the zip file. Restart Ghidra to load the extension
and you should be good to go. Note: if you upgrade your version of Ghidra,
you will need to upgrade your plugin too.
If there is no release for your version of Ghidra, or you want to install a modified version, you may build and install from source instead. You'll need Gradle and a Java compiler. Run the following commands from the root of this repository:
export GHIDRA_INSTALL_DIR=<path to Ghidra install directory>
gradle buildExtension
GHIDRA_INSTALL_DIR should be the directory that contains the Ghidra
installation, i.e. the directory containing Extensions, Ghidra, ghidraRun,
support and so on.
If all goes well, the zipped plugin will be placed in the dist directory and
can be installed using "File -> Install Extensions" as before.
pos-stack compiler when importing the file, or via Set Language... on an existing file in the project window.dyncall_ functions, which take a call-type-specific index as the
first parameter. The index is used to index a sub-section of the main function
table (table0) to find the function to call. The included script
analyze_dyncalls.py can analyze the dyncall_ functions, extract the indices,
and rename referenced functions according to their call type and function index
(which will often serve as function pointer values in memory). This can be used
to resolve function pointer references, for example.WasmLoader.loadElementsToTable. For example, to load element segment #0 to
table #1 at offset 2 in Python:from wasm import WasmLoader
from wasm.analysis import WasmAnalysis
from ghidra.util.task import ConsoleTaskMonitor
monitor = ConsoleTaskMonitor()
WasmLoader.loadElementsToTable(currentProgram, WasmAnalysis.getState(currentProgram).module, 0, 1, 2, monitor)
from wasm import WasmLoader
from wasm.analysis import WasmAnalysis
from ghidra.util.task import ConsoleTaskMonitor
monitor = ConsoleTaskMonitor()
WasmLoader.loadDataToMemory(currentProgram, WasmAnalysis.getState(currentProgram).module, 5, 0, 0x1000, monitor)
This module uses a pre-analyzer (WasmPreAnalyzer) to analyze all functions and opcodes, providing contextual information to the SLEIGH disassembler to enable correct disassembly (for example, operand sizes when they depend on the types in the value stack, branch target addresses, etc). In order to support recovery of the C stack, this module converts Wasm stack operations into operations on a register file. This frees up the decompiler's stack analysis to focus on the behaviour of the C stack, since the decompiler only supports a single stack. Additionally, parameter passing and returns are handled by virtual input/output registers which are copied to/from the stack and locals registers via Pcode injection.
Four different types of "registers" are defined: input (iN), output (oN), stack (sN) and locals (lN). Of these, only the locals will be visible in the disassembly; stack registers will appear in the PCode, and input/output registers will appear in function types.
2,800 followers · starred Mar 2022
881 followers · starred Sep 2021
27 followers · starred May 2023
109 followers · starred Jan 2023
Java
88.4%
Python
9.3%
HTML
2.3%
Ghidra Wasm plugin with disassembly and decompilation support
Java
410
234 commits
updated Dec 15, 2025
Module to load WebAssembly files into Ghidra, supporting disassembly and decompilation.

The easiest way to install the plugin is as a Ghidra extension. Grab a
release that is
compatible with your version of Ghidra - for example, if you're using Ghidra
12.0, download the file beginning with ghidra_12.0_PUBLIC. You don't need
to unzip the file: simply launch Ghidra, go to "File -> Install Extensions",
select the + icon, and select the zip file. Restart Ghidra to load the extension
and you should be good to go. Note: if you upgrade your version of Ghidra,
you will need to upgrade your plugin too.
If there is no release for your version of Ghidra, or you want to install a modified version, you may build and install from source instead. You'll need Gradle and a Java compiler. Run the following commands from the root of this repository:
export GHIDRA_INSTALL_DIR=<path to Ghidra install directory>
gradle buildExtension
GHIDRA_INSTALL_DIR should be the directory that contains the Ghidra
installation, i.e. the directory containing Extensions, Ghidra, ghidraRun,
support and so on.
If all goes well, the zipped plugin will be placed in the dist directory and
can be installed using "File -> Install Extensions" as before.
pos-stack compiler when importing the file, or via Set Language... on an existing file in the project window.dyncall_ functions, which take a call-type-specific index as the
first parameter. The index is used to index a sub-section of the main function
table (table0) to find the function to call. The included script
analyze_dyncalls.py can analyze the dyncall_ functions, extract the indices,
and rename referenced functions according to their call type and function index
(which will often serve as function pointer values in memory). This can be used
to resolve function pointer references, for example.WasmLoader.loadElementsToTable. For example, to load element segment #0 to
table #1 at offset 2 in Python:from wasm import WasmLoader
from wasm.analysis import WasmAnalysis
from ghidra.util.task import ConsoleTaskMonitor
monitor = ConsoleTaskMonitor()
WasmLoader.loadElementsToTable(currentProgram, WasmAnalysis.getState(currentProgram).module, 0, 1, 2, monitor)
from wasm import WasmLoader
from wasm.analysis import WasmAnalysis
from ghidra.util.task import ConsoleTaskMonitor
monitor = ConsoleTaskMonitor()
WasmLoader.loadDataToMemory(currentProgram, WasmAnalysis.getState(currentProgram).module, 5, 0, 0x1000, monitor)
This module uses a pre-analyzer (WasmPreAnalyzer) to analyze all functions and opcodes, providing contextual information to the SLEIGH disassembler to enable correct disassembly (for example, operand sizes when they depend on the types in the value stack, branch target addresses, etc). In order to support recovery of the C stack, this module converts Wasm stack operations into operations on a register file. This frees up the decompiler's stack analysis to focus on the behaviour of the C stack, since the decompiler only supports a single stack. Additionally, parameter passing and returns are handled by virtual input/output registers which are copied to/from the stack and locals registers via Pcode injection.
Four different types of "registers" are defined: input (iN), output (oN), stack (sN) and locals (lN). Of these, only the locals will be visible in the disassembly; stack registers will appear in the PCode, and input/output registers will appear in function types.
2,800 followers · starred Mar 2022
881 followers · starred Sep 2021
27 followers · starred May 2023
109 followers · starred Jan 2023
Java
88.4%
Python
9.3%
HTML
2.3%