Skip to content

Demo: Creating a new analysis specification in Vandal

Lexi Brent edited this page Nov 28, 2018 · 6 revisions

Contents


Datalog Specification

As a simple example, suppose we wanted to write an analysis that lists all static addresses used in CALL instructions in the contract. Let's begin with the following empty template that simply imports Vandal's core static analysis library:

#include "lib/vandal.dl"

We need to declare a new output relation for our analysis. Since we are interested in just the constant address values, we declare a new output relation with a single field of type Value. (The available types are defined in datalog/lib/types.dl and documented in the Vandal technical report.)

#include "lib/vandal.dl"

.decl StaticCallAddresses(staticAddr: Value)
.output StaticCallAddresses

Now we need to write the corresponding logic used to generate the values in this relation. We are interested in statements that:

  1. Execute EVM's CALL opcode; and
  2. Have a known constant value for the second position argument (which is the callee's address).

Hence, we can add the following rule:

#include "lib/vandal.dl"

.decl StaticCallAddresses(staticAddrValue: Value)
.output StaticCallAddresses

StaticCallAddresses(staticAddrValue) :-
  op(callStmt, "CALL"),
  use(addrVar, callStmt, 2),
  value(addrVar, staticAddrValue).

Each respective line of this rule says that:

  1. There exists some statement callStmt that performs an EVM CALL operation.
  2. Some variable addrVar is passed as the 2nd positional argument to the operation in our callStmt.
  3. The addrVar variable has a known, constant value staticAddrValue.

Relations op, use, and value are produced by the Vandal decompiler. The Vandal static analysis library also pre-defines many useful relations; these are documented on this wiki page.

This single rule encapsulates our entire analysis. If we wanted to gather additional information in future, we could add more output relations or add additional fields to the existing relation.

Analyses should be saved in the datalog/ directory.


Executing the Analysis

First, ensure that the new analysis is saved in the datalog/ directory with a .dl extension. In this example, we assume that it is saved as datalog/const_call_addresses.dl. Here's how the analysis can be executed, assuming that the current working directory is the root of the vandal repository:

$ mkdir output

$ cd output

$ ../bin/analyze.sh ../examples/const_call.hex ../datalog/const_call_addresses.dl
+++ dirname ../bin/analyze.sh
++ cd ../bin
++ pwd
+ DIR=/home/user/blockchain/vandal/bin
+ rm -rf facts-tmp
+ /home/user/blockchain/vandal/bin/decompile -o CALL JUMPI SSTORE SLOAD MLOAD MSTORE -d -n -t facts-tmp ../examples/const_call.hex
+ souffle -F facts-tmp ../datalog/const_call_addresses.dl
+ rm -rf facts-tmp

$ ls -l
total 4
-rw-rw-r-- 1 user user 42 Nov 28 11:52 StaticCallAddresses.csv

$ cat StaticCallAddresses.csv
0x9ae9886c971279e771030ad5da37f227fb1e7f9

Hence, we see that for the example contract examples/const_call.hex, there is a CALL made to the constant address 0x9ae9886c971279e771030ad5da37f227fb1e7f9.