Home

Awesome

Module to load WebAssembly files into Ghidra, supporting disassembly and decompilation.

Features

Sample disassembly and decompilation

Installing

Prebuilt Extension

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 10.0.4, download the file beginning with ghidra_10.0.4_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.

Custom Build

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.

Tips

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)

Limitations and Known Bugs

Internals

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.

Acknowledgements