Need help with DrSancov?
Click the “chat” button below for chat support from the developer who created it, or find similar developers for support.

About the developer

149 Stars 27 Forks Apache License 2.0 1 Commits 0 Opened issues


DynamoRIO plugin to get ASAN and SanitizerCoverage compatible output for closed-source executables

Services available


Need anything else?

Contributors list


DrSancov is a small DBI module based on DynamoRIO, which aims to combine the basic functionality of AddressSanitizer and SanitizerCoverage, while being similar to DrCov (hence the name). In other words, it mimics the behavior of the two compiler instrumentations, by printing out ASAN-like reports upon SIGSEGV and similar program crashes, and saving code coverage information to

files compatible with those generated by SanitizerCoverage. The purpose of the tool is to make it easier to test closed-source software using existing fuzzing pipelines which expect the target to be compiled with ASAN/SanitizerCoverage. It works with x86 and x86-64 applications.

Please note that the project does not improve memory error detection; it only produces ASAN compatible reports for conditions that would result in a hard crash anyway. For better sanitization of heap memory accesses in compiled binaries, check e.g. AFL's libdislocator.

The code coverage information is collected with a basic block granularity.


A Makefile for GNU/Linux is provided, and the end result is a
library. The Makefile assumes that DynamoRIO resides in a
directory relative to itself, for example:
|-- code
|   |--
|   |-- common.h
|   |--
|   |-- Makefile
|   |--
|   `-- tokenizer.h
|-- dynamorio
|   |-- bin32
|   |   |-- drconfig
|   |   |-- drconfig.debug

Then, compilation should run smoothly as follows:

$ cd code
$ make
clang++ -c -o drsancov.o -O2 -fPIC -I../dynamorio/include -I../dynamorio/ext/include -DX86_64 -DLINUX -fno-stack-protector
clang++ -c -o common.o -O2 -fPIC -I../dynamorio/include -I../dynamorio/ext/include -DX86_64 -DLINUX -fno-stack-protector
clang++ -c -o tokenizer.o -O2 -fPIC -I../dynamorio/include -I../dynamorio/ext/include -DX86_64 -DLINUX -fno-stack-protector
clang++ -shared -o drsancov.o common.o tokenizer.o -Wl,-hash-style=both ../dynamorio/lib64/debug/ ../dynamorio/ext/lib64/debug/ ../dynamorio/ext/lib64/debug/


In order to use DrSancov, prepend the usual target command line with

drrun -c --
, which will run the program under our instrumentation. Let's consider the following program:
$ cat -n tests/
     1  #include 
     2  #include 
     4  int main(int argc, char **argv) {
     5    if (argc >= 2 && argv[1][0] == 'F' && argv[1][1] == 'U' && argv[1][2] == 'Z' && argv[1][3] == 'Z') {
     6      int *x = (int *)0x12345678;
     7      *x = 0x41414141;
     8    }
    10    return 0;
    11  }
$ g++ tests/ -o tests/test

For argument "FUZZ", we'd typically see a standard "Segmentation fault" message:

$ tests/test FUZZ
Segmentation fault

With DrSancov enabled, we get a familiar report:

$ dynamorio/bin64/drrun -c code/ -- tests/test FUZZ
==7548==ERROR: AddressSanitizer: SEGV on unknown address 0x12345678 (pc 0x7f114701a196 sp 0x7ffe0837a830 bp 0x7ffe0837a830 T0)
    #0 0x7f114701a196 in test+1196

==7548==CONTEXT rax=0000000012345678 rbx=0000000000000000 rcx=0000000000000080 rdx=00007ffe0837a930 rsi=00007ffe0837a918 rdi=0000000000000002 rsp=00007ffe0837a830 rbp=00007ffe0837a830 r8=00007f1149d8ad80 r9=0000000000000000 r10=00007f114701f010 r11=0000000000000000 r12=00007f114701a040 r13=00007ffe0837a910 r14=0000000000000000 r15=0000000000000000 rip=00007f1137b63a18 rflags=0000000000010246 Accessed address: 0x12345678 Faulting code: 0x00007f1137b63a18 mov dword ptr [rax], 0x41414141

==7548==ABORTING $

In addition to the somewhat standarized ASAN header, there is also extra information printed out in the "context" section.

Similarly to ASAN, DrSancov can be controlled with the

environment variable. The currently supported switches are
. Let's try to obtain some code coverage for two inputs:
$ ASAN_OPTIONS=coverage=1 dynamorio/bin64/drrun -c code/ -- tests/test FU
DrSanitizerCoverage: ./test.20345.sancov: 25 PCs written
$ ASAN_OPTIONS=coverage=1 dynamorio/bin64/drrun -c code/ -- tests/test FUZ
DrSanitizerCoverage: ./test.20361.sancov: 26 PCs written
$ xxd -e -g8 -c8 test.20345.sancov | awk '{print $2}' >cov1
$ xxd -e -g8 -c8 test.20361.sancov | awk '{print $2}' >cov2
$ diff cov1 cov2
> 0000000000001174

Here, we can see that the difference in coverage between "FU" and "FUZ" is a single basic block at offset 0x1174, which turns out to be the verification of the final letter of the parameter:

$ objdump -d tests/test
    1174:       48 8b 45 e0             mov    -0x20(%rbp),%rax
    1178:       48 83 c0 08             add    $0x8,%rax
    117c:       48 8b 00                mov    (%rax),%rax
    117f:       48 83 c0 03             add    $0x3,%rax
    1183:       0f b6 00                movzbl (%rax),%eax
    1186:       3c 5a                   cmp    $0x5a,%al
    1188:       75 12                   jne    119c 

This demonstrates basic output compatibility between the DBI and the Sanitizer-family instrumentations.

We use cookies. If you continue to browse the site, you agree to the use of cookies. For more information on our use of cookies please see our Privacy Policy.