Wasabi is a dynamic analysis framework for WebAssembly. What does this mean and why is it useful?
Dynamic analysis means observing some properties of a program while it is running.
Dynamic analysis is routinely used to find and fix bugs, identify performance bottlenecks, or to search for security problems.
Since dynamic analysis has access to runtime information (e.g., program inputs and its current state), it can often be more precise than static analysis, that looks at the program without executing it. Obviously, static analysis has benefits as well. In practice, they often complement each other and you need at least a little bit of both. Dynamic analysis can answer many questions in the areas of
- correctness, e.g., “How much of my code is covered by this test suite?” or “Where does this null pointer come from?”,
- performance, e.g., “In which loop is most of the time spent?” or “Do these memory accesses happen in a cache-friendly order?”, and
- security, e.g., “Is privacy sensitive information leaking to unauthorized places?” or “Is there a memory error that corrupts the heap meta data?”
Writing a (static or dynamic) program analysis is hard, partly because the involved algorithms are complex. But at least some part of that complexity is independent of the individual analyses, for example because it stems from the program representation that is analyzed (e.g., native code or byte code) or the execution model (e.g., a virtual machine or actual hardware). Implementing these parts over and over again for specific analyses would be repetitive and error prone. The frameworks above have been a huge success in academia and practical use by providing a reusable platform for many different dynamic analyses. We would like to follow their path with this first dynamic analysis framework for WebAssembly.
WebAssembly is a new programming language (or more precisely: byte code) for browsers.
We expect it to be hugely successful in the near future.
(Click on the bullets for more information. Simplified for the sake of giving a quick intuition.)
How Does It Work?
The name Wasabi stands for WebAssembly analysis using binary instrumentation, which hints at the two phases Wasabi operates in:
- It statically instruments a WebAssembly binary (e.g.,
program.wasm). That is, it inserts additional instructions, such as function calls, in between the original instructions of the program. This happens before the execution. Since WebAssembly is a binary format, and to be independent of the source code (which is often not available when analyzing third-party code in websites), we directly modify the byte code.
- To perform the dynamic analysis, the program is then executed (by opening the website with the now instrumented
program.wasm). To make the user-written analysis functions known to the WebAssembly program (and for other technical reasons), a
wasabi.jsscript has to be added to the page alongside the
The following picture shows the main steps necessary to analyze a WebAssembly program from the view of a user of Wasabi:
- Write an analysis (e.g.,
- Run the Wasabi tool on the WebAssembly program that shall be analyzed (e.g.,
wasabi.jsthat contains statically extracted information about the program and some glue code to connect the analysis with the program itself.
- Modify the HTML harness (e.g.,
website.html) of the WebAssembly program.
analysis.js(written by you) and
wasabi.js(generated by Wasabi) with
<script ...>tags to the HTML file. Also note that the instrumented WebAssembly program replaces the original file.
- Finally, open the website to execute the WebAssembly program as usual. Because of Wasabi’s instrumentation and runtime library, during the execution the analysis hooks inside
Example and Demo
Typically, WebAssembly programs are compiled from C or C++ via emscripten. But for this example, assume we have a small program written manually in the WebAssembly text format, called
We can create a binary from the text format with
wat2wasm from the WebAssembly Binary Toolkit (WABT).
The program below contains two functions,
$loop, and imports a third function
$ signifies indices in WebAssembly.
That is, these “names” are actually encoded as integers and thus lost in the binary format.
If you are interested, you can download the (uninstrumented) binary here.
(module ;; import function for printing integers from host environment (import "env" "print" (func $print (param i32))) ;; make main function available to the host environment (export "main" (func $main)) (func $main ;; print 42 via the imported function i32.const 42 call $print ;; call the function with index $loop call $loop ) (func $loop (local $counter i32) i32.const 5 set_local $counter loop ;; print current loop counter get_local $counter call $print ;; subtract 1 from loop counter get_local $counter i32.const -1 i32.add tee_local $counter ;; backward branch (== continue) while $loop > 0 i32.const 0 i32.gt_s br_if 0 end ) )
For this demo, we have already run Wasabi on the program above, which results in an instrumented binary and a generated
In the editor below, you can enter a Wasabi analysis.
Once you click on “Run Program”, the WebAssembly program is run and outputs some numbers below.
(Note that your browser needs to support WebAssembly, we tested it with Chrome 61+ and Firefox 58+.)
By default, there is no analysis, so the only output is from the program itself. Click on the links below the editor for small example analyses or have a look into the Wasabi repository.
Program and Analysis Output (via
For now, please refer to the README in the repository.
For more details, you can:
- Read our technical report. It gives a high-level overview of the approach and explains some of the unique challenges when instrumenting WebAssembly. The paper focuses more on the concepts than the implementation.
- Inspect the source code.
This is the definitive source of how everything works in practice.
High-level documentation is scarce, but comments exist.
We are happy to take pull requests, the shorter the better!
- Contact Daniel Lehmann via e-mail.