Compare commits

...

30 Commits
2.61c ... 2.62c

Author SHA1 Message Date
713952b9c7 v2.62c 2020-02-28 01:13:28 +01:00
20b8fc075b v2.62c 2020-02-28 01:12:44 +01:00
fc77f0bb96 i am too tired :-( 2020-02-28 01:02:21 +01:00
2eb7d0d88c update ideas 2020-02-28 00:55:44 +01:00
41493b1e3f cmplog_shm shmat was missing result check 2020-02-28 00:41:56 +01:00
f526bb2ecb better alloc-inl.h 2020-02-28 00:35:59 +01:00
4e37e12c06 code-format 2020-02-28 00:19:36 +01:00
d83ab141f6 cpyright 2020-02-27 23:22:29 +01:00
11236dd545 restore alloc-inl from AFL 2020-02-27 21:11:45 +01:00
bf8a154bec perf-fuzz idea 2020-02-27 20:58:30 +01:00
2b9ecd6eec Merge branch 'master' of github.com:vanhauser-thc/AFLplusplus 2020-02-27 16:04:20 +01:00
3712a70115 bye bye SanCov for CmpLog 2020-02-27 16:04:07 +01:00
e4f01a6825 Merge pull request #213 from Kusoku/master
Fix hanging fork and child with -V -E
2020-02-27 10:52:57 +01:00
3549cbb3a2 Fix hanging fork and child with -V -E
If we let multiple fuzzers end with -V or -E option, it will cause it to think we are still occupying the cores, even if they are free, once we try to run another job it would return an error that no free nodes are available.

This change fixes that problem.
2020-02-27 00:09:26 +01:00
7c17697cae catch if shmat fails 2020-02-26 22:35:09 +01:00
0e1d306b2e beautifying man pages 2020-02-25 21:58:17 +01:00
70c208ead7 Merge branch 'master' of https://github.com/vanhauser-thc/AFLplusplus 2020-02-25 21:42:30 +01:00
2d25662b81 man page tuning 2020-02-25 21:41:31 +01:00
e12edca29a Merge branch 'master' of github.com:vanhauser-thc/AFLplusplus 2020-02-25 21:24:43 +01:00
7e0663e4e0 fix #212 2020-02-25 21:24:31 +01:00
4bd736e1a7 more env info for afl-plot and afl-analyze 2020-02-25 20:54:08 +01:00
d39830a4dc portability: replace GNU extension of date (-I) with posix "+%y-%m-%d" 2020-02-25 20:31:08 +01:00
d7c9f947ed disable arm64 travis because they are buggy 2020-02-25 17:49:39 +01:00
84426631b4 update docker info 2020-02-25 16:30:22 +01:00
2c9c2e139e afl-gcc change -> test.sh 2020-02-25 14:01:55 +01:00
a540bae7a9 left over README reference fix 2020-02-25 08:43:49 +01:00
891b568678 fix references to README docs 2020-02-25 08:34:44 +01:00
901360b902 sync afl-as setup with afl-llvm-rt (add __afl_area_ptr[0] = 1) 2020-02-24 23:19:56 +01:00
c8295e1485 add env info to afl-tmin 2020-02-24 22:23:51 +01:00
9cc8ebd351 2.61d init 2020-02-24 17:26:02 +01:00
44 changed files with 1215 additions and 160 deletions

View File

@ -17,10 +17,10 @@ matrix:
- os: linux
dist: trusty
env: NAME="trusty-amd64" MODERN="no" GCC="4.8"
- os: linux
dist: xenial
arch: arm64
env: NAME="xenial-arm64" MODERN="no" GCC="5" EXTRA="libtool-bin clang-6.0" AFL_NO_X86="1" CPU_TARGET="aarch64"
# - os: linux # until travis can fix this!
# dist: xenial
# arch: arm64
# env: NAME="xenial-arm64" MODERN="no" GCC="5" EXTRA="libtool-bin clang-6.0" AFL_NO_X86="1" CPU_TARGET="aarch64"
# - os: osx
# osx_image: xcode11.2
# env: NAME="osx" HOMEBREW_NO_ANALYTICS="1" LINK="http://releases.llvm.org/9.0.0/" NAME="clang+llvm-9.0.0-x86_64-darwin-apple"

View File

@ -103,9 +103,9 @@ ifneq "$(shell which python)" ""
endif
ifdef SOURCE_DATE_EPOCH
BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" -I 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" -I 2>/dev/null || date -u -I)
BUILD_DATE ?= $(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u -r "$(SOURCE_DATE_EPOCH)" "+%Y-%m-%d" 2>/dev/null || date -u "+%Y-%m-%d")
else
BUILD_DATE ?= $(shell date -I)
BUILD_DATE ?= $(shell date "+%Y-%m-%d")
endif
ifneq "$(filter Linux GNU%,$(shell uname))" ""
@ -344,7 +344,7 @@ endif
all_done: test_build
@if [ ! "`which clang 2>/dev/null`" = "" ]; then echo "[+] LLVM users: see llvm_mode/README.llvm for a faster alternative to afl-gcc."; fi
@if [ ! "`which clang 2>/dev/null`" = "" ]; then echo "[+] LLVM users: see llvm_mode/README.md for a faster alternative to afl-gcc."; fi
@echo "[+] All done! Be sure to review the README.md - it's pretty short and useful."
@if [ "`uname`" = "Darwin" ]; then printf "\nWARNING: Fuzzing on MacOS X is slow because of the unusually high overhead of\nfork() on this OS. Consider using Linux or *BSD. You can also use VirtualBox\n(virtualbox.org) to put AFL inside a Linux or *BSD VM.\n\n"; fi
@! tty <&1 >/dev/null || printf "\033[0;30mNOTE: If you can read this, your terminal probably uses white background.\nThis will make the UI hard to read. See docs/status_screen.md for advice.\033[0m\n" 2>/dev/null

View File

