Merge branch 'master' of github.com:vanhauser-thc/AFLplusplus

This commit is contained in:
Andrea Fioraldi 2019-10-25 14:02:38 +02:00
commit e7871b2c76
5 changed files with 105 additions and 11 deletions

View File

@ -319,11 +319,13 @@ Fuzzer shell for SQLite (Richard Hipp)
Support for Python mutation modules (Christian Holler) Support for Python mutation modules (Christian Holler)
------------------------------------------------------ ------------------------------------------------------
now integrated in AFL++, originally from here
https://github.com/choller/afl/blob/master/docs/mozilla/python_modules.txt https://github.com/choller/afl/blob/master/docs/mozilla/python_modules.txt
Support for selective instrumentation (Christian Holler) Support for selective instrumentation (Christian Holler)
-------------------------------------------------------- --------------------------------------------------------
now integrated in AFL++, originally from here
https://github.com/choller/afl/blob/master/docs/mozilla/partial_instrumentation.txt https://github.com/choller/afl/blob/master/docs/mozilla/partial_instrumentation.txt
Kernel fuzzing (Dmitry Vyukov) Kernel fuzzing (Dmitry Vyukov)

View File

@ -24,6 +24,12 @@ CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign
ifeq "$(shell uname)" "Linux" ifeq "$(shell uname)" "Linux"
TARGETS = libtokencap.so TARGETS = libtokencap.so
endif endif
ifeq "$(shell uname)" "Darwin"
TARGETS = libtokencap.so
endif
ifeq "$(shell uname)" "FreeBSD"
TARGETS = libtokencap.so
endif
all: $(TARGETS) all: $(TARGETS)
libtokencap.so: libtokencap.so.c ../config.h libtokencap.so: libtokencap.so.c ../config.h

View File

@ -2,7 +2,7 @@
(See ../docs/README for the general instruction manual.) (See ../docs/README for the general instruction manual.)
This Linux-only companion library allows you to instrument `strcmp()`, `memcmp()`, This companion library allows you to instrument `strcmp()`, `memcmp()`,
and related functions to automatically extract syntax tokens passed to any of and related functions to automatically extract syntax tokens passed to any of
these libcalls. The resulting list of tokens may be then given as a starting these libcalls. The resulting list of tokens may be then given as a starting
dictionary to afl-fuzz (the -x option) to improve coverage on subsequent dictionary to afl-fuzz (the -x option) to improve coverage on subsequent
@ -55,9 +55,10 @@ If you don't get any results, the target library is probably not using strcmp()
and memcmp() to parse input; or you haven't compiled it with -fno-builtin; or and memcmp() to parse input; or you haven't compiled it with -fno-builtin; or
the whole thing isn't dynamically linked, and LD_PRELOAD is having no effect. the whole thing isn't dynamically linked, and LD_PRELOAD is having no effect.
PS. The library is Linux-only because there is probably no particularly portable Portability hints: There is probably no particularly portable and non-invasive
and non-invasive way to distinguish between read-only and read-write memory way to distinguish between read-only and read-write memory mappings.
mappings. The `__tokencap_load_mappings()` function is the only thing that would The `__tokencap_load_mappings()` function is the only thing that would
need to be changed for other OSes. Porting to platforms with /proc/<pid>/maps need to be changed for other OSes.
(e.g., FreeBSD) should be trivial.
Current supported OSes are: Linux, Darwin, FreeBSD (thanks to @devnexen)

View File

