mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-15 11:28:08 +00:00
add RARE schedule. also fixes doc_path
This commit is contained in:
@ -32,7 +32,7 @@
|
|||||||
* [dev](https://github.com/AFLplusplus/AFLplusplus/tree/dev) : development state of afl++ - bleeding edge and you might catch a
|
* [dev](https://github.com/AFLplusplus/AFLplusplus/tree/dev) : development state of afl++ - bleeding edge and you might catch a
|
||||||
checkout which does not compile or has a bug. *We only accept PRs in dev!!*
|
checkout which does not compile or has a bug. *We only accept PRs in dev!!*
|
||||||
* (any other) : experimental branches to work on specific features or testing
|
* (any other) : experimental branches to work on specific features or testing
|
||||||
new functionality or changes
|
new functionality or changes.
|
||||||
|
|
||||||
For releases, please see the [Releases](https://github.com/AFLplusplus/AFLplusplus/releases) tab.
|
For releases, please see the [Releases](https://github.com/AFLplusplus/AFLplusplus/releases) tab.
|
||||||
|
|
||||||
@ -365,7 +365,8 @@ The available schedules are:
|
|||||||
- quad
|
- quad
|
||||||
- lin
|
- lin
|
||||||
- exploit
|
- exploit
|
||||||
- mmopt
|
- mmopt (experimental)
|
||||||
|
- rare (experimental)
|
||||||
|
|
||||||
In parallel mode (-M/-S, several instances with shared queue), we suggest to
|
In parallel mode (-M/-S, several instances with shared queue), we suggest to
|
||||||
run the master using the explore or fast schedule (-p explore) and the slaves
|
run the master using the explore or fast schedule (-p explore) and the slaves
|
||||||
|
@ -24,10 +24,11 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
- python mutator modules and custom mutator modules now use the same
|
- python mutator modules and custom mutator modules now use the same
|
||||||
interface and hence the API changed
|
interface and hence the API changed
|
||||||
- AFL_AUTORESUME will resume execution without the need to specify `-i -`
|
- AFL_AUTORESUME will resume execution without the need to specify `-i -`
|
||||||
- added experimental power schedule -p mmopt that ignores the runtime of
|
- added experimental power schedules (-p):
|
||||||
queue entries and gives higher weighting to the last 5 queue entries
|
- mmopt: ignores runtime of queue entries, gives higher weighting to
|
||||||
it is currently experimental and subject to change but preliminary
|
the last 5 queue entries
|
||||||
results are good
|
- rare: puts focus on queue entries that hits rare branches, also ignores
|
||||||
|
runtime
|
||||||
- LTO collision free instrumented added in llvm_mode with afl-clang-lto -
|
- LTO collision free instrumented added in llvm_mode with afl-clang-lto -
|
||||||
note that this mode is amazing, but quite some targets won't compile
|
note that this mode is amazing, but quite some targets won't compile
|
||||||
- llvm_mode InsTrim mode:
|
- llvm_mode InsTrim mode:
|
||||||
|
@ -20,6 +20,7 @@ We find that AFL's exploitation-based constant schedule assigns **too much energ
|
|||||||
| `-p lin` |  |
|
| `-p lin` |  |
|
||||||
| `-p exploit` (AFL) |  |
|
| `-p exploit` (AFL) |  |
|
||||||
| `-p mmopt` | Experimental: `explore` with no weighting to runtime and increased weighting on the last 5 queue entries |
|
| `-p mmopt` | Experimental: `explore` with no weighting to runtime and increased weighting on the last 5 queue entries |
|
||||||
|
| `-p rare` | Experimental: `rare` puts focus on queue entries that hit rare edges |
|
||||||
where *α(i)* is the performance score that AFL uses to compute for the seed input *i*, *β(i)>1* is a constant, *s(i)* is the number of times that seed *i* has been chosen from the queue, *f(i)* is the number of generated inputs that exercise the same path as seed *i*, and *μ* is the average number of generated inputs exercising a path.
|
where *α(i)* is the performance score that AFL uses to compute for the seed input *i*, *β(i)>1* is a constant, *s(i)* is the number of times that seed *i* has been chosen from the queue, *f(i)* is the number of generated inputs that exercise the same path as seed *i*, and *μ* is the average number of generated inputs exercising a path.
|
||||||
|
|
||||||
More details can be found in the paper that was accepted at the [23rd ACM Conference on Computer and Communications Security (CCS'16)](https://www.sigsac.org/ccs/CCS2016/accepted-papers/).
|
More details can be found in the paper that was accepted at the [23rd ACM Conference on Computer and Communications Security (CCS'16)](https://www.sigsac.org/ccs/CCS2016/accepted-papers/).
|
||||||
|
@ -235,6 +235,7 @@ enum {
|
|||||||
/* 04 */ QUAD, /* Quadratic schedule */
|
/* 04 */ QUAD, /* Quadratic schedule */
|
||||||
/* 05 */ EXPLOIT, /* AFL's exploitation-based const. */
|
/* 05 */ EXPLOIT, /* AFL's exploitation-based const. */
|
||||||
/* 06 */ MMOPT, /* Modified MOPT schedule */
|
/* 06 */ MMOPT, /* Modified MOPT schedule */
|
||||||
|
/* 07 */ RARE, /* Rare edges */
|
||||||
|
|
||||||
POWER_SCHEDULES_NUM
|
POWER_SCHEDULES_NUM
|
||||||
|
|
||||||
|
0
include/android-ashmem.h
Executable file → Normal file
0
include/android-ashmem.h
Executable file → Normal file
@ -30,8 +30,9 @@ s8 interesting_8[] = {INTERESTING_8};
|
|||||||
s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
|
s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
|
||||||
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
|
s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
|
||||||
|
|
||||||
char *power_names[POWER_SCHEDULES_NUM] = {"explore", "fast", "coe", "lin",
|
char *power_names[POWER_SCHEDULES_NUM] = {
|
||||||
"quad", "exploit", "mmopt"};
|
|
||||||
|
"explore", "fast", "coe", "lin", "quad", "exploit", "mmopt", "rare"};
|
||||||
|
|
||||||
u8 *doc_path = NULL; /* gath to documentation dir */
|
u8 *doc_path = NULL; /* gath to documentation dir */
|
||||||
|
|
||||||
|
@ -185,12 +185,16 @@ void destroy_queue(afl_state_t *afl) {
|
|||||||
void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
||||||
|
|
||||||
u32 i;
|
u32 i;
|
||||||
u64 fav_factor = q->exec_us * q->len;
|
u64 fav_factor;
|
||||||
u64 fuzz_p2 = next_p2(q->n_fuzz);
|
u64 fuzz_p2 = next_p2(q->n_fuzz);
|
||||||
|
|
||||||
|
if (afl->schedule == MMOPT || afl->schedule == RARE)
|
||||||
|
fav_factor = q->len << 2;
|
||||||
|
else
|
||||||
|
fav_factor = q->exec_us * q->len;
|
||||||
|
|
||||||
/* For every byte set in afl->fsrv.trace_bits[], see if there is a previous
|
/* For every byte set in afl->fsrv.trace_bits[], see if there is a previous
|
||||||
winner, and how it compares to us. */
|
winner, and how it compares to us. */
|
||||||
|
|
||||||
for (i = 0; i < MAP_SIZE; ++i)
|
for (i = 0; i < MAP_SIZE; ++i)
|
||||||
|
|
||||||
if (afl->fsrv.trace_bits[i]) {
|
if (afl->fsrv.trace_bits[i]) {
|
||||||
@ -198,20 +202,20 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
if (afl->top_rated[i]) {
|
if (afl->top_rated[i]) {
|
||||||
|
|
||||||
/* Faster-executing or smaller test cases are favored. */
|
/* Faster-executing or smaller test cases are favored. */
|
||||||
|
u64 top_rated_fav_factor;
|
||||||
u64 top_rated_fuzz_p2 = next_p2(afl->top_rated[i]->n_fuzz);
|
u64 top_rated_fuzz_p2 = next_p2(afl->top_rated[i]->n_fuzz);
|
||||||
u64 top_rated_fav_factor =
|
|
||||||
afl->top_rated[i]->exec_us * afl->top_rated[i]->len;
|
|
||||||
|
|
||||||
if (fuzz_p2 > top_rated_fuzz_p2) {
|
if (afl->schedule == MMOPT || afl->schedule == RARE)
|
||||||
|
top_rated_fav_factor = afl->top_rated[i]->len << 2;
|
||||||
|
else
|
||||||
|
top_rated_fav_factor =
|
||||||
|
afl->top_rated[i]->exec_us * afl->top_rated[i]->len;
|
||||||
|
|
||||||
|
if (fuzz_p2 > top_rated_fuzz_p2)
|
||||||
continue;
|
continue;
|
||||||
|
else if (fuzz_p2 == top_rated_fuzz_p2)
|
||||||
} else if (fuzz_p2 == top_rated_fuzz_p2) {
|
|
||||||
|
|
||||||
if (fav_factor > top_rated_fav_factor) continue;
|
if (fav_factor > top_rated_fav_factor) continue;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len)
|
if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -328,7 +332,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
// Longer execution time means longer work on the input, the deeper in
|
// Longer execution time means longer work on the input, the deeper in
|
||||||
// coverage, the better the fuzzing, right? -mh
|
// coverage, the better the fuzzing, right? -mh
|
||||||
|
|
||||||
if (afl->schedule != MMOPT) {
|
if (afl->schedule != MMOPT && afl->schedule != RARE) {
|
||||||
|
|
||||||
if (q->exec_us * 0.1 > avg_exec_us)
|
if (q->exec_us * 0.1 > avg_exec_us)
|
||||||
perf_score = 10;
|
perf_score = 10;
|
||||||
@ -448,8 +452,29 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MMOPT:
|
case MMOPT:
|
||||||
|
/* -- this was a more complex setup, which is good, but competed with
|
||||||
|
-- rare. the simpler algo however is good when rare is not.
|
||||||
|
// the newer the entry, the higher the pref_score
|
||||||
|
perf_score *= (1 + (double)((double)q->depth /
|
||||||
|
(double)afl->queued_paths));
|
||||||
|
// with special focus on the last 8 entries
|
||||||
|
if (afl->max_depth - q->depth < 8) perf_score *= (1 + ((8 -
|
||||||
|
(afl->max_depth - q->depth)) / 5));
|
||||||
|
*/
|
||||||
|
// put focus on the last 5 entries
|
||||||
|
if (afl->max_depth - q->depth < 5) perf_score *= 2;
|
||||||
|
|
||||||
if (afl->max_depth - q->depth < 5) perf_score *= 1.5;
|
break;
|
||||||
|
|
||||||
|
case RARE:
|
||||||
|
|
||||||
|
// increase the score for every bitmap byte for which this entry
|
||||||
|
// is the top contender
|
||||||
|
perf_score += (q->tc_ref * 10);
|
||||||
|
// the more often fuzz result paths are equal to this queue entry,
|
||||||
|
// reduce its value
|
||||||
|
perf_score *=
|
||||||
|
(1 - (double)((double)q->n_fuzz / (double)afl->total_execs));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -32,9 +32,10 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
|||||||
|
|
||||||
struct rusage rus;
|
struct rusage rus;
|
||||||
|
|
||||||
u8 * fn = alloc_printf("%s/fuzzer_stats", afl->out_dir);
|
unsigned long long int cur_time = get_cur_time();
|
||||||
s32 fd;
|
u8 * fn = alloc_printf("%s/fuzzer_stats", afl->out_dir);
|
||||||
FILE *f;
|
s32 fd;
|
||||||
|
FILE * f;
|
||||||
|
|
||||||
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||||
|
|
||||||
@ -69,6 +70,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
|||||||
f,
|
f,
|
||||||
"start_time : %llu\n"
|
"start_time : %llu\n"
|
||||||
"last_update : %llu\n"
|
"last_update : %llu\n"
|
||||||
|
"run_time : %llu\n"
|
||||||
"fuzzer_pid : %d\n"
|
"fuzzer_pid : %d\n"
|
||||||
"cycles_done : %llu\n"
|
"cycles_done : %llu\n"
|
||||||
"execs_done : %llu\n"
|
"execs_done : %llu\n"
|
||||||
@ -99,7 +101,8 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
|||||||
"\n"
|
"\n"
|
||||||
"target_mode : %s%s%s%s%s%s%s%s\n"
|
"target_mode : %s%s%s%s%s%s%s%s\n"
|
||||||
"command_line : %s\n",
|
"command_line : %s\n",
|
||||||
afl->start_time / 1000, get_cur_time() / 1000, getpid(),
|
afl->start_time / 1000, cur_time / 1000,
|
||||||
|
(cur_time - afl->start_time) / 1000, getpid(),
|
||||||
afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->total_execs,
|
afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->total_execs,
|
||||||
/*eps,*/ afl->total_execs /
|
/*eps,*/ afl->total_execs /
|
||||||
((double)(get_cur_time() - afl->start_time) / 1000),
|
((double)(get_cur_time() - afl->start_time) / 1000),
|
||||||
@ -357,9 +360,9 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
/* Lord, forgive me this. */
|
/* Lord, forgive me this. */
|
||||||
|
|
||||||
SAYF(SET_G1 bSTG bLT bH bSTOP cCYA
|
SAYF(SET_G1 bSTG bLT bH bSTOP cCYA
|
||||||
" process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
|
" process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
|
||||||
" overall results " bSTG bH2 bH2 bRT "\n");
|
" overall results " bSTG bH2 bH2 bRT "\n");
|
||||||
|
|
||||||
if (afl->dumb_mode) {
|
if (afl->dumb_mode) {
|
||||||
|
|
||||||
@ -441,9 +444,9 @@ void show_stats(afl_state_t *afl) {
|
|||||||
" uniq hangs : " cRST "%-6s" bSTG bV "\n",
|
" uniq hangs : " cRST "%-6s" bSTG bV "\n",
|
||||||
time_tmp, tmp);
|
time_tmp, tmp);
|
||||||
|
|
||||||
SAYF(bVR bH bSTOP cCYA
|
SAYF(bVR bH bSTOP cCYA
|
||||||
" cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
|
" cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
|
||||||
" map coverage " bSTG bH bHT bH20 bH2 bVL "\n");
|
" map coverage " bSTG bH bHT bH20 bH2 bVL "\n");
|
||||||
|
|
||||||
/* This gets funny because we want to print several variable-length variables
|
/* This gets funny because we want to print several variable-length variables
|
||||||
together, but then cram them into a fixed-width field - so we need to
|
together, but then cram them into a fixed-width field - so we need to
|
||||||
@ -472,9 +475,9 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp);
|
SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp);
|
||||||
|
|
||||||
SAYF(bVR bH bSTOP cCYA
|
SAYF(bVR bH bSTOP cCYA
|
||||||
" stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
|
" stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
|
||||||
" findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
|
" findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
|
||||||
|
|
||||||
sprintf(tmp, "%s (%0.02f%%)", DI(IB(0), afl->queued_favored),
|
sprintf(tmp, "%s (%0.02f%%)", DI(IB(0), afl->queued_favored),
|
||||||
((double)afl->queued_favored) * 100 / afl->queued_paths);
|
((double)afl->queued_favored) * 100 / afl->queued_paths);
|
||||||
@ -546,7 +549,7 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
/* Aaaalmost there... hold on! */
|
/* Aaaalmost there... hold on! */
|
||||||
|
|
||||||
SAYF(bVR bH cCYA bSTOP
|
SAYF(bVR bH cCYA bSTOP
|
||||||
" fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
|
" fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
|
||||||
" path geometry " bSTG bH5 bH2 bVL "\n");
|
" path geometry " bSTG bH5 bH2 bVL "\n");
|
||||||
|
|
||||||
|
@ -96,8 +96,8 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
|
|||||||
"Execution control settings:\n"
|
"Execution control settings:\n"
|
||||||
" -p schedule - power schedules recompute a seed's performance "
|
" -p schedule - power schedules recompute a seed's performance "
|
||||||
"score.\n"
|
"score.\n"
|
||||||
" <explore (default), fast, coe, lin, quad, exploit, "
|
" <explore(default), fast, coe, lin, quad, exploit, "
|
||||||
"mmopt>\n"
|
"mmopt, rare>\n"
|
||||||
" see docs/power_schedules.md\n"
|
" see docs/power_schedules.md\n"
|
||||||
" -f file - location read by the fuzzed program (stdin)\n"
|
" -f file - location read by the fuzzed program (stdin)\n"
|
||||||
" -t msec - timeout for each run (auto-scaled, 50-%d ms)\n"
|
" -t msec - timeout for each run (auto-scaled, 50-%d ms)\n"
|
||||||
@ -250,7 +250,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
SAYF(cCYA "afl-fuzz" VERSION cRST
|
SAYF(cCYA "afl-fuzz" VERSION cRST
|
||||||
" based on afl by Michal Zalewski and a big online community\n");
|
" based on afl by Michal Zalewski and a big online community\n");
|
||||||
|
|
||||||
doc_path = access(DOC_PATH, F_OK) ? (u8 *)"docs" : doc_path;
|
doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH;
|
||||||
|
|
||||||
gettimeofday(&tv, &tz);
|
gettimeofday(&tv, &tz);
|
||||||
afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
|
afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
|
||||||
@ -304,6 +304,10 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
afl->schedule = MMOPT;
|
afl->schedule = MMOPT;
|
||||||
|
|
||||||
|
} else if (!stricmp(optarg, "rare")) {
|
||||||
|
|
||||||
|
afl->schedule = RARE;
|
||||||
|
|
||||||
} else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") ||
|
} else if (!stricmp(optarg, "explore") || !stricmp(optarg, "default") ||
|
||||||
|
|
||||||
!stricmp(optarg, "normal") || !stricmp(optarg, "afl")) {
|
!stricmp(optarg, "normal") || !stricmp(optarg, "afl")) {
|
||||||
@ -760,8 +764,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
case LIN: OKF("Using linear power schedule (LIN)"); break;
|
case LIN: OKF("Using linear power schedule (LIN)"); break;
|
||||||
case QUAD: OKF("Using quadratic power schedule (QUAD)"); break;
|
case QUAD: OKF("Using quadratic power schedule (QUAD)"); break;
|
||||||
case MMOPT: OKF("Using modified MOpt power schedule (MMOPT)"); break;
|
case MMOPT: OKF("Using modified MOpt power schedule (MMOPT)"); break;
|
||||||
|
case RARE: OKF("Using rare edge focus power schedule (RARE)"); break;
|
||||||
case EXPLORE:
|
case EXPLORE:
|
||||||
OKF("Using exploration-based constant power schedule (EXPLORE)");
|
OKF("Using exploration-based constant power schedule (EXPLORE, default)");
|
||||||
break;
|
break;
|
||||||
default: FATAL("Unknown power schedule"); break;
|
default: FATAL("Unknown power schedule"); break;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user