-
Notifications
You must be signed in to change notification settings - Fork 40
Demo: Creating a new analysis specification in Vandal
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:
- Execute EVM's
CALL
opcode; and - 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:
- There exists some statement
callStmt
that performs an EVMCALL
operation. - Some variable
addrVar
is passed as the 2nd positional argument to the operation in ourcallStmt
. - The
addrVar
variable has a known, constant valuestaticAddrValue
.
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.
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
.