-
Notifications
You must be signed in to change notification settings - Fork 28
/
fp_afl_mode.c
97 lines (74 loc) · 2.84 KB
/
fp_afl_mode.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
#include "fpicker.h"
// Forkserver logic
// based on AFL++'s afl-proxy.c example
static bool _start_forkserver() {
uint8_t tmp[4] = {0, 0, 0, 0};
return write(FORKSRV_FD+1, tmp, 4) == 4;
}
static uint32_t _next_testcase(uint8_t *buf, uint32_t max_len) {
int32_t status = 0;
int32_t res = 1;
// Wait for parent by reading from the pipe. Abort if read fails.
if (read(FORKSRV_FD, &status, 4) != 4) return 0;
// afl only writes the test case to stdout when the cmdline does not contain "@@"
status = read(0, buf, max_len);
// Report that we are starting the target
if (write(FORKSRV_FD + 1, &res, 4) != 4) return 0;
return status;
}
static bool _end_testcase(int32_t status) {
if (write(FORKSRV_FD + 1, &status, 4) != 4) {
plog("[!] Error writing status in _end_testcase.\n");
return false;
}
return true;
}
void _forkserver_send_error() {
// we don't really care about the actual status that much, just want to report an error
uint32_t status = 0xffff;
int s = write(FORKSRV_FD + 1, &status, 4);
if (s < 0) {
plog("[!] Error while sending error to forkserver :(\n");
}
}
void run_forkserver(fuzzer_state_t *fstate) {
uint32_t len;
uint8_t buf[FUZZING_PAYLOAD_SIZE];
if(!_start_forkserver()) {
plog("[!] Unable to start forkserver, couldn't write to parent.\n");
return;
}
struct timeval *mut_timer = _start_measure();
plog("[*] Everything ready, starting to fuzz!\n");
while ((len = _next_testcase(buf, sizeof(buf))) >= 0) {
fstate->mutation_time += _stop_measure(mut_timer);
struct timeval *iteration_timer = _start_measure();
do_fuzz_iteration(fstate, buf, len);
// Check if the fuzzed process is still running
if (kill(fstate->target_pid, 0) == -1) {
plog("[!] Target process is not there anymore. Crash?\n");
fstate->exec_ret_status = SIGSEGV;
if (fstate->config->exec_mode == EXEC_MODE_SPAWN) {
spawn_or_attach(fstate);
} else {
_forkserver_send_error();
do_exit(fstate);
}
}
if (!_end_testcase(fstate->exec_ret_status)) {
break;
}
fstate->exec_ret_status = 0;
bzero(buf, len);
fstate->total_payload_count++;
if (fstate->config->metrics) {
uint64_t itime = _stop_measure(iteration_timer);
int mut_avg = fstate->mutation_time / fstate->total_payload_count;
int cov_avg = fstate->coverage_time / fstate->total_payload_count;
plog("[METRICS]: [t=%lu] [fc=%llu] [cur_loop=%d] [mut_avg=%d] [cov_avg=%d]\n",
time(NULL), fstate->total_payload_count, itime, mut_avg, cov_avg);
}
mut_timer = _start_measure();
}
plog("[!] Forkserver execution ended\n");
}