diff options
author | van Hauser <vh@thc.org> | 2018-03-01 13:20:26 +0100 |
---|---|---|
committer | van Hauser <vh@thc.org> | 2018-03-01 13:20:26 +0100 |
commit | 7867e610b5cffd2c0749703eca1333bdd7840824 (patch) | |
tree | bff82df29777761e5eb5a19dfeb4e10357fb91e9 | |
parent | 004d0b084fa51dbf10da19d83859c0500f57dfbd (diff) | |
download | afl-dyninst-7867e610b5cffd2c0749703eca1333bdd7840824.tar.gz |
added -S switch, make install, updated README
-rw-r--r-- | CHANGES | 5 | ||||
-rw-r--r-- | Makefile | 9 | ||||
-rw-r--r-- | README.txt | 25 | ||||
-rw-r--r-- | afl-dyninst.cpp | 14 | ||||
-rw-r--r-- | libAflDyninst.cpp | 2 |
5 files changed, 46 insertions, 9 deletions
diff --git a/CHANGES b/CHANGES index 550a845..8bba0a3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,7 +1,10 @@ Changelog ========= -vh@thc.org / https://github.com/vanhauser-thc/afl-dyninst: +https://github.com/vanhauser-thc/afl-dyninst + - added -S switch to skip instrumenting a specific function + - added make install target + - updated README - Fix for programs that were unable to print to stdout after instrumentation - added -f switch to fix a bug in dyninst where sometimes the edi/rdi register is not saved which is used in the instrumentation function diff --git a/Makefile b/Makefile index 9685c96..25ef545 100644 --- a/Makefile +++ b/Makefile @@ -7,6 +7,9 @@ AFL_ROOT = ./afl # path to libelf and libdwarf DEPS_ROOT = /usr/local +# where to install +INSTALL_ROOT = /usr/local + CXX = g++ CXXFLAGS = -g -Wall -O3 -std=c++11 LIBFLAGS = -fpic -shared @@ -33,3 +36,9 @@ afl-dyninst.o: afl-dyninst.cpp clean: rm -f afl-dyninst *.so *.o + +install: all + install -d $(INSTALL_ROOT)/bin + install -d $(INSTALL_ROOT)/lib + install afl-dyninst $(INSTALL_ROOT)/bin + install libAflDyninst.so $(INSTALL_ROOT)/lib diff --git a/README.txt b/README.txt index adecc8b..b8a4b07 100644 --- a/README.txt +++ b/README.txt @@ -8,6 +8,10 @@ Instrumentation tool (afl-dyninst) instruments the supplied binary by inserting callbacks for each basic block and an initialization callback either at _init or at specified entry point. + +Commandline options +------------------- + Usage: ./afl-dyninst -i <binary> -o <binary> -l <library> -e <address> -s <number> -i: Input binary -o: Output binary @@ -17,6 +21,7 @@ Usage: ./afl-dyninst -i <binary> -o <binary> -l <library> -e <address> -s <numbe -s: Number of basic blocks to skip -m: minimum size of a basic bock to instrument (default: 1) -f: fix dyninst bug to sometimes not save edi/rdi register + -S: do not instrument this function (can be specified only once) -v: Verbose output Switch -l is used to supply the names of the libraries that should @@ -53,15 +58,20 @@ uses the edi/rdi. However dyninst does not always saves and restores it when instrumenting that function leading to crashes and changed program behaviour when the register is used for function parameters. -The instrumentation library "libDyninst.so" must be available in the current working -directory as that is where the instrumented binary will be looking for it. +Switch -S allows you to not instrument a specific function. +This options is mainly to hunt down bugs in dyninst. It can only be set once. + Compiling: +---------- 1. Edit the Makefile and set DYNINST_ROOT and AFL_ROOT to appropriate paths. 2. make +3. make install + -Example of running the tool: +Example of running the tool +--------------------------- Dyninst requires DYNINSTAPI_RT_LIB environment variable to point to the location of libdyninstAPI_RT.so. @@ -78,7 +88,12 @@ Here we are instrumenting the rar binary with entrypoint at 0x4034c0 (manualy found address of main), skipping the first 100 basic blocks and outputing to rar_ins. + Running AFL on instrumented binary +---------------------------------- + +NOTE: The instrumentation library "libDyninst.so" must be available in the current working +directory or LD_LIBRARY_PATH as that is where the instrumented binary will be looking for it. Since AFL checks if the binary has been instrumented by afl-gcc,AFL_SKIP_BIN_CHECK environment variable needs to be set. No modifications to AFL it self is needed. @@ -86,5 +101,5 @@ $ export AFL_SKIP_BIN_CHECK=1 Then, AFL can be run as usual: $ afl-fuzz -i testcases/archives/common/gzip/ -o test_gzip -- ./gzip_ins -d -c - - +Note that there are the helper scripts afl-fuzz.sh and afl-dyninst.sh for you which set the +required environment variables for you. diff --git a/afl-dyninst.cpp b/afl-dyninst.cpp index 787fb18..2f12fc1 100644 --- a/afl-dyninst.cpp +++ b/afl-dyninst.cpp @@ -30,13 +30,14 @@ set < string > runtimeLibraries; int bbSkip = 0, dynfix = 0; unsigned int bbMinSize = 1; bool skipMainModule = false; +char *skipFunc = NULL; BPatch_function *save_rdi; BPatch_function *restore_rdi; const char *instLibrary = "libAflDyninst.so"; -static const char *OPT_STR = "fi:o:l:e:vs:dr:m:"; +static const char *OPT_STR = "fi:o:l:e:vs:dr:m:S:"; static const char *USAGE = " -i <binary> -o <binary> -l <library> -e <address> -s <number> -m <size>\n \ -i: Input binary \n \ -o: Output binary\n \ @@ -47,6 +48,7 @@ static const char *USAGE = " -i <binary> -o <binary> -l <library> -e <address> - -s: Number of basic blocks to skip\n \ -m: minimum size of a basic bock to instrument (default: 1)\n \ -f: try to fix crashes\n \ + -S: do not instrument this function (can be specified only once)\n \ -v: Verbose output\n"; bool parseOptions(int argc, char **argv) { @@ -54,6 +56,9 @@ bool parseOptions(int argc, char **argv) { while ((c = getopt(argc, argv, OPT_STR)) != -1) { switch ((char) c) { + case 'S': + skipFunc = optarg; + break; case 'e': entryPoint = strtoul(optarg, NULL, 16);; break; @@ -181,7 +186,7 @@ bool insertBBCallback(BPatch_binaryEdit *appBin, BPatch_function *curFunc, char randID = rand() % USHRT_MAX; if (verbose) { - cout << "Instrumenting Basic Block 0x" << hex << address << " of " << funcName << " of size " << dec << (*iter)->size() << " with random id " << randID << endl; + cout << "Instrumenting Basic Block 0x" << hex << address << " of " << funcName << " with size " << dec << (*iter)->size() << " with random id " << randID << "/0x" << hex << randID << endl; } BPatch_Vector < BPatch_snippet * >instArgs1; @@ -322,6 +327,11 @@ int main(int argc, char **argv) { curFunc->getName(funcName, 1024); if (string(funcName) == string("_start")) continue; // here's a bug on hlt // XXX: check what happens if removed + if (skipFunc != NULL && strcmp(skipFunc, funcName) == 0) { + if (verbose) + cout << "Skipping instrumenting function " << funcName << endl; + continue; + } insertBBCallback(appBin, curFunc, funcName, bbCallback, &bbIndex); } } diff --git a/libAflDyninst.cpp b/libAflDyninst.cpp index 3374010..51fa41d 100644 --- a/libAflDyninst.cpp +++ b/libAflDyninst.cpp @@ -20,7 +20,7 @@ static int __afl_temp_data; static pid_t __afl_fork_pid; static unsigned short prev_id; static long saved_di; -register long rdi asm("di"); // the warning is fine - we need the warning because of a bug in dyninst +register long rdi asm("di"); // the warning is fine - we need the warning because of a bug in dyninst #define PRINT_ERROR(string) write(2, string, strlen(string)) |