@ -22,13 +22,24 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#include <unistd.h>
#include "../types.h" #include "../types.h"
#include "../config.h" #include "../config.h"
#ifndef __linux__ #if !defined __linux__ && !defined __APPLE__ && !defined __FreeBSD__
#error "Sorry, this library is Linux-specific for now!" # error "Sorry, this library is unsupported in this platform for now!"
#endif /* !__linux__ */ #endif /* !__linux__ && !__APPLE__ && ! __FreeBSD__ */
#if defined __APPLE__
# include <mach/vm_map.h>
# include <mach/mach_init.h>
#elif defined __FreeBSD__
# include <sys/types.h>
# include <sys/sysctl.h>
# include <sys/user.h>
# include <sys/mman.h>
#endif
/* Mapping data and such */ /* Mapping data and such */
@ -46,6 +57,8 @@ static FILE* __tokencap_out_file;
static void __tokencap_load_mappings(void) { static void __tokencap_load_mappings(void) {
#if defined __linux__
u8 buf[MAX_LINE]; u8 buf[MAX_LINE];
FILE* f = fopen("/proc/self/maps", "r"); FILE* f = fopen("/proc/self/maps", "r");
@ -70,6 +83,78 @@ static void __tokencap_load_mappings(void) {
fclose(f); fclose(f);
#elif defined __APPLE__
struct vm_region_submap_info_64 region;
mach_msg_type_number_t cnt = VM_REGION_SUBMAP_INFO_COUNT_64;
vm_address_t base = 0;
vm_size_t size = 0;
natural_t depth = 0;
__tokencap_ro_loaded = 1;
while (1) {
if (vm_region_recurse_64(mach_task_self(), &base, &size, &depth,
(vm_region_info_64_t)&region, &cnt) != KERN_SUCCESS) break;
if (region.is_submap) {
depth++;
} else {
/* We only care of main map addresses and the read only kinds */
if ((region.protection & VM_PROT_READ) && !(region.protection & VM_PROT_WRITE)) {
__tokencap_ro[__tokencap_ro_cnt].st = (void *)base;
__tokencap_ro[__tokencap_ro_cnt].en = (void *)(base + size);
if (++__tokencap_ro_cnt == MAX_MAPPINGS) break;
}
}
}
#elif defined __FreeBSD__
int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid()};
char *buf, *low, *high;
size_t miblen = sizeof(mib)/sizeof(mib[0]);
size_t len;
if (sysctl(mib, miblen, NULL, &len, NULL, 0) == -1) return;
len = len * 4 / 3;
buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
if (sysctl(mib, miblen, buf, &len, NULL, 0) == -1) {
munmap(buf, len);
return;
}
low = buf;
high = low + len;
__tokencap_ro_loaded = 1;
while (low < high) {
struct kinfo_vmentry *region = (struct kinfo_vmentry *)low;
size_t size = region->kve_structsize;
if (size == 0) break;
/* We go through the whole mapping of the process and track read-only addresses */
if ((region->kve_protection & KVME_PROT_READ) &&
!(region->kve_protection & KVME_PROT_WRITE)) {
__tokencap_ro[__tokencap_ro_cnt].st = (void *)region->kve_start;
__tokencap_ro[__tokencap_ro_cnt].en = (void *)region->kve_end;
if (++__tokencap_ro_cnt == MAX_MAPPINGS) break;
}
low += size;
}
munmap(buf, len);
#endif
} }
/* Check an address against the list of read-only mappings. */ /* Check an address against the list of read-only mappings. */

View File

@ -271,9 +271,9 @@ test -e ../afl-gcc-fast && {
} || $ECHO "$YELLOW[-] gcc_plugin not compiled, cannot test" } || $ECHO "$YELLOW[-] gcc_plugin not compiled, cannot test"
$ECHO "$BLUE[*] Testing: shared library extensions" $ECHO "$BLUE[*] Testing: shared library extensions"
gcc -o test-compcov test-compcov.c > /dev/null 2>&1 cc -o test-compcov test-compcov.c > /dev/null 2>&1
test -e ../libtokencap.so && { test -e ../libtokencap.so && {
AFL_TOKEN_FILE=token.out LD_PRELOAD=../libtokencap.so ./test-compcov foobar > /dev/null 2>&1 AFL_TOKEN_FILE=token.out LD_PRELOAD=../libtokencap.so DYLD_INSERT_LIBRARIES=../libtokencap.so DYLD_FORCE_FLAT_NAMESPACE=1 ./test-compcov foobar > /dev/null 2>&1
grep -q BUGMENOT token.out > /dev/null 2>&1 && { grep -q BUGMENOT token.out > /dev/null 2>&1 && {
$ECHO "$GREEN[+] libtokencap did successfully capture tokens" $ECHO "$GREEN[+] libtokencap did successfully capture tokens"
} || $ECHO "$RED[!] libtokencap did not capture tokens" } || $ECHO "$RED[!] libtokencap did not capture tokens"