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