A dynamic analysis framework for WebAssembly programs.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.
lib make some parts of the conversion hl<->ll AST more parallel (namely f… Jul 30, 2018
src add (now: commented out) code for maximum call hook argument length (… Aug 7, 2018
.gitignore helper script to build in-browser tests from small .wat files Jun 6, 2018
Cargo.toml change (commented out) release profile: enable debug info if running … Jul 30, 2018
LICENSE add license Sep 4, 2018
README.md add instructions how to build/run Docker image Sep 20, 2018
TODO.md cleanup todos to stuff that is implementation level Aug 28, 2018



Installation from Source

  • Dependencies and tools

    • Git, CMake, and GCC or Clang for building the dependencies (those for sure, but possibly more)
    • Firefox >= 52 (which is what I use, or Chrome >= 57) for running WebAssembly
    • WebAssembly Binary Toolkit (WABT): wat2wasm/wasm2wat for converting Wasm binaries to/from text, wasm-objdump for inspecting binaries, and wasm-interp for a simple interpreter.
    git clone --recursive https://github.com/WebAssembly/wabt
    cd wabt
    # add binaries to $PATH, e.g., by appending the following line to ~/.profile or ~/.bashrc
    export PATH="path/to/your/wabt/bin:$PATH"
    # test
    > usage: wat2wasm [options] filename
    • Emscripten: emcc for compiling C/C++ programs to WebAssembly.
    git clone https://github.com/juj/emsdk.git
    cd emsdk
    ./emsdk install latest
    ./emsdk activate latest
    # add emcc to $PATH, e.g., by appending the following line to ~/.profile or ~/.bashrc
    # WARNING unfortunately, this also exports a quite old emscripten-included clang version,
    # so maybe do this manually before using emscripten and not for all shells. 
    source path/to/your/emsdk/emsdk_env.sh
    # test
    emcc --version
    > emcc (Emscripten gcc/clang-like replacement) 1.38.1
    • Rust (>=1.27.0 nightly): cargo as Rust's package manager and build tool (no need to call rustc manually) and rustup for managing different Rust toolchain versions (e.g., nightly vs. stable).
    curl https://sh.rustup.rs -o rustup-init.sh
    # follow instructions (typically just enter 1 to proceed)
    # should automatically change ~/.profile to include the binaries in $PATH
    sh rustup-init.sh --default-toolchain=nightly
    # test
    cargo --version
    > cargo 1.27.0-nightly
  • Wasabi itself

git clone https://github.com/danleh/wasabi.git
cd wasabi
# download dependencies from https://crates.io, compile with optimizations, make wasabi binary available in $PATH
cargo install --path .

# test
> Error: expected at least one argument
> Usage: wasabi <input_wasm_file> [<output_dir>]

Alternative Setup via Docker

  • Thanks to ctfhacker for the Dockerfile contribution.
  • After having cloned this repo, you build the Docker image with
docker build --rm -t wasabi .
  • Once built, you can use the container via (assuming you have a hello.wasm file in your working directory)
> hello.wasm
docker run --rm -t -v `pwd`:/data  wasabi /data/hello.wasm /data

Usage Tutorial

  • Create WebAssembly programs

    • Manually:
    ;; paste into hello-manual.wat
      (import "host" "print" (func $i (param i32)))
      (func $somefun
        i32.const 42
        call $i)
      (export "somefun" (func $somefun))
    # assemble binary Wasm file
    wat2wasm hello-manual.wat
    # run binary (imported function host.print is provided by the interpreter)
    wasm-interp --host-print --run-all-exports hello-manual.wasm
    > called host host.print(i32:42) =>
    > somefun() =>
    • From C with Emscripten:
    // paste into hello.c
    #include <stdio.h>
    int main(int argc, char const *argv[]) {
        printf("Hello, world!\n");
        return 0;
    # emscripten produces asm.js by default, so use WASM=1 flag
    # note that this generates 3 files: 
    # - hello.wasm: actual binary
    # - hello.js: glue code for compiling and running WebAssembly in the browser, uses fetch() to get hello.wasm
    # - hello.html: website that emulates a console, includes hello.js
    emcc hello.c -s WASM=1 -o hello.html
    # (necessary for Chrome, optional for Firefox:) some-origin policy disallows getting 
    # hello.wasm file from inside hello.js unless it is served from an actual webserver
    # emrun is just a minimal webserver provided by emscripten  
    emrun --no_browser --port 8080 .
    # browse to local webserver with Firefox or Chrome
    firefox http://localhost:8080/hello.html
    chromium-browser http://localhost:8080/hello.html
    # (optional:) inspect the produced binary with wasm2wat or wasm-objdump
    wasm2wat hello.wasm -o hello.wat
    wasm-objdump hello.wasm -hdx | less
  • Apply Wasabi to WebAssembly programs in the browser

    • Step 1: Instrument

      # start with C to Wasm (via Emscripten) project from previous point, that is:  
      > hello.c  hello.html  hello.js  hello.wasm
      # instrument hello.wasm, produces 2 files in out/:
      # - out/hello.wasm: instrumented binary, with imported hooks and calls to these hooks inserted between instructions
      # - out/hello.wasabi.js: Wasabi loader, runtime, and generated program-dependent JavaScript (low-level monomorphized hooks and statically extracted information about the binary)
      wasabi hello.wasm
      # replace original binary with instrumented one and copy generated JavaScript 
      mv hello.wasm hello.orig.wasm
      cp out/* .
      # insert Wasabi-generated JavaScript into emscripten-generated HTML harness (FIXME hacky)
      sed -i '/<script async type="text\/javascript" src="hello.js"><\/script>/a <script src="hello.wasabi.js"></script>' hello.html
      # should still work as before instrumentation
      emrun --no_browser --port 8080 .
      firefox http://localhost:8080/hello.html
    • Step 2: Analyze

      # use example analysis that just logs all instructions with their inputs and results
      cp /path/to/wasabi/analyses/log-all.js .
      # include analysis in emscripten-generated HTML harness (FIXME hacky)
      # NOTE analysis must be loaded *after* the Wasabi-generated JavaScript
      sed -i '/<script src="hello.wasabi.js"><\/script>/a <script src="log-all.js"></script>' hello.html
      # run in browser again, see lots of output on JavaScript console
      emrun --no_browser --port 8080 .
      firefox http://localhost:8080/hello.html
  • Running WebAssembly and instrumenting with Wasabi for Node.js: TODO