1# qbdi-based binary-only instrumentation for afl-fuzz 2 3NOTE: this code is outdated and first would need to be adapted to the current 4AFL++ versions. 5Try FRIDA mode or fpicker [https://github.com/ttdennis/fpicker/](https://github.com/ttdennis/fpicker/) first, maybe they suite your need. 6 7## 1) Introduction 8 9The code in ./qbdi_mode allows you to build a standalone feature that 10using the QBDI framework to fuzz android native library. 11 12## 2) Build 13 14First download the Android NDK 15 16``` 17https://developer.android.com/ndk/downloads 18https://dl.google.com/android/repository/android-ndk-r20-linux-x86_64.zip 19``` 20 21Then unzip it and build the standalone-toolchain 22For x86_64 standalone-toolchain 23 24``` 25unzip android-ndk-r20-linux-x86_64.zip 26cd android-ndk-r20/ 27./build/tools/make_standalone_toolchain.py --arch x86_64 --api 21 --install-dir ../android-standalone-toolchain-x86_64 28``` 29 30For x86 standalone-toolchain 31 32``` 33./build/tools/make_standalone_toolchain.py --arch x86 --api 21 --install-dir ../android-standalone-toolchain-x86 34``` 35 36In alternative you can also use the pre-built toolchain, in that case make sure 37to set the proper CC and CXX environment variables because there are many 38different compilers for each API version in the pre-built toolchain. 39 40For example: 41 42``` 43export STANDALONE_TOOLCHAIN_PATH=~/Android/Sdk/ndk/20.1.5948944/toolchains/llvm/prebuilt/linux-x86_64/ 44export CC=x86_64-linux-android21-clang 45export CXX=x86_64-linux-android21-clang++ 46``` 47 48Then download the QBDI SDK from website 49 50``` 51https://qbdi.quarkslab.com/ 52``` 53 54For Android x86_64 55 56``` 57https://github.com/QBDI/QBDI/releases/download/v0.7.0/QBDI-0.7.0-android-X86_64.tar.gz 58``` 59 60Then decompress the sdk 61 62``` 63mkdir android-qbdi-sdk-x86_64 64cp QBDI-0.7.0-android-X86_64.tar.gz android-qbdi-sdk-x86_64/ 65cd android-qbdi-sdk-x86_64/ 66tar xvf QBDI-0.7.0-android-X86_64.tar.gz 67``` 68 69Now set the `STANDALONE_TOOLCHAIN_PATH` to the path of standalone-toolchain 70 71``` 72export STANDALONE_TOOLCHAIN_PATH=/home/hac425/workspace/android-standalone-toolchain-x86_64 73``` 74 75set the `QBDI_SDK_PATH` to the path of QBDI SDK 76 77``` 78export QBDI_SDK_PATH=/home/hac425/workspace/AFLplusplus/qbdi_mode/android-qbdi-sdk-x86_64/ 79``` 80 81Then run the build.sh 82 83``` 84./build.sh x86_64 85``` 86 87this could build the afl-fuzz and also the qbdi template for android x86_64 88 89### Example 90 91The demo-so.c is an vulnerable library, it has a function for test 92 93```c 94int target_func(char *buf, int size) { 95 96 printf("buffer:%p, size:%p\n", buf, size); 97 switch (buf[0]) { 98 99 case 1: 100 puts("222"); 101 if (buf[1] == '\x44') { 102 103 puts("null ptr deference"); 104 *(char *)(0) = 1; 105 106 } 107 108 break; 109 case 0xff: 110 if (buf[2] == '\xff') { 111 112 if (buf[1] == '\x44') { 113 114 puts("crash...."); 115 *(char *)(0xdeadbeef) = 1; 116 117 } 118 119 } 120 121 break; 122 default: puts("default action"); break; 123 124 } 125 126 return 1; 127 128} 129``` 130 131This could be built to `libdemo.so`. 132 133Then load the library in template.cpp and find the `target` function address: 134 135```c 136 void *handle = dlopen(lib_path, RTLD_LAZY); 137 .......................................... 138 .......................................... 139 .......................................... 140 p_target_func = (target_func)dlsym(handle, "target_func"); 141``` 142 143Then read the data from file and call the function in `fuzz_func`: 144 145```c 146QBDI_NOINLINE int fuzz_func() { 147 148 if (afl_setup()) { afl_forkserver(); } 149 150 /* Read the input from file */ 151 unsigned long len = 0; 152 char * data = read_file(input_pathname, &len); 153 154 /* Call the target function with the input data */ 155 p_target_func(data, len); 156 return 1; 157 158} 159``` 160 161Just compile it 162 163``` 164./build.sh x86_64 165``` 166 167Then 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 168 169``` 170adb push afl-fuzz /data/local/tmp 171adb push libdemo.so /data/local/tmp 172adb push loader /data/local/tmp 173adb push android-qbdi-sdk-x86_64/usr/local/lib/libQBDI.so /data/local/tmp 174adb push ../../android-standalone-toolchain-x86_64/sysroot/usr/lib/x86_64-linux-android/libc++_shared.so 175/data/local/tmp 176``` 177 178In android adb shell, run the loader to test if it runs 179 180``` 181cd /data/local/tmp 182export LD_LIBRARY_PATH=/data/local/tmp 183mkdir in 184echo 0000 > in/1 185./loader libdemo.so in/1 186p_target_func:0x716d96a98600 187 offset:0x600 188 offset:0x580 189buffer:0x716d96609050, size:0x5 190 offset:0x628 191 offset:0x646 192 offset:0x64b 193 offset:0x65c 194 offset:0x6df 195 offset:0x590 196default action 197 offset:0x6eb 198``` 199 200Now run `afl-fuzz` to fuzz the demo library 201 202``` 203./afl-fuzz -i in -o out -- ./loader /data/local/tmp/libdemo.so @@ 204``` 205 206