• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2    american fuzzy lop++ - persistent mode example
3    --------------------------------------------
4 
5    Originally written by Michal Zalewski
6 
7    Copyright 2015 Google Inc. All rights reserved.
8 
9    Licensed under the Apache License, Version 2.0 (the "License");
10    you may not use this file except in compliance with the License.
11    You may obtain a copy of the License at:
12 
13      http://www.apache.org/licenses/LICENSE-2.0
14 
15    This file demonstrates the high-performance "persistent mode" that may be
16    suitable for fuzzing certain fast and well-behaved libraries, provided that
17    they are stateless or that their internal state can be easily reset
18    across runs.
19 
20    To make this work, the library and this shim need to be compiled in LLVM
21    mode using afl-clang-fast (other compiler wrappers will *not* work).
22 
23  */
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <signal.h>
29 #include <string.h>
30 #include <limits.h>
31 
32 /* this lets the source compile without afl-clang-fast/lto */
33 #ifndef __AFL_FUZZ_TESTCASE_LEN
34 
35 ssize_t       fuzz_len;
36 unsigned char fuzz_buf[1024000];
37 
38   #define __AFL_FUZZ_TESTCASE_LEN fuzz_len
39   #define __AFL_FUZZ_TESTCASE_BUF fuzz_buf
40   #define __AFL_FUZZ_INIT() void sync(void);
41   #define __AFL_LOOP(x) \
42     ((fuzz_len = read(0, fuzz_buf, sizeof(fuzz_buf))) > 0 ? 1 : 0)
43   #define __AFL_INIT() sync()
44 
45 #endif
46 
47 __AFL_FUZZ_INIT();
48 
49 /* Main entry point. */
50 
51 /* To ensure checks are not optimized out it is recommended to disable
52    code optimization for the fuzzer harness main() */
53 #pragma clang optimize off
54 #pragma GCC            optimize("O0")
55 
main(int argc,char ** argv)56 int main(int argc, char **argv) {
57 
58   ssize_t        len;                        /* how much input did we read? */
59   unsigned char *buf;                        /* test case buffer pointer    */
60 
61   /* The number passed to __AFL_LOOP() controls the maximum number of
62      iterations before the loop exits and the program is allowed to
63      terminate normally. This limits the impact of accidental memory leaks
64      and similar hiccups. */
65 
66   __AFL_INIT();
67   buf = __AFL_FUZZ_TESTCASE_BUF;  // this must be assigned before __AFL_LOOP!
68 
69   while (__AFL_LOOP(UINT_MAX)) {  // increase if you have good stability
70 
71     len = __AFL_FUZZ_TESTCASE_LEN;  // do not use the macro directly in a call!
72 
73     // fprintf(stderr, "input: %zd \"%s\"\n", len, buf);
74 
75     /* do we have enough data? */
76     if (len < 8) continue;
77 
78     if (strcmp((char *)buf, "thisisateststring") == 0) printf("teststring\n");
79 
80     if (buf[0] == 'f') {
81 
82       printf("one\n");
83       if (buf[1] == 'o') {
84 
85         printf("two\n");
86         if (buf[2] == 'o') {
87 
88           printf("three\n");
89           if (buf[3] == '!') {
90 
91             printf("four\n");
92             if (buf[4] == '!') {
93 
94               printf("five\n");
95               if (buf[5] == '!') {
96 
97                 printf("six\n");
98                 abort();
99 
100               }
101 
102             }
103 
104           }
105 
106         }
107 
108       }
109 
110     }
111 
112     /*** END PLACEHOLDER CODE ***/
113 
114   }
115 
116   /* Once the loop is exited, terminate normally - AFL will restart the process
117      when this happens, with a clean slate when it comes to allocated memory,
118      leftover file descriptors, etc. */
119 
120   return 0;
121 
122 }
123 
124