SafeDispatch is a series of LLVM passes for C++ vtable protection. It checks the target address of every indirect call in advance to ensure the address is legitimate. SafeDispatch NDSS '14 Paper
This repository implements class pointer protection (ValidM Table) of SafeDispatch in an ad-hoc manner.
This implementation includes two ASTVistitors based on Clang LibTooling and one pass on LLVM IR. I believe all comments in the code are easy to read and understand.
The code is tested on LLVM version 9.0 with clang & clang-tools-extra.
$ cd docker
$ docker build -t ubuntu:safedispatch .
$ docker run -it ubuntu:safedispatch /bin/bash
- Download the LLVM project source code from [llvm-project 9.0 Source Code Release].
$ wget https://github.com/llvm/llvm-project/archive/llvmorg-9.0.0.zip
- Build LLVM with clang and clang-tools-extra (choose one between Unix Make and Ninja)
$ unzip llvmorg-9.0.0.zip $ cd llvm-project-llvmorg-9.0.0 $ mkdir build $ cd build # Using Unix Make $ cmake -G 'Unix Makefiles' -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" ../llvm $ make -jN # Using Ninja $ cmake -G 'Ninja' -DLLVM_ENABLE_PROJECTS="clang;clang-tools-extra" ../llvm $ ninja
- Install binaries
$ sudo make install $ export PATH="{PATH-TO-LLVM-PROJECT}/build/bin:$PATH"
- Download project
git clone https://github.com/kongxiao0532/safedispatch-reproduce cd safedispatch-reproduce
- Configure LLVM path in
./Makefile
LLVM_SRC_PATH := {PATH-TO-LLVM-PROJECT}
An all-in-one script ./run.sh
is provided for building the project and using it to compile a C++ program, so that no extra operations are needed. The C++ program is delared as a argument passed to run.sh
.
$ ./run.sh [xxx.cpp]
The default program is ./build/classtest.cpp
which contains a five-class hierachy. The standard output of ./build/classtest.cpp
will be as follows.
$ ./run.sh
Target: ./cpptest/classtest.cpp
[run.sh]: Building target: ./cpptest/classtest.cpp ...
(LLVM&Clang compilation output)
[run.sh]: Building source code... ['file not found' errors are normal for Clang Tooling]
(Clang Tooling output)
[run.sh]: Running ./cpptest/classtest.cpp :
m1 with no arguments in A
m1 with int argument in A
m2 in A
m3 in A
foo in A
m1 with no arguments in B
m1 with int argument in B
m2 in A
m3 in A
foo in B
m1 in C
m1 with int argument in A
m2 in A
m3 in A
foo in A
m1 in C
m1 with int argument in A
m2 in D
m3 in A
foo in A
m1 in C
m1 with int argument in A
m2 in A
m3 in E
foo in A
m1 with no arguments in B
m1 with int argument in B
m2 in A
m3 in A
foo in B
m1 in C
m2 in A
m3 in A
foo in A
m1 in C
m2 in D
m3 in A
foo in A
m1 in C
m2 in A
m3 in E
foo in A
m1 in C
m2 in D
m3 in A
foo in A
m1 in C
m2 in A
m3 in E
foo in A
make
The binary file of the Clang tool is ./build/CHAToooling
.
The binary file of the LLVM pass is ./build/CHAToooling
.
Modify code in
./common.h
#define VALIDM_WITH_PARAMS true // enable advanced ValidM #define VALIDM_WITH_PARAMS false // disable advanced ValidMModify code in
./common.h
#define CUSTOM_DEBUG 0 // enable debug output // #define CUSTOM_DEBUG 0 // disable debug output
- Clang LibTooling for class hierachy analysis and instrumentation
./build/CHATooling {source_code}
- LLVM pass for a complete instrumentation
opt -load build/SafeDispatchIns.so -SafeDispatchIns {input_bitcode} > {output_bitcode}