1*08b48e0bSAndroid Build Coastguard Worker /*
2*08b48e0bSAndroid Build Coastguard Worker american fuzzy lop++ - afl-proxy skeleton example
3*08b48e0bSAndroid Build Coastguard Worker ---------------------------------------------------
4*08b48e0bSAndroid Build Coastguard Worker
5*08b48e0bSAndroid Build Coastguard Worker Written by Marc Heuse <[email protected]>
6*08b48e0bSAndroid Build Coastguard Worker
7*08b48e0bSAndroid Build Coastguard Worker Copyright 2019-2024 AFLplusplus Project. All rights reserved.
8*08b48e0bSAndroid Build Coastguard Worker
9*08b48e0bSAndroid Build Coastguard Worker Licensed under the Apache License, Version 2.0 (the "License");
10*08b48e0bSAndroid Build Coastguard Worker you may not use this file except in compliance with the License.
11*08b48e0bSAndroid Build Coastguard Worker You may obtain a copy of the License at:
12*08b48e0bSAndroid Build Coastguard Worker
13*08b48e0bSAndroid Build Coastguard Worker http://www.apache.org/licenses/LICENSE-2.0
14*08b48e0bSAndroid Build Coastguard Worker
15*08b48e0bSAndroid Build Coastguard Worker
16*08b48e0bSAndroid Build Coastguard Worker HOW-TO
17*08b48e0bSAndroid Build Coastguard Worker ======
18*08b48e0bSAndroid Build Coastguard Worker
19*08b48e0bSAndroid Build Coastguard Worker You only need to change the while() loop of the main() to send the
20*08b48e0bSAndroid Build Coastguard Worker data of buf[] with length len to the target and write the coverage
21*08b48e0bSAndroid Build Coastguard Worker information to __afl_area_ptr[__afl_map_size]
22*08b48e0bSAndroid Build Coastguard Worker
23*08b48e0bSAndroid Build Coastguard Worker
24*08b48e0bSAndroid Build Coastguard Worker */
25*08b48e0bSAndroid Build Coastguard Worker
26*08b48e0bSAndroid Build Coastguard Worker #ifdef __ANDROID__
27*08b48e0bSAndroid Build Coastguard Worker #include "android-ashmem.h"
28*08b48e0bSAndroid Build Coastguard Worker #endif
29*08b48e0bSAndroid Build Coastguard Worker #include "config.h"
30*08b48e0bSAndroid Build Coastguard Worker #include "types.h"
31*08b48e0bSAndroid Build Coastguard Worker
32*08b48e0bSAndroid Build Coastguard Worker #include <stdio.h>
33*08b48e0bSAndroid Build Coastguard Worker #include <stdlib.h>
34*08b48e0bSAndroid Build Coastguard Worker #include <signal.h>
35*08b48e0bSAndroid Build Coastguard Worker #include <unistd.h>
36*08b48e0bSAndroid Build Coastguard Worker #include <string.h>
37*08b48e0bSAndroid Build Coastguard Worker #include <assert.h>
38*08b48e0bSAndroid Build Coastguard Worker #include <stdint.h>
39*08b48e0bSAndroid Build Coastguard Worker #include <errno.h>
40*08b48e0bSAndroid Build Coastguard Worker
41*08b48e0bSAndroid Build Coastguard Worker #include <sys/mman.h>
42*08b48e0bSAndroid Build Coastguard Worker #include <sys/shm.h>
43*08b48e0bSAndroid Build Coastguard Worker #include <sys/wait.h>
44*08b48e0bSAndroid Build Coastguard Worker #include <sys/types.h>
45*08b48e0bSAndroid Build Coastguard Worker #include <fcntl.h>
46*08b48e0bSAndroid Build Coastguard Worker
47*08b48e0bSAndroid Build Coastguard Worker u8 *__afl_area_ptr;
48*08b48e0bSAndroid Build Coastguard Worker
49*08b48e0bSAndroid Build Coastguard Worker #ifdef __ANDROID__
50*08b48e0bSAndroid Build Coastguard Worker u32 __afl_map_size = MAP_SIZE;
51*08b48e0bSAndroid Build Coastguard Worker #else
52*08b48e0bSAndroid Build Coastguard Worker __thread u32 __afl_map_size = MAP_SIZE;
53*08b48e0bSAndroid Build Coastguard Worker #endif
54*08b48e0bSAndroid Build Coastguard Worker
55*08b48e0bSAndroid Build Coastguard Worker /* Error reporting to forkserver controller */
56*08b48e0bSAndroid Build Coastguard Worker
send_forkserver_error(int error)57*08b48e0bSAndroid Build Coastguard Worker void send_forkserver_error(int error) {
58*08b48e0bSAndroid Build Coastguard Worker
59*08b48e0bSAndroid Build Coastguard Worker u32 status;
60*08b48e0bSAndroid Build Coastguard Worker if (!error || error > 0xffff) return;
61*08b48e0bSAndroid Build Coastguard Worker status = (FS_OPT_ERROR | FS_OPT_SET_ERROR(error));
62*08b48e0bSAndroid Build Coastguard Worker if (write(FORKSRV_FD + 1, (char *)&status, 4) != 4) return;
63*08b48e0bSAndroid Build Coastguard Worker
64*08b48e0bSAndroid Build Coastguard Worker }
65*08b48e0bSAndroid Build Coastguard Worker
66*08b48e0bSAndroid Build Coastguard Worker /* SHM setup. */
67*08b48e0bSAndroid Build Coastguard Worker
__afl_map_shm(void)68*08b48e0bSAndroid Build Coastguard Worker static void __afl_map_shm(void) {
69*08b48e0bSAndroid Build Coastguard Worker
70*08b48e0bSAndroid Build Coastguard Worker char *id_str = getenv(SHM_ENV_VAR);
71*08b48e0bSAndroid Build Coastguard Worker char *ptr;
72*08b48e0bSAndroid Build Coastguard Worker
73*08b48e0bSAndroid Build Coastguard Worker /* NOTE TODO BUG FIXME: if you want to supply a variable sized map then
74*08b48e0bSAndroid Build Coastguard Worker uncomment the following: */
75*08b48e0bSAndroid Build Coastguard Worker
76*08b48e0bSAndroid Build Coastguard Worker /*
77*08b48e0bSAndroid Build Coastguard Worker if ((ptr = getenv("AFL_MAP_SIZE")) != NULL) {
78*08b48e0bSAndroid Build Coastguard Worker
79*08b48e0bSAndroid Build Coastguard Worker u32 val = atoi(ptr);
80*08b48e0bSAndroid Build Coastguard Worker if (val > 0) __afl_map_size = val;
81*08b48e0bSAndroid Build Coastguard Worker
82*08b48e0bSAndroid Build Coastguard Worker }
83*08b48e0bSAndroid Build Coastguard Worker
84*08b48e0bSAndroid Build Coastguard Worker */
85*08b48e0bSAndroid Build Coastguard Worker
86*08b48e0bSAndroid Build Coastguard Worker if (__afl_map_size > MAP_SIZE) {
87*08b48e0bSAndroid Build Coastguard Worker
88*08b48e0bSAndroid Build Coastguard Worker if (__afl_map_size > FS_OPT_MAX_MAPSIZE) {
89*08b48e0bSAndroid Build Coastguard Worker
90*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr,
91*08b48e0bSAndroid Build Coastguard Worker "Error: AFL++ tools *require* to set AFL_MAP_SIZE to %u to "
92*08b48e0bSAndroid Build Coastguard Worker "be able to run this instrumented program!\n",
93*08b48e0bSAndroid Build Coastguard Worker __afl_map_size);
94*08b48e0bSAndroid Build Coastguard Worker if (id_str) {
95*08b48e0bSAndroid Build Coastguard Worker
96*08b48e0bSAndroid Build Coastguard Worker send_forkserver_error(FS_ERROR_MAP_SIZE);
97*08b48e0bSAndroid Build Coastguard Worker exit(-1);
98*08b48e0bSAndroid Build Coastguard Worker
99*08b48e0bSAndroid Build Coastguard Worker }
100*08b48e0bSAndroid Build Coastguard Worker
101*08b48e0bSAndroid Build Coastguard Worker } else {
102*08b48e0bSAndroid Build Coastguard Worker
103*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr,
104*08b48e0bSAndroid Build Coastguard Worker "Warning: AFL++ tools will need to set AFL_MAP_SIZE to %u to "
105*08b48e0bSAndroid Build Coastguard Worker "be able to run this instrumented program!\n",
106*08b48e0bSAndroid Build Coastguard Worker __afl_map_size);
107*08b48e0bSAndroid Build Coastguard Worker
108*08b48e0bSAndroid Build Coastguard Worker }
109*08b48e0bSAndroid Build Coastguard Worker
110*08b48e0bSAndroid Build Coastguard Worker }
111*08b48e0bSAndroid Build Coastguard Worker
112*08b48e0bSAndroid Build Coastguard Worker if (id_str) {
113*08b48e0bSAndroid Build Coastguard Worker
114*08b48e0bSAndroid Build Coastguard Worker #ifdef USEMMAP
115*08b48e0bSAndroid Build Coastguard Worker const char *shm_file_path = id_str;
116*08b48e0bSAndroid Build Coastguard Worker int shm_fd = -1;
117*08b48e0bSAndroid Build Coastguard Worker unsigned char *shm_base = NULL;
118*08b48e0bSAndroid Build Coastguard Worker
119*08b48e0bSAndroid Build Coastguard Worker /* create the shared memory segment as if it was a file */
120*08b48e0bSAndroid Build Coastguard Worker shm_fd = shm_open(shm_file_path, O_RDWR, 0600);
121*08b48e0bSAndroid Build Coastguard Worker if (shm_fd == -1) {
122*08b48e0bSAndroid Build Coastguard Worker
123*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr, "shm_open() failed\n");
124*08b48e0bSAndroid Build Coastguard Worker send_forkserver_error(FS_ERROR_SHM_OPEN);
125*08b48e0bSAndroid Build Coastguard Worker exit(1);
126*08b48e0bSAndroid Build Coastguard Worker
127*08b48e0bSAndroid Build Coastguard Worker }
128*08b48e0bSAndroid Build Coastguard Worker
129*08b48e0bSAndroid Build Coastguard Worker /* map the shared memory segment to the address space of the process */
130*08b48e0bSAndroid Build Coastguard Worker shm_base =
131*08b48e0bSAndroid Build Coastguard Worker mmap(0, __afl_map_size, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0);
132*08b48e0bSAndroid Build Coastguard Worker
133*08b48e0bSAndroid Build Coastguard Worker if (shm_base == MAP_FAILED) {
134*08b48e0bSAndroid Build Coastguard Worker
135*08b48e0bSAndroid Build Coastguard Worker close(shm_fd);
136*08b48e0bSAndroid Build Coastguard Worker shm_fd = -1;
137*08b48e0bSAndroid Build Coastguard Worker
138*08b48e0bSAndroid Build Coastguard Worker fprintf(stderr, "mmap() failed\n");
139*08b48e0bSAndroid Build Coastguard Worker send_forkserver_error(FS_ERROR_MMAP);
140*08b48e0bSAndroid Build Coastguard Worker exit(2);
141*08b48e0bSAndroid Build Coastguard Worker
142*08b48e0bSAndroid Build Coastguard Worker }
143*08b48e0bSAndroid Build Coastguard Worker
144*08b48e0bSAndroid Build Coastguard Worker __afl_area_ptr = shm_base;
145*08b48e0bSAndroid Build Coastguard Worker #else
146*08b48e0bSAndroid Build Coastguard Worker u32 shm_id = atoi(id_str);
147*08b48e0bSAndroid Build Coastguard Worker
148*08b48e0bSAndroid Build Coastguard Worker __afl_area_ptr = shmat(shm_id, 0, 0);
149*08b48e0bSAndroid Build Coastguard Worker
150*08b48e0bSAndroid Build Coastguard Worker #endif
151*08b48e0bSAndroid Build Coastguard Worker
152*08b48e0bSAndroid Build Coastguard Worker if (__afl_area_ptr == (void *)-1) {
153*08b48e0bSAndroid Build Coastguard Worker
154*08b48e0bSAndroid Build Coastguard Worker send_forkserver_error(FS_ERROR_SHMAT);
155*08b48e0bSAndroid Build Coastguard Worker exit(1);
156*08b48e0bSAndroid Build Coastguard Worker
157*08b48e0bSAndroid Build Coastguard Worker }
158*08b48e0bSAndroid Build Coastguard Worker
159*08b48e0bSAndroid Build Coastguard Worker /* Write something into the bitmap so that the parent doesn't give up */
160*08b48e0bSAndroid Build Coastguard Worker
161*08b48e0bSAndroid Build Coastguard Worker __afl_area_ptr[0] = 1;
162*08b48e0bSAndroid Build Coastguard Worker
163*08b48e0bSAndroid Build Coastguard Worker }
164*08b48e0bSAndroid Build Coastguard Worker
165*08b48e0bSAndroid Build Coastguard Worker }
166*08b48e0bSAndroid Build Coastguard Worker
167*08b48e0bSAndroid Build Coastguard Worker /* Fork server logic. */
168*08b48e0bSAndroid Build Coastguard Worker
__afl_start_forkserver(void)169*08b48e0bSAndroid Build Coastguard Worker static void __afl_start_forkserver(void) {
170*08b48e0bSAndroid Build Coastguard Worker
171*08b48e0bSAndroid Build Coastguard Worker u8 tmp[4] = {0, 0, 0, 0};
172*08b48e0bSAndroid Build Coastguard Worker u32 status = 0;
173*08b48e0bSAndroid Build Coastguard Worker
174*08b48e0bSAndroid Build Coastguard Worker if (__afl_map_size <= FS_OPT_MAX_MAPSIZE)
175*08b48e0bSAndroid Build Coastguard Worker status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
176*08b48e0bSAndroid Build Coastguard Worker if (status) status |= (FS_OPT_ENABLED);
177*08b48e0bSAndroid Build Coastguard Worker memcpy(tmp, &status, 4);
178*08b48e0bSAndroid Build Coastguard Worker
179*08b48e0bSAndroid Build Coastguard Worker /* Phone home and tell the parent that we're OK. */
180*08b48e0bSAndroid Build Coastguard Worker
181*08b48e0bSAndroid Build Coastguard Worker if (write(FORKSRV_FD + 1, tmp, 4) != 4) return;
182*08b48e0bSAndroid Build Coastguard Worker
183*08b48e0bSAndroid Build Coastguard Worker }
184*08b48e0bSAndroid Build Coastguard Worker
__afl_next_testcase(u8 * buf,u32 max_len)185*08b48e0bSAndroid Build Coastguard Worker static u32 __afl_next_testcase(u8 *buf, u32 max_len) {
186*08b48e0bSAndroid Build Coastguard Worker
187*08b48e0bSAndroid Build Coastguard Worker s32 status, res = 0xffffff;
188*08b48e0bSAndroid Build Coastguard Worker
189*08b48e0bSAndroid Build Coastguard Worker /* Wait for parent by reading from the pipe. Abort if read fails. */
190*08b48e0bSAndroid Build Coastguard Worker if (read(FORKSRV_FD, &status, 4) != 4) return 0;
191*08b48e0bSAndroid Build Coastguard Worker
192*08b48e0bSAndroid Build Coastguard Worker /* we have a testcase - read it */
193*08b48e0bSAndroid Build Coastguard Worker status = read(0, buf, max_len);
194*08b48e0bSAndroid Build Coastguard Worker
195*08b48e0bSAndroid Build Coastguard Worker /* report that we are starting the target */
196*08b48e0bSAndroid Build Coastguard Worker if (write(FORKSRV_FD + 1, &res, 4) != 4) return 0;
197*08b48e0bSAndroid Build Coastguard Worker
198*08b48e0bSAndroid Build Coastguard Worker return status;
199*08b48e0bSAndroid Build Coastguard Worker
200*08b48e0bSAndroid Build Coastguard Worker }
201*08b48e0bSAndroid Build Coastguard Worker
__afl_end_testcase(void)202*08b48e0bSAndroid Build Coastguard Worker static void __afl_end_testcase(void) {
203*08b48e0bSAndroid Build Coastguard Worker
204*08b48e0bSAndroid Build Coastguard Worker int status = 0xffffff;
205*08b48e0bSAndroid Build Coastguard Worker
206*08b48e0bSAndroid Build Coastguard Worker if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(1);
207*08b48e0bSAndroid Build Coastguard Worker
208*08b48e0bSAndroid Build Coastguard Worker }
209*08b48e0bSAndroid Build Coastguard Worker
210*08b48e0bSAndroid Build Coastguard Worker /* you just need to modify the while() loop in this main() */
211*08b48e0bSAndroid Build Coastguard Worker
main(int argc,char * argv[])212*08b48e0bSAndroid Build Coastguard Worker int main(int argc, char *argv[]) {
213*08b48e0bSAndroid Build Coastguard Worker
214*08b48e0bSAndroid Build Coastguard Worker /* This is were the testcase data is written into */
215*08b48e0bSAndroid Build Coastguard Worker u8 buf[1024]; // this is the maximum size for a test case! set it!
216*08b48e0bSAndroid Build Coastguard Worker s32 len;
217*08b48e0bSAndroid Build Coastguard Worker
218*08b48e0bSAndroid Build Coastguard Worker /* here you specify the map size you need that you are reporting to
219*08b48e0bSAndroid Build Coastguard Worker afl-fuzz. Any value is fine as long as it can be divided by 32. */
220*08b48e0bSAndroid Build Coastguard Worker __afl_map_size = MAP_SIZE; // default is 65536
221*08b48e0bSAndroid Build Coastguard Worker
222*08b48e0bSAndroid Build Coastguard Worker /* then we initialize the shared memory map and start the forkserver */
223*08b48e0bSAndroid Build Coastguard Worker __afl_map_shm();
224*08b48e0bSAndroid Build Coastguard Worker __afl_start_forkserver();
225*08b48e0bSAndroid Build Coastguard Worker
226*08b48e0bSAndroid Build Coastguard Worker while ((len = __afl_next_testcase(buf, sizeof(buf))) > 0) {
227*08b48e0bSAndroid Build Coastguard Worker
228*08b48e0bSAndroid Build Coastguard Worker if (len > 4) { // the minimum data size you need for the target
229*08b48e0bSAndroid Build Coastguard Worker
230*08b48e0bSAndroid Build Coastguard Worker /* here you have to create the magic that feeds the buf/len to the
231*08b48e0bSAndroid Build Coastguard Worker target and write the coverage to __afl_area_ptr */
232*08b48e0bSAndroid Build Coastguard Worker
233*08b48e0bSAndroid Build Coastguard Worker // ... the magic ...
234*08b48e0bSAndroid Build Coastguard Worker
235*08b48e0bSAndroid Build Coastguard Worker // remove this, this is just to make afl-fuzz not complain when run
236*08b48e0bSAndroid Build Coastguard Worker if (buf[0] == 0xff)
237*08b48e0bSAndroid Build Coastguard Worker __afl_area_ptr[1] = 1;
238*08b48e0bSAndroid Build Coastguard Worker else
239*08b48e0bSAndroid Build Coastguard Worker __afl_area_ptr[2] = 2;
240*08b48e0bSAndroid Build Coastguard Worker
241*08b48e0bSAndroid Build Coastguard Worker }
242*08b48e0bSAndroid Build Coastguard Worker
243*08b48e0bSAndroid Build Coastguard Worker /* report the test case is done and wait for the next */
244*08b48e0bSAndroid Build Coastguard Worker __afl_end_testcase();
245*08b48e0bSAndroid Build Coastguard Worker
246*08b48e0bSAndroid Build Coastguard Worker }
247*08b48e0bSAndroid Build Coastguard Worker
248*08b48e0bSAndroid Build Coastguard Worker return 0;
249*08b48e0bSAndroid Build Coastguard Worker
250*08b48e0bSAndroid Build Coastguard Worker }
251*08b48e0bSAndroid Build Coastguard Worker
252