Name Date Size #Lines LOC

..--

assets/H25-Apr-2025-

README.mdH A D25-Apr-20254.6 KiB206146

build.shH A D25-Apr-20251.8 KiB5843

demo-so.cH A D25-Apr-2025602 4225

template.cppH A D25-Apr-20255.5 KiB252155

README.md

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![screen1](assets/screen1.png)