From 814242225725f338e35f9af372ee55daba5b4f38 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Wed, 23 Oct 2019 20:07:16 +0100 Subject: [PATCH 1/7] Porting libtokencap to Darwin. Reading only main addresses and read only's. --- libtokencap/Makefile | 3 +++ libtokencap/libtokencap.so.c | 37 ++++++++++++++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/libtokencap/Makefile b/libtokencap/Makefile index 91933140..702ce696 100644 --- a/libtokencap/Makefile +++ b/libtokencap/Makefile @@ -24,6 +24,9 @@ CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign ifeq "$(shell uname)" "Linux" TARGETS = libtokencap.so endif +ifeq "$(shell uname)" "Darwin" + TARGETS = libtokencap.so +endif all: $(TARGETS) libtokencap.so: libtokencap.so.c ../config.h diff --git a/libtokencap/libtokencap.so.c b/libtokencap/libtokencap.so.c index 39095beb..212fa31d 100644 --- a/libtokencap/libtokencap.so.c +++ b/libtokencap/libtokencap.so.c @@ -26,10 +26,15 @@ #include "../types.h" #include "../config.h" -#ifndef __linux__ -#error "Sorry, this library is Linux-specific for now!" +#if !defined(__linux__) && !defined(__APPLE__) +#error "Sorry, this library is unsupported in this platform for now!" #endif /* !__linux__ */ +#if defined(__APPLE__) +#include +#include +#endif + /* Mapping data and such */ #define MAX_MAPPINGS 1024 @@ -46,6 +51,7 @@ static FILE* __tokencap_out_file; static void __tokencap_load_mappings(void) { +#if defined(__linux__) u8 buf[MAX_LINE]; FILE* f = fopen("/proc/self/maps", "r"); @@ -69,7 +75,34 @@ static void __tokencap_load_mappings(void) { } 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)®ion, &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; + } + } + } + +#endif } /* Check an address against the list of read-only mappings. */ From cb7ada2e78333c3d53928adf0575cf04be8bb907 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Thu, 24 Oct 2019 22:32:37 +0200 Subject: [PATCH 2/7] fix libtokencap test for Darwin --- test/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.sh b/test/test.sh index da0590ef..e4a5eb63 100755 --- a/test/test.sh +++ b/test/test.sh @@ -273,7 +273,7 @@ test -e ../afl-gcc-fast && { $ECHO "$BLUE[*] Testing: shared library extensions" gcc -o test-compcov test-compcov.c > /dev/null 2>&1 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 && { $ECHO "$GREEN[+] libtokencap did successfully capture tokens" } || $ECHO "$RED[!] libtokencap did not capture tokens" From b4b26d420771ca19a26828d9fdd53cdd66dab9ee Mon Sep 17 00:00:00 2001 From: David Carlier Date: Thu, 24 Oct 2019 18:48:08 +0100 Subject: [PATCH 3/7] FreeBSD implementation --- libtokencap/Makefile | 3 +++ libtokencap/libtokencap.so.c | 50 +++++++++++++++++++++++++++++++++++- 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/libtokencap/Makefile b/libtokencap/Makefile index 702ce696..07c13144 100644 --- a/libtokencap/Makefile +++ b/libtokencap/Makefile @@ -27,6 +27,9 @@ endif ifeq "$(shell uname)" "Darwin" TARGETS = libtokencap.so endif +ifeq "$(shell uname)" "FreeBSD" + TARGETS = libtokencap.so +endif all: $(TARGETS) libtokencap.so: libtokencap.so.c ../config.h diff --git a/libtokencap/libtokencap.so.c b/libtokencap/libtokencap.so.c index 212fa31d..1050378c 100644 --- a/libtokencap/libtokencap.so.c +++ b/libtokencap/libtokencap.so.c @@ -22,17 +22,23 @@ #include #include #include +#include #include "../types.h" #include "../config.h" -#if !defined(__linux__) && !defined(__APPLE__) +#if !defined(__linux__) && !defined(__APPLE__) && !defined(__FreeBSD__) #error "Sorry, this library is unsupported in this platform for now!" #endif /* !__linux__ */ #if defined(__APPLE__) #include #include +#elif defined(__FreeBSD__) +#include +#include +#include +#include #endif /* Mapping data and such */ @@ -102,6 +108,48 @@ static void __tokencap_load_mappings(void) { } } +#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 } From b0036759fa991f5c940e40ad4b313fbe3504f6f8 Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Fri, 25 Oct 2019 01:22:20 +0200 Subject: [PATCH 4/7] portability fix: use cc instead of gcc for test-compcov --- test/test.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test.sh b/test/test.sh index e4a5eb63..42ddf70b 100755 --- a/test/test.sh +++ b/test/test.sh @@ -271,7 +271,7 @@ test -e ../afl-gcc-fast && { } || $ECHO "$YELLOW[-] gcc_plugin not compiled, cannot test" $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 && { 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 && { From e0ff20dd372579f4e4a540df00c8d6f4e218672b Mon Sep 17 00:00:00 2001 From: hexcoder- Date: Fri, 25 Oct 2019 01:51:53 +0200 Subject: [PATCH 5/7] cosmetics --- libtokencap/libtokencap.so.c | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/libtokencap/libtokencap.so.c b/libtokencap/libtokencap.so.c index 1050378c..ddeae8b8 100644 --- a/libtokencap/libtokencap.so.c +++ b/libtokencap/libtokencap.so.c @@ -27,18 +27,18 @@ #include "../types.h" #include "../config.h" -#if !defined(__linux__) && !defined(__APPLE__) && !defined(__FreeBSD__) -#error "Sorry, this library is unsupported in this platform for now!" -#endif /* !__linux__ */ +#if !defined __linux__ && !defined __APPLE__ && !defined __FreeBSD__ +# error "Sorry, this library is unsupported in this platform for now!" +#endif /* !__linux__ && !__APPLE__ && ! __FreeBSD__ */ -#if defined(__APPLE__) -#include -#include -#elif defined(__FreeBSD__) -#include -#include -#include -#include +#if defined __APPLE__ +# include +# include +#elif defined __FreeBSD__ +# include +# include +# include +# include #endif /* Mapping data and such */ @@ -57,7 +57,8 @@ static FILE* __tokencap_out_file; static void __tokencap_load_mappings(void) { -#if defined(__linux__) +#if defined __linux__ + u8 buf[MAX_LINE]; FILE* f = fopen("/proc/self/maps", "r"); @@ -81,7 +82,9 @@ static void __tokencap_load_mappings(void) { } fclose(f); -#elif defined(__APPLE__) + +#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; @@ -108,7 +111,8 @@ static void __tokencap_load_mappings(void) { } } -#elif defined(__FreeBSD__) +#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]); From b8abf27b86e74a4ab6889322ef232a00f1f018c4 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Fri, 25 Oct 2019 09:36:17 +0200 Subject: [PATCH 6/7] Update README.md remove Linux-only :-), list supported OSes --- libtokencap/README.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/libtokencap/README.md b/libtokencap/README.md index baf69da1..8aae38bf 100644 --- a/libtokencap/README.md +++ b/libtokencap/README.md @@ -2,7 +2,7 @@ (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 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 @@ -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 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 -and non-invasive way to distinguish between read-only and read-write memory -mappings. The `__tokencap_load_mappings()` function is the only thing that would -need to be changed for other OSes. Porting to platforms with /proc//maps -(e.g., FreeBSD) should be trivial. +Portability hints: There is probably no particularly portable and non-invasive +way to distinguish between read-only and read-write memory mappings. +The `__tokencap_load_mappings()` function is the only thing that would +need to be changed for other OSes. + +Current supported OSes are: Linux, Darwin, FreeBSD (thanks to @devnexen) From 7e9b6fe0aa820c8bce258eaa24d230ce96347d38 Mon Sep 17 00:00:00 2001 From: hexcoder Date: Fri, 25 Oct 2019 10:44:34 +0200 Subject: [PATCH 7/7] Update sister_projects.txt status updates for python mutators and whitelist selective instrumentation feature. --- docs/sister_projects.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/sister_projects.txt b/docs/sister_projects.txt index a2eb2a22..25e5560c 100644 --- a/docs/sister_projects.txt +++ b/docs/sister_projects.txt @@ -319,11 +319,13 @@ Fuzzer shell for SQLite (Richard Hipp) 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 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 Kernel fuzzing (Dmitry Vyukov)