@ -4,9 +4,9 @@
![Travis State](https://api.travis-ci.com/vanhauser-thc/AFLplusplus.svg?branch=master)
Release Version: 2.61c
Release Version: 2.62c
Github Version: 2.61d
Github Version: 2.62d
includes all necessary/interesting changes from Google's afl 2.56b
@ -14,8 +14,11 @@
Repository: [https://github.com/vanhauser-thc/AFLplusplus](https://github.com/vanhauser-thc/AFLplusplus)
afl++ is maintained by Marc "van Hauser" Heuse <mh@mh-sec.de>,
Heiko "hexcoder-" Eißfeldt <heiko.eissfeldt@hexco.de>, Andrea Fioraldi <andreafioraldi@gmail.com> and Dominik Maier <mail@dmnk.co>.
afl++ is maintained by:
* Marc "van Hauser" Heuse <mh@mh-sec.de>,
* Heiko "hexcoder-" Eißfeldt <heiko.eissfeldt@hexco.de>,
* Andrea Fioraldi <andreafioraldi@gmail.com> and
* Dominik Maier <mail@dmnk.co>.
Note that although afl now has a Google afl repository [https://github.com/Google/afl](https://github.com/Google/afl),
it is unlikely to receive any noteable enhancements: [https://twitter.com/Dor3s/status/1154737061787660288](https://twitter.com/Dor3s/status/1154737061787660288)
@ -156,7 +159,8 @@ Hence gcc-9 and especially llvm-9 should be the compilers of choice.
If your distribution does not have them, you can use the Dockerfile:
```shell
$ docker build -t aflplusplus
$ cd AFLplusplus
$ sudo docker build -t aflplusplus .
```
@ -701,7 +705,7 @@ without feedback, bug reports, or patches from:
Nathan Voss Dominik Maier
Andrea Biondo Vincent Le Garrec
Khaled Yakdan Kuang-che Wu
Josephine Calliotte
Josephine Calliotte Konrad Welc
```
Thank you!

View File

@ -94,15 +94,13 @@ function getopt(argc, argv, options, thisopt, i)
function usage() {
print \
"Usage: afl-cmin [ options ] -- /path/to/target_app [ ... ]\n" \
"afl-cmin [ options ] -- /path/to/target_app [ ... ]\n" \
"\n" \
"Required parameters:\n" \
"\n" \
" -i dir - input directory with starting corpus\n" \
" -o dir - output directory for minimized files\n" \
"\n" \
"Execution control settings:\n" \
"\n" \
" -f file - location read by the fuzzed program (stdin)\n" \
" -m megs - memory limit for child process ("mem_limit" MB)\n" \
" -t msec - run time limit for child process (none)\n" \
@ -116,11 +114,10 @@ function usage() {
"For additional tips, please consult docs/README.md\n" \
"\n" \
"Environment variables used:\n" \
"AFL_KEEP_TRACES: leave the temporary <out_dir>\.traces directory\n" \
"AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \
"AFL_PATH: path for the afl-showmap binary\n" \
"AFL_SKIP_BIN_CHECK: skip check for target binary\n" \
"AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp\n" \
> "/dev/stderr"
"AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp\n"
exit 1
}

View File

@ -126,7 +126,7 @@ Minimization settings:
-C - keep crashing inputs, reject everything else
-e - solve for edge coverage only, ignore hit counts
For additional tips, please consult docs/README.
For additional tips, please consult docs/README.md.
Environment variables used:
AFL_KEEP_TRACES: leave the temporary <out_dir>\.traces directory

View File

@ -32,6 +32,8 @@ an empty directory where this tool can write the resulting plots to.
The program will put index.html and three PNG images in the output directory;
you should be able to view it with any web browser of your choice.
Environment variables used:
AFL_ALLOW_TMP: allow /var/tmp or /tmp for input and output directories
_EOF_
exit 1

View File

@ -18,12 +18,13 @@
# instances of afl-fuzz.
#
echo "status check tool for afl-fuzz by Michal Zalewski"
echo "$0 status check tool for afl-fuzz by Michal Zalewski"
echo
test "$1" = "-h" && {
echo $0
echo $0 [-s] output_directory
echo
echo afl-whatsup has no command line options
echo Options:
echo -s - skip details and output summary results only
echo
exit 1
}

View File

@ -1,7 +1,7 @@
# Changelog
This is the list of all noteworthy changes made in every public release of
the tool. See README for the general instruction manual.
the tool. See README.md for the general instruction manual.
## Staying informed
@ -9,6 +9,14 @@ Want to stay in the loop on major new features? Join our mailing list by
sending a mail to <afl-users+subscribe@googlegroups.com>.
### Version ++2.62c (release):
- Important fix for memory allocation functions that result in afl-fuzz
not identifying crashes - UPDATE!
- Small fix for -E/-V to release the CPU
- CmpLog does not need sancov anymore
### Version ++2.61c (release):
- use -march=native if available
@ -40,7 +48,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- now does not need to be recompiled between trace-pc and pass
instrumentation. compile normally and set AFL_LLVM_USE_TRACE_PC :)
- LLVM 11 is supported
- CmpLog instrumentation using SanCov (see llvm_mode/README.cmplog)
- CmpLog instrumentation using SanCov (see llvm_mode/README.cmplog.md)
- afl-gcc, afl-clang-fast, afl-gcc-fast:
- experimental support for undefined behaviour sanitizer UBSAN
(set AFL_USE_UBSAN=1)
@ -184,7 +192,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- fix llvm_mode AFL_TRACE_PC with modern llvm
- fix a crash in qemu_mode which also exists in stock afl
- added libcompcov, a laf-intel implementation for qemu! :)
see qemu_mode/libcompcov/README.libcompcov
see qemu_mode/libcompcov/README.libcompcov.md
- afl-fuzz now displays the selected core in the status screen (blue {#})
- updated afl-fuzz and afl-system-config for new scaling governor location
in modern kernels
@ -193,8 +201,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- if llvm_mode was compiled, afl-clang/afl-clang++ will point to these
instead of afl-gcc
- added instrim, a much faster llvm_mode instrumentation at the cost of
path discovery. See llvm_mode/README.instrim (https://github.com/csienslab/instrim)
- added MOpt (github.com/puppet-meteor/MOpt-AFL) mode, see docs/README.MOpt
path discovery. See llvm_mode/README.instrim.md (https://github.com/csienslab/instrim)
- added MOpt (github.com/puppet-meteor/MOpt-AFL) mode, see docs/README.MOpt.md
- added code to make it more portable to other platforms than Intel Linux
- added never zero counters for afl-gcc and optionally (because of an
optimization issue in llvm < 9) for llvm_mode (AFL_LLVM_NEVER_ZERO=1)
@ -224,11 +232,11 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
LLVM and Qemu modes are now faster.
Important changes:
afl-fuzz: -e EXTENSION commandline option
llvm_mode: LAF-intel performance (needs activation, see llvm/README.laf-intel)
a few new environment variables for afl-fuzz, llvm and qemu, see docs/env_variables.txt
llvm_mode: LAF-intel performance (needs activation, see llvm/README.laf-intel.md)
a few new environment variables for afl-fuzz, llvm and qemu, see docs/env_variables.md
- Added the power schedules of AFLfast by Marcel Boehme, but set the default
to the AFL schedule, not to the FAST schedule. So nothing changes unless
you use the new -p option :-) - see docs/power_schedules.txt
you use the new -p option :-) - see docs/power_schedules.md
- added afl-system-config script to set all system performance options for fuzzing
- llvm_mode works with llvm 3.9 up to including 8 !
- qemu_mode got upgraded from 2.1 to 3.1 - incorporated from
@ -471,7 +479,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- Added libtokencap, a simple feature to intercept strcmp / memcmp and
generate dictionary entries that can help extend coverage.
- Moved libdislocator to its own dir, added README.
- Moved libdislocator to its own dir, added README.md.
- The demo in examples/instrumented_cmp is no more.

View File

@ -27,7 +27,7 @@ how to hit the ground running:
4) Get a small but valid input file that makes sense to the program. When
fuzzing verbose syntax (SQL, HTTP, etc), create a dictionary as described in
dictionaries/README.dictionaries, too.
dictionaries/README.md, too.
5) If the program reads from stdin, run 'afl-fuzz' like so:

View File

@ -2,7 +2,7 @@
This document discusses the environment variables used by American Fuzzy Lop++
to expose various exotic functions that may be (rarely) useful for power
users or for some types of custom fuzzing setups. See README for the general
users or for some types of custom fuzzing setups. See README.md for the general
instruction manual.
## 1) Settings for afl-gcc, afl-clang, and afl-as - and gcc_plugin afl-gcc-fast

View File

@ -1,6 +1,7 @@
# Ideas for afl++
In the following, we describe a variety of ideas that could be implemented for further AFL++ versions.
In the following, we describe a variety of ideas that could be implemented
for future AFL++ versions.
## Flexible Grammar Mutator
@ -19,6 +20,8 @@ common issues of the academic code.
We aim to develop a pluggable grammar mutator for afl++ that combines
various results.
Mentor: andreafioraldi
## Expand on the MOpt mutator
Work on the MOpt mutator that is already in AFL++.
@ -32,6 +35,21 @@ on Redqueen, the Radamsa mutator, the Custom mutator (the user can define
its own mutator) and the work is to generalize MOpt for all the current
and future mutators.
Mentor: vanhauser-thc or andreafioraldi
## perf-fuzz Linux Kernel Module
Port the parts of the Linux Kernel modified by
[perf-fuzz](https://gts3.org/assets/papers/2017/xu:os-fuzz.pdf)
into a linux kernel module, so no source in the kernel needs to be changed.
Or write your worn LKM from scratch to do this.
The perf-fuzz kernel can be found at [https://github.com/sslab-gatech/perf-fuzz](https://github.com/sslab-gatech/perf-fuzz)
There also is/was a FreeBSD project at [https://github.com/veracode-research/freebsd-perf-fuzz](https://github.com/veracode-research/freebsd-perf-fuzz)
This enables snapshot fuzzing on Linux with an incredible performance!
Mentor: any
## QEMU 4-based Instrumentation
First tests to use QEMU 4 for binary-only AFL++ showed that caching behavior
@ -42,6 +60,8 @@ This is the cause why, right now, we cannot switch to QEMU 4.2.
Understanding the current instrumentation and fixing the current caching
issues will be needed.
Mentor: andreafioraldi
## WASM Instrumentation
Currently, AFL++ can be used for source code fuzzing and traditional binaries.
@ -51,10 +71,16 @@ This can either be done by inserting instrumentation directly into the
WASM AST, or by patching feedback into a WASM VMs of choice, similar to
the current Unicorn instrumentation.
Mentor: any
## Machine Learning
Something with machine learning, better than NEUZZ :-)
Either improve a single mutator thorugh learning of many different bugs (a bug class) or gather deep insights about a single target beforehand (CFG, DFG, VFG, ...?) and improve performance for a single target.
Something with machine learning, better than [NEUZZ](https://github.com/dongdongshe/neuzz) :-)
Either improve a single mutator thorugh learning of many different bugs
(a bug class) or gather deep insights about a single target beforehand
(CFG, DFG, VFG, ...?) and improve performance for a single target.
Mentor: domenukk
## Reengineer `afl-fuzz` as Thread Safe, Embeddable Library
@ -62,13 +88,18 @@ Right now, afl-fuzz is single threaded, cannot safely be embedded in tools, and
Instead, afl-fuzz could be refactored to contain no global state and globals.
This allows for different use cases that could be implemented during this project.
Mentor: hexcoder- or vanhauser-thc
## Collision-free Binary-Only Maps
AFL++ supports collison-free maps using an LTO (link-time-optimization) pass.
This should be possile to implement for QEMU and Unicorn instrumentations.
As the forkserver parent caches just in time translated translation blocks, adding a simple counter between jumps should be doable.
Mentor: andreafioraldi or domenukk
## Your idea!
Finally, we are open to proposals!
Create an issue at https://github.com/vanhauser-thc/AFLplusplus/issues and let's discuss :-)

View File

@ -62,7 +62,7 @@ Specify `AFL_HARDEN=1` in the environment to enable hardening flags.
## Bumping into problems with non-reproducible crashes?
It happens, but usually
isn't hard to diagnose. See section #7 in README for tips.
isn't hard to diagnose. See section #7 in README.md for tips.
## Fuzzing is not just about memory corruption issues in the codebase.
Add some
@ -87,4 +87,4 @@ use a postprocessor! See examples/post_library/ for more.
## Dealing with a very slow target or hoping for instant results?
Specify `-d` when calling afl-fuzz!
Specify `-d` when calling afl-fuzz!

View File

@ -1,7 +1,7 @@
# Notes for using ASAN with afl-fuzz
This file discusses some of the caveats for fuzzing under ASAN, and suggests
a handful of alternatives. See README for the general instruction manual.
a handful of alternatives. See README.md for the general instruction manual.
## 1) Short version

View File

@ -1,7 +1,7 @@
# Tips for parallel fuzzing
This document talks about synchronizing afl-fuzz jobs on a single machine
or across a fleet of systems. See README for the general instruction manual.
or across a fleet of systems. See README.md for the general instruction manual.
## 1) Introduction

View File

@ -1,7 +1,7 @@
## Tips for performance optimization
This file provides tips for troubleshooting slow or wasteful fuzzing jobs.
See README for the general instruction manual.
See README.md for the general instruction manual.
## 1. Keep your test cases small
@ -221,4 +221,4 @@ early on, you can always resort to the `-d` mode.
The mode causes `afl-fuzz` to skip all the deterministic fuzzing steps, which
makes output a lot less neat and can ultimately make the testing a bit less
in-depth, but it will give you an experience more familiar from other fuzzing
tools.
tools.

View File

@ -1,7 +1,7 @@
# Sister projects
This doc lists some of the projects that are inspired by, derived from,
designed for, or meant to integrate with AFL. See README for the general
designed for, or meant to integrate with AFL. See README.md for the general
instruction manual.
!!!
@ -252,7 +252,7 @@ https://code.google.com/p/address-sanitizer/wiki/AsanCoverage#Coverage_counters
### AFL JS (Han Choongwoo)
One-off optimizations to speed up the fuzzing of JavaScriptCore (now likely
superseded by LLVM deferred forkserver init - see llvm_mode/README.llvm).
superseded by LLVM deferred forkserver init - see llvm_mode/README.md).
https://github.com/tunz/afl-fuzz-js

View File

@ -1,7 +1,7 @@
# Understanding the status screen
This document provides an overview of the status screen - plus tips for
troubleshooting any warnings and red text shown in the UI. See README for
troubleshooting any warnings and red text shown in the UI. See README.md for
the general instruction manual.
## A note about colors

View File

@ -1,7 +1,7 @@
# Technical "whitepaper" for afl-fuzz
This document provides a quick overview of the guts of American Fuzzy Lop.
See README for the general instruction manual; and for a discussion of
See README.md for the general instruction manual; and for a discussion of
motivations and design goals behind AFL, see historical_notes.md.
## 0. Design statement
@ -542,4 +542,4 @@ It uses the following classification scheme:
takes place.
- "Magic value section" - a generic token where changes cause the type
of binary behavior outlined earlier, but that doesn't meet any of the
other criteria. May be an atomically compared keyword or so.
other criteria. May be an atomically compared keyword or so.

View File

@ -330,7 +330,9 @@ int main(int argc, char** argv, char** envp) {
exit(1);
} else if (isatty(2) && !getenv("AFL_QUIET")) {
} else if ((isatty(2) && !getenv("AFL_QUIET")) ||
getenv("AFL_DEBUG") != NULL) {
SAYF(cCYA "afl-gcc-fast" VERSION cRST
" initially by <aseipp@pobox.com>, maintainer: hexcoder-\n");

View File

@ -533,7 +533,7 @@ int plugin_init(struct plugin_name_args * plugin_info,
}
/* Show a banner */
if (isatty(2) && !getenv("AFL_QUIET")) {
if ((isatty(2) && !getenv("AFL_QUIET")) || getenv("AFL_DEBUG") != NULL) {
SAYF(G_(cCYA "afl-gcc-pass" VERSION cRST
" initially by <aseipp@pobox.com>, maintainer: hexcoder-\n"));

View File

@ -214,7 +214,7 @@ static void __afl_start_forkserver(void) {
}
/* A simplified persistent mode handler, used as explained in README.llvm. */
/* A simplified persistent mode handler, used as explained in README.md. */
int __afl_persistent_loop(unsigned int max_cnt) {

View File

@ -261,6 +261,7 @@ static const u8* main_payload_32 =
" je __afl_setup_abort\n"
"\n"
#endif
" movb $1, (%eax)\n"
" /* Store the address of the SHM region. */\n"
"\n"
" movl %eax, __afl_area_ptr\n"
@ -563,6 +564,7 @@ static const u8* main_payload_64 =
" je __afl_setup_abort\n"
"\n"
#endif
" movb $1, (%rax)\n"
" /* Store the address of the SHM region. */\n"
"\n"
" movq %rax, %rdx\n"

View File

@ -34,6 +34,9 @@
#include "types.h"
#include "debug.h"
#ifndef _WANT_ORIGINAL_AFL_ALLOC
// afl++ stuff without memory corruption checks - for speed
/* User-facing macro to sprintf() to a dynamically allocated buffer. */
#define alloc_printf(_str...) \
@ -101,10 +104,13 @@ static inline void* DFL_ck_alloc(u32 size) {
}
/* Free memory */
/* Free memory, checking for double free and corrupted heap. When DEBUG_BUILD
is set, the old memory will be also clobbered with 0xFF. */
static inline void DFL_ck_free(void* mem) {
if (!mem) return;
free(mem);
}
@ -116,7 +122,6 @@ static inline void DFL_ck_free(void* mem) {
static inline void* DFL_ck_realloc(void* orig, u32 size) {
u8* ret;
u32 old_size = 0;
if (!size) {
@ -127,10 +132,12 @@ static inline void* DFL_ck_realloc(void* orig, u32 size) {
ALLOC_CHECK_SIZE(size);
ret = realloc(orig, size);
ALLOC_CHECK_RESULT(ret, size);
/* Catch pointer issues sooner: force relocation and make sure that the
original buffer is wiped. */
if (size > old_size) memset(ret + old_size, 0, size - old_size);
ret = realloc(orig, size);
ALLOC_CHECK_RESULT(ret, size);
return (void*)ret;
@ -141,8 +148,6 @@ static inline void* DFL_ck_realloc(void* orig, u32 size) {
static inline void* DFL_ck_realloc_block(void* orig, u32 size) {
if (orig) size += ALLOC_BLK_INC;
return DFL_ck_realloc(orig, size);
}
@ -217,5 +222,544 @@ static inline u8* DFL_ck_memdup_str(u8* mem, u32 size) {
#define alloc_report()
#else
// This is the original alloc-inl of stock afl
/* User-facing macro to sprintf() to a dynamically allocated buffer. */
#define alloc_printf(_str...) \
({ \
\
u8* _tmp; \
s32 _len = snprintf(NULL, 0, _str); \
if (_len < 0) FATAL("Whoa, snprintf() fails?!"); \
_tmp = ck_alloc(_len + 1); \
snprintf((char*)_tmp, _len + 1, _str); \
_tmp; \
\
})
/* Macro to enforce allocation limits as a last-resort defense against
integer overflows. */
#define ALLOC_CHECK_SIZE(_s) \
do { \
\
if ((_s) > MAX_ALLOC) ABORT("Bad alloc request: %u bytes", (_s)); \
\
} while (0)
/* Macro to check malloc() failures and the like. */
#define ALLOC_CHECK_RESULT(_r, _s) \
do { \
\
if (!(_r)) ABORT("Out of memory: can't allocate %u bytes", (_s)); \
\
} while (0)
/* Magic tokens used to mark used / freed chunks. */
#define ALLOC_MAGIC_C1 0xFF00FF00 /* Used head (dword) */
#define ALLOC_MAGIC_F 0xFE00FE00 /* Freed head (dword) */
#define ALLOC_MAGIC_C2 0xF0 /* Used tail (byte) */
/* Positions of guard tokens in relation to the user-visible pointer. */
#define ALLOC_C1(_ptr) (((u32*)(_ptr))[-2])
#define ALLOC_S(_ptr) (((u32*)(_ptr))[-1])
#define ALLOC_C2(_ptr) (((u8*)(_ptr))[ALLOC_S(_ptr)])
#define ALLOC_OFF_HEAD 8
#define ALLOC_OFF_TOTAL (ALLOC_OFF_HEAD + 1)
/* Allocator increments for ck_realloc_block(). */
#define ALLOC_BLK_INC 256
/* Sanity-checking macros for pointers. */
#define CHECK_PTR(_p) \
do { \
\
if (_p) { \
\
if (ALLOC_C1(_p) ^ ALLOC_MAGIC_C1) { \
\
if (ALLOC_C1(_p) == ALLOC_MAGIC_F) \
ABORT("Use after free."); \
else \
ABORT("Corrupted head alloc canary."); \
\
} \
if (ALLOC_C2(_p) ^ ALLOC_MAGIC_C2) \
ABORT("Corrupted tail alloc canary."); \
\
} \
\
} while (0)
#define CHECK_PTR_EXPR(_p) \
({ \
\
typeof(_p) _tmp = (_p); \
CHECK_PTR(_tmp); \
_tmp; \
\
})
/* Allocate a buffer, explicitly not zeroing it. Returns NULL for zero-sized
requests. */
static inline void* DFL_ck_alloc_nozero(u32 size) {
void* ret;
if (!size) return NULL;
ALLOC_CHECK_SIZE(size);
ret = malloc(size + ALLOC_OFF_TOTAL);
ALLOC_CHECK_RESULT(ret, size);
ret += ALLOC_OFF_HEAD;
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
ALLOC_S(ret) = size;
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
return ret;
}
/* Allocate a buffer, returning zeroed memory. */
static inline void* DFL_ck_alloc(u32 size) {
void* mem;
if (!size) return NULL;
mem = DFL_ck_alloc_nozero(size);
return memset(mem, 0, size);
}
/* Free memory, checking for double free and corrupted heap. When DEBUG_BUILD
is set, the old memory will be also clobbered with 0xFF. */
static inline void DFL_ck_free(void* mem) {
if (!mem) return;
CHECK_PTR(mem);
#ifdef DEBUG_BUILD
/* Catch pointer issues sooner. */
memset(mem, 0xFF, ALLOC_S(mem));
#endif /* DEBUG_BUILD */
ALLOC_C1(mem) = ALLOC_MAGIC_F;
free(mem - ALLOC_OFF_HEAD);
}
/* Re-allocate a buffer, checking for issues and zeroing any newly-added tail.
With DEBUG_BUILD, the buffer is always reallocated to a new addresses and the
old memory is clobbered with 0xFF. */
static inline void* DFL_ck_realloc(void* orig, u32 size) {
void* ret;
u32 old_size = 0;
if (!size) {
DFL_ck_free(orig);
return NULL;
}
if (orig) {
CHECK_PTR(orig);
#ifndef DEBUG_BUILD
ALLOC_C1(orig) = ALLOC_MAGIC_F;
#endif /* !DEBUG_BUILD */
old_size = ALLOC_S(orig);
orig -= ALLOC_OFF_HEAD;
ALLOC_CHECK_SIZE(old_size);
}
ALLOC_CHECK_SIZE(size);
#ifndef DEBUG_BUILD
ret = realloc(orig, size + ALLOC_OFF_TOTAL);
ALLOC_CHECK_RESULT(ret, size);
#else
/* Catch pointer issues sooner: force relocation and make sure that the
original buffer is wiped. */
ret = malloc(size + ALLOC_OFF_TOTAL);
ALLOC_CHECK_RESULT(ret, size);
if (orig) {
memcpy(ret + ALLOC_OFF_HEAD, orig + ALLOC_OFF_HEAD, MIN(size, old_size));
memset(orig + ALLOC_OFF_HEAD, 0xFF, old_size);
ALLOC_C1(orig + ALLOC_OFF_HEAD) = ALLOC_MAGIC_F;
free(orig);
}
#endif /* ^!DEBUG_BUILD */
ret += ALLOC_OFF_HEAD;
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
ALLOC_S(ret) = size;
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
if (size > old_size) memset(ret + old_size, 0, size - old_size);
return ret;
}
/* Re-allocate a buffer with ALLOC_BLK_INC increments (used to speed up
repeated small reallocs without complicating the user code). */
static inline void* DFL_ck_realloc_block(void* orig, u32 size) {
#ifndef DEBUG_BUILD
if (orig) {
CHECK_PTR(orig);
if (ALLOC_S(orig) >= size) return orig;
size += ALLOC_BLK_INC;
}
#endif /* !DEBUG_BUILD */
return DFL_ck_realloc(orig, size);
}
/* Create a buffer with a copy of a string. Returns NULL for NULL inputs. */
static inline u8* DFL_ck_strdup(u8* str) {
void* ret;
u32 size;
if (!str) return NULL;
size = strlen((char*)str) + 1;
ALLOC_CHECK_SIZE(size);
ret = malloc(size + ALLOC_OFF_TOTAL);
ALLOC_CHECK_RESULT(ret, size);
ret += ALLOC_OFF_HEAD;
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
ALLOC_S(ret) = size;
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
return memcpy(ret, str, size);
}
/* Create a buffer with a copy of a memory block. Returns NULL for zero-sized
or NULL inputs. */
static inline void* DFL_ck_memdup(void* mem, u32 size) {
void* ret;
if (!mem || !size) return NULL;
ALLOC_CHECK_SIZE(size);
ret = malloc(size + ALLOC_OFF_TOTAL);
ALLOC_CHECK_RESULT(ret, size);
ret += ALLOC_OFF_HEAD;
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
ALLOC_S(ret) = size;
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
return memcpy(ret, mem, size);
}
/* Create a buffer with a block of text, appending a NUL terminator at the end.
Returns NULL for zero-sized or NULL inputs. */
static inline u8* DFL_ck_memdup_str(u8* mem, u32 size) {
u8* ret;
if (!mem || !size) return NULL;
ALLOC_CHECK_SIZE(size);
ret = malloc(size + ALLOC_OFF_TOTAL + 1);
ALLOC_CHECK_RESULT(ret, size);
ret += ALLOC_OFF_HEAD;
ALLOC_C1(ret) = ALLOC_MAGIC_C1;
ALLOC_S(ret) = size;
ALLOC_C2(ret) = ALLOC_MAGIC_C2;
memcpy(ret, mem, size);
ret[size] = 0;
return ret;
}
#ifndef DEBUG_BUILD
/* In non-debug mode, we just do straightforward aliasing of the above functions
to user-visible names such as ck_alloc(). */
#define ck_alloc DFL_ck_alloc
#define ck_alloc_nozero DFL_ck_alloc_nozero
#define ck_realloc DFL_ck_realloc
#define ck_realloc_block DFL_ck_realloc_block
#define ck_strdup DFL_ck_strdup
#define ck_memdup DFL_ck_memdup
#define ck_memdup_str DFL_ck_memdup_str
#define ck_free DFL_ck_free
#define alloc_report()
#else
/* In debugging mode, we also track allocations to detect memory leaks, and the
flow goes through one more layer of indirection. */
/* Alloc tracking data structures: */
#define ALLOC_BUCKETS 4096
struct TRK_obj {
void* ptr;
char *file, *func;
u32 line;
};
#ifdef AFL_MAIN
struct TRK_obj* TRK[ALLOC_BUCKETS];
u32 TRK_cnt[ALLOC_BUCKETS];
#define alloc_report() TRK_report()
#else
extern struct TRK_obj* TRK[ALLOC_BUCKETS];
extern u32 TRK_cnt[ALLOC_BUCKETS];
#define alloc_report()
#endif /* ^AFL_MAIN */
/* Bucket-assigning function for a given pointer: */
#define TRKH(_ptr) (((((u32)(_ptr)) >> 16) ^ ((u32)(_ptr))) % ALLOC_BUCKETS)
/* Add a new entry to the list of allocated objects. */
static inline void TRK_alloc_buf(void* ptr, const char* file, const char* func,
u32 line) {
u32 i, bucket;
if (!ptr) return;
bucket = TRKH(ptr);
/* Find a free slot in the list of entries for that bucket. */
for (i = 0; i < TRK_cnt[bucket]; i++)
if (!TRK[bucket][i].ptr) {
TRK[bucket][i].ptr = ptr;
TRK[bucket][i].file = (char*)file;
TRK[bucket][i].func = (char*)func;
TRK[bucket][i].line = line;
return;
}
/* No space available - allocate more. */
TRK[bucket] = DFL_ck_realloc_block(
TRK[bucket], (TRK_cnt[bucket] + 1) * sizeof(struct TRK_obj));
TRK[bucket][i].ptr = ptr;
TRK[bucket][i].file = (char*)file;
TRK[bucket][i].func = (char*)func;
TRK[bucket][i].line = line;
TRK_cnt[bucket]++;
}
/* Remove entry from the list of allocated objects. */
static inline void TRK_free_buf(void* ptr, const char* file, const char* func,
u32 line) {
u32 i, bucket;
if (!ptr) return;
bucket = TRKH(ptr);
/* Find the element on the list... */
for (i = 0; i < TRK_cnt[bucket]; i++)
if (TRK[bucket][i].ptr == ptr) {
TRK[bucket][i].ptr = 0;
return;
}
WARNF("ALLOC: Attempt to free non-allocated memory in %s (%s:%u)", func, file,
line);
}
/* Do a final report on all non-deallocated objects. */
static inline void TRK_report(void) {
u32 i, bucket;
fflush(0);
for (bucket = 0; bucket < ALLOC_BUCKETS; bucket++)
for (i = 0; i < TRK_cnt[bucket]; i++)
if (TRK[bucket][i].ptr)
WARNF("ALLOC: Memory never freed, created in %s (%s:%u)",
TRK[bucket][i].func, TRK[bucket][i].file, TRK[bucket][i].line);
}
/* Simple wrappers for non-debugging functions: */
static inline void* TRK_ck_alloc(u32 size, const char* file, const char* func,
u32 line) {
void* ret = DFL_ck_alloc(size);
TRK_alloc_buf(ret, file, func, line);
return ret;
}
static inline void* TRK_ck_realloc(void* orig, u32 size, const char* file,
const char* func, u32 line) {
void* ret = DFL_ck_realloc(orig, size);
TRK_free_buf(orig, file, func, line);
TRK_alloc_buf(ret, file, func, line);
return ret;
}
static inline void* TRK_ck_realloc_block(void* orig, u32 size, const char* file,
const char* func, u32 line) {
void* ret = DFL_ck_realloc_block(orig, size);
TRK_free_buf(orig, file, func, line);
TRK_alloc_buf(ret, file, func, line);
return ret;
}
static inline void* TRK_ck_strdup(u8* str, const char* file, const char* func,
u32 line) {
void* ret = DFL_ck_strdup(str);
TRK_alloc_buf(ret, file, func, line);
return ret;
}
static inline void* TRK_ck_memdup(void* mem, u32 size, const char* file,
const char* func, u32 line) {
void* ret = DFL_ck_memdup(mem, size);
TRK_alloc_buf(ret, file, func, line);
return ret;
}
static inline void* TRK_ck_memdup_str(void* mem, u32 size, const char* file,
const char* func, u32 line) {
void* ret = DFL_ck_memdup_str(mem, size);
TRK_alloc_buf(ret, file, func, line);
return ret;
}
static inline void TRK_ck_free(void* ptr, const char* file, const char* func,
u32 line) {
TRK_free_buf(ptr, file, func, line);
DFL_ck_free(ptr);
}
/* Aliasing user-facing names to tracking functions: */
#define ck_alloc(_p1) TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)
#define ck_alloc_nozero(_p1) TRK_ck_alloc(_p1, __FILE__, __FUNCTION__, __LINE__)
#define ck_realloc(_p1, _p2) \
TRK_ck_realloc(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
#define ck_realloc_block(_p1, _p2) \
TRK_ck_realloc_block(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
#define ck_strdup(_p1) TRK_ck_strdup(_p1, __FILE__, __FUNCTION__, __LINE__)
#define ck_memdup(_p1, _p2) \
TRK_ck_memdup(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
#define ck_memdup_str(_p1, _p2) \
TRK_ck_memdup_str(_p1, _p2, __FILE__, __FUNCTION__, __LINE__)
#define ck_free(_p1) TRK_ck_free(_p1, __FILE__, __FUNCTION__, __LINE__)
#endif /* ^!DEBUG_BUILD */
#endif /* _WANT_ORIGINAL_AFL_ALLOC */
#endif /* ! _HAVE_ALLOC_INL_H */

View File

@ -27,7 +27,7 @@
/* Version string: */
// c = release, d = volatile github dev, e = experimental branch
#define VERSION "++2.61c"
#define VERSION "++2.62c"
/******************************************************
* *
@ -40,6 +40,11 @@
#define USE_COLOR
/* If you want to have the original afl internal memory corruption checks.
Disabled by default for speed. it is better to use "make ASAN_BUILD=1". */
//#define _WANT_ORIGINAL_AFL_ALLOC
/* Comment out to disable fancy ANSI boxes and use poor man's 7-bit UI: */
#ifndef ANDROID_DISABLE_FANCY // Fancy boxes are ugly from adb

View File

@ -1,6 +1,6 @@
# libdislocator, an abusive allocator
(See ../docs/README for the general instruction manual.)
(See ../docs/README.md for the general instruction manual.)
This is a companion library that can be used as a drop-in replacement for the
libc allocator in the fuzzed binaries. It improves the odds of bumping into

View File

@ -1,6 +1,6 @@
# strcmp() / memcmp() token capture library
(See ../docs/README for the general instruction manual.)
(See ../docs/README.md for the general instruction manual.)
This companion library allows you to instrument `strcmp()`, `memcmp()`,
and related functions to automatically extract syntax tokens passed to any of

View File

@ -132,9 +132,9 @@ ifeq "$(TEST_MMAP)" "1"
endif
ifndef AFL_TRACE_PC
PROGS = ../afl-clang-fast ../afl-llvm-pass.so ../libLLVMInsTrim.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so
PROGS = ../afl-clang-fast ../afl-llvm-pass.so ../libLLVMInsTrim.so ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so
else
PROGS = ../afl-clang-fast ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so
PROGS = ../afl-clang-fast ../afl-llvm-rt.o ../afl-llvm-rt-32.o ../afl-llvm-rt-64.o ../compare-transform-pass.so ../split-compares-pass.so ../split-switches-pass.so ../cmplog-routines-pass.so ../cmplog-instructions-pass.so
endif
ifneq "$(CLANGVER)" "$(LLVMVER)"
@ -222,6 +222,9 @@ afl-common.o: ../src/afl-common.c
../cmplog-routines-pass.so: cmplog-routines-pass.cc | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
../cmplog-instructions-pass.so: cmplog-instructions-pass.cc | test_deps
$(CXX) $(CLANG_CFL) -shared $< -o $@ $(CLANG_LFL)
../afl-llvm-rt.o: afl-llvm-rt.o.c | test_deps
$(CC) $(CFLAGS) -fPIC -c $< -o $@

View File

@ -2,7 +2,7 @@
(See [../README](../README.md) for the general instruction manual.)
(See [../gcc_plugin/README.gcc](../gcc_plugin/README.gcc.md) for the GCC-based instrumentation.)
(See [../gcc_plugin/README](../gcc_plugin/README.md) for the GCC-based instrumentation.)
## 1) Introduction

View File

@ -201,50 +201,58 @@ static void edit_params(u32 argc, char** argv) {
if (cmplog_mode) {
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard,trace-cmp";
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load";
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] =
alloc_printf("%s/cmplog-routines-pass.so", obj_path);
// reuse split switches from laf
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load";
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] =
alloc_printf("%s/split-switches-pass.so", obj_path);
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load";
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] =
alloc_printf("%s/cmplog-instructions-pass.so", obj_path);
cc_params[cc_par_cnt++] = "-fno-inline";
} else {
}
#ifdef USE_TRACE_PC
cc_params[cc_par_cnt++] =
"-fsanitize-coverage=trace-pc-guard"; // edge coverage by default
// cc_params[cc_par_cnt++] = "-mllvm";
// cc_params[cc_par_cnt++] =
// "-fsanitize-coverage=trace-cmp,trace-div,trace-gep";
// cc_params[cc_par_cnt++] = "-sanitizer-coverage-block-threshold=0";
#else
if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") ||
getenv("AFL_LLVM_USE_TRACE_PC") || getenv("AFL_TRACE_PC")) {
cc_params[cc_par_cnt++] =
"-fsanitize-coverage=trace-pc-guard"; // edge coverage by default
// cc_params[cc_par_cnt++] = "-mllvm";
// cc_params[cc_par_cnt++] =
// "-fsanitize-coverage=trace-cmp,trace-div,trace-gep";
// cc_params[cc_par_cnt++] = "-sanitizer-coverage-block-threshold=0";
#else
if (getenv("USE_TRACE_PC") || getenv("AFL_USE_TRACE_PC") ||
getenv("AFL_LLVM_USE_TRACE_PC") || getenv("AFL_TRACE_PC")) {
cc_params[cc_par_cnt++] =
"-fsanitize-coverage=trace-pc-guard"; // edge coverage by default
} else {
} else {
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load";
cc_params[cc_par_cnt++] = "-Xclang";
if (getenv("AFL_LLVM_INSTRIM") != NULL || getenv("INSTRIM_LIB") != NULL)
cc_params[cc_par_cnt++] =
alloc_printf("%s/libLLVMInsTrim.so", obj_path);
else
cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path);
}
#endif /* ^USE_TRACE_PC */
cc_params[cc_par_cnt++] = "-Xclang";
cc_params[cc_par_cnt++] = "-load";
cc_params[cc_par_cnt++] = "-Xclang";
if (getenv("AFL_LLVM_INSTRIM") != NULL || getenv("INSTRIM_LIB") != NULL)
cc_params[cc_par_cnt++] = alloc_printf("%s/libLLVMInsTrim.so", obj_path);
else
cc_params[cc_par_cnt++] = alloc_printf("%s/afl-llvm-pass.so", obj_path);
}
#endif /* ^USE_TRACE_PC */
cc_params[cc_par_cnt++] = "-Qunused-arguments";
/* Detect stray -v calls from ./configure scripts. */

View File

@ -260,7 +260,8 @@ static void __afl_start_forkserver(void) {
}
/* A simplified persistent mode handler, used as explained in README.llvm. */
/* A simplified persistent mode handler, used as explained in
* llvm_mode/README.md. */
int __afl_persistent_loop(unsigned int max_cnt) {
@ -346,7 +347,7 @@ __attribute__((constructor(CONST_PRIO))) void __afl_auto_init(void) {
/* The following stuff deals with supporting -fsanitize-coverage=trace-pc-guard.
It remains non-operational in the traditional, plugin-backed LLVM mode.
For more info about 'trace-pc-guard', see README.llvm.
For more info about 'trace-pc-guard', see llvm_mode/README.md.
The first function (__sanitizer_cov_trace_pc_guard) is called back on every
edge (as opposed to every basic block). */
@ -399,13 +400,13 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t* start, uint32_t* stop) {
///// CmpLog instrumentation
void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2) {
void __cmplog_ins_hook1(uint8_t Arg1, uint8_t Arg2) {
return;
}
void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2) {
void __cmplog_ins_hook2(uint16_t Arg1, uint16_t Arg2) {
if (!__afl_cmp_map) return;
@ -429,7 +430,7 @@ void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2) {
}
void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2) {
void __cmplog_ins_hook4(uint32_t Arg1, uint32_t Arg2) {
if (!__afl_cmp_map) return;
@ -450,7 +451,7 @@ void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2) {
}
void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2) {
void __cmplog_ins_hook8(uint64_t Arg1, uint64_t Arg2) {
if (!__afl_cmp_map) return;
@ -472,19 +473,33 @@ void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2) {
}
#if defined(__APPLE__)
#pragma weak __sanitizer_cov_trace_const_cmp1 = __sanitizer_cov_trace_cmp1
#pragma weak __sanitizer_cov_trace_const_cmp2 = __sanitizer_cov_trace_cmp2
#pragma weak __sanitizer_cov_trace_const_cmp4 = __sanitizer_cov_trace_cmp4
#pragma weak __sanitizer_cov_trace_const_cmp8 = __sanitizer_cov_trace_cmp8
#pragma weak __sanitizer_cov_trace_const_cmp1 = __cmplog_ins_hook1
#pragma weak __sanitizer_cov_trace_const_cmp2 = __cmplog_ins_hook2
#pragma weak __sanitizer_cov_trace_const_cmp4 = __cmplog_ins_hook4
#pragma weak __sanitizer_cov_trace_const_cmp8 = __cmplog_ins_hook8
#pragma weak __sanitizer_cov_trace_cmp1 = __cmplog_ins_hook1
#pragma weak __sanitizer_cov_trace_cmp2 = __cmplog_ins_hook2
#pragma weak __sanitizer_cov_trace_cmp4 = __cmplog_ins_hook4
#pragma weak __sanitizer_cov_trace_cmp8 = __cmplog_ins_hook8
#else
void __sanitizer_cov_trace_const_cmp1(uint8_t Arg1, uint8_t Arg2)
__attribute__((alias("__sanitizer_cov_trace_cmp1")));
__attribute__((alias("__cmplog_ins_hook1")));
void __sanitizer_cov_trace_const_cmp2(uint16_t Arg1, uint16_t Arg2)
__attribute__((alias("__sanitizer_cov_trace_cmp2")));
__attribute__((alias("__cmplog_ins_hook2")));
void __sanitizer_cov_trace_const_cmp4(uint32_t Arg1, uint32_t Arg2)
__attribute__((alias("__sanitizer_cov_trace_cmp4")));
__attribute__((alias("__cmplog_ins_hook4")));
void __sanitizer_cov_trace_const_cmp8(uint64_t Arg1, uint64_t Arg2)
__attribute__((alias("__sanitizer_cov_trace_cmp8")));
__attribute__((alias("__cmplog_ins_hook8")));
void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2)
__attribute__((alias("__cmplog_ins_hook1")));
void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2)
__attribute__((alias("__cmplog_ins_hook2")));
void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2)
__attribute__((alias("__cmplog_ins_hook4")));
void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2)
__attribute__((alias("__cmplog_ins_hook8")));
#endif /* defined(__APPLE__) */
void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t* Cases) {

View File

@ -0,0 +1,401 @@
/*
american fuzzy lop++ - LLVM CmpLog instrumentation
--------------------------------------------------
Written by Andrea Fioraldi <andreafioraldi@gmail.com>
Copyright 2015, 2016 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <list>
#include <string>
#include <fstream>
#include <sys/time.h>
#include "llvm/Config/llvm-config.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/ValueTracking.h"
#if LLVM_VERSION_MAJOR > 3 || \
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
#include "llvm/IR/Verifier.h"
#include "llvm/IR/DebugInfo.h"
#else
#include "llvm/Analysis/Verifier.h"
#include "llvm/DebugInfo.h"
#define nullptr 0
#endif
#include <set>
using namespace llvm;
namespace {
class CmpLogInstructions : public ModulePass {
public:
static char ID;
CmpLogInstructions() : ModulePass(ID) {
char *instWhiteListFilename = getenv("AFL_LLVM_WHITELIST");
if (instWhiteListFilename) {
std::string line;
std::ifstream fileStream;
fileStream.open(instWhiteListFilename);
if (!fileStream) report_fatal_error("Unable to open AFL_LLVM_WHITELIST");
getline(fileStream, line);
while (fileStream) {
myWhitelist.push_back(line);
getline(fileStream, line);
}
}
}
bool runOnModule(Module &M) override;
#if LLVM_VERSION_MAJOR < 4
const char *getPassName() const override {
#else
StringRef getPassName() const override {
#endif
return "cmplog instructions";
}
protected:
std::list<std::string> myWhitelist;
private:
bool hookInstrs(Module &M);
};
} // namespace
char CmpLogInstructions::ID = 0;
bool CmpLogInstructions::hookInstrs(Module &M) {
std::vector<Instruction *> icomps;
LLVMContext & C = M.getContext();
Type * VoidTy = Type::getVoidTy(C);
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
IntegerType *Int16Ty = IntegerType::getInt16Ty(C);
IntegerType *Int32Ty = IntegerType::getInt32Ty(C);
IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
#if LLVM_VERSION_MAJOR < 9
Constant *
#else
FunctionCallee
#endif
c1 = M.getOrInsertFunction("__cmplog_ins_hook1", VoidTy, Int8Ty, Int8Ty
#if LLVM_VERSION_MAJOR < 5
,
NULL
#endif
);
#if LLVM_VERSION_MAJOR < 9
Function *cmplogHookIns1 = cast<Function>(c1);
#else
FunctionCallee cmplogHookIns1 = c1;
#endif
#if LLVM_VERSION_MAJOR < 9
Constant *
#else
FunctionCallee
#endif
c2 = M.getOrInsertFunction("__cmplog_ins_hook2", VoidTy, Int16Ty, Int16Ty
#if LLVM_VERSION_MAJOR < 5
,
NULL
#endif
);
#if LLVM_VERSION_MAJOR < 9
Function *cmplogHookIns2 = cast<Function>(c2);
#else
FunctionCallee cmplogHookIns2 = c2;
#endif
#if LLVM_VERSION_MAJOR < 9
Constant *
#else
FunctionCallee
#endif
c4 = M.getOrInsertFunction("__cmplog_ins_hook4", VoidTy, Int32Ty, Int32Ty
#if LLVM_VERSION_MAJOR < 5
,
NULL
#endif
);
#if LLVM_VERSION_MAJOR < 9
Function *cmplogHookIns4 = cast<Function>(c4);
#else
FunctionCallee cmplogHookIns4 = c4;
#endif
#if LLVM_VERSION_MAJOR < 9
Constant *
#else
FunctionCallee
#endif
c8 = M.getOrInsertFunction("__cmplog_ins_hook8", VoidTy, Int64Ty, Int64Ty
#if LLVM_VERSION_MAJOR < 5
,
NULL
#endif
);
#if LLVM_VERSION_MAJOR < 9
Function *cmplogHookIns8 = cast<Function>(c8);
#else
FunctionCallee cmplogHookIns8 = c8;
#endif
/* iterate over all functions, bbs and instruction and add suitable calls */
for (auto &F : M) {
for (auto &BB : F) {
if (!myWhitelist.empty()) {
BasicBlock::iterator IP = BB.getFirstInsertionPt();
bool instrumentBlock = false;
/* Get the current location using debug information.
* For now, just instrument the block if we are not able
* to determine our location. */
DebugLoc Loc = IP->getDebugLoc();
#if LLVM_VERSION_MAJOR >= 4 || \
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 7)
if (Loc) {
DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
unsigned int instLine = cDILoc->getLine();
StringRef instFilename = cDILoc->getFilename();
if (instFilename.str().empty()) {
/* If the original location is empty, try using the inlined location
*/
DILocation *oDILoc = cDILoc->getInlinedAt();
if (oDILoc) {
instFilename = oDILoc->getFilename();
instLine = oDILoc->getLine();
}
}
(void)instLine;
/* Continue only if we know where we actually are */
if (!instFilename.str().empty()) {
for (std::list<std::string>::iterator it = myWhitelist.begin();
it != myWhitelist.end(); ++it) {
/* We don't check for filename equality here because
* filenames might actually be full paths. Instead we
* check that the actual filename ends in the filename
* specified in the list. */
if (instFilename.str().length() >= it->length()) {
if (instFilename.str().compare(
instFilename.str().length() - it->length(),
it->length(), *it) == 0) {
instrumentBlock = true;
break;
}
}
}
}
}
#else
if (!Loc.isUnknown()) {
DILocation cDILoc(Loc.getAsMDNode(C));
unsigned int instLine = cDILoc.getLineNumber();
StringRef instFilename = cDILoc.getFilename();
(void)instLine;
/* Continue only if we know where we actually are */
if (!instFilename.str().empty()) {
for (std::list<std::string>::iterator it = myWhitelist.begin();
it != myWhitelist.end(); ++it) {
/* We don't check for filename equality here because
* filenames might actually be full paths. Instead we
* check that the actual filename ends in the filename
* specified in the list. */
if (instFilename.str().length() >= it->length()) {
if (instFilename.str().compare(
instFilename.str().length() - it->length(),
it->length(), *it) == 0) {
instrumentBlock = true;
break;
}
}
}
}
}
#endif
/* Either we couldn't figure out our location or the location is
* not whitelisted, so we skip instrumentation. */
if (!instrumentBlock) continue;
}
for (auto &IN : BB) {
CmpInst *selectcmpInst = nullptr;
if ((selectcmpInst = dyn_cast<CmpInst>(&IN))) {
if (selectcmpInst->getPredicate() == CmpInst::ICMP_EQ ||
selectcmpInst->getPredicate() == CmpInst::ICMP_NE ||
selectcmpInst->getPredicate() == CmpInst::ICMP_UGT ||
selectcmpInst->getPredicate() == CmpInst::ICMP_SGT ||
selectcmpInst->getPredicate() == CmpInst::ICMP_ULT ||
selectcmpInst->getPredicate() == CmpInst::ICMP_SLT ||
selectcmpInst->getPredicate() == CmpInst::ICMP_UGE ||
selectcmpInst->getPredicate() == CmpInst::ICMP_SGE ||
selectcmpInst->getPredicate() == CmpInst::ICMP_ULE ||
selectcmpInst->getPredicate() == CmpInst::ICMP_SLE) {
auto op0 = selectcmpInst->getOperand(0);
auto op1 = selectcmpInst->getOperand(1);
IntegerType *intTyOp0 = dyn_cast<IntegerType>(op0->getType());
IntegerType *intTyOp1 = dyn_cast<IntegerType>(op1->getType());
/* this is probably not needed but we do it anyway */
if (!intTyOp0 || !intTyOp1) { continue; }
icomps.push_back(selectcmpInst);
}
}
}
}
}
if (!icomps.size()) return false;
errs() << "Hooking " << icomps.size() << " cmp instructions\n";
for (auto &selectcmpInst : icomps) {
IRBuilder<> IRB(selectcmpInst->getParent());
IRB.SetInsertPoint(selectcmpInst);
auto op0 = selectcmpInst->getOperand(0);
auto op1 = selectcmpInst->getOperand(1);
IntegerType *intTyOp0 = dyn_cast<IntegerType>(op0->getType());
IntegerType *intTyOp1 = dyn_cast<IntegerType>(op1->getType());
unsigned max_size = intTyOp0->getBitWidth() > intTyOp1->getBitWidth()
? intTyOp0->getBitWidth()
: intTyOp1->getBitWidth();
std::vector<Value *> args;
args.push_back(op0);
args.push_back(op1);
switch (max_size) {
case 8: IRB.CreateCall(cmplogHookIns1, args, "tmp"); break;
case 16: IRB.CreateCall(cmplogHookIns2, args, "tmp"); break;
case 32: IRB.CreateCall(cmplogHookIns4, args, "tmp"); break;
case 64: IRB.CreateCall(cmplogHookIns8, args, "tmp"); break;
default: break;
}
}
return true;
}
bool CmpLogInstructions::runOnModule(Module &M) {
if (getenv("AFL_QUIET") == NULL)
llvm::errs()
<< "Running cmplog-instructions-pass by andreafioraldi@gmail.com\n";
hookInstrs(M);
verifyModule(M);
return true;
}
static void registerCmpLogInstructionsPass(const PassManagerBuilder &,
legacy::PassManagerBase &PM) {
auto p = new CmpLogInstructions();
PM.add(p);
}
static RegisterStandardPasses RegisterCmpLogInstructionsPass(
PassManagerBuilder::EP_OptimizerLast, registerCmpLogInstructionsPass);
static RegisterStandardPasses RegisterCmpLogInstructionsPass0(
PassManagerBuilder::EP_EnabledOnOptLevel0, registerCmpLogInstructionsPass);

View File

@ -1,6 +1,6 @@
# High-performance binary-only instrumentation for afl-fuzz
(See ../docs/README for the general instruction manual.)
(See ../docs/README.md for the general instruction manual.)
## 1) Introduction
@ -60,7 +60,7 @@ binary on x86_64) use QEMU_LD_PREFIX.
## 3) Bonus feature #1: deferred initialization
As for LLVM mode (refer to its README for mode details) QEMU mode supports
As for LLVM mode (refer to its README.md for mode details) QEMU mode supports
the deferred initialization.
This can be enabled setting the environment variable AFL_ENTRYPOINT which allows

View File

@ -15,7 +15,7 @@
This Linux-only companion library allows you to instrument strcmp(),
memcmp(), and related functions to get compare coverage.
See README.compcov for more info.
See README.md for more info.
*/

View File

@ -80,7 +80,7 @@ unsigned char is_persistent;
target_long persistent_stack_offset;
unsigned char persistent_first_pass = 1;
unsigned char persistent_save_gpr;
target_ulong persistent_saved_gpr[AFL_REGS_NUM];
uint64_t persistent_saved_gpr[AFL_REGS_NUM];
int persisent_retaddr_offset;
afl_persistent_hook_fn afl_persistent_hook_ptr;
@ -407,7 +407,8 @@ void afl_forkserver(CPUState *cpu) {
}
/* A simplified persistent mode handler, used as explained in README.llvm. */
/* A simplified persistent mode handler, used as explained in
* llvm_mode/README.md. */
void afl_persistent_loop(void) {

View File

@ -780,11 +780,11 @@ static void usage(u8* argv0) {
SAYF(
"\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
"Required parameters:\n\n"
"Required parameters:\n"
" -i file - input test case to be analyzed by the tool\n"
" -i file - input test case to be analyzed by the tool\n\n"
"Execution control settings:\n\n"
"Execution control settings:\n"
" -f file - input file read by the tested program (stdin)\n"
" -t msec - timeout for each run (%d ms)\n"
@ -794,13 +794,23 @@ static void usage(u8* argv0) {
" -W - use qemu-based instrumentation with Wine (Wine "
"mode)\n\n"
"Analysis settings:\n\n"
"Analysis settings:\n"
" -e - look for edge coverage only, ignore hit counts\n\n"
"For additional tips, please consult %s/README.\n\n",
"For additional tips, please consult %s/README.md.\n\n"
argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
"Environment variables used:\n"
"TMPDIR: directory to use for temporary input files\n"
"ASAN_OPTIONS: custom settings for ASAN\n"
" (must contain abort_on_error=1 and symbolize=0)\n"
"MSAN_OPTIONS: custom settings for MSAN\n"
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
"AFL_PRELOAD: LD_PRELOAD settings for target\n"
"AFL_ANALYZE_HEX: print file offsets in hexadecimal instead of decimal\n"
"AFL_SKIP_BIN_CHECK: skip checking the location of and the target\n"
, argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
exit(1);

View File

@ -520,8 +520,11 @@ int main(int argc, char** argv) {
if (argc < 2 || (argc == 2 && strcmp(argv[1], "-h") == 0)) {
SAYF(
"\n"
fprintf(
stdout,
"afl-as" VERSION
" by Michal Zalewski\n"
"\n%s [-h]\n\n"
"This is a helper application for afl-fuzz. It is a wrapper around GNU "
"'as',\n"
"executed by the toolchain whenever using afl-gcc or afl-clang. You "
@ -545,7 +548,8 @@ int main(int argc, char** argv) {
"AFL_KEEP_ASSEMBLY: leave instrumented assembly files\n"
"AFL_AS_FORCE_INSTRUMENT: force instrumentation for asm sources\n"
"AFL_HARDEN, AFL_USE_ASAN, AFL_USE_MSAN, AFL_USE_UBSAN:\n"
" used in the instrumentation summary message\n");
" used in the instrumentation summary message\n",
argv[0]);
exit(1);

View File

@ -163,7 +163,7 @@ char** get_qemu_argv(u8* own_loc, char** argv, int argc) {
SAYF("\n" cLRD "[-] " cRST
"Oops, unable to find the 'afl-qemu-trace' binary. The binary must be "
"built\n"
" separately by following the instructions in qemu_mode/README.qemu. "
" separately by following the instructions in qemu_mode/README.md. "
"If you\n"
" already have the binary installed, you may need to specify "
"AFL_PATH in the\n"
@ -259,7 +259,7 @@ char** get_wine_argv(u8* own_loc, char** argv, int argc) {
SAYF("\n" cLRD "[-] " cRST
"Oops, unable to find the '%s' binary. The binary must be "
"built\n"
" separately by following the instructions in qemu_mode/README.qemu. "
" separately by following the instructions in qemu_mode/README.md. "
"If you\n"
" already have the binary installed, you may need to specify "
"AFL_PATH in the\n"

View File

@ -1972,25 +1972,25 @@ void check_binary(u8* fname) {
if (!qemu_mode && !unicorn_mode && !dumb_mode &&
!memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
SAYF(
"\n" cLRD "[-] " cRST
"Looks like the target binary is not instrumented! The fuzzer depends "
"on\n"
" compile-time instrumentation to isolate interesting test cases "
"while\n"
" mutating the input data. For more information, and for tips on "
"how to\n"
" instrument binaries, please see %s/README.\n\n"
SAYF("\n" cLRD "[-] " cRST
"Looks like the target binary is not instrumented! The fuzzer depends "
"on\n"
" compile-time instrumentation to isolate interesting test cases "
"while\n"
" mutating the input data. For more information, and for tips on "
"how to\n"
" instrument binaries, please see %s/README.md.\n\n"
" When source code is not available, you may be able to leverage "
"QEMU\n"
" mode support. Consult the README for tips on how to enable this.\n"
" When source code is not available, you may be able to leverage "
"QEMU\n"
" mode support. Consult the README.md for tips on how to enable "
"this.\n"
" (It is also possible to use afl-fuzz as a traditional, \"dumb\" "
"fuzzer.\n"
" For that, you can use the -n option - but expect much worse "
"results.)\n",
doc_path);
" (It is also possible to use afl-fuzz as a traditional, \"dumb\" "
"fuzzer.\n"
" For that, you can use the -n option - but expect much worse "
"results.)\n",
doc_path);
FATAL("No instrumentation detected");

View File

@ -118,8 +118,8 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) {
stage_max = 1000;
struct range* rng;
stage_cur = stage_max;
while ((rng = pop_biggest_range(&ranges)) != NULL && stage_cur) {
stage_cur = 0;
while ((rng = pop_biggest_range(&ranges)) != NULL && stage_cur < stage_max) {
u32 s = rng->end - rng->start;
if (s == 0) goto empty_range;
@ -142,15 +142,15 @@ u8 colorization(u8* buf, u32 len, u32 exec_cksum) {
empty_range:
ck_free(rng);
--stage_cur;
++stage_cur;
}
if (stage_cur) queue_cur->fully_colorized = 1;
if (stage_cur < stage_max) queue_cur->fully_colorized = 1;
new_hit_cnt = queued_paths + unique_crashes;
stage_finds[STAGE_COLORIZATION] += new_hit_cnt - orig_hit_cnt;
stage_cycles[STAGE_COLORIZATION] += stage_max - stage_cur;
stage_cycles[STAGE_COLORIZATION] += stage_cur;
ck_free(backup);
while (ranges) {

View File

@ -112,7 +112,8 @@ static void usage(u8* argv0) {
"entering the\n"
" pacemaker mode (minutes of no new paths, 0 = "
"immediately).\n"
" a recommended value is 10-60. see docs/README.MOpt\n"
" a recommended value is 10-60. see "
"docs/README.MOpt.md\n"
" -c program - enable CmpLog by specifying a binary compiled for "
"it.\n"
" if using QEMU, just use -c 0.\n\n"
@ -121,7 +122,7 @@ static void usage(u8* argv0) {
" -N - do not unlink the fuzzing input file\n"
" -d - quick & dirty mode (skips deterministic steps)\n"
" -n - fuzz without instrumentation (dumb mode)\n"
" -x dir - optional fuzzer dictionary (see README, its really "
" -x dir - optional fuzzer dictionary (see README.md, its really "
"good!)\n\n"
"Testing settings:\n"
@ -1024,6 +1025,7 @@ int main(int argc, char** argv, char** envp) {
if (most_time * 1000 < cur_ms_lv - start_time) {
most_time_key = 2;
stop_soon = 2;
break;
}
@ -1035,6 +1037,7 @@ int main(int argc, char** argv, char** envp) {
if (most_execs <= total_execs) {
most_execs_key = 2;
stop_soon = 2;
break;
}
@ -1087,7 +1090,7 @@ stop_fuzzing:
SAYF("\n" cYEL "[!] " cRST
"Stopped during the first cycle, results may be incomplete.\n"
" (For info on resuming, see %s/README)\n",
" (For info on resuming, see %s/README.md)\n",
doc_path);
}

View File

@ -146,7 +146,7 @@ void setup_shm(unsigned char dumb_mode) {
trace_bits = g_shm_base;
if (!trace_bits) PFATAL("mmap() failed");
if (trace_bits == -1 || !trace_bits) PFATAL("mmap() failed");
#else
u8 *shm_str;
@ -189,9 +189,15 @@ void setup_shm(unsigned char dumb_mode) {
trace_bits = shmat(shm_id, NULL, 0);
if (cmplog_mode) cmp_map = shmat(cmplog_shm_id, NULL, 0);
if (trace_bits == (void *)-1 || !trace_bits) PFATAL("shmat() failed");
if (!trace_bits) PFATAL("shmat() failed");
if (cmplog_mode) {
cmp_map = shmat(cmplog_shm_id, NULL, 0);
if (cmp_map == (void *)-1 || !cmp_map) PFATAL("shmat() failed");
}
#endif

View File

@ -622,11 +622,11 @@ static void usage(u8* argv0) {
SAYF(
"\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
"Required parameters:\n\n"
"Required parameters:\n"
" -o file - file to write the trace data to\n\n"
"Execution control settings:\n\n"
"Execution control settings:\n"
" -t msec - timeout for each run (none)\n"
" -m megs - memory limit for child process (%d MB)\n"
@ -636,7 +636,7 @@ static void usage(u8* argv0) {
" (Not necessary, here for consistency with other afl-* "
"tools)\n\n"
"Other settings:\n\n"
"Other settings:\n"
" -i dir - process all files in this directory, -o must be a "
"directory\n"
@ -647,8 +647,7 @@ static void usage(u8* argv0) {
" -c - allow core dumps\n\n"
"This tool displays raw tuple data captured by AFL instrumentation.\n"
"For additional help, consult %s/README.\n\n" cRST,
"For additional help, consult %s/README.md.\n",
argv0, MEM_LIMIT, doc_path);
exit(1);

View File

@ -955,12 +955,12 @@ static void usage(u8* argv0) {
SAYF(
"\n%s [ options ] -- /path/to/target_app [ ... ]\n\n"
"Required parameters:\n\n"
"Required parameters:\n"
" -i file - input test case to be shrunk by the tool\n"
" -o file - final output location for the minimized data\n\n"
"Execution control settings:\n\n"
"Execution control settings:\n"
" -f file - input file read by the tested program (stdin)\n"
" -t msec - timeout for each run (%d ms)\n"
@ -968,18 +968,27 @@ static void usage(u8* argv0) {
" -Q - use binary-only instrumentation (QEMU mode)\n"
" -U - use unicorn-based instrumentation (Unicorn mode)\n"
" -W - use qemu-based instrumentation with Wine (Wine "
"mode)\n\n"
"mode)\n"
" (Not necessary, here for consistency with other afl-* "
"tools)\n\n"
"Minimization settings:\n\n"
"Minimization settings:\n"
" -e - solve for edge coverage only, ignore hit counts\n"
" -x - treat non-zero exit codes as crashes\n\n"
"For additional tips, please consult %s/README.\n\n",
"For additional tips, please consult %s/README.md.\n\n"
argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
"Environment variables used:\n"
"TMPDIR: directory to use for temporary input files\n"
"ASAN_OPTIONS: custom settings for ASAN\n"
" (must contain abort_on_error=1 and symbolize=0)\n"
"MSAN_OPTIONS: custom settings for MSAN\n"
" (must contain exitcode="STRINGIFY(MSAN_ERROR)" and symbolize=0)\n"
"AFL_PRELOAD: LD_PRELOAD settings for target\n"
"AFL_TMIN_EXACT: require execution paths to match for crashing inputs\n"
, argv0, EXEC_TIMEOUT, MEM_LIMIT, doc_path);
exit(1);

View File

@ -120,7 +120,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
rm -f test-instr.plain.0 test-instr.plain.1
TUPLES=`echo 0|../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- ./test-instr.plain 2>&1 | grep Captur | awk '{print$3}'`
test "$TUPLES" -gt 3 -a "$TUPLES" -lt 7 && {
test "$TUPLES" -gt 3 -a "$TUPLES" -lt 8 && {
$ECHO "$GREEN[+] ${AFL_GCC} run reported $TUPLES instrumented locations which is fine"
} || {
$ECHO "$RED[!] ${AFL_GCC} produces weird instrumentation numbers: $TUPLES"