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