forked from mirrorer/afl
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit dea4f90
Showing
69 changed files
with
9,676 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
# | ||
# american fuzzy lop - make wrapper | ||
# --------------------------------- | ||
# | ||
# Written and maintained by Michal Zalewski <lcamtuf@google.com> | ||
# | ||
# Copyright 2013, 2014 Google Inc. 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 | ||
# | ||
|
||
PROGNAME = afl | ||
VERSION = 0.47b | ||
|
||
BIN_PATH = /usr/local/bin | ||
HELPER_PATH = /usr/local/lib/afl | ||
|
||
PROGS = afl-gcc afl-as afl-fuzz afl-showmap | ||
|
||
CFLAGS += -O3 -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \ | ||
-DAFL_PATH=\"$(HELPER_PATH)\" -DVERSION=\"$(VERSION)\" | ||
|
||
GCC48PLUS := $(shell expr `$(CC) -dumpversion | cut -f-2 -d.` \>= 4.8) | ||
|
||
ifeq "$(GCC48PLUS)" "1" | ||
CFLAGS += -DUSE_ASAN=1 | ||
endif | ||
|
||
ifneq "$(HOSTNAME)" "raccoon" | ||
CFLAGS += -Wno-format | ||
endif | ||
|
||
COMM_HDR = alloc-inl.h config.h debug.h types.h | ||
|
||
all: test_gcc test_x86 $(PROGS) test_build test_prev all_done | ||
|
||
test_gcc: | ||
@echo "[*] Checking for an installation of GCC..." | ||
@$(CC) -v >.test 2>&1; grep -iq '^gcc.version' .test || ( echo; echo "Oops, looks like you don't have GCC installed (or you need to specify \$CC)."; echo; rm -f .test; exit 1 ) | ||
@rm -f .test | ||
|
||
test_x86: | test_gcc | ||
@echo "[*] Checking for the ability to compile x86 code..." | ||
@echo 'main() { __asm__("xorb %al, %al"); }' | $(CC) -w -x c - -o .test || ( echo; echo "Oops, looks like your compiler can't generate x86 code."; echo; echo "(If you are looking for ARM, see experimental/arm_support/README.)"; echo; exit 1 ) | ||
@rm -f .test | ||
|
||
afl-gcc: afl-gcc.c $(COMM_HDR) | test_x86 | ||
$(CC) $(CFLAGS) $(LDFLAGS) $@.c -o $@ | ||
ln -s afl-gcc afl-g++ 2>/dev/null || true | ||
|
||
afl-as: afl-as.c afl-as.h $(COMM_HDR) | test_x86 | ||
$(CC) $(CFLAGS) $(LDFLAGS) $@.c -o $@ | ||
ln -s afl-as as 2>/dev/null || true | ||
|
||
afl-fuzz: afl-fuzz.c $(COMM_HDR) | test_x86 | ||
$(CC) $(CFLAGS) $(LDFLAGS) $@.c -o $@ | ||
|
||
afl-showmap: afl-showmap.c $(COMM_HDR) | test_x86 | ||
$(CC) $(CFLAGS) $(LDFLAGS) $@.c -o $@ | ||
|
||
test_build: afl-gcc afl-as afl-showmap | ||
@echo "[*] Testing GCC wrapper and instrumentation output..." | ||
AFL_QUIET=1 AFL_PATH=. ./afl-gcc $(CFLAGS) test-instr.c -o test-instr | ||
echo 0 | AFL_SINK_OUTPUT=1 AFL_QUIET=1 ./afl-showmap ./test-instr 2>.test-instr0 | ||
echo 1 | AFL_SINK_OUTPUT=1 AFL_QUIET=1 ./afl-showmap ./test-instr 2>.test-instr1 | ||
@rm -f test-instr | ||
@diff -qs .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation does not seem to be behaving correctly!"; echo; echo "Please ping <lcamtuf@google.com> to troubleshoot the issue."; echo; exit 1; fi | ||
@echo "[+] All right, the instrumentation seems to be working!" | ||
|
||
test_prev: test_build | ||
@test -f "$(HELPER_PATH)/as"; TR="$$?"; if [ "$$TR" = "0" ]; then echo "[!] NOTE: You seem to have another copy of afl installed in $(HELPER_PATH)."; echo " You must use 'make install' or set AFL_PATH to use the current build instead."; else echo "[+] No previously-installed build detected, no need to replace anything."; fi | ||
|
||
all_done: test_prev | ||
@echo "[+] All done! Be sure to review README - it's pretty short and useful." | ||
|
||
clean: | ||
rm -f $(PROGS) as afl-g++ *.o *~ a.out core core.[1-9][0-9]* *.stackdump test .test | ||
rm -rf out_dir | ||
|
||
install: all | ||
install afl-gcc afl-g++ afl-fuzz afl-showmap $${DESTDIR}$(BIN_PATH) | ||
mkdir -p -m 755 $${DESTDIR}$(HELPER_PATH) 2>/dev/null | ||
install afl-as as $${DESTDIR}$(HELPER_PATH) | ||
|
||
publish: clean | ||
test "`basename $$PWD`" = "afl" || exit 1 | ||
cd ..; rm -rf $(PROGNAME)-$(VERSION); cp -pr $(PROGNAME) $(PROGNAME)-$(VERSION); \ | ||
tar cfvz ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz $(PROGNAME)-$(VERSION) | ||
chmod 644 ~/www/afl/releases/$(PROGNAME)-$(VERSION).tgz | ||
( cd ~/www/afl/releases/; ln -s -f $(PROGNAME)-$(VERSION).tgz $(PROGNAME)-latest.tgz ) | ||
cat docs/README >~/www/afl/README.txt | ||
cat docs/status_screen.txt >~/www/afl/status_screen.txt | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
docs/README |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
/* | ||
american fuzzy lop - wrapper for GNU as | ||
--------------------------------------- | ||
Written and maintained by Michal Zalewski <lcamtuf@google.com> | ||
Copyright 2013, 2014 Google Inc. 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 | ||
The sole purpose of this wrapper is to preprocess assembly files generated | ||
by GCC and inject the instrumentation bits included from afl-as.h. It is | ||
automatically invoked by the toolchain when compiling programs using | ||
afl-gcc. | ||
If AFL_QUIET is set, non-essential messages will not be shown. This is | ||
useful when dealing with wonky build systems. | ||
*/ | ||
|
||
#define AFL_MAIN | ||
|
||
#include "config.h" | ||
#include "types.h" | ||
#include "debug.h" | ||
#include "alloc-inl.h" | ||
|
||
#include "afl-as.h" | ||
|
||
#include <stdio.h> | ||
#include <unistd.h> | ||
#include <stdlib.h> | ||
#include <string.h> | ||
#include <time.h> | ||
#include <ctype.h> | ||
#include <sys/fcntl.h> | ||
#include <sys/wait.h> | ||
#include <sys/time.h> | ||
|
||
static u8** as_params; /* Parameters passed to the real 'as' */ | ||
|
||
static u8* input_file; /* Originally specified input file */ | ||
static u8* modified_file; /* Instrumented file for the real 'as' */ | ||
|
||
static u32 rand_seed; /* Random seed used for instrumentation */ | ||
|
||
static u8 be_quiet, /* Quiet mode (no stderr output) */ | ||
use_64bit; /* Output 64-bit instrumentation */ | ||
|
||
|
||
/* Examine and modify parameters to pass to 'as'. Note that the file name | ||
is always the last parameter passed by GCC, so we exploit this property | ||
to keep the code simple. */ | ||
|
||
static void edit_params(int argc, char** argv) { | ||
|
||
u8* tmp_dir = getenv("TMPDIR"); | ||
u32 i; | ||
|
||
if (!tmp_dir) tmp_dir = "/tmp"; | ||
|
||
as_params = ck_alloc((argc + 1) * sizeof(u8*)); | ||
|
||
memcpy(as_params, argv, argc * sizeof(u8*)); | ||
|
||
as_params[0] = "as"; | ||
as_params[argc] = 0; | ||
|
||
for (i = 1; i < argc; i++) | ||
if (!strcmp(as_params[i], "--64")) use_64bit = 1; | ||
|
||
input_file = as_params[argc - 1]; | ||
|
||
if (input_file[0] == '-') { | ||
|
||
if (input_file[1]) FATAL("Incorrect use (not called through afl-gcc?)"); | ||
else input_file = NULL; | ||
|
||
} | ||
|
||
modified_file = alloc_printf("%s/.afl-%u-%u.s", tmp_dir, getpid(), | ||
(u32)time(NULL)); | ||
|
||
as_params[argc - 1] = modified_file; | ||
|
||
} | ||
|
||
|
||
/* Process input file, generate modified_file. Insert instrumentation in all | ||
the appropriate places. */ | ||
|
||
static void add_instrumentation(void) { | ||
|
||
static u8 line[MAX_AS_LINE]; | ||
|
||
FILE* inf; | ||
FILE* outf; | ||
s32 outfd; | ||
u32 ins_lines = 0; | ||
u8 now_instr = 0, force_inhibit = 0; | ||
|
||
if (input_file) { | ||
|
||
inf = fopen(input_file, "r"); | ||
if (!inf) PFATAL("Unable to read '%s'", input_file); | ||
|
||
} else inf = stdin; | ||
|
||
outfd = open(modified_file, O_WRONLY | O_EXCL | O_CREAT, 0600); | ||
|
||
if (outfd < 0) PFATAL("Unable to write to '%s'", modified_file); | ||
|
||
outf = fdopen(outfd, "w"); | ||
|
||
if (!outf) PFATAL("fdopen() failed"); | ||
|
||
while (fgets(line, MAX_AS_LINE, inf)) { | ||
|
||
fputs(line, outf); | ||
|
||
/* We only want to instrument the .text section. So, let's keep track | ||
of that in processed files. */ | ||
|
||
if (line[0] == '\t' && line[1] == '.') { | ||
|
||
if (!strncmp(line + 2, "text\n", 5) || | ||
!strncmp(line + 2, "section\t.text", 13)) { | ||
now_instr = 1; | ||
continue; | ||
} | ||
|
||
if (!strncmp(line + 2, "section\t", 8) || | ||
!strncmp(line + 2, "bss\n", 4) || | ||
!strncmp(line + 2, "data\n", 5)) { | ||
now_instr = 0; | ||
continue; | ||
} | ||
|
||
} | ||
|
||
if (strstr(line, ".code")) { | ||
|
||
if (strstr(line, ".code32")) force_inhibit = use_64bit; | ||
if (strstr(line, ".code64")) force_inhibit = !use_64bit; | ||
|
||
} | ||
|
||
/* If we're in the right mood for instrumenting, check for function | ||
names or conditional labels. */ | ||
|
||
if (!force_inhibit && now_instr && ( | ||
(strstr(line, ":\n") && (line[0] == '.' ? isdigit(line[2]) : 1)) || | ||
(line[0] == '\t' && line[1] == 'j' && line[2] != 'm'))) { | ||
|
||
/* Every function name and conditional label is given a random ID. | ||
This ID, XORed with the ID of the previously executed one, is used | ||
to selected a byte in the execution bitmap that is updated by the | ||
runtime instrumentation. | ||
All of this forms an almost-unique identifier of a particular state | ||
transition in program's control flow. | ||
If COVERAGE_ONLY is set, the instrumentation will use the current | ||
location only, and skip the XOR part. */ | ||
|
||
fprintf(outf, use_64bit ? trampoline_fmt_64 : trampoline_fmt_32, | ||
R(MAP_SIZE)); | ||
|
||
ins_lines++; | ||
|
||
} | ||
|
||
} | ||
|
||
if (ins_lines) | ||
fputs(use_64bit ? main_payload_64 : main_payload_32, outf); | ||
|
||
if (input_file) fclose(inf); | ||
fclose(outf); | ||
|
||
if (!be_quiet) { | ||
|
||
if (!ins_lines) WARNF("No instrumentation targets found."); | ||
else OKF("Instrumented %u locations (%s-bit mode, seed 0x%08x).", | ||
ins_lines, use_64bit ? "64" : "32", rand_seed); | ||
|
||
} | ||
|
||
} | ||
|
||
|
||
/* Main entry point */ | ||
|
||
int main(int argc, char** argv) { | ||
|
||
s32 pid; | ||
int status; | ||
|
||
struct timeval tv; | ||
struct timezone tz; | ||
|
||
if (!getenv("AFL_QUIET") && !getenv("as_nl")) { | ||
|
||
SAYF(cCYA "afl-as " cBRI VERSION cRST " (" __DATE__ " " __TIME__ | ||
") by <lcamtuf@google.com>\n"); | ||
|
||
} else be_quiet = 1; | ||
|
||
if (argc < 2) { | ||
|
||
SAYF("\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. You probably don't want to\n" | ||
"run this program directly.\n\n"); | ||
|
||
exit(1); | ||
|
||
} | ||
|
||
gettimeofday(&tv, &tz); | ||
|
||
rand_seed = tv.tv_sec ^ tv.tv_usec ^ getpid(); | ||
|
||
srandom(rand_seed); | ||
|
||
edit_params(argc, argv); | ||
|
||
add_instrumentation(); | ||
|
||
if (!(pid = fork())) { | ||
|
||
execvp(as_params[0], (char**)as_params); | ||
FATAL("Oops, failed to execute '%s' - check your PATH", as_params[0]); | ||
|
||
} | ||
|
||
if (pid < 0) PFATAL("fork() failed"); | ||
|
||
if (waitpid(pid, &status, 0) <= 0) PFATAL("waitpid() failed"); | ||
|
||
unlink(modified_file); | ||
|
||
exit(WEXITSTATUS(status)); | ||
|
||
} | ||
|
Oops, something went wrong.