From d02483e40d9ba0529c978dc4cfbcfc1429f8eeba Mon Sep 17 00:00:00 2001 From: Jonathan Wilson Date: Tue, 27 Jul 2021 08:19:06 +0100 Subject: Added test for fuzzing a lib on OSX --- frida_mode/test/osx-lib/harness.c | 77 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 frida_mode/test/osx-lib/harness.c (limited to 'frida_mode/test/osx-lib/harness.c') diff --git a/frida_mode/test/osx-lib/harness.c b/frida_mode/test/osx-lib/harness.c new file mode 100644 index 00000000..4ffddbf6 --- /dev/null +++ b/frida_mode/test/osx-lib/harness.c @@ -0,0 +1,77 @@ +#include +#include +#include +#include +#include + + +//typedef for our exported target function. +typedef void (*CRASHME)(const uint8_t *Data, size_t Size); + +//globals +CRASHME fpn_crashme = NULL; + + +int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size){ + fpn_crashme(data, size); + return 0; +} + +void run (int argc, const char * argv[]) +{ + for (int i = 1; i < argc; i++) { + fprintf(stderr, "Running: %s\n", argv[i]); + FILE *f = fopen(argv[i], "r"); + assert(f); + fseek(f, 0, SEEK_END); + size_t len = ftell(f); + fseek(f, 0, SEEK_SET); + unsigned char *buf = (unsigned char*)malloc(len); + size_t n_read = fread(buf, 1, len, f); + fclose(f); + assert(n_read == len); + LLVMFuzzerTestOneInput(buf, len); + free(buf); + fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read); + } +} + +static int load() +{ + // handles to required libs + void *dylib = NULL; + + dylib = dlopen("./libcrashme.dylib", RTLD_LAZY); + if (dylib == NULL) + { + + printf("[-] Failed to load lib\n"); + printf("[-] Dlerror: %s\n", dlerror()); + return 1; + + } + + printf("[+] Resolve function\n"); + + fpn_crashme = (CRASHME)dlsym(dylib, "crashme"); + if (!fpn_crashme) + { + + printf("[-] Failed to find function\n"); + return 1; + + } + + printf("[+] Found function.\n"); + return 0; +} + +int main(int argc, const char * argv[]) +{ + + if (load() != 0) { return 1; } + + run(argc, argv); + + return 0; +} -- cgit 1.4.1 From 58636fd54e869f1b4c256529721a194ca6ce4e6d Mon Sep 17 00:00:00 2001 From: Jonathan Wilson Date: Tue, 27 Jul 2021 09:18:53 +0100 Subject: Update readme, minor tweaks --- frida_mode/README.md | 12 ++++++++++++ frida_mode/test/osx-lib/GNUmakefile | 3 ++- frida_mode/test/osx-lib/harness.c | 26 +++++++++----------------- 3 files changed, 23 insertions(+), 18 deletions(-) (limited to 'frida_mode/test/osx-lib/harness.c') diff --git a/frida_mode/README.md b/frida_mode/README.md index 3009e171..63959af6 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -300,6 +300,18 @@ to validate memory accesses against the shadow memory. FRIDA mode has also introduced some improvements to reduce collisions in the map. See [here](MapDensity.md) for details. +# OSX Library Fuzzing +An example of how to fuzz a dynamic library on OSX is included [here](test/osx-lib). +This requires the use of a simple test harness executable which will load the +library and call a target function within it. The dependent library can either +be loaded in using `dlopen` and `dlsym` in a function marked +`__attribute__((constructor()))` or the test harness can simply be linked +against it. It is important that the target library is loaded before execution +of `main`, since this is the point that FRIDA mode is initialized. Otherwise, it +will not be possible to configure coverage for the test library using +`AFL_FRIDA_INST_RANGES` or similar. + + ## TODO The next features to be added are Aarch32 support as well as looking at diff --git a/frida_mode/test/osx-lib/GNUmakefile b/frida_mode/test/osx-lib/GNUmakefile index a095783e..fb99fd6a 100644 --- a/frida_mode/test/osx-lib/GNUmakefile +++ b/frida_mode/test/osx-lib/GNUmakefile @@ -21,7 +21,7 @@ HARNESS_LDFLAGS:=-Wl,-no_pie LIB_CFLAGS:=-dynamiclib GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh -AFL_FRIDA_MAIN_ADDR=$(shell $(GET_SYMBOL_ADDR) $(HARNESS_BIN) run 0x0) +AFL_FRIDA_MAIN_ADDR=$(shell $(GET_SYMBOL_ADDR) $(HARNESS_BIN) main 0x0) AFL_FRIDA_FUZZ_ADDR=$(shell $(GET_SYMBOL_ADDR) $(HARNESS_BIN) LLVMFuzzerTestOneInput 0x0) AFL_FRIDA_FUZZ_ADDR2=$(shell $(GET_SYMBOL_ADDR) $(HARNESS2_BIN) LLVMFuzzerTestOneInput 0x0) @@ -82,6 +82,7 @@ frida_persistent_hook: $(HARNESS_BIN) $(LIB_BIN) $(AFLPP_DRIVER_DUMMY_INPUT) $(T AFL_FRIDA_PERSISTENT_CNT=1000000 \ AFL_ENTRYPOINT=$(AFL_FRIDA_FUZZ_ADDR) \ AFL_FRIDA_PERSISTENT_HOOK=$(AFLPP_FRIDA_DRIVER_HOOK_OBJ) \ + AFL_FRIDA_INST_RANGES=libcrashme.dylib,harness \ $(ROOT)afl-fuzz \ -D \ -O \ diff --git a/frida_mode/test/osx-lib/harness.c b/frida_mode/test/osx-lib/harness.c index 4ffddbf6..3d427b4a 100644 --- a/frida_mode/test/osx-lib/harness.c +++ b/frida_mode/test/osx-lib/harness.c @@ -17,8 +17,9 @@ int LLVMFuzzerTestOneInput(const unsigned char* data, size_t size){ return 0; } -void run (int argc, const char * argv[]) +int main(int argc, const char * argv[]) { + for (int i = 1; i < argc; i++) { fprintf(stderr, "Running: %s\n", argv[i]); FILE *f = fopen(argv[i], "r"); @@ -34,20 +35,22 @@ void run (int argc, const char * argv[]) free(buf); fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read); } + + return 0; } -static int load() -{ +__attribute__((constructor())) +void constructor(void) { // handles to required libs void *dylib = NULL; - dylib = dlopen("./libcrashme.dylib", RTLD_LAZY); + dylib = dlopen("./libcrashme.dylib", RTLD_NOW); if (dylib == NULL) { printf("[-] Failed to load lib\n"); printf("[-] Dlerror: %s\n", dlerror()); - return 1; + exit(1); } @@ -58,20 +61,9 @@ static int load() { printf("[-] Failed to find function\n"); - return 1; + exit(1); } printf("[+] Found function.\n"); - return 0; -} - -int main(int argc, const char * argv[]) -{ - - if (load() != 0) { return 1; } - - run(argc, argv); - - return 0; } -- cgit 1.4.1