From 574de9ff4cb2fdf2c28c32a3c2d7c5c773adb6ab Mon Sep 17 00:00:00 2001 From: hac425 Date: Sat, 9 Nov 2019 14:21:39 +0000 Subject: add basic supprt for qbdi_mode, test x86_64 Linux --- qbdi_mode/demo-so.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100755 qbdi_mode/demo-so.c (limited to 'qbdi_mode/demo-so.c') diff --git a/qbdi_mode/demo-so.c b/qbdi_mode/demo-so.c new file mode 100755 index 00000000..1820ea2f --- /dev/null +++ b/qbdi_mode/demo-so.c @@ -0,0 +1,46 @@ +#include + + + +// gcc -shared -o libdemo.so demo-so.c -w + + +int target_func(char* buf, int size){ + + printf("buffer:%p, size:%p\n", buf, size); + + switch (buf[0]) + { + case 1: + puts("222"); + if(buf[1]=='\x44'){ + puts("xxxiiii"); + } + break; + case '\xfe': + // assert(0); + if(buf[4]=='\xf0'){ + puts("xxxiiii"); + } + break; + case 0xff: + if(buf[2]=='\xff'){ + if(buf[1]=='\x44'){ + puts("xxxiiii"); + assert(0); + }else{ + puts("xxxiiii"); + } + } + puts("xxxx"); + break; + default: + puts("xxxxxxx"); + break; + } + + return 1; +} + + + -- cgit 1.4.1 From ab8fb271f71c50f46fac86fb7ac09593542726b3 Mon Sep 17 00:00:00 2001 From: hac425 Date: Sat, 9 Nov 2019 15:18:24 +0000 Subject: add support for android x86, x86-64 in qbdi mode --- include/android-ashmem.h | 2 +- qbdi_mode/build.sh | 14 ++++++++++---- qbdi_mode/demo-so.c | 8 ++++---- qbdi_mode/template.cpp | 16 ++++++++++++++-- 4 files changed, 29 insertions(+), 11 deletions(-) mode change 100644 => 100755 include/android-ashmem.h (limited to 'qbdi_mode/demo-so.c') diff --git a/include/android-ashmem.h b/include/android-ashmem.h old mode 100644 new mode 100755 index f4d31739..7d34b877 --- a/include/android-ashmem.h +++ b/include/android-ashmem.h @@ -52,7 +52,7 @@ static inline int shmctl(int __shmid, int __cmd, struct shmid_ds *__buf) { if (__cmd == IPC_RMID) { int length = ioctl(__shmid, ASHMEM_GET_SIZE, NULL); - struct ashmem_pin pin = {0, length}; + struct ashmem_pin pin = {0, (unsigned int)length}; ret = ioctl(__shmid, ASHMEM_UNPIN, &pin); close(__shmid); diff --git a/qbdi_mode/build.sh b/qbdi_mode/build.sh index 28b68e40..a45c76e6 100755 --- a/qbdi_mode/build.sh +++ b/qbdi_mode/build.sh @@ -1,6 +1,12 @@ -# ~/workspace/android-standalone-toolchain-21-x86/bin/i686-linux-android-g++ -o loader -Wl,-rpath,/data/lsl template.cpp -Iusr/local/include/ -Lusr/local/lib/ -lQBDI -# ~/workspace/android-standalone-toolchain-21-x86/bin/i686-linux-android-gcc -shared -o libdemo.so demo-so.c -w +compiler_prefix="/home/hac425/workspace/android-standalone-toolchain-21-x86/bin/i686-linux-android-" +CFLAGS="-Iusr/local/include/ -Lusr/local/lib/" +# for x86-64 android +# compiler_prefix="/home/hac425/workspace/android-standalone-toolchain-21/bin/x86_64-linux-android-" +# CFLAGS="-Iandroid-x64/usr/local/include/ -Landroid-x64/usr/local/lib/" -g++ -o loader template.cpp -lQBDI -ldl -w -gcc -shared -o libdemo.so demo-so.c -w \ No newline at end of file +${compiler_prefix}g++ -o loader template.cpp -lQBDI -ldl -w -g ${CFLAGS} +${compiler_prefix}gcc -shared -o libdemo.so demo-so.c -w -g + +cd .. +${compiler_prefix}gcc -O3 -funroll-loops -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -I include/ -DAFL_PATH=\"/usr/local/lib/afl\" -DBIN_PATH=\"/usr/local/bin\" -DDOC_PATH=\"/usr/local/share/doc/afl\" -Wno-unused-function src/afl-fuzz-misc.c src/afl-fuzz-extras.c src/afl-fuzz-queue.c src/afl-fuzz-one.c src/afl-fuzz-python.c src/afl-fuzz-stats.c src/afl-fuzz-init.c src/afl-fuzz.c src/afl-fuzz-bitmap.c src/afl-fuzz-run.c src/afl-fuzz-globals.c src/afl-common.c src/afl-sharedmem.c src/afl-forkserver.c -o qbdi_mode/afl-fuzz -ldl -w diff --git a/qbdi_mode/demo-so.c b/qbdi_mode/demo-so.c index 1820ea2f..3ba7c449 100755 --- a/qbdi_mode/demo-so.c +++ b/qbdi_mode/demo-so.c @@ -14,7 +14,8 @@ int target_func(char* buf, int size){ case 1: puts("222"); if(buf[1]=='\x44'){ - puts("xxxiiii"); + puts("aaaaaaaaaaaaaaaaaaaaa"); + *(char*)(0) = 1; } break; case '\xfe': @@ -26,10 +27,9 @@ int target_func(char* buf, int size){ case 0xff: if(buf[2]=='\xff'){ if(buf[1]=='\x44'){ - puts("xxxiiii"); - assert(0); + *(char*)(0xdeadbeef) = 1; }else{ - puts("xxxiiii"); + puts("kkkkkk"); } } puts("xxxx"); diff --git a/qbdi_mode/template.cpp b/qbdi_mode/template.cpp index 6c118a12..85b46d2f 100755 --- a/qbdi_mode/template.cpp +++ b/qbdi_mode/template.cpp @@ -10,10 +10,17 @@ #include #include +#ifdef __ANDROID__ +#include "../include/android-ashmem.h" +#endif +#include #include #include "../config.h" + + + #include using namespace QBDI; @@ -49,7 +56,6 @@ int afl_setup(void) { /* Fork server logic, invoked once we hit _start. */ - static void afl_forkserver() { @@ -141,8 +147,14 @@ QBDI_NOINLINE int fuzz_func() static QBDI::VMAction bbcallback(QBDI::VMInstanceRef vm, const QBDI::VMState *state, QBDI::GPRState *gprState, QBDI::FPRState *fprState, void *data) { // errno = SAVED_ERRNO; +#ifdef __x86_64__ unsigned long pc = gprState->rip; - // printf("%p\n", pc); +#elif defined(i386) + unsigned long pc = gprState->eip; +#elif defined(__arm__) + unsigned long pc = gprState->pc; +#endif + if(pc >= module_base && pc <= module_end){ unsigned long offset = pc - module_base; printf("\toffset:%p\n", offset); -- cgit 1.4.1 From c8c004d568f639b09a70deecce6c634ac45d4842 Mon Sep 17 00:00:00 2001 From: hac425 Date: Thu, 14 Nov 2019 14:30:29 +0000 Subject: modify build.sh and add document --- qbdi_mode/README.md | 197 +++++++++++++++++++++++++++++++++++++++++++++++++ qbdi_mode/build.sh | 37 ++++++++-- qbdi_mode/demo-so.c | 39 ++++------ qbdi_mode/template.cpp | 90 +++++++++++----------- 4 files changed, 288 insertions(+), 75 deletions(-) create mode 100755 qbdi_mode/README.md (limited to 'qbdi_mode/demo-so.c') diff --git a/qbdi_mode/README.md b/qbdi_mode/README.md new file mode 100755 index 00000000..8891d99e --- /dev/null +++ b/qbdi_mode/README.md @@ -0,0 +1,197 @@ +# qbdi-based binary-only instrumentation for afl-fuzz + +## 1) Introduction + +The code in ./qbdi_mode allows you to build a standalone feature that +using the QBDI framework to fuzz android native library. + + +## 2) Build + +First download the Android NDK + +``` +https://developer.android.com/ndk/downloads +https://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip +``` + +Then unzip it and build the standalone-toolchain +For x86_64 standalone-toolchain + +``` +unzip android-ndk-r20-linux-x86_64.zip +cd android-ndk-r20/ +./build/tools/make_standalone_toolchain.py --arch x86_64 --api 21 --install-dir ../android-standalone-toolchain-x86_64 +``` + +For x86 standalone-toolchain + +``` +./build/tools/make_standalone_toolchain.py --arch x86 --api 21 --install-dir ../android-standalone-toolchain-x86 +``` + +Then download the QBDI SDK from website + +``` +https://qbdi.quarkslab.com/ +``` + +For Android x86_64 +``` +https://github.com/QBDI/QBDI/releases/download/v0.7.0/QBDI-0.7.0-android-X86_64.tar.gz +``` + +Then decompress the sdk + +``` +mkdir android-qbdi-sdk-x86_64 +cp QBDI-0.7.0-android-X86_64.tar.gz android-qbdi-sdk-x86_64/ +cd android-qbdi-sdk-x86_64/ +tar xvf QBDI-0.7.0-android-X86_64.tar.gz +``` + +Now set the `STANDALONE_TOOLCHAIN_PATH` to the path of standalone-toolchain + +``` +export STANDALONE_TOOLCHAIN_PATH=/home/hac425/workspace/android-standalone-toolchain-x86_64 +``` + +set the `QBDI_SDK_PATH` to the path of QBDI SDK + +``` +export QBDI_SDK_PATH=/home/hac425/workspace/AFLplusplus/qbdi_mode/android-qbdi-sdk-x86_64/ +``` + +Then run the build.sh + +``` +./build.sh x86_64 +``` + +this could build the afl-fuzz and also the qbdi template for android x86_64 + + +### Example + +The demo-so.c is an vulnerable library, it has a function for test + +``` +int target_func(char *buf, int size) +{ + printf("buffer:%p, size:%p\n", buf, size); + switch (buf[0]) + { + case 1: + puts("222"); + if (buf[1] == '\x44') + { + puts("null ptr deference"); + *(char *)(0) = 1; + } + break; + case 0xff: + if (buf[2] == '\xff') + { + if (buf[1] == '\x44') + { + puts("crash...."); + *(char *)(0xdeadbeef) = 1; + } + } + break; + default: + puts("default action"); + break; + } + + return 1; +} +``` + +This could be build to `libdemo.so`. + +Then we should load the library in template.cpp and find the `target` function address. +``` + void *handle = dlopen(lib_path, RTLD_LAZY); + .......................................... + .......................................... + .......................................... + p_target_func = (target_func)dlsym(handle, "target_func"); +``` + +then we read the data from file and call the function in `fuzz_func` + +``` +QBDI_NOINLINE int fuzz_func() +{ + // afl forkserver stuff + if (afl_setup()) + { + afl_forkserver(); + } + + // read the data from file(argv[2]) + unsigned long len = 0; + char *data = read_file(FPATH, &len); + + + printf("In fuzz_func\n"); + + // call the target function with input data. + p_target_func(data, len); + return 1; +} +``` + +Just compile it +``` +./build.sh x86_64 +``` + +Then push the `afl-fuzz`, `loader`, `libdemo.so`, the `libQBDI.so` from the QBDI SDK and the `libc++_shared.so` from android-standalone-toolchain to android device + +``` +adb push afl-fuzz /data/local/tmp +adb push libdemo.so /data/local/tmp +adb push loader /data/local/tmp +adb push android-qbdi-sdk-x86_64/usr/local/lib/libQBDI.so /data/local/tmp +adb push ../../android-standalone-toolchain-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so +/data/local/tmp +``` + +In android adb shell, we could try to run the loader +``` +export LD_LIBRARY_PATH=/data/local/tmp +./loader /data/local/tmp/libdemo.so init +``` +the normal output like + +``` +# ./loader /data/local/tmp/libdemo.so init p_target_func:0x7b41ac26e600 +In fuzz_func + offset:0x600 + offset:0x580 +buffer:0x7b41abe2b050, size:0x4 + offset:0x628 + offset:0x646 + offset:0x64b + offset:0x65c + offset:0x6df + offset:0x590 +default action + offset:0x6eb +``` + +now run `afl-fuzz` to fuzz the library + +``` +mkdir in +echo xxxx > in/1 +./afl-fuzz -i in -o out -- ./loader /data/local/tmp/libdemo.so @@ +``` + +the snapshot + +![image-20191114222336674](assets/image-20191114222336674.png) + +good job. \ No newline at end of file diff --git a/qbdi_mode/build.sh b/qbdi_mode/build.sh index a45c76e6..7ac4c75d 100755 --- a/qbdi_mode/build.sh +++ b/qbdi_mode/build.sh @@ -1,12 +1,39 @@ -compiler_prefix="/home/hac425/workspace/android-standalone-toolchain-21-x86/bin/i686-linux-android-" -CFLAGS="-Iusr/local/include/ -Lusr/local/lib/" +if [ -z ${STANDALONE_TOOLCHAIN_PATH} ]; then + echo "please set the android-standalone-toolchain path in STANDALONE_TOOLCHAIN_PATH environmental variable" + echo "for example: " + echo " export STANDALONE_TOOLCHAIN_PATH=/home/android-standalone-toolchain-21/" + exit +fi -# for x86-64 android -# compiler_prefix="/home/hac425/workspace/android-standalone-toolchain-21/bin/x86_64-linux-android-" -# CFLAGS="-Iandroid-x64/usr/local/include/ -Landroid-x64/usr/local/lib/" +if [ -z ${QBDI_SDK_PATH} ]; then + echo "please set the qbdi sdk path in QBDI_SDK_PATH environmental variable" + echo "for example: " + echo " export QBDI_SDK_PATH=/home/QBDI-Android/" + exit +fi + + +if [ "$1" = "x86" ]; then + echo "build x86 qbdi" + compiler_prefix="${STANDALONE_TOOLCHAIN_PATH}/bin/i686-linux-android-" +elif [ "$1" = "x86_64" ]; then + echo "build x86_64 qbdi" + compiler_prefix="${STANDALONE_TOOLCHAIN_PATH}/bin/x86_64-linux-android-" +else + echo "usage: ./build.sh arch[x86, x86_64]" + exit +fi + + +CFLAGS="-I${QBDI_SDK_PATH}/usr/local/include/ -L${QBDI_SDK_PATH}/usr/local/lib/" + +# build the qbdi template ${compiler_prefix}g++ -o loader template.cpp -lQBDI -ldl -w -g ${CFLAGS} + +# build the demo share library ${compiler_prefix}gcc -shared -o libdemo.so demo-so.c -w -g +# build afl-fuzz cd .. ${compiler_prefix}gcc -O3 -funroll-loops -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -I include/ -DAFL_PATH=\"/usr/local/lib/afl\" -DBIN_PATH=\"/usr/local/bin\" -DDOC_PATH=\"/usr/local/share/doc/afl\" -Wno-unused-function src/afl-fuzz-misc.c src/afl-fuzz-extras.c src/afl-fuzz-queue.c src/afl-fuzz-one.c src/afl-fuzz-python.c src/afl-fuzz-stats.c src/afl-fuzz-init.c src/afl-fuzz.c src/afl-fuzz-bitmap.c src/afl-fuzz-run.c src/afl-fuzz-globals.c src/afl-common.c src/afl-sharedmem.c src/afl-forkserver.c -o qbdi_mode/afl-fuzz -ldl -w diff --git a/qbdi_mode/demo-so.c b/qbdi_mode/demo-so.c index 3ba7c449..5e74f268 100755 --- a/qbdi_mode/demo-so.c +++ b/qbdi_mode/demo-so.c @@ -1,46 +1,33 @@ #include - - // gcc -shared -o libdemo.so demo-so.c -w - - -int target_func(char* buf, int size){ - +int target_func(char *buf, int size) +{ printf("buffer:%p, size:%p\n", buf, size); - switch (buf[0]) { case 1: puts("222"); - if(buf[1]=='\x44'){ - puts("aaaaaaaaaaaaaaaaaaaaa"); - *(char*)(0) = 1; - } - break; - case '\xfe': - // assert(0); - if(buf[4]=='\xf0'){ - puts("xxxiiii"); + if (buf[1] == '\x44') + { + puts("null ptr deference"); + *(char *)(0) = 1; } break; case 0xff: - if(buf[2]=='\xff'){ - if(buf[1]=='\x44'){ - *(char*)(0xdeadbeef) = 1; - }else{ - puts("kkkkkk"); + if (buf[2] == '\xff') + { + if (buf[1] == '\x44') + { + puts("crash...."); + *(char *)(0xdeadbeef) = 1; } } - puts("xxxx"); break; default: - puts("xxxxxxx"); + puts("default action"); break; } return 1; } - - - diff --git a/qbdi_mode/template.cpp b/qbdi_mode/template.cpp index 85b46d2f..f0b0c601 100755 --- a/qbdi_mode/template.cpp +++ b/qbdi_mode/template.cpp @@ -18,9 +18,6 @@ #include #include "../config.h" - - - #include using namespace QBDI; @@ -33,20 +30,21 @@ target_func p_target_func = NULL; rword module_base = 0; rword module_end = 0; static unsigned char - dummy[MAP_SIZE]; /* costs MAP_SIZE but saves a few instructions */ -unsigned char *afl_area_ptr = NULL; /* Exported for afl_gen_trace */ + dummy[MAP_SIZE]; /* costs MAP_SIZE but saves a few instructions */ +unsigned char *afl_area_ptr = NULL; /* Exported for afl_gen_trace */ unsigned long afl_prev_loc = 0; - /* Set up SHM region and initialize other stuff. */ -int afl_setup(void) { +int afl_setup(void) +{ char *id_str = getenv(SHM_ENV_VAR); int shm_id; - if (id_str) { + if (id_str) + { shm_id = atoi(id_str); - afl_area_ptr = (unsigned char*)shmat(shm_id, NULL, 0); + afl_area_ptr = (unsigned char *)shmat(shm_id, NULL, 0); if (afl_area_ptr == (void *)-1) return 0; memset(afl_area_ptr, 0, MAP_SIZE); @@ -54,7 +52,6 @@ int afl_setup(void) { return 1; } - /* Fork server logic, invoked once we hit _start. */ static void afl_forkserver() { @@ -74,7 +71,6 @@ static void afl_forkserver() if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2); - child_pid = fork(); if (child_pid < 0) exit(4); @@ -101,25 +97,28 @@ static void afl_forkserver() } } -void afl_maybe_log(unsigned long cur_loc) { - if(afl_area_ptr == NULL){ - return; - } - unsigned long afl_idx = cur_loc ^ afl_prev_loc; - afl_area_ptr[afl_idx % MAP_SIZE]++; - afl_prev_loc = cur_loc >> 1; +void afl_maybe_log(unsigned long cur_loc) +{ + if (afl_area_ptr == NULL) + { + return; + } + unsigned long afl_idx = cur_loc ^ afl_prev_loc; + afl_area_ptr[afl_idx % MAP_SIZE]++; + afl_prev_loc = cur_loc >> 1; } -char* read_file(char* path, unsigned long* length) { - FILE *pFile = fopen(path, "rb"); - char *pBuf; - fseek(pFile, 0, SEEK_END); - unsigned long len = ftell(pFile); - pBuf = (char*)malloc(len); - rewind(pFile); - fread(pBuf, 1, len, pFile); - fclose(pFile); - *length = len; - return pBuf; +char *read_file(char *path, unsigned long *length) +{ + FILE *pFile = fopen(path, "rb"); + char *pBuf; + fseek(pFile, 0, SEEK_END); + unsigned long len = ftell(pFile); + pBuf = (char *)malloc(len); + rewind(pFile); + fread(pBuf, 1, len, pFile); + fclose(pFile); + *length = len; + return pBuf; } char FPATH[200]; @@ -127,24 +126,21 @@ char FPATH[200]; QBDI_NOINLINE int fuzz_func() { - if(afl_setup()){ + if (afl_setup()) + { afl_forkserver(); } unsigned long len = 0; - char* data = read_file(FPATH, &len); + char *data = read_file(FPATH, &len); printf("In fuzz_func\n"); p_target_func(data, len); return 1; } - - - - - -static QBDI::VMAction bbcallback(QBDI::VMInstanceRef vm, const QBDI::VMState *state, QBDI::GPRState *gprState, QBDI::FPRState *fprState, void *data) { +static QBDI::VMAction bbcallback(QBDI::VMInstanceRef vm, const QBDI::VMState *state, QBDI::GPRState *gprState, QBDI::FPRState *fprState, void *data) +{ // errno = SAVED_ERRNO; #ifdef __x86_64__ @@ -154,9 +150,11 @@ static QBDI::VMAction bbcallback(QBDI::VMInstanceRef vm, const QBDI::VMState *st #elif defined(__arm__) unsigned long pc = gprState->pc; #endif - - if(pc >= module_base && pc <= module_end){ - unsigned long offset = pc - module_base; + + // just log the module path + if (pc >= module_base && pc <= module_end) + { + unsigned long offset = pc - module_base; printf("\toffset:%p\n", offset); afl_maybe_log(offset); } @@ -166,6 +164,12 @@ static QBDI::VMAction bbcallback(QBDI::VMInstanceRef vm, const QBDI::VMState *st int main(int argc, char **argv) { + if (argc < 3) + { + puts("usage: ./loader library_path input_file_path"); + exit(0); + } + const char *lib_path; lib_path = argv[1]; // FPATH = argv[2]; @@ -183,9 +187,9 @@ int main(int argc, char **argv) lib_name = strrchr(lib_name, '/') + 1; // printf("library name:%s\n", lib_name); - + // load library module address for log path for (MemoryMap &map : getCurrentProcessMaps()) - { + { // printf("module:%s\n", map.name.c_str()); if ((map.permission & PF_EXEC) && strstr(map.name.c_str(), lib_name) != NULL) { @@ -212,10 +216,8 @@ int main(int argc, char **argv) vm.addInstrumentedModuleFromAddr(module_base); vm.addInstrumentedModuleFromAddr((rword)&main); - vm.addVMEventCB(BASIC_BLOCK_ENTRY, bbcallback, nullptr); - // QBDI::simulateCall(state, FAKE_RET_ADDR); // vm.run((rword)&fuzz_func, (rword)FAKE_RET_ADDR); -- cgit 1.4.1 From 0071e537f3aa1ccb6dbc38a2e88bd53595021775 Mon Sep 17 00:00:00 2001 From: hac425 Date: Thu, 14 Nov 2019 14:38:04 +0000 Subject: format code for demo-so.c and template.cpp --- qbdi_mode/demo-so.c | 56 +++++---- qbdi_mode/template.cpp | 325 +++++++++++++++++++++++++------------------------ 2 files changed, 197 insertions(+), 184 deletions(-) (limited to 'qbdi_mode/demo-so.c') diff --git a/qbdi_mode/demo-so.c b/qbdi_mode/demo-so.c index 5e74f268..dbb7b714 100755 --- a/qbdi_mode/demo-so.c +++ b/qbdi_mode/demo-so.c @@ -1,33 +1,39 @@ #include // gcc -shared -o libdemo.so demo-so.c -w -int target_func(char *buf, int size) -{ - printf("buffer:%p, size:%p\n", buf, size); - switch (buf[0]) - { +int target_func(char *buf, int size) { + + printf("buffer:%p, size:%p\n", buf, size); + switch (buf[0]) { + case 1: - puts("222"); - if (buf[1] == '\x44') - { - puts("null ptr deference"); - *(char *)(0) = 1; - } - break; + puts("222"); + if (buf[1] == '\x44') { + + puts("null ptr deference"); + *(char *)(0) = 1; + + } + + break; case 0xff: - if (buf[2] == '\xff') - { - if (buf[1] == '\x44') - { - puts("crash...."); - *(char *)(0xdeadbeef) = 1; - } + if (buf[2] == '\xff') { + + if (buf[1] == '\x44') { + + puts("crash...."); + *(char *)(0xdeadbeef) = 1; + } - break; - default: - puts("default action"); - break; - } + + } + + break; + default: puts("default action"); break; + + } - return 1; + return 1; + } + diff --git a/qbdi_mode/template.cpp b/qbdi_mode/template.cpp index f0b0c601..601860d2 100755 --- a/qbdi_mode/template.cpp +++ b/qbdi_mode/template.cpp @@ -24,205 +24,212 @@ using namespace QBDI; typedef int (*target_func)(char *buf, int size); -static const size_t STACK_SIZE = 0x100000; // 1MB +static const size_t STACK_SIZE = 0x100000; // 1MB static const QBDI::rword FAKE_RET_ADDR = 0x40000; -target_func p_target_func = NULL; -rword module_base = 0; -rword module_end = 0; +target_func p_target_func = NULL; +rword module_base = 0; +rword module_end = 0; static unsigned char - dummy[MAP_SIZE]; /* costs MAP_SIZE but saves a few instructions */ -unsigned char *afl_area_ptr = NULL; /* Exported for afl_gen_trace */ + dummy[MAP_SIZE]; /* costs MAP_SIZE but saves a few instructions */ +unsigned char *afl_area_ptr = NULL; /* Exported for afl_gen_trace */ unsigned long afl_prev_loc = 0; /* Set up SHM region and initialize other stuff. */ -int afl_setup(void) -{ - char *id_str = getenv(SHM_ENV_VAR); - int shm_id; - if (id_str) - { - shm_id = atoi(id_str); - afl_area_ptr = (unsigned char *)shmat(shm_id, NULL, 0); - if (afl_area_ptr == (void *)-1) - return 0; - memset(afl_area_ptr, 0, MAP_SIZE); - } - return 1; +int afl_setup(void) { + + char *id_str = getenv(SHM_ENV_VAR); + int shm_id; + if (id_str) { + + shm_id = atoi(id_str); + afl_area_ptr = (unsigned char *)shmat(shm_id, NULL, 0); + if (afl_area_ptr == (void *)-1) return 0; + memset(afl_area_ptr, 0, MAP_SIZE); + + } + + return 1; + } /* Fork server logic, invoked once we hit _start. */ -static void afl_forkserver() -{ - - static unsigned char tmp[4]; - pid_t child_pid; - - if (write(FORKSRV_FD + 1, tmp, 4) != 4) - return; - - while (1) - { - - int status; - u32 was_killed; - // wait for afl-fuzz - if (read(FORKSRV_FD, &was_killed, 4) != 4) - exit(2); - - child_pid = fork(); - if (child_pid < 0) - exit(4); - - if (!child_pid) - { - // child return to execute code - close(FORKSRV_FD); - close(FORKSRV_FD + 1); - return; - } - - // write child pid to afl-fuzz - if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) - exit(5); - - // wait child stop - if (waitpid(child_pid, &status, 0) < 0) - exit(6); - - // send child stop status to afl-fuzz - if (write(FORKSRV_FD + 1, &status, 4) != 4) - exit(7); +static void afl_forkserver() { + + static unsigned char tmp[4]; + pid_t child_pid; + + if (write(FORKSRV_FD + 1, tmp, 4) != 4) return; + + while (1) { + + int status; + u32 was_killed; + // wait for afl-fuzz + if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(2); + + child_pid = fork(); + if (child_pid < 0) exit(4); + + if (!child_pid) { + + // child return to execute code + close(FORKSRV_FD); + close(FORKSRV_FD + 1); + return; + } + + // write child pid to afl-fuzz + if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(5); + + // wait child stop + if (waitpid(child_pid, &status, 0) < 0) exit(6); + + // send child stop status to afl-fuzz + if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(7); + + } + } -void afl_maybe_log(unsigned long cur_loc) -{ - if (afl_area_ptr == NULL) - { - return; - } - unsigned long afl_idx = cur_loc ^ afl_prev_loc; - afl_area_ptr[afl_idx % MAP_SIZE]++; - afl_prev_loc = cur_loc >> 1; +void afl_maybe_log(unsigned long cur_loc) { + + if (afl_area_ptr == NULL) { return; } + unsigned long afl_idx = cur_loc ^ afl_prev_loc; + afl_area_ptr[afl_idx % MAP_SIZE]++; + afl_prev_loc = cur_loc >> 1; + } -char *read_file(char *path, unsigned long *length) -{ - FILE *pFile = fopen(path, "rb"); - char *pBuf; - fseek(pFile, 0, SEEK_END); - unsigned long len = ftell(pFile); - pBuf = (char *)malloc(len); - rewind(pFile); - fread(pBuf, 1, len, pFile); - fclose(pFile); - *length = len; - return pBuf; + +char *read_file(char *path, unsigned long *length) { + + FILE *pFile = fopen(path, "rb"); + char *pBuf; + fseek(pFile, 0, SEEK_END); + unsigned long len = ftell(pFile); + pBuf = (char *)malloc(len); + rewind(pFile); + fread(pBuf, 1, len, pFile); + fclose(pFile); + *length = len; + return pBuf; + } char FPATH[200]; -QBDI_NOINLINE int fuzz_func() -{ +QBDI_NOINLINE int fuzz_func() { - if (afl_setup()) - { - afl_forkserver(); - } + if (afl_setup()) { afl_forkserver(); } - unsigned long len = 0; - char *data = read_file(FPATH, &len); + unsigned long len = 0; + char * data = read_file(FPATH, &len); + + printf("In fuzz_func\n"); + p_target_func(data, len); + return 1; - printf("In fuzz_func\n"); - p_target_func(data, len); - return 1; } -static QBDI::VMAction bbcallback(QBDI::VMInstanceRef vm, const QBDI::VMState *state, QBDI::GPRState *gprState, QBDI::FPRState *fprState, void *data) -{ - // errno = SAVED_ERRNO; +static QBDI::VMAction bbcallback(QBDI::VMInstanceRef vm, + const QBDI::VMState *state, + QBDI::GPRState * gprState, + QBDI::FPRState *fprState, void *data) { + + // errno = SAVED_ERRNO; #ifdef __x86_64__ - unsigned long pc = gprState->rip; + unsigned long pc = gprState->rip; #elif defined(i386) - unsigned long pc = gprState->eip; + unsigned long pc = gprState->eip; #elif defined(__arm__) - unsigned long pc = gprState->pc; + unsigned long pc = gprState->pc; #endif - - // just log the module path - if (pc >= module_base && pc <= module_end) - { - unsigned long offset = pc - module_base; - printf("\toffset:%p\n", offset); - afl_maybe_log(offset); - } - return QBDI::VMAction::CONTINUE; + + // just log the module path + if (pc >= module_base && pc <= module_end) { + + unsigned long offset = pc - module_base; + printf("\toffset:%p\n", offset); + afl_maybe_log(offset); + + } + + return QBDI::VMAction::CONTINUE; + } -int main(int argc, char **argv) -{ +int main(int argc, char **argv) { - if (argc < 3) - { - puts("usage: ./loader library_path input_file_path"); - exit(0); - } + if (argc < 3) { - const char *lib_path; - lib_path = argv[1]; - // FPATH = argv[2]; - strcpy(FPATH, argv[2]); - void *handle = dlopen(lib_path, RTLD_LAZY); + puts("usage: ./loader library_path input_file_path"); + exit(0); - if (handle == nullptr) - { - perror("Cannot load library"); - exit(EXIT_FAILURE); - } + } - const char *lib_name = lib_path; - if (strrchr(lib_name, '/') != nullptr) - lib_name = strrchr(lib_name, '/') + 1; - - // printf("library name:%s\n", lib_name); - // load library module address for log path - for (MemoryMap &map : getCurrentProcessMaps()) - { - // printf("module:%s\n", map.name.c_str()); - if ((map.permission & PF_EXEC) && strstr(map.name.c_str(), lib_name) != NULL) - { - module_base = map.range.start; - module_end = map.range.end; - } - } + const char *lib_path; + lib_path = argv[1]; + // FPATH = argv[2]; + strcpy(FPATH, argv[2]); + void *handle = dlopen(lib_path, RTLD_LAZY); + + if (handle == nullptr) { + + perror("Cannot load library"); + exit(EXIT_FAILURE); + + } + + const char *lib_name = lib_path; + if (strrchr(lib_name, '/') != nullptr) lib_name = strrchr(lib_name, '/') + 1; + + // printf("library name:%s\n", lib_name); + // load library module address for log path + for (MemoryMap &map : getCurrentProcessMaps()) { + + // printf("module:%s\n", map.name.c_str()); + if ((map.permission & PF_EXEC) && + strstr(map.name.c_str(), lib_name) != NULL) { + + module_base = map.range.start; + module_end = map.range.end; - if (module_base == 0) - { - std::cerr << "Fail to find base address" << std::endl; - return -1; } - // printf("module base:%p, module end:%p\n", module_base, module_end); - p_target_func = (target_func)dlsym(handle, "target_func"); - // p_target_func = (target_func)(module_base + 0x61a); - printf("p_target_func:%p\n", p_target_func); - VM vm; - uint8_t *fakestack = nullptr; + } + + if (module_base == 0) { - GPRState *state = vm.getGPRState(); - allocateVirtualStack(state, STACK_SIZE, &fakestack); - vm.addInstrumentedModuleFromAddr(module_base); - vm.addInstrumentedModuleFromAddr((rword)&main); + std::cerr << "Fail to find base address" << std::endl; + return -1; - vm.addVMEventCB(BASIC_BLOCK_ENTRY, bbcallback, nullptr); + } - // QBDI::simulateCall(state, FAKE_RET_ADDR); - // vm.run((rword)&fuzz_func, (rword)FAKE_RET_ADDR); + // printf("module base:%p, module end:%p\n", module_base, module_end); + p_target_func = (target_func)dlsym(handle, "target_func"); + // p_target_func = (target_func)(module_base + 0x61a); + printf("p_target_func:%p\n", p_target_func); - rword ret; - vm.call(&ret, (rword)&fuzz_func, {}); + VM vm; + uint8_t *fakestack = nullptr; + + GPRState *state = vm.getGPRState(); + allocateVirtualStack(state, STACK_SIZE, &fakestack); + vm.addInstrumentedModuleFromAddr(module_base); + vm.addInstrumentedModuleFromAddr((rword)&main); + + vm.addVMEventCB(BASIC_BLOCK_ENTRY, bbcallback, nullptr); + + // QBDI::simulateCall(state, FAKE_RET_ADDR); + // vm.run((rword)&fuzz_func, (rword)FAKE_RET_ADDR); + + rword ret; + vm.call(&ret, (rword)&fuzz_func, {}); + + return 0; - return 0; } + -- cgit 1.4.1