diff options
Diffstat (limited to 'README.md')
-rw-r--r-- | README.md | 135 |
1 files changed, 42 insertions, 93 deletions
diff --git a/README.md b/README.md index 6caac73..2119d58 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ -# American Fuzzy Lop + Dyninst == AFL Fuzzing blackbox binaries +# AFL Dyninst + +AFL Dyninst uses Dyninst to insert AFL instrumentations into binaries +for binary fuzzing. The tool has two parts. The instrumentation tool and the instrumentation library. Instrumentation library has an initialization callback and basic @@ -6,68 +9,24 @@ block callback functions which are designed to emulate what AFL is doing with afl-gcc/afl-g++/afl-as. 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. - -You can pull a docker image from hub (last push February 2021): -``` -docker pull vanhauser/afl-dyninst -``` - -## Building / Compiling - -### docker - -simply run -``` -docker build -t afl-dyninst . -``` -which will take ~25 minutes. -Afterwards you have a containers with afl-dyninst and afl++: -``` -docker run -ti afl-dyninst -``` - -### on your own - -1. Clone, compile and install dyninst: [https://github.com/dyninst/dyninst](https://github.com/dyninst/dyninst) - -Note that you could also use dyninst 9.3.2, but has less platform support and -quite a few bugs. For using dyninst 9.x you have to edit the Makefile -Using at least 10.1.0 is highly recommended! - -2. Download and install afl++ from [https://github.com/vanhauser-thc/AFLplusplus](https://github.com/vanhauser-thc/AFLplusplus) -It's an up to date and enhanced version to the original afl with better -performance, new features and bugfixes. - -3. Edit the Makefile and set DYNINST_ROOT and AFL_ROOT to appropriate paths. - -4. make +inserting callbacks for each basic block and an initialization +callback either at `_init` or at specified entry point. -5. sudo make install +## Installation +As its name suggest, AFL Dyninst requires [AFL++] 4.22 or above +and [Dyninst] 10 or above at running time. To build afl-dyninst, +you also need make(1p), m4(1p) and a C++11 compiler. -### Building dyninst 10 - -Building dyninst10 can be a pain. -If you are not on debian-testing or kali-rolling, I recommend the following steps: -1. remove elfutils if installed as a distribution package -2. install libboost-all-dev for your distribution -3. execute (depending where your libboost is installed, for me its /usr/lib/x86_64-linux-gnu): -```shell -cd /usr/lib/x86_64-linux-gnu && for i in libboost*.so libboost*.a; do - n=`echo $i|sed 's/\./-mt./'` - ln -s $i $n 2> /dev/null -done -``` -4. git clone https://github.com/dyninst/dyninst ; mkdir build ; cd build ; cmake .. ; make ; make install -If dyninst complains about any missing packages - install them. -Depending on the age of your Linux OS you can try to use packages from your distro, and install from source otherwise. +Since `afl-dyninst` does not relink the output binary, +path to Dyninst library needs to be passed to the build tools +to be injected into wrapper scripts: + make DYNINST_LIB=$dyninst_prefix/lib PREFIX=$afl_dyninst_prefix install ## Commandline options ``` -Usage: afl-dyninst -dfvxD -i binary -o binary -l library -e address -E address -s number -S funcname -I funcname -m size +Usage: afl-dyninst -vxD -i binary -o binary -e address -E address -s number -S funcname -I funcname -m size -i: input binary program -o: output binary program -r: runtime library to instrument (path to, repeat for more than one) @@ -75,21 +34,19 @@ Usage: afl-dyninst -dfvxD -i binary -o binary -l library -e address -E address -E: exit point - force exit(0) at this address (repeat for more than one) -s: number of initial basic blocks to skip in binary -m: minimum size of a basic bock to instrument (default: 10) - -f: try to fix a dyninst bug that leads to crashes (loss of 20%% performance, only required for dyninst9) -I: only instrument this function and nothing else (repeat for more than one) -S: do not instrument this function (repeat for more than one) -D: instrument only a simple fork server and also forced exit functions -x: experimental performance mode (~25-50% speed improvement) -v: verbose output - Note: options -l and -d have been deprecated, use -r and -D instead. ``` Switch -e is used to manualy specify the entry point where initialization callback is to be inserted. For unstipped binaries, afl-dyninst defaults -to using _init of the binary as an entry point. In case of stripped binaries +to using `_init` of the binary as an entry point. In case of stripped binaries this option is required and is best set to the address of main which can easily be determined by disassembling the binary and looking for an -argument to __libc_start_main. +argument to `__libc_start_main`. Switch -E is used to specify addresses that should force a clean exit when reached. This can speed up the fuzzing tremendously. @@ -109,12 +66,6 @@ instrumented ones to original name. Switch -m allows you to only instrument basic blocks of a minimum size - the default minimum size is 1 -Switch -f fixes a dyninst bug that lead to bugs in the instrumented program: -our basic block instrumentation function loaded into the instrumentd binaries -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. - Switch -S allows you to not instrument specific functions. This options is mainly to hunt down bugs in dyninst. Can be specified multiple times. @@ -126,27 +77,18 @@ Can be specified multiple times. Switch -D installs the afl fork server and forced exit functions but no basic block instrumentation. That would serve no purpose - unless there are other tools that need that: - * [https://github.com/vanhauser-thc/afl-dynamorio](https://github.com/vanhauser-thc/afl-dynamorio) - * [https://github.com/vanhauser-thc/afl-pin](https://github.com/vanhauser-thc/afl-pin) +* [afl-dynamorio] +* [afl-pin] Switch -x enables an experimental performance mode (+25-50% speed). Just try it and if the target crashes too often, instrument again without this. Should not crash though. -Note that the -l option has been deprecated, use -r instead. - -Note that the -d option has been deprecated, use -D instead (or ignore the -o output file). - - ## Example of instrumenting a target binary -Dyninst requires DYNINSTAPI_RT_LIB environment variable to point to the location -of libdyninstAPI_RT.so. - ``` -$ export DYNINSTAPI_RT_LIB=/usr/local/lib/libdyninstAPI_RT.so $ ./afl-dyninst -i ./unrar -o ./rar_ins -e 0x4034c0 -x -Skipping library: libAflDyninst.so +Skipping library: libafldyninst.so Instrumenting module: DEFAULT_MODULE Inserting init callback. Saving the instrumented binary to ./unrar_ins... @@ -155,14 +97,7 @@ All done! Happy fuzzing! Here we are instrumenting the rar binary with entrypoint at 0x4034c0 (manually found address of main), skipping the first 10 basic blocks -and outputing to unrar_ins - -You can also use the afl-dyninst.sh helper script which sets the required -environment variables for you: -``` -$ ./afl-dyninst.sh -i ./unrar -o ./rar_ins -e 0x4034c0 -x -``` - +and outputing to `unrar_ins`. ## Running AFL on the instrumented binary @@ -180,11 +115,10 @@ Then, AFL can be run as usual: $ afl-fuzz -i testcases/archives/common/gzip/ -o test_gzip -- ./gzip_ins -d -c ``` -You can also use the afl-fuzz-dyninst.sh helper script which sets the required -environment variables for you. -``` -$ afl-fuzz-dyninst.sh -i testcases/archives/common/gzip/ -o test_gzip -- ./gzip_ins -d -c -``` +You can also use the afl-dyninst-env helper script +which sets the required environment variables for you. + + afl-dyninst-env afl-fuzz -i testcases/archives/common/gzip/ -o test_gzip -- ./gzip_ins -d -c ## Problems @@ -206,6 +140,21 @@ Solution: This happens if the target is using throw/catch, and dyninst's modification result in that the caught exception is not resetted and hence abort() is triggered. No solution to this issue is known yet. - Binary editing the target binary to perform _exit(0) would help though. + Binary editing the target binary + to perform `_exit(0)` would help though. + +## Copying + +AFL Dyninst is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +AFL Dyninst was originally developed as part of a project +with the Cisco Talos VULNDEV Team and released under the Apache License, +version 2.0. -More problems? Create an issue at [https://github.com/vanhauser-thc/afl-dyninst](https://github.com/vanhauser-thc/afl-dyninst) +[AFL++]: https://github.com/AFLplusplus/AFLplusplus +[Dyninst]: https://github.com/dyninst/dyninst +[afl-dynamorio]: https://github.com/vanhauser-thc/afl-dynamorio +[afl-pin]: https://github.com/vanhauser-thc/afl-pin |