From 5218c0b187dfeb2c722c41e3e0b3180d671c85ca Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 29 Mar 2023 22:53:15 +0200
Subject: all mutation strategies
---
src/afl-fuzz-one.c | 571 ++++++++++++++++++++++++++++++++++-------------------
1 file changed, 368 insertions(+), 203 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 070669c5..3eed2b70 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2118,39 +2118,17 @@ havoc_stage:
/* We essentially just do several thousand runs (depending on perf_score)
where we take the input file and make random stacked tweaks. */
-#define MAX_HAVOC_ENTRY 64
-#define MUTATE_ASCII_DICT 64
+#define MAX_HAVOC_ENTRY 31
+#define MUTATE_ASCII_DICT 0
u32 r_max, r;
- r_max = (MAX_HAVOC_ENTRY + 1) + (afl->extras_cnt ? 4 : 0) +
- (afl->a_extras_cnt
- ? (unlikely(afl->cmplog_binary && afl->queue_cur->is_ascii)
- ? MUTATE_ASCII_DICT
- : 4)
- : 0);
-
- if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
-
- /* add expensive havoc cases here, they are activated after a full
- cycle without finds happened */
-
- r_max += 4;
-
- }
-
- if (unlikely(get_cur_time() - afl->last_find_time > 5000 /* 5 seconds */ &&
- afl->ready_for_splicing_count > 1)) {
-
- /* add expensive havoc cases here if there is no findings in the last 5s */
-
- r_max += 4;
-
- }
+ r_max = (MAX_HAVOC_ENTRY + 1) + (afl->extras_cnt ? 2 : 0) +
+ (afl->a_extras_cnt ? 2 : 0);
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
- u32 use_stacking = 1 << (1 + rand_below(afl, afl->havoc_stack_pow2));
+ u32 use_stacking = 2 + rand_below(afl, 15), item;
afl->stage_cur_val = use_stacking;
@@ -2198,146 +2176,157 @@ havoc_stage:
switch ((r = rand_below(afl, r_max))) {
- case 0 ... 3: {
+ case 0: {
/* Flip a single bit somewhere. Spooky! */
+ u8 bit = rand_below(afl, 8);
+ u32 off = rand_below(afl, temp_len);
+ out_buf[off] ^= 1 << bit;
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP_BIT1");
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP-BIT_%u", bit);
strcat(afl->mutation, afl->m_tmp);
#endif
- FLIP_BIT(out_buf, rand_below(afl, temp_len << 3));
break;
}
- case 4 ... 7: {
+ case 1: {
/* Set byte to interesting value. */
+ item = rand_below(afl, sizeof(interesting_8));
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING8");
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING8_%u", item);
strcat(afl->mutation, afl->m_tmp);
#endif
- out_buf[rand_below(afl, temp_len)] =
- interesting_8[rand_below(afl, sizeof(interesting_8))];
+ out_buf[rand_below(afl, temp_len)] = interesting_8[item];
break;
}
- case 8 ... 9: {
+ case 2: {
/* Set word to interesting value, little endian. */
if (temp_len < 2) { break; }
+ item = rand_below(afl, sizeof(interesting_16) >> 1);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16");
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16_%u", item);
strcat(afl->mutation, afl->m_tmp);
#endif
+
*(u16 *)(out_buf + rand_below(afl, temp_len - 1)) =
- interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)];
+ interesting_16[item];
break;
}
- case 10 ... 11: {
+ case 3: {
/* Set word to interesting value, big endian. */
if (temp_len < 2) { break; }
+ item = rand_below(afl, sizeof(interesting_16) >> 1);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16BE");
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING16BE_%u", item);
strcat(afl->mutation, afl->m_tmp);
#endif
- *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) = SWAP16(
- interesting_16[rand_below(afl, sizeof(interesting_16) >> 1)]);
+ *(u16 *)(out_buf + rand_below(afl, temp_len - 1)) =
+ SWAP16(interesting_16[item]);
break;
}
- case 12 ... 13: {
+ case 4: {
/* Set dword to interesting value, little endian. */
if (temp_len < 4) { break; }
+ item = rand_below(afl, sizeof(interesting_32) >> 2);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32");
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32_%u", item);
strcat(afl->mutation, afl->m_tmp);
#endif
+
*(u32 *)(out_buf + rand_below(afl, temp_len - 3)) =
- interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)];
+ interesting_32[item];
break;
}
- case 14 ... 15: {
+ case 5: {
/* Set dword to interesting value, big endian. */
if (temp_len < 4) { break; }
+ item = rand_below(afl, sizeof(interesting_32) >> 2);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32BE");
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INTERESTING32BE_%u", item);
strcat(afl->mutation, afl->m_tmp);
#endif
- *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) = SWAP32(
- interesting_32[rand_below(afl, sizeof(interesting_32) >> 2)]);
+ *(u32 *)(out_buf + rand_below(afl, temp_len - 3)) =
+ SWAP32(interesting_32[item]);
break;
}
- case 16 ... 19: {
+ case 6: {
/* Randomly subtract from byte. */
+ item = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8_");
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8-_%u", item);
strcat(afl->mutation, afl->m_tmp);
#endif
- out_buf[rand_below(afl, temp_len)] -= 1 + rand_below(afl, ARITH_MAX);
+ out_buf[rand_below(afl, temp_len)] -= item;
break;
}
- case 20 ... 23: {
+ case 7: {
/* Randomly add to byte. */
+ item = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8+");
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH8+_%u", item);
strcat(afl->mutation, afl->m_tmp);
#endif
- out_buf[rand_below(afl, temp_len)] += 1 + rand_below(afl, ARITH_MAX);
+ out_buf[rand_below(afl, temp_len)] += item;
break;
}
- case 24 ... 25: {
+ case 8: {
/* Randomly subtract from word, little endian. */
if (temp_len < 2) { break; }
u32 pos = rand_below(afl, temp_len - 1);
+ item = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16_-%u", pos);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16-_%u", item);
strcat(afl->mutation, afl->m_tmp);
#endif
- *(u16 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
+ *(u16 *)(out_buf + pos) -= item;
break;
}
- case 26 ... 27: {
+ case 9: {
/* Randomly subtract from word, big endian. */
@@ -2347,8 +2336,7 @@ havoc_stage:
u16 num = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16_BE-%u_%u", pos,
- num);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16BE-_%u", num);
strcat(afl->mutation, afl->m_tmp);
#endif
*(u16 *)(out_buf + pos) =
@@ -2358,25 +2346,26 @@ havoc_stage:
}
- case 28 ... 29: {
+ case 10: {
/* Randomly add to word, little endian. */
if (temp_len < 2) { break; }
u32 pos = rand_below(afl, temp_len - 1);
+ item = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+-%u", pos);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+_%u", item);
strcat(afl->mutation, afl->m_tmp);
#endif
- *(u16 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
+ *(u16 *)(out_buf + pos) += item;
break;
}
- case 30 ... 31: {
+ case 11: {
/* Randomly add to word, big endian. */
@@ -2386,8 +2375,7 @@ havoc_stage:
u16 num = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16+BE-%u_%u", pos,
- num);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH16BE+__%u", num);
strcat(afl->mutation, afl->m_tmp);
#endif
*(u16 *)(out_buf + pos) =
@@ -2397,25 +2385,26 @@ havoc_stage:
}
- case 32 ... 33: {
+ case 12: {
/* Randomly subtract from dword, little endian. */
if (temp_len < 4) { break; }
u32 pos = rand_below(afl, temp_len - 3);
+ item = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32_-%u", pos);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32-_%u", item);
strcat(afl->mutation, afl->m_tmp);
#endif
- *(u32 *)(out_buf + pos) -= 1 + rand_below(afl, ARITH_MAX);
+ *(u32 *)(out_buf + pos) -= item;
break;
}
- case 34 ... 35: {
+ case 13: {
/* Randomly subtract from dword, big endian. */
@@ -2425,8 +2414,7 @@ havoc_stage:
u32 num = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32_BE-%u-%u", pos,
- num);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32BE-_%u", num);
strcat(afl->mutation, afl->m_tmp);
#endif
*(u32 *)(out_buf + pos) =
@@ -2436,25 +2424,26 @@ havoc_stage:
}
- case 36 ... 37: {
+ case 14: {
/* Randomly add to dword, little endian. */
if (temp_len < 4) { break; }
u32 pos = rand_below(afl, temp_len - 3);
+ item = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+-%u", pos);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+_%u", item);
strcat(afl->mutation, afl->m_tmp);
#endif
- *(u32 *)(out_buf + pos) += 1 + rand_below(afl, ARITH_MAX);
+ *(u32 *)(out_buf + pos) += item;
break;
}
- case 38 ... 39: {
+ case 15: {
/* Randomly add to dword, big endian. */
@@ -2464,8 +2453,7 @@ havoc_stage:
u32 num = 1 + rand_below(afl, ARITH_MAX);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32+BE-%u-%u", pos,
- num);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ARITH32BE+_%u", num);
strcat(afl->mutation, afl->m_tmp);
#endif
*(u32 *)(out_buf + pos) =
@@ -2475,22 +2463,25 @@ havoc_stage:
}
- case 40 ... 43: {
+ case 16: {
/* Just set a random byte to a random value. Because,
why not. We use XOR with 1-255 to eliminate the
possibility of a no-op. */
+ u32 pos = rand_below(afl, temp_len);
+ item = 1 + rand_below(afl, 255);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " RAND8");
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " RAND8_%u",
+ out_buf[pos] ^ item);
strcat(afl->mutation, afl->m_tmp);
#endif
- out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255);
+ out_buf[pos] ^= item;
break;
}
- case 44 ... 46: {
+ case 17: {
if (temp_len + HAVOC_BLK_XL < MAX_FILE) {
@@ -2501,8 +2492,8 @@ havoc_stage:
u32 clone_to = rand_below(afl, temp_len);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s-%u-%u-%u",
- "clone", clone_from, clone_to, clone_len);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s_%u_%u_%u",
+ "overwrite", clone_from, clone_to, clone_len);
strcat(afl->mutation, afl->m_tmp);
#endif
u8 *new_buf =
@@ -2531,7 +2522,7 @@ havoc_stage:
}
- case 47: {
+ case 18: {
if (temp_len + HAVOC_BLK_XL < MAX_FILE) {
@@ -2539,10 +2530,13 @@ havoc_stage:
u32 clone_len = choose_block_len(afl, HAVOC_BLK_XL);
u32 clone_to = rand_below(afl, temp_len);
+ u32 strat = rand_below(afl, 2);
+ u32 clone_from = clone_to ? clone_to - 1 : 0;
+ item = strat ? rand_below(afl, 256) : out_buf[clone_from];
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s-%u-%u",
- "insert", clone_to, clone_len);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s_%u_%u_%u",
+ "insert", strat, clone_to, clone_len);
strcat(afl->mutation, afl->m_tmp);
#endif
u8 *new_buf =
@@ -2555,10 +2549,7 @@ havoc_stage:
/* Inserted part */
- memset(new_buf + clone_to,
- rand_below(afl, 2) ? rand_below(afl, 256)
- : out_buf[rand_below(afl, temp_len)],
- clone_len);
+ memset(new_buf + clone_to, item, clone_len);
/* Tail */
memcpy(new_buf + clone_to + clone_len, out_buf + clone_to,
@@ -2574,7 +2565,7 @@ havoc_stage:
}
- case 48 ... 50: {
+ case 19: {
/* Overwrite bytes with a randomly selected chunk bytes. */
@@ -2587,7 +2578,7 @@ havoc_stage:
if (likely(copy_from != copy_to)) {
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " OVERWRITE_COPY-%u-%u-%u",
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " OVERWRITE-COPY_%u_%u_%u",
copy_from, copy_to, copy_len);
strcat(afl->mutation, afl->m_tmp);
#endif
@@ -2599,7 +2590,7 @@ havoc_stage:
}
- case 51: {
+ case 20: {
/* Overwrite bytes with fixed bytes. */
@@ -2607,27 +2598,28 @@ havoc_stage:
u32 copy_len = choose_block_len(afl, temp_len - 1);
u32 copy_to = rand_below(afl, temp_len - copy_len + 1);
+ u32 strat = rand_below(afl, 2);
+ u32 copy_from = copy_to ? copy_to - 1 : 0;
+ item = strat ? rand_below(afl, 256) : out_buf[copy_from];
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " OVERWRITE_FIXED-%u-%u",
- copy_to, copy_len);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp),
+ " OVERWRITE-FIXED_%u_%u_%u-%u", strat, item, copy_to,
+ copy_len);
strcat(afl->mutation, afl->m_tmp);
#endif
- memset(out_buf + copy_to,
- rand_below(afl, 2) ? rand_below(afl, 256)
- : out_buf[rand_below(afl, temp_len)],
- copy_len);
+ memset(out_buf + copy_to, item, copy_len);
break;
}
- case 52: {
+ case 21: {
/* Increase byte by 1. */
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ADDBYTE_");
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " BYTEADD_");
strcat(afl->mutation, afl->m_tmp);
#endif
out_buf[rand_below(afl, temp_len)]++;
@@ -2635,12 +2627,12 @@ havoc_stage:
}
- case 53: {
+ case 22: {
/* Decrease byte by 1. */
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " SUBBYTE_");
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " BYTESUB_");
strcat(afl->mutation, afl->m_tmp);
#endif
out_buf[rand_below(afl, temp_len)]--;
@@ -2648,7 +2640,7 @@ havoc_stage:
}
- case 54: {
+ case 23: {
/* Flip byte. */
@@ -2661,7 +2653,7 @@ havoc_stage:
}
- case 55 ... 56: {
+ case 24: {
if (temp_len < 4) { break; }
@@ -2690,7 +2682,7 @@ havoc_stage:
switch_len = choose_block_len(afl, MIN(switch_len, to_end));
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " SWITCH-%s-%u-%u-%u",
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " SWITCH-%s_%u_%u_%u",
"switch", switch_from, switch_to, switch_len);
strcat(afl->mutation, afl->m_tmp);
#endif
@@ -2714,7 +2706,7 @@ havoc_stage:
}
// MAX_HAVOC_ENTRY = 64
- case 57 ... MAX_HAVOC_ENTRY: {
+ case 25: {
/* Delete bytes. */
@@ -2726,7 +2718,7 @@ havoc_stage:
u32 del_from = rand_below(afl, temp_len - del_len + 1);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " DEL-%u-%u", del_from,
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " DEL_%u_%u", del_from,
del_len);
strcat(afl->mutation, afl->m_tmp);
#endif
@@ -2739,13 +2731,274 @@ havoc_stage:
}
+ case 26: {
+
+ /* Shuffle bytes. */
+
+ if (temp_len < 4) { break; }
+
+ u32 len = choose_block_len(afl, temp_len - 1);
+ u32 off = rand_below(afl, temp_len - len + 1);
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " SHUFFLE_%u", len);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+
+ for (u32 i = len - 1; i > 0; i--) {
+
+ u32 j;
+ do {
+
+ j = rand_below(afl, i + 1);
+
+ } while (i == j);
+
+ unsigned char temp = out_buf[off + i];
+ out_buf[off + i] = out_buf[off + j];
+ out_buf[off + j] = temp;
+
+ }
+
+ break;
+
+ }
+
+ case 27: {
+
+ /* Delete bytes. */
+
+ if (temp_len < 2) { break; }
+
+ /* Don't delete too much. */
+
+ u32 del_len = 1;
+ u32 del_from = rand_below(afl, temp_len - del_len + 1);
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " DELONE_%u", del_from);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+ memmove(out_buf + del_from, out_buf + del_from + del_len,
+ temp_len - del_from - del_len);
+
+ temp_len -= del_len;
+
+ break;
+
+ }
+
+ case 28: {
+
+ u32 clone_len = 1;
+ u32 clone_to = rand_below(afl, temp_len);
+ u32 strat = rand_below(afl, 2);
+ u32 clone_from = clone_to ? clone_to - 1 : 0;
+ item = strat ? rand_below(afl, 256) : out_buf[clone_from];
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INSERTONE_%u_%u", strat,
+ clone_to);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+ u8 *new_buf =
+ afl_realloc(AFL_BUF_PARAM(out_scratch), temp_len + clone_len);
+ if (unlikely(!new_buf)) { PFATAL("alloc"); }
+
+ /* Head */
+
+ memcpy(new_buf, out_buf, clone_to);
+
+ /* Inserted part */
+
+ memset(new_buf + clone_to, item, clone_len);
+
+ /* Tail */
+ memcpy(new_buf + clone_to + clone_len, out_buf + clone_to,
+ temp_len - clone_to);
+
+ out_buf = new_buf;
+ afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch));
+ temp_len += clone_len;
+
+ break;
+
+ }
+
+ case 29: {
+
+ if (temp_len < 4) { break; }
+
+ u32 off = rand_below(afl, temp_len), off2 = off, cnt = 0;
+
+ while (off2 + cnt < temp_len && !isdigit(out_buf[off2 + cnt])) {
+
+ ++cnt;
+
+ }
+
+ // none found, wrap
+ if (off2 + cnt == temp_len) {
+
+ off2 = 0;
+ cnt = 0;
+
+ while (cnt < off && !isdigit(out_buf[off2 + cnt])) {
+
+ ++cnt;
+
+ }
+
+ if (cnt == off) { break; }
+
+ }
+
+ off = off2 + cnt;
+ off2 = off + 1;
+
+ while (off2 < temp_len && isdigit(out_buf[off2])) {
+
+ ++off2;
+
+ }
+
+ s64 val = out_buf[off] - '0';
+ for (u32 i = off + 1; i < off2; ++i) {
+
+ val = (val * 10) + out_buf[i] - '0';
+
+ }
+
+ if (off && out_buf[off - 1] == '-') { val = -val; }
+
+ u32 strat = rand_below(afl, 8);
+ switch (strat) {
+
+ case 0:
+ val++;
+ break;
+ case 1:
+ val--;
+ break;
+ case 2:
+ val *= 2;
+ break;
+ case 3:
+ val /= 2;
+ break;
+ case 4:
+ if (val) {
+
+ val = rand_next(afl) % (val * 10);
+
+ } else {
+
+ val = rand_below(afl, 256);
+
+ }
+
+ break;
+ case 5:
+ val += rand_below(afl, 256);
+ break;
+ case 6:
+ val -= rand_below(afl, 256);
+ break;
+ case 7:
+ val = ~(val);
+ break;
+
+ }
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " ASCIINUM_%u_%u_%u",
+ afl->queue_cur->is_ascii, strat, off);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+ // fprintf(stderr, "val: %u-%u = %ld\n", off, off2, val);
+
+ char buf[20];
+ snprintf(buf, sizeof(buf), "%ld", val);
+
+ // fprintf(stderr, "BEFORE: %s\n", out_buf);
+
+ u32 old_len = off2 - off;
+ u32 new_len = strlen(buf);
+
+ if (old_len == new_len) {
+
+ memcpy(out_buf + off, buf, new_len);
+
+ } else {
+
+ u8 *new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch),
+ temp_len + new_len - old_len);
+ if (unlikely(!new_buf)) { PFATAL("alloc"); }
+
+ /* Head */
+
+ memcpy(new_buf, out_buf, off);
+
+ /* Inserted part */
+
+ memcpy(new_buf + off, buf, new_len);
+
+ /* Tail */
+ memcpy(new_buf + off + new_len, out_buf + off2, temp_len - off2);
+
+ out_buf = new_buf;
+ afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch));
+ temp_len += (new_len - old_len);
+
+ }
+
+ // fprintf(stderr, "AFTER : %s\n", out_buf);
+ break;
+
+ }
+
+ case 30: {
+
+ /* Neg byte. */
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " NEG_");
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+ item = rand_below(afl, temp_len);
+
+ out_buf[item] = ~out_buf[item];
+ break;
+
+ }
+
+ case 31: {
+
+ u32 len = 1 + rand_below(afl, 8);
+ u32 pos = rand_below(afl, temp_len);
+ /* Insert ascii number. */
+ if (temp_len < pos + len) { break; }
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INSERTASCIINUM_");
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+ u64 val = rand_next(afl);
+ char buf[20];
+ snprintf(buf, sizeof(buf), "%llu", val);
+ memcpy(out_buf + pos, buf, len);
+
+ break;
+
+ }
+
default:
r -= (MAX_HAVOC_ENTRY + 1);
if (afl->extras_cnt) {
- if (r < 2) {
+ if (r < 1) {
/* Use the dictionary. */
@@ -2765,7 +3018,7 @@ havoc_stage:
break;
- } else if (r < 4) {
+ } else if (r < 2) {
u32 use_extra = rand_below(afl, afl->extras_cnt);
u32 extra_len = afl->extras[use_extra].len;
@@ -2794,7 +3047,7 @@ havoc_stage:
} else {
- r -= 4;
+ r -= 2;
}
@@ -2802,15 +3055,7 @@ havoc_stage:
if (afl->a_extras_cnt) {
- u32 r_cmp = 2;
-
- if (unlikely(afl->cmplog_binary && afl->queue_cur->is_ascii)) {
-
- r_cmp = MUTATE_ASCII_DICT >> 1;
-
- }
-
- if (r < r_cmp) {
+ if (r < 1) {
/* Use the dictionary. */
@@ -2830,7 +3075,7 @@ havoc_stage:
break;
- } else if (r < (r_cmp << 1)) {
+ } else if (r < 2) {
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
u32 extra_len = afl->a_extras[use_extra].len;
@@ -2859,92 +3104,12 @@ havoc_stage:
} else {
- r -= (r_cmp << 1);
+ r -= 2;
}
}
- /* Splicing otherwise if we are still here.
- Overwrite bytes with a randomly selected chunk from another
- testcase or insert that chunk. */
-
- /* Pick a random queue entry and seek to it. */
-
- u32 tid;
- do {
-
- tid = rand_below(afl, afl->queued_items);
-
- } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4);
-
- /* Get the testcase for splicing. */
- struct queue_entry *target = afl->queue_buf[tid];
- u32 new_len = target->len;
- u8 *new_buf = queue_testcase_get(afl, target);
-
- if ((temp_len >= 2 && r % 2) || temp_len + HAVOC_BLK_XL >= MAX_FILE) {
-
- /* overwrite mode */
-
- u32 copy_from, copy_to, copy_len;
-
- copy_len = choose_block_len(afl, new_len - 1);
- if (copy_len > temp_len) copy_len = temp_len;
-
- copy_from = rand_below(afl, new_len - copy_len + 1);
- copy_to = rand_below(afl, temp_len - copy_len + 1);
-
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp),
- " SPLICE_OVERWRITE-%u-%u-%u-%s", copy_from, copy_to,
- copy_len, target->fname);
- strcat(afl->mutation, afl->m_tmp);
-#endif
- memmove(out_buf + copy_to, new_buf + copy_from, copy_len);
-
- } else {
-
- /* insert mode */
-
- u32 clone_from, clone_to, clone_len;
-
- clone_len = choose_block_len(afl, new_len);
- clone_from = rand_below(afl, new_len - clone_len + 1);
- clone_to = rand_below(afl, temp_len + 1);
-
- u8 *temp_buf = afl_realloc(AFL_BUF_PARAM(out_scratch),
- temp_len + clone_len + 1);
- if (unlikely(!temp_buf)) { PFATAL("alloc"); }
-
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp),
- " SPLICE_INSERT-%u-%u-%u-%s", clone_from, clone_to,
- clone_len, target->fname);
- strcat(afl->mutation, afl->m_tmp);
-#endif
- /* Head */
-
- memcpy(temp_buf, out_buf, clone_to);
-
- /* Inserted part */
-
- memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len);
-
- /* Tail */
- memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to,
- temp_len - clone_to);
-
- out_buf = temp_buf;
- afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch));
- temp_len += clone_len;
-
- }
-
- break;
-
- // end of default
-
}
}
--
cgit 1.4.1
From 7893347e13d99b7e39ec4ebb95fbb5356bdd7f2b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 29 Mar 2023 22:56:12 +0200
Subject: final touches
---
src/afl-fuzz-one.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 3eed2b70..e3ec8267 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2133,8 +2133,8 @@ havoc_stage:
afl->stage_cur_val = use_stacking;
#ifdef INTROSPECTION
- snprintf(afl->mutation, sizeof(afl->mutation), "%s HAVOC-%u",
- afl->queue_cur->fname, use_stacking);
+ snprintf(afl->mutation, sizeof(afl->mutation), "%s HAVOC-%u-%u",
+ afl->queue_cur->fname, afl->queue_cur->is_ascii, use_stacking);
#endif
for (i = 0; i < use_stacking; ++i) {
--
cgit 1.4.1
From 145748a7e0b85c34660d0fe72ef1d4499ace2933 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 30 Mar 2023 14:00:45 +0200
Subject: prepare new mutation strategies
---
src/afl-fuzz-one.c | 178 ++++++++++++++++++++++++++++-------------------------
1 file changed, 94 insertions(+), 84 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index e3ec8267..b1c38572 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -28,6 +28,21 @@
#include
#include "cmplog.h"
+static u32 mutation_array_explore[] = {
+
+ 0, 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};
+// static u32 mutation_array_exploit[] = { 0, 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 }; static u32 mutation_array_txt_explore[] = { 0, 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 }; static u32 mutation_array_txt_exploit[] = { 0, 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 };
+
+// what about more splicing?
+// what about -x and cmplog learn?
+
/* MOpt */
static int select_algorithm(afl_state_t *afl, u32 max_algorithm) {
@@ -2121,10 +2136,15 @@ havoc_stage:
#define MAX_HAVOC_ENTRY 31
#define MUTATE_ASCII_DICT 0
- u32 r_max, r;
+ u32 r_max, mutation_array_len;
+ u32 **mutation_array;
- r_max = (MAX_HAVOC_ENTRY + 1) + (afl->extras_cnt ? 2 : 0) +
- (afl->a_extras_cnt ? 2 : 0);
+ // if ( ... )
+ mutation_array = (u32 **)&mutation_array_explore;
+ mutation_array_len = sizeof(mutation_array_explore) + 1;
+
+ r_max = mutation_array_len;
+ // + (afl->extras_cnt ? 2 : 0) + (afl->a_extras_cnt ? 2 : 0);
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
@@ -2174,7 +2194,7 @@ havoc_stage:
}
- switch ((r = rand_below(afl, r_max))) {
+ switch (*mutation_array[rand_below(afl, r_max)]) {
case 0: {
@@ -2992,123 +3012,113 @@ havoc_stage:
}
- default:
-
- r -= (MAX_HAVOC_ENTRY + 1);
-
- if (afl->extras_cnt) {
+ case 32: {
- if (r < 1) {
+ if (!afl->extras_cnt) { break; }
- /* Use the dictionary. */
+ /* Use the dictionary. */
- u32 use_extra = rand_below(afl, afl->extras_cnt);
- u32 extra_len = afl->extras[use_extra].len;
+ u32 use_extra = rand_below(afl, afl->extras_cnt);
+ u32 extra_len = afl->extras[use_extra].len;
- if (extra_len > temp_len) { break; }
+ if (extra_len > temp_len) { break; }
- u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
+ u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA_OVERWRITE-%u-%u",
- insert_at, extra_len);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA-OVERWRITE_%u_%u",
+ insert_at, extra_len);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- memcpy(out_buf + insert_at, afl->extras[use_extra].data,
- extra_len);
+ memcpy(out_buf + insert_at, afl->extras[use_extra].data, extra_len);
- break;
+ break;
- } else if (r < 2) {
+ }
- u32 use_extra = rand_below(afl, afl->extras_cnt);
- u32 extra_len = afl->extras[use_extra].len;
- if (temp_len + extra_len >= MAX_FILE) { break; }
+ case 33: {
- u8 *ptr = afl->extras[use_extra].data;
- u32 insert_at = rand_below(afl, temp_len + 1);
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA_INSERT-%u-%u",
- insert_at, extra_len);
- strcat(afl->mutation, afl->m_tmp);
-#endif
+ if (!afl->extras_cnt) { break; }
- out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len);
- if (unlikely(!out_buf)) { PFATAL("alloc"); }
+ u32 use_extra = rand_below(afl, afl->extras_cnt);
+ u32 extra_len = afl->extras[use_extra].len;
+ if (temp_len + extra_len >= MAX_FILE) { break; }
- /* Tail */
- memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
- temp_len - insert_at);
+ u8 *ptr = afl->extras[use_extra].data;
+ u32 insert_at = rand_below(afl, temp_len + 1);
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " EXTRA-INSERT_%u_%u",
+ insert_at, extra_len);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
- /* Inserted part */
- memcpy(out_buf + insert_at, ptr, extra_len);
- temp_len += extra_len;
+ out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len);
+ if (unlikely(!out_buf)) { PFATAL("alloc"); }
- break;
-
- } else {
+ /* Tail */
+ memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
+ temp_len - insert_at);
- r -= 2;
+ /* Inserted part */
+ memcpy(out_buf + insert_at, ptr, extra_len);
+ temp_len += extra_len;
- }
+ break;
- }
+ }
- if (afl->a_extras_cnt) {
+ case 34: {
- if (r < 1) {
+ if (!afl->a_extras_cnt) { break; }
- /* Use the dictionary. */
+ /* Use the dictionary. */
- u32 use_extra = rand_below(afl, afl->a_extras_cnt);
- u32 extra_len = afl->a_extras[use_extra].len;
+ u32 use_extra = rand_below(afl, afl->a_extras_cnt);
+ u32 extra_len = afl->a_extras[use_extra].len;
- if (extra_len > temp_len) { break; }
+ if (extra_len > temp_len) { break; }
- u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
+ u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp),
- " AUTO_EXTRA_OVERWRITE-%u-%u", insert_at, extra_len);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp),
+ " AUTO-EXTRA-OVERWRITE_%u_%u", insert_at, extra_len);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- memcpy(out_buf + insert_at, afl->a_extras[use_extra].data,
- extra_len);
+ memcpy(out_buf + insert_at, afl->a_extras[use_extra].data, extra_len);
- break;
-
- } else if (r < 2) {
+ break;
- u32 use_extra = rand_below(afl, afl->a_extras_cnt);
- u32 extra_len = afl->a_extras[use_extra].len;
- if (temp_len + extra_len >= MAX_FILE) { break; }
+ }
- u8 *ptr = afl->a_extras[use_extra].data;
- u32 insert_at = rand_below(afl, temp_len + 1);
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp),
- " AUTO_EXTRA_INSERT-%u-%u", insert_at, extra_len);
- strcat(afl->mutation, afl->m_tmp);
-#endif
+ case 35: {
- out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len);
- if (unlikely(!out_buf)) { PFATAL("alloc"); }
+ if (!afl->a_extras_cnt) { break; }
- /* Tail */
- memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
- temp_len - insert_at);
+ u32 use_extra = rand_below(afl, afl->a_extras_cnt);
+ u32 extra_len = afl->a_extras[use_extra].len;
+ if (temp_len + extra_len >= MAX_FILE) { break; }
- /* Inserted part */
- memcpy(out_buf + insert_at, ptr, extra_len);
- temp_len += extra_len;
+ u8 *ptr = afl->a_extras[use_extra].data;
+ u32 insert_at = rand_below(afl, temp_len + 1);
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " AUTO-EXTRA-INSERT_%u_%u",
+ insert_at, extra_len);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
- break;
+ out_buf = afl_realloc(AFL_BUF_PARAM(out), temp_len + extra_len);
+ if (unlikely(!out_buf)) { PFATAL("alloc"); }
- } else {
+ /* Tail */
+ memmove(out_buf + insert_at + extra_len, out_buf + insert_at,
+ temp_len - insert_at);
- r -= 2;
+ /* Inserted part */
+ memcpy(out_buf + insert_at, ptr, extra_len);
+ temp_len += extra_len;
- }
+ break;
- }
+ }
}
--
cgit 1.4.1
From 506f6b134987d47da6c1a2e172f50b47559e7b4f Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 30 Mar 2023 19:28:59 +0200
Subject: nits
---
src/afl-fuzz-one.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++---
src/afl-fuzz-queue.c | 2 +-
2 files changed, 99 insertions(+), 7 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index b1c38572..36259d9b 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -30,8 +30,8 @@
static u32 mutation_array_explore[] = {
- 0, 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};
+ 0, 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};
// static u32 mutation_array_exploit[] = { 0, 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 }; static u32 mutation_array_txt_explore[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8,
@@ -2133,9 +2133,6 @@ havoc_stage:
/* We essentially just do several thousand runs (depending on perf_score)
where we take the input file and make random stacked tweaks. */
-#define MAX_HAVOC_ENTRY 31
-#define MUTATE_ASCII_DICT 0
-
u32 r_max, mutation_array_len;
u32 **mutation_array;
@@ -2725,7 +2722,6 @@ havoc_stage:
}
- // MAX_HAVOC_ENTRY = 64
case 25: {
/* Delete bytes. */
@@ -3120,6 +3116,102 @@ havoc_stage:
}
+ case 36: {
+
+ if (afl->ready_for_splicing_count <= 1) { break; }
+
+ /* Pick a random queue entry and seek to it. */
+
+ u32 tid;
+ do {
+
+ tid = rand_below(afl, afl->queued_items);
+
+ } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4);
+
+ /* Get the testcase for splicing. */
+ struct queue_entry *target = afl->queue_buf[tid];
+ u32 new_len = target->len;
+ u8 *new_buf = queue_testcase_get(afl, target);
+
+ /* overwrite mode */
+
+ u32 copy_from, copy_to, copy_len;
+
+ copy_len = choose_block_len(afl, new_len - 1);
+ if (copy_len > temp_len) copy_len = temp_len;
+
+ copy_from = rand_below(afl, new_len - copy_len + 1);
+ copy_to = rand_below(afl, temp_len - copy_len + 1);
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp),
+ " SPLICE-OVERWRITE_%u_%u_%u_%s", copy_from, copy_to,
+ copy_len, target->fname);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+ memmove(out_buf + copy_to, new_buf + copy_from, copy_len);
+
+ break;
+
+ }
+
+ case 37: {
+
+ if (afl->ready_for_splicing_count <= 1) { break; }
+ if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { break; }
+
+ /* Pick a random queue entry and seek to it. */
+
+ u32 tid;
+ do {
+
+ tid = rand_below(afl, afl->queued_items);
+
+ } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4);
+
+ /* Get the testcase for splicing. */
+ struct queue_entry *target = afl->queue_buf[tid];
+ u32 new_len = target->len;
+ u8 *new_buf = queue_testcase_get(afl, target);
+
+ /* insert mode */
+
+ u32 clone_from, clone_to, clone_len;
+
+ clone_len = choose_block_len(afl, new_len);
+ clone_from = rand_below(afl, new_len - clone_len + 1);
+ clone_to = rand_below(afl, temp_len + 1);
+
+ u8 *temp_buf =
+ afl_realloc(AFL_BUF_PARAM(out_scratch), temp_len + clone_len + 1);
+ if (unlikely(!temp_buf)) { PFATAL("alloc"); }
+
+#ifdef INTROSPECTION
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " SPLICE-INSERT_%u_%u_%u_%s",
+ clone_from, clone_to, clone_len, target->fname);
+ strcat(afl->mutation, afl->m_tmp);
+#endif
+ /* Head */
+
+ memcpy(temp_buf, out_buf, clone_to);
+
+ /* Inserted part */
+
+ memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len);
+
+ /* Tail */
+ memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to,
+ temp_len - clone_to);
+
+ out_buf = temp_buf;
+ afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch));
+ temp_len += clone_len;
+
+ break;
+
+ }
+
}
}
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 40184645..fff8db03 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -563,7 +563,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
}
- if (likely(q->len > 4)) afl->ready_for_splicing_count++;
+ if (likely(q->len > 4)) { ++afl->ready_for_splicing_count; }
++afl->queued_items;
++afl->active_items;
--
cgit 1.4.1
From 74baebd93e6ad65de297e812d53f06592166ef9a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 30 Mar 2023 20:02:59 +0200
Subject: fix
---
src/afl-fuzz-one.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 36259d9b..fc37d493 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2134,11 +2134,11 @@ havoc_stage:
where we take the input file and make random stacked tweaks. */
u32 r_max, mutation_array_len;
- u32 **mutation_array;
+ u32 *mutation_array;
// if ( ... )
mutation_array = (u32 **)&mutation_array_explore;
- mutation_array_len = sizeof(mutation_array_explore) + 1;
+ mutation_array_len = sizeof(mutation_array_explore) / 4;
r_max = mutation_array_len;
// + (afl->extras_cnt ? 2 : 0) + (afl->a_extras_cnt ? 2 : 0);
@@ -2191,7 +2191,8 @@ havoc_stage:
}
- switch (*mutation_array[rand_below(afl, r_max)]) {
+ u32 r = rand_below(afl, r_max);
+ switch (mutation_array[r]) {
case 0: {
--
cgit 1.4.1
From 8f17c816919301b870b9c7dad84e475370c87381 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 30 Mar 2023 22:41:02 +0200
Subject: less mutation
---
src/afl-fuzz-one.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index fc37d493..b01814a3 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2145,7 +2145,7 @@ havoc_stage:
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
- u32 use_stacking = 2 + rand_below(afl, 15), item;
+ u32 use_stacking = 1 + rand_below(afl, 8), item;
afl->stage_cur_val = use_stacking;
--
cgit 1.4.1
From 9eed60d1055ada484798d6de51101043ecaf462d Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 31 Mar 2023 08:12:32 +0200
Subject: nit
---
src/afl-fuzz-one.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index b01814a3..1a120733 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2137,7 +2137,7 @@ havoc_stage:
u32 *mutation_array;
// if ( ... )
- mutation_array = (u32 **)&mutation_array_explore;
+ mutation_array = (u32 *)&mutation_array_explore;
mutation_array_len = sizeof(mutation_array_explore) / 4;
r_max = mutation_array_len;
@@ -2192,6 +2192,7 @@ havoc_stage:
}
u32 r = rand_below(afl, r_max);
+
switch (mutation_array[r]) {
case 0: {
--
cgit 1.4.1
From 21203c2ea6b0586d3c63f9d33190dfd364677b1a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 2 Apr 2023 12:39:02 +0200
Subject: fix
---
src/afl-fuzz-one.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 1a120733..c550fbc2 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2905,7 +2905,7 @@ havoc_stage:
val /= 2;
break;
case 4:
- if (val) {
+ if (val && val < 0xfffffff) {
val = rand_next(afl) % (val * 10);
--
cgit 1.4.1
From 71e2aa5d2bb99bd7edc2efcebd52eee5736c35fd Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 2 Apr 2023 13:42:08 +0200
Subject: more fix
---
src/afl-fuzz-one.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index c550fbc2..a52fb4c6 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2133,7 +2133,7 @@ havoc_stage:
/* We essentially just do several thousand runs (depending on perf_score)
where we take the input file and make random stacked tweaks. */
- u32 r_max, mutation_array_len;
+ u32 r_max, mutation_array_len;
u32 *mutation_array;
// if ( ... )
@@ -2905,9 +2905,9 @@ havoc_stage:
val /= 2;
break;
case 4:
- if (val && val < 0xfffffff) {
+ if (val && (u64)val < 0x19999999) {
- val = rand_next(afl) % (val * 10);
+ val = (u64)rand_next(afl) % (u64)((u64)val * 10);
} else {
--
cgit 1.4.1
From 635da39bd135b7db3529a4b3b059b85260ce14a5 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 3 Apr 2023 14:41:52 +0200
Subject: preparation for mutation arrays
---
src/afl-fuzz-one.c | 176 +++++++++++++++++++++++++++++++++++++++--------------
1 file changed, 131 insertions(+), 45 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index a52fb4c6..1636c323 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2133,19 +2133,35 @@ havoc_stage:
/* We essentially just do several thousand runs (depending on perf_score)
where we take the input file and make random stacked tweaks. */
- u32 r_max, mutation_array_len;
u32 *mutation_array;
+ u32 stack_max;
// if ( ... )
mutation_array = (u32 *)&mutation_array_explore;
- mutation_array_len = sizeof(mutation_array_explore) / 4;
- r_max = mutation_array_len;
+ if (temp_len < 64) {
+
+ stack_max = 4;
+
+ } else if (temp_len < 512) {
+
+ stack_max = 8;
+
+ } else if (temp_len < 8096) {
+
+ stack_max = 16;
+
+ } else {
+
+ stack_max = 32;
+
+ }
+
// + (afl->extras_cnt ? 2 : 0) + (afl->a_extras_cnt ? 2 : 0);
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
- u32 use_stacking = 1 + rand_below(afl, 8), item;
+ u32 use_stacking = 1 + rand_below(afl, stack_max);
afl->stage_cur_val = use_stacking;
@@ -2191,7 +2207,8 @@ havoc_stage:
}
- u32 r = rand_below(afl, r_max);
+ retry_havoc_step:
+ u32 r = rand_below(afl, 256), item;
switch (mutation_array[r]) {
@@ -2228,7 +2245,7 @@ havoc_stage:
/* Set word to interesting value, little endian. */
- if (temp_len < 2) { break; }
+ if (unlikely(temp_len < 2)) { break; } // no retry
item = rand_below(afl, sizeof(interesting_16) >> 1);
#ifdef INTROSPECTION
@@ -2247,7 +2264,7 @@ havoc_stage:
/* Set word to interesting value, big endian. */
- if (temp_len < 2) { break; }
+ if (unlikely(temp_len < 2)) { break; } // no retry
item = rand_below(afl, sizeof(interesting_16) >> 1);
#ifdef INTROSPECTION
@@ -2265,7 +2282,7 @@ havoc_stage:
/* Set dword to interesting value, little endian. */
- if (temp_len < 4) { break; }
+ if (unlikely(temp_len < 4)) { break; } // no retry
item = rand_below(afl, sizeof(interesting_32) >> 2);
#ifdef INTROSPECTION
@@ -2284,7 +2301,7 @@ havoc_stage:
/* Set dword to interesting value, big endian. */
- if (temp_len < 4) { break; }
+ if (unlikely(temp_len < 4)) { break; } // no retry
item = rand_below(afl, sizeof(interesting_32) >> 2);
#ifdef INTROSPECTION
@@ -2330,7 +2347,7 @@ havoc_stage:
/* Randomly subtract from word, little endian. */
- if (temp_len < 2) { break; }
+ if (unlikely(temp_len < 2)) { break; } // no retry
u32 pos = rand_below(afl, temp_len - 1);
item = 1 + rand_below(afl, ARITH_MAX);
@@ -2349,7 +2366,7 @@ havoc_stage:
/* Randomly subtract from word, big endian. */
- if (temp_len < 2) { break; }
+ if (unlikely(temp_len < 2)) { break; } // no retry
u32 pos = rand_below(afl, temp_len - 1);
u16 num = 1 + rand_below(afl, ARITH_MAX);
@@ -2369,7 +2386,7 @@ havoc_stage:
/* Randomly add to word, little endian. */
- if (temp_len < 2) { break; }
+ if (unlikely(temp_len < 2)) { break; } // no retry
u32 pos = rand_below(afl, temp_len - 1);
item = 1 + rand_below(afl, ARITH_MAX);
@@ -2388,7 +2405,7 @@ havoc_stage:
/* Randomly add to word, big endian. */
- if (temp_len < 2) { break; }
+ if (unlikely(temp_len < 2)) { break; } // no retry
u32 pos = rand_below(afl, temp_len - 1);
u16 num = 1 + rand_below(afl, ARITH_MAX);
@@ -2408,7 +2425,7 @@ havoc_stage:
/* Randomly subtract from dword, little endian. */
- if (temp_len < 4) { break; }
+ if (unlikely(temp_len < 4)) { break; } // no retry
u32 pos = rand_below(afl, temp_len - 3);
item = 1 + rand_below(afl, ARITH_MAX);
@@ -2427,7 +2444,7 @@ havoc_stage:
/* Randomly subtract from dword, big endian. */
- if (temp_len < 4) { break; }
+ if (unlikely(temp_len < 4)) { break; } // no retry
u32 pos = rand_below(afl, temp_len - 3);
u32 num = 1 + rand_below(afl, ARITH_MAX);
@@ -2447,7 +2464,7 @@ havoc_stage:
/* Randomly add to dword, little endian. */
- if (temp_len < 4) { break; }
+ if (unlikely(temp_len < 4)) { break; } // no retry
u32 pos = rand_below(afl, temp_len - 3);
item = 1 + rand_below(afl, ARITH_MAX);
@@ -2466,7 +2483,7 @@ havoc_stage:
/* Randomly add to dword, big endian. */
- if (temp_len < 4) { break; }
+ if (unlikely(temp_len < 4)) { break; } // no retry
u32 pos = rand_below(afl, temp_len - 3);
u32 num = 1 + rand_below(afl, ARITH_MAX);
@@ -2502,7 +2519,7 @@ havoc_stage:
case 17: {
- if (temp_len + HAVOC_BLK_XL < MAX_FILE) {
+ if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) {
/* Clone bytes. */
@@ -2535,6 +2552,14 @@ havoc_stage:
afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch));
temp_len += clone_len;
+ } else if (unlikely(temp_len < 8)) {
+
+ break;
+
+ } else {
+
+ goto retry_havoc_step;
+
}
break;
@@ -2543,7 +2568,7 @@ havoc_stage:
case 18: {
- if (temp_len + HAVOC_BLK_XL < MAX_FILE) {
+ if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) {
/* Insert a block of constant bytes (25%). */
@@ -2578,6 +2603,14 @@ havoc_stage:
afl_swap_bufs(AFL_BUF_PARAM(out), AFL_BUF_PARAM(out_scratch));
temp_len += clone_len;
+ } else if (unlikely(temp_len < 8)) {
+
+ break;
+
+ } else {
+
+ goto retry_havoc_step;
+
}
break;
@@ -2588,7 +2621,7 @@ havoc_stage:
/* Overwrite bytes with a randomly selected chunk bytes. */
- if (temp_len < 2) { break; }
+ if (unlikely(temp_len < 2)) { break; } // no retry
u32 copy_len = choose_block_len(afl, temp_len - 1);
u32 copy_from = rand_below(afl, temp_len - copy_len + 1);
@@ -2613,7 +2646,7 @@ havoc_stage:
/* Overwrite bytes with fixed bytes. */
- if (temp_len < 2) { break; }
+ if (unlikely(temp_len < 2)) { break; } // no retry
u32 copy_len = choose_block_len(afl, temp_len - 1);
u32 copy_to = rand_below(afl, temp_len - copy_len + 1);
@@ -2674,7 +2707,7 @@ havoc_stage:
case 24: {
- if (temp_len < 4) { break; }
+ if (unlikely(temp_len < 4)) { break; } // no retry
/* Switch bytes. */
@@ -2684,7 +2717,7 @@ havoc_stage:
switch_to = rand_below(afl, temp_len);
- } while (switch_from == switch_to);
+ } while (unlikely(switch_from == switch_to));
if (switch_from < switch_to) {
@@ -2728,7 +2761,7 @@ havoc_stage:
/* Delete bytes. */
- if (temp_len < 2) { break; }
+ if (unlikely(temp_len < 2)) { break; } // no retry
/* Don't delete too much. */
@@ -2753,7 +2786,7 @@ havoc_stage:
/* Shuffle bytes. */
- if (temp_len < 4) { break; }
+ if (unlikely(temp_len < 4)) { break; } // no retry
u32 len = choose_block_len(afl, temp_len - 1);
u32 off = rand_below(afl, temp_len - len + 1);
@@ -2770,7 +2803,7 @@ havoc_stage:
j = rand_below(afl, i + 1);
- } while (i == j);
+ } while (unlikely(i == j));
unsigned char temp = out_buf[off + i];
out_buf[off + i] = out_buf[off + j];
@@ -2786,7 +2819,7 @@ havoc_stage:
/* Delete bytes. */
- if (temp_len < 2) { break; }
+ if (unlikely(temp_len < 2)) { break; } // no retry
/* Don't delete too much. */
@@ -2808,6 +2841,8 @@ havoc_stage:
case 28: {
+ if (unlikely(temp_len < 2)) { break; } // no retry
+
u32 clone_len = 1;
u32 clone_to = rand_below(afl, temp_len);
u32 strat = rand_below(afl, 2);
@@ -2845,7 +2880,7 @@ havoc_stage:
case 29: {
- if (temp_len < 4) { break; }
+ if (unlikely(temp_len < 4)) { break; } // no retry
u32 off = rand_below(afl, temp_len), off2 = off, cnt = 0;
@@ -2867,7 +2902,19 @@ havoc_stage:
}
- if (cnt == off) { break; }
+ if (cnt == off) {
+
+ if (temp_len < 8) {
+
+ break;
+
+ } else {
+
+ goto retry_havoc_step;
+
+ }
+
+ }
}
@@ -2905,7 +2952,7 @@ havoc_stage:
val /= 2;
break;
case 4:
- if (val && (u64)val < 0x19999999) {
+ if (likely(val && (u64)val < 0x19999999)) {
val = (u64)rand_next(afl) % (u64)((u64)val * 10);
@@ -2995,7 +3042,19 @@ havoc_stage:
u32 len = 1 + rand_below(afl, 8);
u32 pos = rand_below(afl, temp_len);
/* Insert ascii number. */
- if (temp_len < pos + len) { break; }
+ if (unlikely(temp_len < pos + len)) {
+
+ if (unlikely(temp_len < 8)) {
+
+ break;
+
+ } else {
+
+ goto retry_havoc_step;
+
+ }
+
+ }
#ifdef INTROSPECTION
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " INSERTASCIINUM_");
@@ -3012,14 +3071,14 @@ havoc_stage:
case 32: {
- if (!afl->extras_cnt) { break; }
+ if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; }
/* Use the dictionary. */
u32 use_extra = rand_below(afl, afl->extras_cnt);
u32 extra_len = afl->extras[use_extra].len;
- if (extra_len > temp_len) { break; }
+ if (unlikely(extra_len > temp_len)) { goto retry_havoc_step; }
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
#ifdef INTROSPECTION
@@ -3035,11 +3094,15 @@ havoc_stage:
case 33: {
- if (!afl->extras_cnt) { break; }
+ if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; }
u32 use_extra = rand_below(afl, afl->extras_cnt);
u32 extra_len = afl->extras[use_extra].len;
- if (temp_len + extra_len >= MAX_FILE) { break; }
+ if (unlikely(temp_len + extra_len >= MAX_FILE)) {
+
+ goto retry_havoc_step;
+
+ }
u8 *ptr = afl->extras[use_extra].data;
u32 insert_at = rand_below(afl, temp_len + 1);
@@ -3066,14 +3129,14 @@ havoc_stage:
case 34: {
- if (!afl->a_extras_cnt) { break; }
+ if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; }
/* Use the dictionary. */
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
u32 extra_len = afl->a_extras[use_extra].len;
- if (extra_len > temp_len) { break; }
+ if (unlikely(extra_len > temp_len)) { goto retry_havoc_step; }
u32 insert_at = rand_below(afl, temp_len - extra_len + 1);
#ifdef INTROSPECTION
@@ -3089,11 +3152,15 @@ havoc_stage:
case 35: {
- if (!afl->a_extras_cnt) { break; }
+ if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; }
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
u32 extra_len = afl->a_extras[use_extra].len;
- if (temp_len + extra_len >= MAX_FILE) { break; }
+ if (unlikely(temp_len + extra_len >= MAX_FILE)) {
+
+ goto retry_havoc_step;
+
+ }
u8 *ptr = afl->a_extras[use_extra].data;
u32 insert_at = rand_below(afl, temp_len + 1);
@@ -3120,7 +3187,11 @@ havoc_stage:
case 36: {
- if (afl->ready_for_splicing_count <= 1) { break; }
+ if (unlikely(afl->ready_for_splicing_count <= 1)) {
+
+ goto retry_havoc_step;
+
+ }
/* Pick a random queue entry and seek to it. */
@@ -3129,7 +3200,9 @@ havoc_stage:
tid = rand_below(afl, afl->queued_items);
- } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4);
+ } while (unlikely(tid == afl->current_entry ||
+
+ afl->queue_buf[tid]->len < 4));
/* Get the testcase for splicing. */
struct queue_entry *target = afl->queue_buf[tid];
@@ -3160,8 +3233,17 @@ havoc_stage:
case 37: {
- if (afl->ready_for_splicing_count <= 1) { break; }
- if (temp_len + HAVOC_BLK_XL >= MAX_FILE) { break; }
+ if (unlikely(afl->ready_for_splicing_count <= 1)) {
+
+ goto retry_havoc_step;
+
+ }
+
+ if (unlikely(temp_len + HAVOC_BLK_XL >= MAX_FILE)) {
+
+ goto retry_havoc_step;
+
+ }
/* Pick a random queue entry and seek to it. */
@@ -3170,7 +3252,9 @@ havoc_stage:
tid = rand_below(afl, afl->queued_items);
- } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4);
+ } while (unlikely(tid == afl->current_entry ||
+
+ afl->queue_buf[tid]->len < 4));
/* Get the testcase for splicing. */
struct queue_entry *target = afl->queue_buf[tid];
@@ -3303,7 +3387,9 @@ retry_splicing:
tid = rand_below(afl, afl->queued_items);
- } while (tid == afl->current_entry || afl->queue_buf[tid]->len < 4);
+ } while (
+
+ unlikely(tid == afl->current_entry || afl->queue_buf[tid]->len < 4));
/* Get the testcase */
afl->splicing_with = tid;
--
cgit 1.4.1
From fcd21256780fd21c55e72e9338b3992c60db22dc Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 4 Apr 2023 15:47:53 +0200
Subject: prepare for strategies
---
custom_mutators/aflpp/Makefile | 10 +
custom_mutators/aflpp/README.md | 8 +
custom_mutators/aflpp/aflpp.c | 68 +++
include/afl-mutations.h | 992 ++++++++++++++++++++++++++++++++++++++++
src/afl-fuzz-one.c | 165 +++----
5 files changed, 1143 insertions(+), 100 deletions(-)
create mode 100644 custom_mutators/aflpp/Makefile
create mode 100644 custom_mutators/aflpp/README.md
create mode 100644 custom_mutators/aflpp/aflpp.c
create mode 100644 include/afl-mutations.h
diff --git a/custom_mutators/aflpp/Makefile b/custom_mutators/aflpp/Makefile
new file mode 100644
index 00000000..8efdf3e4
--- /dev/null
+++ b/custom_mutators/aflpp/Makefile
@@ -0,0 +1,10 @@
+
+CFLAGS = -O3 -funroll-loops -fPIC -Wl,-Bsymbolic
+
+all: aflpp-mutator.so
+
+aflpp-mutator.so: aflpp.c
+ $(CC) $(CFLAGS) -I../../include -I. -shared -o aflpp-mutator.so aflpp.c ../../src/afl-performance.c
+
+clean:
+ rm -f *.o *~ *.so core
diff --git a/custom_mutators/aflpp/README.md b/custom_mutators/aflpp/README.md
new file mode 100644
index 00000000..04d605c1
--- /dev/null
+++ b/custom_mutators/aflpp/README.md
@@ -0,0 +1,8 @@
+# custum mutator: AFL++
+
+this is the AFL++ havoc mutator as a custom mutator module for AFL++.
+
+just type `make` to build
+
+```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/aflpp/aflpp-mutator.so afl-fuzz ...```
+
diff --git a/custom_mutators/aflpp/aflpp.c b/custom_mutators/aflpp/aflpp.c
new file mode 100644
index 00000000..2b69ad9c
--- /dev/null
+++ b/custom_mutators/aflpp/aflpp.c
@@ -0,0 +1,68 @@
+#include "afl-mutations.h"
+
+typedef struct my_mutator {
+
+ afl_state_t *afl;
+ u8 *buf;
+
+} my_mutator_t;
+
+my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
+
+ (void)seed;
+
+ my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
+ if (!data) {
+
+ perror("afl_custom_init alloc");
+ return NULL;
+
+ }
+
+ data->buf = malloc(MAX_FILE);
+ if (!data->buf) {
+
+ perror("afl_custom_init alloc");
+ return NULL;
+
+ }
+
+ data->afl = afl;
+
+ return data;
+
+}
+
+/* here we run the AFL++ mutator, which is the best! */
+
+size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
+ u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
+ size_t max_size) {
+
+ u32 havoc_steps = 1 + rand_below(data->afl, 16);
+
+ /* set everything up, costly ... :( */
+ memcpy(data->buf, buf, buf_size);
+
+ /* the mutation */
+ u32 out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps,
+ false, true, add_buf, add_buf_size);
+
+ /* return size of mutated data */
+ *out_buf = data->buf;
+ return out_buf_len;
+
+}
+
+/**
+ * Deinitialize everything
+ *
+ * @param data The data ptr from afl_custom_init
+ */
+void afl_custom_deinit(my_mutator_t *data) {
+
+ free(data->buf);
+ free(data);
+
+}
+
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
new file mode 100644
index 00000000..43b7927d
--- /dev/null
+++ b/include/afl-mutations.h
@@ -0,0 +1,992 @@
+/* Implementation of afl havoc mutation to be used in AFL++ custom mutators and
+ partially in afl-fuzz itself.
+
+ How to use:
+
+ #include "afl-mutations.h" // needs afl-fuzz.h
+
+ u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32t steps, bool is_text,
+ bool is_exploration, u8 *splice_buf, u32 splice_len);
+
+ Returns:
+ u32 - the length of the mutated data return in *buf. 0 = error
+ Parameters:
+ afl_state_t *afl - the *afl state pointer
+ u8 *buf - the input buffer to mutate which will be mutated into.
+ NOTE: must be of MAX_FILE size!
+ u32 len - the length of the input
+ u32 steps - how many mutations to perform on the input
+ bool is_text - is the target expecting text inputs
+ bool is_exploration - mutate for exploration mode (instead of exploitation)
+ splice_buf - a buffer from another corpus item to splice with.
+ If NULL then no splicing
+ splice_len - the length of the splice buffer. If 0 then no splicing
+*/
+
+#ifndef _ANDROID_ASHMEM_H
+ #define AFL_MUTATIONS_H
+
+ #include
+ #include "afl-fuzz.h"
+
+ #define MUT_STRATEGY_ARRAY_SIZE 256
+
+enum {
+
+ /* 00 */ MUT_FLIPBIT,
+ /* 01 */ MUT_INTERESTING8,
+ /* 02 */ MUT_INTERESTING16,
+ /* 03 */ MUT_INTERESTING16BE,
+ /* 04 */ MUT_INTERESTING32,
+ /* 05 */ MUT_INTERESTING32BE,
+ /* 06 */ MUT_ARITH8_,
+ /* 07 */ MUT_ARITH8,
+ /* 08 */ MUT_ARITH16_,
+ /* 09 */ MUT_ARITH16BE_,
+ /* 10 */ MUT_ARITH16,
+ /* 11 */ MUT_ARITH16BE,
+ /* 12 */ MUT_ARITH32_,
+ /* 13 */ MUT_ARITH32BE_,
+ /* 14 */ MUT_ARITH32,
+ /* 15 */ MUT_ARITH32BE,
+ /* 16 */ MUT_RAND8,
+ /* 17 */ MUT_CLONE_OVERWRITE,
+ /* 18 */ MUT_CLONE_INSERT,
+ /* 19 */ MUT_OVERWRITE_COPY,
+ /* 20 */ MUT_OVERWRITE_FIXED,
+ /* 21 */ MUT_BYTEADD,
+ /* 22 */ MUT_BYTESUB,
+ /* 23 */ MUT_FLIP8,
+ /* 24 */ MUT_SWITCH,
+ /* 25 */ MUT_DEL,
+ /* 26 */ MUT_SHUFFLE,
+ /* 27 */ MUT_DELONE,
+ /* 28 */ MUT_INSERTONE,
+ /* 29 */ MUT_ASCIINUM,
+ /* 30 */ MUT_NEG,
+ /* 31 */ MUT_INSERTASCIINUM,
+ /* 32 */ MUT_EXTRA_OVERWRITE,
+ /* 33 */ MUT_EXTRA_INSERT,
+ /* 34 */ MUT_AUTO_EXTRA_OVERWRITE,
+ /* 35 */ MUT_AUTO_EXTRA_INSERT,
+ /* 36 */ MUT_SPLICE_OVERWRITE,
+ /* 37 */ MUT_SPLICE_INSERT,
+
+ MUT_MAX
+
+};
+
+unsigned int mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {};
+unsigned int mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {};
+unsigned int mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {};
+unsigned int mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] =
+ {};
+
+unsigned int afl_mutate(afl_state_t *, unsigned char *, unsigned int,
+ unsigned int, bool, bool, unsigned char *,
+ unsigned int);
+u32 choose_block_len(afl_state_t *, u32);
+
+/* Helper to choose random block len for block operations in fuzz_one().
+ Doesn't return zero, provided that max_len is > 0. */
+
+inline u32 choose_block_len(afl_state_t *afl, u32 limit) {
+
+ u32 min_value, max_value;
+ u32 rlim = MIN(afl->queue_cycle, (u32)3);
+
+ if (unlikely(!afl->run_over10m)) { rlim = 1; }
+
+ switch (rand_below(afl, rlim)) {
+
+ case 0:
+ min_value = 1;
+ max_value = HAVOC_BLK_SMALL;
+ break;
+
+ case 1:
+ min_value = HAVOC_BLK_SMALL;
+ max_value = HAVOC_BLK_MEDIUM;
+ break;
+
+ default:
+
+ if (likely(rand_below(afl, 10))) {
+
+ min_value = HAVOC_BLK_MEDIUM;
+ max_value = HAVOC_BLK_LARGE;
+
+ } else {
+
+ min_value = HAVOC_BLK_LARGE;
+ max_value = HAVOC_BLK_XL;
+
+ }
+
+ }
+
+ if (min_value >= limit) { min_value = 1; }
+
+ return min_value + rand_below(afl, MIN(max_value, limit) - min_value + 1);
+
+}
+
+unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len,
+ unsigned int steps, bool is_text, bool is_exploration,
+ unsigned char *splice_buf, unsigned int splice_len) {
+
+ if (!buf || !len) { return 0; }
+
+ u32 *mutation_array;
+ static unsigned char *tmp_buf = NULL;
+
+ if (!tmp_buf) {
+
+ if ((tmp_buf = malloc(MAX_FILE)) == NULL) { return 0; }
+
+ }
+
+ if (is_text) {
+
+ if (is_exploration) {
+
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
+
+ } else {
+
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
+
+ }
+
+ } else {
+
+ if (is_exploration) {
+
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
+
+ } else {
+
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
+
+ }
+
+ }
+
+ for (unsigned int step = 0; step < steps; ++step) {
+
+ retry_havoc_step:
+
+ u32 r = rand_below(afl, MUT_STRATEGY_ARRAY_SIZE), item;
+
+ switch (mutation_array[r]) {
+
+ case MUT_FLIPBIT: {
+
+ /* Flip a single bit somewhere. Spooky! */
+ u8 bit = rand_below(afl, 8);
+ u32 off = rand_below(afl, len);
+ buf[off] ^= 1 << bit;
+
+ break;
+
+ }
+
+ case MUT_INTERESTING8: {
+
+ /* Set byte to interesting value. */
+
+ item = rand_below(afl, sizeof(interesting_8));
+ buf[rand_below(afl, len)] = interesting_8[item];
+ break;
+
+ }
+
+ case MUT_INTERESTING16: {
+
+ /* Set word to interesting value, little endian. */
+
+ if (unlikely(len < 2)) { break; } // no retry
+
+ item = rand_below(afl, sizeof(interesting_16) >> 1);
+ *(u16 *)(buf + rand_below(afl, len - 1)) = interesting_16[item];
+
+ break;
+
+ }
+
+ case MUT_INTERESTING16BE: {
+
+ /* Set word to interesting value, big endian. */
+
+ if (unlikely(len < 2)) { break; } // no retry
+
+ item = rand_below(afl, sizeof(interesting_16) >> 1);
+ *(u16 *)(buf + rand_below(afl, len - 1)) = SWAP16(interesting_16[item]);
+
+ break;
+
+ }
+
+ case MUT_INTERESTING32: {
+
+ /* Set dword to interesting value, little endian. */
+
+ if (unlikely(len < 4)) { break; } // no retry
+
+ item = rand_below(afl, sizeof(interesting_32) >> 2);
+ *(u32 *)(buf + rand_below(afl, len - 3)) = interesting_32[item];
+
+ break;
+
+ }
+
+ case MUT_INTERESTING32BE: {
+
+ /* Set dword to interesting value, big endian. */
+
+ if (unlikely(len < 4)) { break; } // no retry
+
+ item = rand_below(afl, sizeof(interesting_32) >> 2);
+ *(u32 *)(buf + rand_below(afl, len - 3)) = SWAP32(interesting_32[item]);
+
+ break;
+
+ }
+
+ case MUT_ARITH8_: {
+
+ /* Randomly subtract from byte. */
+
+ item = 1 + rand_below(afl, ARITH_MAX);
+ buf[rand_below(afl, len)] -= item;
+ break;
+
+ }
+
+ case MUT_ARITH8: {
+
+ /* Randomly add to byte. */
+
+ item = 1 + rand_below(afl, ARITH_MAX);
+ buf[rand_below(afl, len)] += item;
+ break;
+
+ }
+
+ case MUT_ARITH16_: {
+
+ /* Randomly subtract from word, little endian. */
+
+ if (unlikely(len < 2)) { break; } // no retry
+
+ u32 pos = rand_below(afl, len - 1);
+ item = 1 + rand_below(afl, ARITH_MAX);
+ *(u16 *)(buf + pos) -= item;
+
+ break;
+
+ }
+
+ case MUT_ARITH16BE_: {
+
+ /* Randomly subtract from word, big endian. */
+
+ if (unlikely(len < 2)) { break; } // no retry
+
+ u32 pos = rand_below(afl, len - 1);
+ u16 num = 1 + rand_below(afl, ARITH_MAX);
+ *(u16 *)(buf + pos) = SWAP16(SWAP16(*(u16 *)(buf + pos)) - num);
+
+ break;
+
+ }
+
+ case MUT_ARITH16: {
+
+ /* Randomly add to word, little endian. */
+
+ if (unlikely(len < 2)) { break; } // no retry
+
+ u32 pos = rand_below(afl, len - 1);
+ item = 1 + rand_below(afl, ARITH_MAX);
+ *(u16 *)(buf + pos) += item;
+
+ break;
+
+ }
+
+ case MUT_ARITH16BE: {
+
+ /* Randomly add to word, big endian. */
+
+ if (unlikely(len < 2)) { break; } // no retry
+
+ u32 pos = rand_below(afl, len - 1);
+ u16 num = 1 + rand_below(afl, ARITH_MAX);
+ *(u16 *)(buf + pos) = SWAP16(SWAP16(*(u16 *)(buf + pos)) + num);
+
+ break;
+
+ }
+
+ case MUT_ARITH32_: {
+
+ /* Randomly subtract from dword, little endian. */
+
+ if (unlikely(len < 4)) { break; } // no retry
+
+ u32 pos = rand_below(afl, len - 3);
+ item = 1 + rand_below(afl, ARITH_MAX);
+ *(u32 *)(buf + pos) -= item;
+
+ break;
+
+ }
+
+ case MUT_ARITH32BE_: {
+
+ /* Randomly subtract from dword, big endian. */
+
+ if (unlikely(len < 4)) { break; } // no retry
+
+ u32 pos = rand_below(afl, len - 3);
+ u32 num = 1 + rand_below(afl, ARITH_MAX);
+ *(u32 *)(buf + pos) = SWAP32(SWAP32(*(u32 *)(buf + pos)) - num);
+
+ break;
+
+ }
+
+ case MUT_ARITH32: {
+
+ /* Randomly add to dword, little endian. */
+
+ if (unlikely(len < 4)) { break; } // no retry
+
+ u32 pos = rand_below(afl, len - 3);
+ item = 1 + rand_below(afl, ARITH_MAX);
+ *(u32 *)(buf + pos) += item;
+
+ break;
+
+ }
+
+ case MUT_ARITH32BE: {
+
+ /* Randomly add to dword, big endian. */
+
+ if (unlikely(len < 4)) { break; } // no retry
+
+ u32 pos = rand_below(afl, len - 3);
+ u32 num = 1 + rand_below(afl, ARITH_MAX);
+ *(u32 *)(buf + pos) = SWAP32(SWAP32(*(u32 *)(buf + pos)) + num);
+
+ break;
+
+ }
+
+ case MUT_RAND8: {
+
+ /* Just set a random byte to a random value. Because,
+ why not. We use XOR with 1-255 to eliminate the
+ possibility of a no-op. */
+
+ u32 pos = rand_below(afl, len);
+ item = 1 + rand_below(afl, 255);
+ buf[pos] ^= item;
+ break;
+
+ }
+
+ case MUT_CLONE_OVERWRITE: {
+
+ if (likely(len + HAVOC_BLK_XL < MAX_FILE)) {
+
+ /* Clone bytes. */
+
+ u32 clone_len = choose_block_len(afl, len);
+ u32 clone_from = rand_below(afl, len - clone_len + 1);
+ u32 clone_to = rand_below(afl, len);
+
+ /* Head */
+
+ memcpy(tmp_buf, buf, clone_to);
+
+ /* Inserted part */
+
+ memcpy(tmp_buf + clone_to, buf + clone_from, clone_len);
+
+ /* Tail */
+ memcpy(tmp_buf + clone_to + clone_len, buf + clone_to,
+ len - clone_to);
+
+ len += clone_len;
+ memcpy(buf, tmp_buf, len);
+
+ } else if (unlikely(len < 8)) {
+
+ break;
+
+ } else {
+
+ goto retry_havoc_step;
+
+ }
+
+ break;
+
+ }
+
+ case MUT_CLONE_INSERT: {
+
+ if (likely(len + HAVOC_BLK_XL < MAX_FILE)) {
+
+ /* Insert a block of constant bytes (25%). */
+
+ u32 clone_len = choose_block_len(afl, HAVOC_BLK_XL);
+ u32 clone_to = rand_below(afl, len);
+ u32 strat = rand_below(afl, 2);
+ u32 clone_from = clone_to ? clone_to - 1 : 0;
+ item = strat ? rand_below(afl, 256) : buf[clone_from];
+
+ /* Head */
+
+ memcpy(tmp_buf, buf, clone_to);
+
+ /* Inserted part */
+
+ memset(tmp_buf + clone_to, item, clone_len);
+
+ /* Tail */
+ memcpy(tmp_buf + clone_to + clone_len, buf + clone_to,
+ len - clone_to);
+
+ len += clone_len;
+ memcpy(buf, tmp_buf, len);
+
+ } else if (unlikely(len < 8)) {
+
+ break;
+
+ } else {
+
+ goto retry_havoc_step;
+
+ }
+
+ break;
+
+ }
+
+ case MUT_OVERWRITE_COPY: {
+
+ /* Overwrite bytes with a randomly selected chunk bytes. */
+
+ if (unlikely(len < 2)) { break; } // no retry
+
+ u32 copy_len = choose_block_len(afl, len - 1);
+ u32 copy_from = rand_below(afl, len - copy_len + 1);
+ u32 copy_to = rand_below(afl, len - copy_len + 1);
+
+ if (likely(copy_from != copy_to)) {
+
+ memmove(buf + copy_to, buf + copy_from, copy_len);
+
+ }
+
+ break;
+
+ }
+
+ case MUT_OVERWRITE_FIXED: {
+
+ /* Overwrite bytes with fixed bytes. */
+
+ if (unlikely(len < 2)) { break; } // no retry
+
+ u32 copy_len = choose_block_len(afl, len - 1);
+ u32 copy_to = rand_below(afl, len - copy_len + 1);
+ u32 strat = rand_below(afl, 2);
+ u32 copy_from = copy_to ? copy_to - 1 : 0;
+ item = strat ? rand_below(afl, 256) : buf[copy_from];
+ memset(buf + copy_to, item, copy_len);
+
+ break;
+
+ }
+
+ case MUT_BYTEADD: {
+
+ /* Increase byte by 1. */
+
+ buf[rand_below(afl, len)]++;
+ break;
+
+ }
+
+ case MUT_BYTESUB: {
+
+ /* Decrease byte by 1. */
+
+ buf[rand_below(afl, len)]--;
+ break;
+
+ }
+
+ case MUT_FLIP8: {
+
+ /* Flip byte. */
+
+ buf[rand_below(afl, len)] ^= 0xff;
+ break;
+
+ }
+
+ case MUT_SWITCH: {
+
+ if (unlikely(len < 4)) { break; } // no retry
+
+ /* Switch bytes. */
+
+ u32 to_end, switch_to, switch_len, switch_from;
+ switch_from = rand_below(afl, len);
+ do {
+
+ switch_to = rand_below(afl, len);
+
+ } while (unlikely(switch_from == switch_to));
+
+ if (switch_from < switch_to) {
+
+ switch_len = switch_to - switch_from;
+ to_end = len - switch_to;
+
+ } else {
+
+ switch_len = switch_from - switch_to;
+ to_end = len - switch_from;
+
+ }
+
+ switch_len = choose_block_len(afl, MIN(switch_len, to_end));
+
+ /* Backup */
+
+ memcpy(tmp_buf, buf + switch_from, switch_len);
+
+ /* Switch 1 */
+
+ memcpy(buf + switch_from, buf + switch_to, switch_len);
+
+ /* Switch 2 */
+
+ memcpy(buf + switch_to, tmp_buf, switch_len);
+
+ break;
+
+ }
+
+ case MUT_DEL: {
+
+ /* Delete bytes. */
+
+ if (unlikely(len < 2)) { break; } // no retry
+
+ /* Don't delete too much. */
+
+ u32 del_len = choose_block_len(afl, len - 1);
+ u32 del_from = rand_below(afl, len - del_len + 1);
+ memmove(buf + del_from, buf + del_from + del_len,
+ len - del_from - del_len);
+ len -= del_len;
+
+ break;
+
+ }
+
+ case MUT_SHUFFLE: {
+
+ /* Shuffle bytes. */
+
+ if (unlikely(len < 4)) { break; } // no retry
+
+ u32 len = choose_block_len(afl, len - 1);
+ u32 off = rand_below(afl, len - len + 1);
+
+ for (u32 i = len - 1; i > 0; i--) {
+
+ u32 j;
+ do {
+
+ j = rand_below(afl, i + 1);
+
+ } while (unlikely(i == j));
+
+ unsigned char temp = buf[off + i];
+ buf[off + i] = buf[off + j];
+ buf[off + j] = temp;
+
+ }
+
+ break;
+
+ }
+
+ case MUT_DELONE: {
+
+ /* Delete bytes. */
+
+ if (unlikely(len < 2)) { break; } // no retry
+
+ /* Don't delete too much. */
+
+ u32 del_len = 1;
+ u32 del_from = rand_below(afl, len - del_len + 1);
+ memmove(buf + del_from, buf + del_from + del_len,
+ len - del_from - del_len);
+
+ len -= del_len;
+
+ break;
+
+ }
+
+ case MUT_INSERTONE: {
+
+ if (unlikely(len < 2)) { break; } // no retry
+
+ u32 clone_len = 1;
+ u32 clone_to = rand_below(afl, len);
+ u32 strat = rand_below(afl, 2);
+ u32 clone_from = clone_to ? clone_to - 1 : 0;
+ item = strat ? rand_below(afl, 256) : buf[clone_from];
+
+ /* Head */
+
+ memcpy(tmp_buf, buf, clone_to);
+
+ /* Inserted part */
+
+ memset(tmp_buf + clone_to, item, clone_len);
+
+ /* Tail */
+ memcpy(tmp_buf + clone_to + clone_len, buf + clone_to, len - clone_to);
+
+ len += clone_len;
+ memcpy(buf, tmp_buf, len);
+
+ break;
+
+ }
+
+ case MUT_ASCIINUM: {
+
+ if (unlikely(len < 4)) { break; } // no retry
+
+ u32 off = rand_below(afl, len), off2 = off, cnt = 0;
+
+ while (off2 + cnt < len && !isdigit(buf[off2 + cnt])) {
+
+ ++cnt;
+
+ }
+
+ // none found, wrap
+ if (off2 + cnt == len) {
+
+ off2 = 0;
+ cnt = 0;
+
+ while (cnt < off && !isdigit(buf[off2 + cnt])) {
+
+ ++cnt;
+
+ }
+
+ if (cnt == off) {
+
+ if (len < 8) {
+
+ break;
+
+ } else {
+
+ goto retry_havoc_step;
+
+ }
+
+ }
+
+ }
+
+ off = off2 + cnt;
+ off2 = off + 1;
+
+ while (off2 < len && isdigit(buf[off2])) {
+
+ ++off2;
+
+ }
+
+ s64 val = buf[off] - '0';
+ for (u32 i = off + 1; i < off2; ++i) {
+
+ val = (val * 10) + buf[i] - '0';
+
+ }
+
+ if (off && buf[off - 1] == '-') { val = -val; }
+
+ u32 strat = rand_below(afl, 8);
+ switch (strat) {
+
+ case 0:
+ val++;
+ break;
+ case 1:
+ val--;
+ break;
+ case 2:
+ val *= 2;
+ break;
+ case 3:
+ val /= 2;
+ break;
+ case 4:
+ if (likely(val && (u64)val < 0x19999999)) {
+
+ val = (u64)rand_next(afl) % (u64)((u64)val * 10);
+
+ } else {
+
+ val = rand_below(afl, 256);
+
+ }
+
+ break;
+ case 5:
+ val += rand_below(afl, 256);
+ break;
+ case 6:
+ val -= rand_below(afl, 256);
+ break;
+ case 7:
+ val = ~(val);
+ break;
+
+ }
+
+ char buf[20];
+ snprintf(buf, sizeof(buf), "%ld", val);
+ u32 old_len = off2 - off;
+ u32 new_len = strlen(buf);
+
+ if (old_len == new_len) {
+
+ memcpy(buf + off, buf, new_len);
+
+ } else {
+
+ /* Head */
+
+ memcpy(tmp_buf, buf, off);
+
+ /* Inserted part */
+
+ memcpy(tmp_buf + off, buf, new_len);
+
+ /* Tail */
+ memcpy(tmp_buf + off + new_len, buf + off2, len - off2);
+
+ len += (new_len - old_len);
+ memcpy(buf, tmp_buf, len);
+
+ }
+
+ // fprintf(stderr, "AFTER : %s\n", buf);
+ break;
+
+ }
+
+ case MUT_NEG: {
+
+ /* Neg byte. */
+
+ item = rand_below(afl, len);
+ buf[item] = ~buf[item];
+
+ break;
+
+ }
+
+ case MUT_INSERTASCIINUM: {
+
+ u32 len = 1 + rand_below(afl, 8);
+ u32 pos = rand_below(afl, len);
+
+ /* Insert ascii number. */
+ if (unlikely(len < pos + len)) {
+
+ if (unlikely(len < 8)) {
+
+ break;
+
+ } else {
+
+ goto retry_havoc_step;
+
+ }
+
+ }
+
+ u64 val = rand_next(afl);
+ char buf[20];
+ snprintf(buf, sizeof(buf), "%llu", val);
+ memcpy(buf + pos, buf, len);
+
+ break;
+
+ }
+
+ case MUT_EXTRA_OVERWRITE: {
+
+ if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; }
+
+ /* Use the dictionary. */
+
+ u32 use_extra = rand_below(afl, afl->extras_cnt);
+ u32 extra_len = afl->extras[use_extra].len;
+
+ if (unlikely(extra_len > len)) { goto retry_havoc_step; }
+
+ u32 insert_at = rand_below(afl, len - extra_len + 1);
+ memcpy(buf + insert_at, afl->extras[use_extra].data, extra_len);
+
+ break;
+
+ }
+
+ case MUT_EXTRA_INSERT: {
+
+ if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; }
+
+ u32 use_extra = rand_below(afl, afl->extras_cnt);
+ u32 extra_len = afl->extras[use_extra].len;
+ if (unlikely(len + extra_len >= MAX_FILE)) { goto retry_havoc_step; }
+
+ u8 *ptr = afl->extras[use_extra].data;
+ u32 insert_at = rand_below(afl, len + 1);
+
+ /* Tail */
+ memmove(buf + insert_at + extra_len, buf + insert_at, len - insert_at);
+
+ /* Inserted part */
+ memcpy(buf + insert_at, ptr, extra_len);
+ len += extra_len;
+
+ break;
+
+ }
+
+ case MUT_AUTO_EXTRA_OVERWRITE: {
+
+ if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; }
+
+ /* Use the dictionary. */
+
+ u32 use_extra = rand_below(afl, afl->a_extras_cnt);
+ u32 extra_len = afl->a_extras[use_extra].len;
+
+ if (unlikely(extra_len > len)) { goto retry_havoc_step; }
+
+ u32 insert_at = rand_below(afl, len - extra_len + 1);
+ memcpy(buf + insert_at, afl->a_extras[use_extra].data, extra_len);
+
+ break;
+
+ }
+
+ case MUT_AUTO_EXTRA_INSERT: {
+
+ if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; }
+
+ u32 use_extra = rand_below(afl, afl->a_extras_cnt);
+ u32 extra_len = afl->a_extras[use_extra].len;
+ if (unlikely(len + extra_len >= MAX_FILE)) { goto retry_havoc_step; }
+
+ u8 *ptr = afl->a_extras[use_extra].data;
+ u32 insert_at = rand_below(afl, len + 1);
+
+ /* Tail */
+ memmove(buf + insert_at + extra_len, buf + insert_at, len - insert_at);
+
+ /* Inserted part */
+ memcpy(buf + insert_at, ptr, extra_len);
+ len += extra_len;
+
+ break;
+
+ }
+
+ case MUT_SPLICE_OVERWRITE: {
+
+ if (unlikely(!splice_buf || !splice_len)) { goto retry_havoc_step; }
+
+ /* overwrite mode */
+
+ u32 copy_from, copy_to, copy_len;
+
+ copy_len = choose_block_len(afl, splice_len - 1);
+
+ if (copy_len > len) copy_len = len;
+
+ copy_from = rand_below(afl, splice_len - copy_len + 1);
+ copy_to = rand_below(afl, len - copy_len + 1);
+ memmove(buf + copy_to, splice_buf + copy_from, copy_len);
+
+ break;
+
+ }
+
+ case MUT_SPLICE_INSERT: {
+
+ if (unlikely(!splice_buf || !splice_len)) { goto retry_havoc_step; }
+
+ if (unlikely(len + HAVOC_BLK_XL >= MAX_FILE)) { goto retry_havoc_step; }
+
+ /* insert mode */
+
+ u32 clone_from, clone_to, clone_len;
+
+ clone_len = choose_block_len(afl, splice_len);
+ clone_from = rand_below(afl, splice_len - clone_len + 1);
+ clone_to = rand_below(afl, len + 1);
+
+ /* Head */
+
+ memcpy(tmp_buf, buf, clone_to);
+
+ /* Inserted part */
+
+ memcpy(tmp_buf + clone_to, splice_buf + clone_from, clone_len);
+
+ /* Tail */
+ memcpy(tmp_buf + clone_to + clone_len, buf + clone_to, len - clone_to);
+
+ len += clone_len;
+ memcpy(buf, tmp_buf, len);
+
+ break;
+
+ }
+
+ }
+
+ }
+
+ return len;
+
+}
+
+#endif /* !AFL_MUTATIONS_H */
+
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 1636c323..226fb40e 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -27,21 +27,7 @@
#include
#include
#include "cmplog.h"
-
-static u32 mutation_array_explore[] = {
-
- 0, 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};
-// static u32 mutation_array_exploit[] = { 0, 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 }; static u32 mutation_array_txt_explore[] = { 0, 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 }; static u32 mutation_array_txt_exploit[] = { 0, 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 };
-
-// what about more splicing?
-// what about -x and cmplog learn?
+#include "afl-mutations.h"
/* MOpt */
@@ -85,50 +71,6 @@ static int select_algorithm(afl_state_t *afl, u32 max_algorithm) {
}
-/* Helper to choose random block len for block operations in fuzz_one().
- Doesn't return zero, provided that max_len is > 0. */
-
-static inline u32 choose_block_len(afl_state_t *afl, u32 limit) {
-
- u32 min_value, max_value;
- u32 rlim = MIN(afl->queue_cycle, (u32)3);
-
- if (unlikely(!afl->run_over10m)) { rlim = 1; }
-
- switch (rand_below(afl, rlim)) {
-
- case 0:
- min_value = 1;
- max_value = HAVOC_BLK_SMALL;
- break;
-
- case 1:
- min_value = HAVOC_BLK_SMALL;
- max_value = HAVOC_BLK_MEDIUM;
- break;
-
- default:
-
- if (likely(rand_below(afl, 10))) {
-
- min_value = HAVOC_BLK_MEDIUM;
- max_value = HAVOC_BLK_LARGE;
-
- } else {
-
- min_value = HAVOC_BLK_LARGE;
- max_value = HAVOC_BLK_XL;
-
- }
-
- }
-
- if (min_value >= limit) { min_value = 1; }
-
- return min_value + rand_below(afl, MIN(max_value, limit) - min_value + 1);
-
-}
-
/* Helper function to see if a particular change (xor_val = old ^ new) could
be a product of deterministic bit flips with the lengths and stepovers
attempted by afl-fuzz. This is used to avoid dupes in some of the
@@ -2136,8 +2078,31 @@ havoc_stage:
u32 *mutation_array;
u32 stack_max;
- // if ( ... )
- mutation_array = (u32 *)&mutation_array_explore;
+ if (afl->queue_cur->is_ascii) { // is text?
+
+ if (1) { // is exploration?
+
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
+
+ } else { // is exploitation!
+
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
+
+ }
+
+ } else { // is binary!
+
+ if (1) { // is exploration?
+
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
+
+ } else { // is exploitation!
+
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
+
+ }
+
+ }
if (temp_len < 64) {
@@ -2208,11 +2173,11 @@ havoc_stage:
}
retry_havoc_step:
- u32 r = rand_below(afl, 256), item;
+ u32 r = rand_below(afl, MUT_STRATEGY_ARRAY_SIZE), item;
switch (mutation_array[r]) {
- case 0: {
+ case MUT_FLIPBIT: {
/* Flip a single bit somewhere. Spooky! */
u8 bit = rand_below(afl, 8);
@@ -2227,7 +2192,7 @@ havoc_stage:
}
- case 1: {
+ case MUT_INTERESTING8: {
/* Set byte to interesting value. */
@@ -2241,7 +2206,7 @@ havoc_stage:
}
- case 2: {
+ case MUT_INTERESTING16: {
/* Set word to interesting value, little endian. */
@@ -2260,7 +2225,7 @@ havoc_stage:
}
- case 3: {
+ case MUT_INTERESTING16BE: {
/* Set word to interesting value, big endian. */
@@ -2278,7 +2243,7 @@ havoc_stage:
}
- case 4: {
+ case MUT_INTERESTING32: {
/* Set dword to interesting value, little endian. */
@@ -2297,7 +2262,7 @@ havoc_stage:
}
- case 5: {
+ case MUT_INTERESTING32BE: {
/* Set dword to interesting value, big endian. */
@@ -2315,7 +2280,7 @@ havoc_stage:
}
- case 6: {
+ case MUT_ARITH8_: {
/* Randomly subtract from byte. */
@@ -2329,7 +2294,7 @@ havoc_stage:
}
- case 7: {
+ case MUT_ARITH8: {
/* Randomly add to byte. */
@@ -2343,7 +2308,7 @@ havoc_stage:
}
- case 8: {
+ case MUT_ARITH16_: {
/* Randomly subtract from word, little endian. */
@@ -2362,7 +2327,7 @@ havoc_stage:
}
- case 9: {
+ case MUT_ARITH16BE_: {
/* Randomly subtract from word, big endian. */
@@ -2382,7 +2347,7 @@ havoc_stage:
}
- case 10: {
+ case MUT_ARITH16: {
/* Randomly add to word, little endian. */
@@ -2401,7 +2366,7 @@ havoc_stage:
}
- case 11: {
+ case MUT_ARITH16BE: {
/* Randomly add to word, big endian. */
@@ -2421,7 +2386,7 @@ havoc_stage:
}
- case 12: {
+ case MUT_ARITH32_: {
/* Randomly subtract from dword, little endian. */
@@ -2440,7 +2405,7 @@ havoc_stage:
}
- case 13: {
+ case MUT_ARITH32BE_: {
/* Randomly subtract from dword, big endian. */
@@ -2460,7 +2425,7 @@ havoc_stage:
}
- case 14: {
+ case MUT_ARITH32: {
/* Randomly add to dword, little endian. */
@@ -2479,7 +2444,7 @@ havoc_stage:
}
- case 15: {
+ case MUT_ARITH32BE: {
/* Randomly add to dword, big endian. */
@@ -2499,7 +2464,7 @@ havoc_stage:
}
- case 16: {
+ case MUT_RAND8: {
/* Just set a random byte to a random value. Because,
why not. We use XOR with 1-255 to eliminate the
@@ -2517,7 +2482,7 @@ havoc_stage:
}
- case 17: {
+ case MUT_CLONE_OVERWRITE: {
if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) {
@@ -2566,7 +2531,7 @@ havoc_stage:
}
- case 18: {
+ case MUT_CLONE_INSERT: {
if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) {
@@ -2617,7 +2582,7 @@ havoc_stage:
}
- case 19: {
+ case MUT_OVERWRITE_COPY: {
/* Overwrite bytes with a randomly selected chunk bytes. */
@@ -2642,7 +2607,7 @@ havoc_stage:
}
- case 20: {
+ case MUT_OVERWRITE_FIXED: {
/* Overwrite bytes with fixed bytes. */
@@ -2666,7 +2631,7 @@ havoc_stage:
}
- case 21: {
+ case MUT_BYTEADD: {
/* Increase byte by 1. */
@@ -2679,7 +2644,7 @@ havoc_stage:
}
- case 22: {
+ case MUT_BYTESUB: {
/* Decrease byte by 1. */
@@ -2692,7 +2657,7 @@ havoc_stage:
}
- case 23: {
+ case MUT_FLIP8: {
/* Flip byte. */
@@ -2705,7 +2670,7 @@ havoc_stage:
}
- case 24: {
+ case MUT_SWITCH: {
if (unlikely(temp_len < 4)) { break; } // no retry
@@ -2757,7 +2722,7 @@ havoc_stage:
}
- case 25: {
+ case MUT_DEL: {
/* Delete bytes. */
@@ -2782,7 +2747,7 @@ havoc_stage:
}
- case 26: {
+ case MUT_SHUFFLE: {
/* Shuffle bytes. */
@@ -2815,7 +2780,7 @@ havoc_stage:
}
- case 27: {
+ case MUT_DELONE: {
/* Delete bytes. */
@@ -2839,7 +2804,7 @@ havoc_stage:
}
- case 28: {
+ case MUT_INSERTONE: {
if (unlikely(temp_len < 2)) { break; } // no retry
@@ -2878,7 +2843,7 @@ havoc_stage:
}
- case 29: {
+ case MUT_ASCIINUM: {
if (unlikely(temp_len < 4)) { break; } // no retry
@@ -3022,7 +2987,7 @@ havoc_stage:
}
- case 30: {
+ case MUT_NEG: {
/* Neg byte. */
@@ -3037,7 +3002,7 @@ havoc_stage:
}
- case 31: {
+ case MUT_INSERTASCIINUM: {
u32 len = 1 + rand_below(afl, 8);
u32 pos = rand_below(afl, temp_len);
@@ -3069,7 +3034,7 @@ havoc_stage:
}
- case 32: {
+ case MUT_EXTRA_OVERWRITE: {
if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; }
@@ -3092,7 +3057,7 @@ havoc_stage:
}
- case 33: {
+ case MUT_EXTRA_INSERT: {
if (unlikely(!afl->extras_cnt)) { goto retry_havoc_step; }
@@ -3127,7 +3092,7 @@ havoc_stage:
}
- case 34: {
+ case MUT_AUTO_EXTRA_OVERWRITE: {
if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; }
@@ -3150,7 +3115,7 @@ havoc_stage:
}
- case 35: {
+ case MUT_AUTO_EXTRA_INSERT: {
if (unlikely(!afl->a_extras_cnt)) { goto retry_havoc_step; }
@@ -3185,7 +3150,7 @@ havoc_stage:
}
- case 36: {
+ case MUT_SPLICE_OVERWRITE: {
if (unlikely(afl->ready_for_splicing_count <= 1)) {
@@ -3231,7 +3196,7 @@ havoc_stage:
}
- case 37: {
+ case MUT_SPLICE_INSERT: {
if (unlikely(afl->ready_for_splicing_count <= 1)) {
--
cgit 1.4.1
From 32ffa2664cdfa2cc377df12cbf6efdcecbc2e78a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 4 Apr 2023 16:23:19 +0200
Subject: max_len support
---
custom_mutators/aflpp/aflpp.c | 27 +++++++++++++--
include/afl-mutations.h | 76 +++++++++++++++++++++++++++----------------
2 files changed, 72 insertions(+), 31 deletions(-)
diff --git a/custom_mutators/aflpp/aflpp.c b/custom_mutators/aflpp/aflpp.c
index 2b69ad9c..e15d0391 100644
--- a/custom_mutators/aflpp/aflpp.c
+++ b/custom_mutators/aflpp/aflpp.c
@@ -4,6 +4,7 @@ typedef struct my_mutator {
afl_state_t *afl;
u8 *buf;
+ u32 buf_size;
} my_mutator_t;
@@ -19,12 +20,15 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
}
- data->buf = malloc(MAX_FILE);
- if (!data->buf) {
+ if ((data->buf = malloc(MAX_FILE)) == NULL) {
perror("afl_custom_init alloc");
return NULL;
+ } else {
+
+ data->buf_size = MAX_FILE;
+
}
data->afl = afl;
@@ -39,6 +43,23 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
size_t max_size) {
+ if (max_size > data->buf_size) {
+
+ u8 *ptr = realloc(data->buf, max_size);
+
+ if (ptr) {
+
+ return 0;
+
+ } else {
+
+ data->buf = ptr;
+ data->buf_size = max_size;
+
+ }
+
+ }
+
u32 havoc_steps = 1 + rand_below(data->afl, 16);
/* set everything up, costly ... :( */
@@ -46,7 +67,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
/* the mutation */
u32 out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps,
- false, true, add_buf, add_buf_size);
+ false, true, add_buf, add_buf_size, max_size);
/* return size of mutated data */
*out_buf = data->buf;
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 43b7927d..e3f69214 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -6,7 +6,8 @@
#include "afl-mutations.h" // needs afl-fuzz.h
u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32t steps, bool is_text,
- bool is_exploration, u8 *splice_buf, u32 splice_len);
+ bool is_exploration, u8 *splice_buf, u32 splice_len,
+ u32 max_len);
Returns:
u32 - the length of the mutated data return in *buf. 0 = error
@@ -21,6 +22,7 @@
splice_buf - a buffer from another corpus item to splice with.
If NULL then no splicing
splice_len - the length of the splice buffer. If 0 then no splicing
+ u32 max_len - the maximum size the mutated buffer may grow to
*/
#ifndef _ANDROID_ASHMEM_H
@@ -76,16 +78,13 @@ enum {
};
-unsigned int mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {};
-unsigned int mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {};
-unsigned int mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {};
-unsigned int mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] =
- {};
+u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {};
+u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {};
+u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {};
+u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {};
-unsigned int afl_mutate(afl_state_t *, unsigned char *, unsigned int,
- unsigned int, bool, bool, unsigned char *,
- unsigned int);
-u32 choose_block_len(afl_state_t *, u32);
+u32 afl_mutate(afl_state_t *, u8 *, u32, u32, bool, bool, u8 *, u32, u32);
+u32 choose_block_len(afl_state_t *, u32);
/* Helper to choose random block len for block operations in fuzz_one().
Doesn't return zero, provided that max_len is > 0. */
@@ -131,18 +130,39 @@ inline u32 choose_block_len(afl_state_t *afl, u32 limit) {
}
-unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len,
- unsigned int steps, bool is_text, bool is_exploration,
- unsigned char *splice_buf, unsigned int splice_len) {
+inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
+ bool is_text, bool is_exploration, u8 *splice_buf,
+ u32 splice_len, u32 max_len) {
if (!buf || !len) { return 0; }
- u32 *mutation_array;
- static unsigned char *tmp_buf = NULL;
+ u32 *mutation_array;
+ static u8 *tmp_buf = NULL;
+ static u32 tmp_buf_size = 0;
- if (!tmp_buf) {
+ if (max_len > tmp_buf_size) {
- if ((tmp_buf = malloc(MAX_FILE)) == NULL) { return 0; }
+ if (tmp_buf) {
+
+ u8 *ptr = realloc(tmp_buf, max_len);
+
+ if (!ptr) {
+
+ return 0;
+
+ } else {
+
+ tmp_buf = ptr;
+
+ }
+
+ } else {
+
+ if ((tmp_buf = malloc(max_len)) == NULL) { return 0; }
+
+ }
+
+ tmp_buf_size = max_len;
}
@@ -150,11 +170,11 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len,
if (is_exploration) {
- mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
+ mutation_array = (u32 *)&mutation_strategy_exploration_text;
} else {
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
+ mutation_array = (u32 *)&mutation_strategy_exploitation_text;
}
@@ -162,17 +182,17 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len,
if (is_exploration) {
- mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
+ mutation_array = (u32 *)&mutation_strategy_exploration_binary;
} else {
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
+ mutation_array = (u32 *)&mutation_strategy_exploitation_binary;
}
}
- for (unsigned int step = 0; step < steps; ++step) {
+ for (u32 step = 0; step < steps; ++step) {
retry_havoc_step:
@@ -400,7 +420,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len,
case MUT_CLONE_OVERWRITE: {
- if (likely(len + HAVOC_BLK_XL < MAX_FILE)) {
+ if (likely(len + HAVOC_BLK_XL < max_len)) {
/* Clone bytes. */
@@ -439,7 +459,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len,
case MUT_CLONE_INSERT: {
- if (likely(len + HAVOC_BLK_XL < MAX_FILE)) {
+ if (likely(len + HAVOC_BLK_XL < max_len)) {
/* Insert a block of constant bytes (25%). */
@@ -622,7 +642,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len,
} while (unlikely(i == j));
- unsigned char temp = buf[off + i];
+ u8 temp = buf[off + i];
buf[off + i] = buf[off + j];
buf[off + j] = temp;
@@ -872,7 +892,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len,
u32 use_extra = rand_below(afl, afl->extras_cnt);
u32 extra_len = afl->extras[use_extra].len;
- if (unlikely(len + extra_len >= MAX_FILE)) { goto retry_havoc_step; }
+ if (unlikely(len + extra_len >= max_len)) { goto retry_havoc_step; }
u8 *ptr = afl->extras[use_extra].data;
u32 insert_at = rand_below(afl, len + 1);
@@ -912,7 +932,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len,
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
u32 extra_len = afl->a_extras[use_extra].len;
- if (unlikely(len + extra_len >= MAX_FILE)) { goto retry_havoc_step; }
+ if (unlikely(len + extra_len >= max_len)) { goto retry_havoc_step; }
u8 *ptr = afl->a_extras[use_extra].data;
u32 insert_at = rand_below(afl, len + 1);
@@ -952,7 +972,7 @@ unsigned int afl_mutate(afl_state_t *afl, unsigned char *buf, unsigned int len,
if (unlikely(!splice_buf || !splice_len)) { goto retry_havoc_step; }
- if (unlikely(len + HAVOC_BLK_XL >= MAX_FILE)) { goto retry_havoc_step; }
+ if (unlikely(len + HAVOC_BLK_XL >= max_len)) { goto retry_havoc_step; }
/* insert mode */
--
cgit 1.4.1
From 2bff92c603463410fa0f97e7c4db7eb14c45e5ed Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 4 Apr 2023 16:25:05 +0200
Subject: nit
---
include/afl-mutations.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index e3f69214..707db799 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -14,7 +14,7 @@
Parameters:
afl_state_t *afl - the *afl state pointer
u8 *buf - the input buffer to mutate which will be mutated into.
- NOTE: must be of MAX_FILE size!
+ NOTE: must be able to contain a size of at least max_len (see below)!
u32 len - the length of the input
u32 steps - how many mutations to perform on the input
bool is_text - is the target expecting text inputs
--
cgit 1.4.1
From 3ab18d286142e2e19e37850c051e0b07b9d7b296 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 4 Apr 2023 19:44:12 +0200
Subject: mode switch
---
include/afl-fuzz.h | 69 +++++++------
include/afl-mutations.h | 259 +++++++++++++++++++++++++++++++++++++++++++++++-
include/config.h | 6 ++
src/afl-fuzz-one.c | 6 +-
src/afl-fuzz-state.c | 1 +
src/afl-fuzz-stats.c | 5 +-
src/afl-fuzz.c | 51 ++++++++--
7 files changed, 351 insertions(+), 46 deletions(-)
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 58d02af5..6573eabf 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -490,7 +490,9 @@ typedef struct afl_state {
*orig_cmdline, /* Original command line */
*infoexec; /* Command to execute on a new crash */
- u32 hang_tmout; /* Timeout used for hang det (ms) */
+ u32 hang_tmout, /* Timeout used for hang det (ms) */
+ stats_update_freq, /* Stats update frequency (execs) */
+ switch_fuzz_mode; /* auto or fixed fuzz mode */
u8 havoc_stack_pow2, /* HAVOC_STACK_POW2 */
no_unlink, /* do not unlink cur_input */
@@ -499,40 +501,37 @@ typedef struct afl_state {
custom_splice_optout, /* Custom mutator no splice buffer */
is_main_node, /* if this is the main node */
is_secondary_node, /* if this is a secondary instance */
- pizza_is_served; /* pizza mode */
-
- u32 stats_update_freq; /* Stats update frequency (execs) */
-
- u8 schedule; /* Power schedule (default: EXPLORE)*/
- u8 havoc_max_mult;
-
- u8 skip_deterministic, /* Skip deterministic stages? */
- use_splicing, /* Recombine input files? */
- non_instrumented_mode, /* Run in non-instrumented mode? */
- score_changed, /* Scoring for favorites changed? */
- resuming_fuzz, /* Resuming an older fuzzing job? */
- timeout_given, /* Specific timeout given? */
- not_on_tty, /* stdout is not a tty */
- term_too_small, /* terminal dimensions too small */
- no_forkserver, /* Disable forkserver? */
- crash_mode, /* Crash mode! Yeah! */
- in_place_resume, /* Attempt in-place resume? */
- autoresume, /* Resume if afl->out_dir exists? */
- auto_changed, /* Auto-generated tokens changed? */
- no_cpu_meter_red, /* Feng shui on the status screen */
- no_arith, /* Skip most arithmetic ops */
- shuffle_queue, /* Shuffle input queue? */
- bitmap_changed, /* Time to update bitmap? */
- unicorn_mode, /* Running in Unicorn mode? */
- use_wine, /* Use WINE with QEMU mode */
- skip_requested, /* Skip request, via SIGUSR1 */
- run_over10m, /* Run time over 10 minutes? */
- persistent_mode, /* Running in persistent mode? */
- deferred_mode, /* Deferred forkserver mode? */
- fixed_seed, /* do not reseed */
- fast_cal, /* Try to calibrate faster? */
- disable_trim, /* Never trim in fuzz_one */
- shmem_testcase_mode, /* If sharedmem testcases are used */
+ pizza_is_served, /* pizza mode */
+ text_input, /* target wants text inputs */
+ fuzz_mode, /* current mode: coverage/exploration or crash/exploitation */
+ schedule, /* Power schedule (default: EXPLORE)*/
+ havoc_max_mult, skip_deterministic, /* Skip deterministic stages? */
+ use_splicing, /* Recombine input files? */
+ non_instrumented_mode, /* Run in non-instrumented mode? */
+ score_changed, /* Scoring for favorites changed? */
+ resuming_fuzz, /* Resuming an older fuzzing job? */
+ timeout_given, /* Specific timeout given? */
+ not_on_tty, /* stdout is not a tty */
+ term_too_small, /* terminal dimensions too small */
+ no_forkserver, /* Disable forkserver? */
+ crash_mode, /* Crash mode! Yeah! */
+ in_place_resume, /* Attempt in-place resume? */
+ autoresume, /* Resume if afl->out_dir exists? */
+ auto_changed, /* Auto-generated tokens changed? */
+ no_cpu_meter_red, /* Feng shui on the status screen */
+ no_arith, /* Skip most arithmetic ops */
+ shuffle_queue, /* Shuffle input queue? */
+ bitmap_changed, /* Time to update bitmap? */
+ unicorn_mode, /* Running in Unicorn mode? */
+ use_wine, /* Use WINE with QEMU mode */
+ skip_requested, /* Skip request, via SIGUSR1 */
+ run_over10m, /* Run time over 10 minutes? */
+ persistent_mode, /* Running in persistent mode? */
+ deferred_mode, /* Deferred forkserver mode? */
+ fixed_seed, /* do not reseed */
+ fast_cal, /* Try to calibrate faster? */
+ disable_trim, /* Never trim in fuzz_one */
+ shmem_testcase_mode, /* If sharedmem testcases are used */
expand_havoc, /* perform expensive havoc after no find */
cycle_schedules, /* cycle power schedules? */
old_seed_selection, /* use vanilla afl seed selection */
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 707db799..5a1b6356 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -81,7 +81,264 @@ enum {
u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {};
u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {};
u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {};
-u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {};
+u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {
+
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT};
u32 afl_mutate(afl_state_t *, u8 *, u32, u32, bool, bool, u8 *, u32, u32);
u32 choose_block_len(afl_state_t *, u32);
diff --git a/include/config.h b/include/config.h
index e46f515a..c1297bdd 100644
--- a/include/config.h
+++ b/include/config.h
@@ -43,6 +43,12 @@
Default: 8MB (defined in bytes) */
#define DEFAULT_SHMEM_SIZE (8 * 1024 * 1024)
+/* Default time until when no more coverage finds are happening afl-fuzz
+ switches to exploitation mode. It automatically switches back when new
+ coverage is found.
+ Default: 300 (seconds) */
+#define STRATEGY_SWITCH_TIME 300
+
/* Default file permission umode when creating files (default: 0600) */
#define DEFAULT_PERMISSION 0600
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 226fb40e..e6b58713 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2078,9 +2078,9 @@ havoc_stage:
u32 *mutation_array;
u32 stack_max;
- if (afl->queue_cur->is_ascii) { // is text?
+ if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text?
- if (1) { // is exploration?
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
@@ -2092,7 +2092,7 @@ havoc_stage:
} else { // is binary!
- if (1) { // is exploration?
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index f9aa5cfe..907861e9 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -108,6 +108,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->cmplog_lvl = 2;
afl->min_length = 1;
afl->max_length = MAX_FILE;
+ afl->switch_fuzz_mode = STRATEGY_SWITCH_TIME;
#ifndef NO_SPLICING
afl->use_splicing = 1;
#endif
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 25ebe987..de48e10a 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -1282,7 +1282,10 @@ void show_stats_normal(afl_state_t *afl) {
}
/* Last line */
- SAYF(SET_G1 "\n" bSTG bLB bH30 bH20 bH2 bRB bSTOP cRST RESET_G1);
+
+ SAYF(SET_G1 "\n" bSTG bLB bH cCYA bSTOP
+ " strategy:%s %s " bSTG bH20 bH10 bH2 bRB bSTOP cRST RESET_G1,
+ cPIN, afl->fuzz_mode == 0 ? "explore" : "exploit");
#undef IB
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 3380fd90..315107d7 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -128,6 +128,13 @@ static void usage(u8 *argv0, int more_help) {
" -o dir - output directory for fuzzer findings\n\n"
"Execution control settings:\n"
+ " -P strategy - set fix mutation strategy: explore (focus on new "
+ "coverage),\n"
+ " exploit (focus on triggering crashes). You can also "
+ "set a\n"
+ " number of seconds after without any finds it switches "
+ "to\n"
+ " exploit mode, and back on new coverage (default: %u)\n"
" -p schedule - power schedules compute a seed's performance score:\n"
" fast(default), explore, exploit, seek, rare, mmopt, "
"coe, lin\n"
@@ -156,6 +163,7 @@ static void usage(u8 *argv0, int more_help) {
"\n"
"Mutator settings:\n"
+ " -a - target expects ascii text input\n"
" -g minlength - set min length of generated fuzz input (default: 1)\n"
" -G maxlength - set max length of generated fuzz input (default: "
"%lu)\n"
@@ -212,7 +220,8 @@ static void usage(u8 *argv0, int more_help) {
" -e ext - file extension for the fuzz test input file (if "
"needed)\n"
"\n",
- argv0, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, FOREIGN_SYNCS_MAX);
+ argv0, STRATEGY_SWITCH_TIME, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE,
+ FOREIGN_SYNCS_MAX);
if (more_help > 1) {
@@ -553,14 +562,44 @@ int main(int argc, char **argv_orig, char **envp) {
afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing
- while (
- (opt = getopt(
- argc, argv,
- "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) >
- 0) {
+ // still available: aHjJkKPqruvwz
+ while ((opt = getopt(argc, argv,
+ "+aAb:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:"
+ "T:UV:WXx:YZ")) > 0) {
switch (opt) {
+ case 'a':
+ afl->text_input = 1;
+ break;
+
+ case 'P':
+ if (!stricmp(optarg, "explore") || !stricmp(optarg, "exploration")) {
+
+ afl->fuzz_mode = 0;
+ afl->switch_fuzz_mode = 1;
+
+ } else if (!stricmp(optarg, "exploit") ||
+
+ !stricmp(optarg, "exploitation")) {
+
+ afl->fuzz_mode = 1;
+ afl->switch_fuzz_mode = 0;
+
+ } else {
+
+ if ((s32)(afl->switch_fuzz_mode = (u32)atoi(optarg)) < 1) {
+
+ FATAL(
+ "Parameter for option -P must be \"explore\", \"exploit\" or a "
+ "number!");
+
+ }
+
+ }
+
+ break;
+
case 'g':
afl->min_length = atoi(optarg);
break;
--
cgit 1.4.1
From 41a452d4e8038461f730736439346eb8a7a3968f Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 4 Apr 2023 21:48:51 +0200
Subject: mutation lists
---
include/afl-mutations.h | 786 +++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 783 insertions(+), 3 deletions(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 5a1b6356..31d0898a 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -78,9 +78,789 @@ enum {
};
-u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {};
-u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {};
-u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {};
+u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {
+
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+
+};
+
+u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {
+
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+
+};
+
+u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {
+
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_OVERWRITE,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_SHUFFLE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_DELONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_INSERTONE,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_ASCIINUM,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_NEG,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_INSERTASCIINUM,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+
+};
+
u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_FLIPBIT,
--
cgit 1.4.1
From 53b70ef104a334424fd5226c7504130b3bd45625 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 5 Apr 2023 09:33:09 +0200
Subject: mut changes
---
include/afl-mutations.h | 83 +++++++++++++++++++++----------------------------
src/afl-fuzz-one.c | 17 +---------
2 files changed, 37 insertions(+), 63 deletions(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 31d0898a..9188a37f 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -65,14 +65,13 @@ enum {
/* 27 */ MUT_DELONE,
/* 28 */ MUT_INSERTONE,
/* 29 */ MUT_ASCIINUM,
- /* 30 */ MUT_NEG,
- /* 31 */ MUT_INSERTASCIINUM,
- /* 32 */ MUT_EXTRA_OVERWRITE,
- /* 33 */ MUT_EXTRA_INSERT,
- /* 34 */ MUT_AUTO_EXTRA_OVERWRITE,
- /* 35 */ MUT_AUTO_EXTRA_INSERT,
- /* 36 */ MUT_SPLICE_OVERWRITE,
- /* 37 */ MUT_SPLICE_INSERT,
+ /* 30 */ MUT_INSERTASCIINUM,
+ /* 31 */ MUT_EXTRA_OVERWRITE,
+ /* 32 */ MUT_EXTRA_INSERT,
+ /* 33 */ MUT_AUTO_EXTRA_OVERWRITE,
+ /* 34 */ MUT_AUTO_EXTRA_INSERT,
+ /* 35 */ MUT_SPLICE_OVERWRITE,
+ /* 36 */ MUT_SPLICE_INSERT,
MUT_MAX
@@ -199,6 +198,7 @@ u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_CLONE_INSERT,
MUT_CLONE_INSERT,
MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
@@ -233,6 +233,9 @@ u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_FLIP8,
MUT_FLIP8,
MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
MUT_SWITCH,
MUT_SWITCH,
MUT_SWITCH,
@@ -276,12 +279,8 @@ u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_ASCIINUM,
MUT_ASCIINUM,
MUT_ASCIINUM,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
+ MUT_ASCIINUM,
+ MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
@@ -335,7 +334,7 @@ u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
- MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT
};
@@ -468,6 +467,7 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_CLONE_INSERT,
MUT_CLONE_INSERT,
MUT_CLONE_INSERT,
+ MUT_CLONE_INSERT,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
@@ -504,6 +504,10 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_FLIP8,
MUT_FLIP8,
MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
MUT_SWITCH,
MUT_SWITCH,
MUT_SWITCH,
@@ -541,12 +545,6 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_ASCIINUM,
MUT_ASCIINUM,
MUT_ASCIINUM,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
@@ -596,7 +594,7 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
- MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT
};
@@ -766,6 +764,9 @@ u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_FLIP8,
MUT_FLIP8,
MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
MUT_SWITCH,
MUT_SWITCH,
MUT_SWITCH,
@@ -785,6 +786,7 @@ u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_SHUFFLE,
MUT_SHUFFLE,
MUT_SHUFFLE,
+ MUT_SHUFFLE,
MUT_DELONE,
MUT_DELONE,
MUT_DELONE,
@@ -801,12 +803,8 @@ u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_ASCIINUM,
MUT_ASCIINUM,
MUT_ASCIINUM,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
+ MUT_ASCIINUM,
+ MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
@@ -857,7 +855,7 @@ u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
- MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT
};
@@ -959,6 +957,8 @@ u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_ARITH32BE_,
MUT_ARITH32BE_,
MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32,
MUT_ARITH32,
MUT_ARITH32,
MUT_ARITH32,
@@ -1027,6 +1027,10 @@ u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_FLIP8,
MUT_FLIP8,
MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
MUT_SWITCH,
MUT_SWITCH,
MUT_SWITCH,
@@ -1062,12 +1066,6 @@ u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_ASCIINUM,
MUT_ASCIINUM,
MUT_ASCIINUM,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
- MUT_NEG,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
MUT_INSERTASCIINUM,
@@ -1118,7 +1116,9 @@ u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT,
- MUT_SPLICE_INSERT};
+ MUT_SPLICE_INSERT
+
+};
u32 afl_mutate(afl_state_t *, u8 *, u32, u32, bool, bool, u8 *, u32, u32);
u32 choose_block_len(afl_state_t *, u32);
@@ -1865,17 +1865,6 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
}
- case MUT_NEG: {
-
- /* Neg byte. */
-
- item = rand_below(afl, len);
- buf[item] = ~buf[item];
-
- break;
-
- }
-
case MUT_INSERTASCIINUM: {
u32 len = 1 + rand_below(afl, 8);
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index e6b58713..bc267b15 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2659,7 +2659,7 @@ havoc_stage:
case MUT_FLIP8: {
- /* Flip byte. */
+ /* Flip byte with a XOR 0xff. This is the same as NEG. */
#ifdef INTROSPECTION
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " FLIP8_");
@@ -2987,21 +2987,6 @@ havoc_stage:
}
- case MUT_NEG: {
-
- /* Neg byte. */
-
-#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " NEG_");
- strcat(afl->mutation, afl->m_tmp);
-#endif
- item = rand_below(afl, temp_len);
-
- out_buf[item] = ~out_buf[item];
- break;
-
- }
-
case MUT_INSERTASCIINUM: {
u32 len = 1 + rand_below(afl, 8);
--
cgit 1.4.1
From 1fc0731604c1ea1abb38ab345d9046a6f1e9b7de Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 5 Apr 2023 09:42:27 +0200
Subject: stack pow
---
src/afl-fuzz-one.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index bc267b15..48aa6eb0 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2076,7 +2076,7 @@ havoc_stage:
where we take the input file and make random stacked tweaks. */
u32 *mutation_array;
- u32 stack_max;
+ u32 stack_max, stack_max_pow = afl->havoc_stack_pow2;
if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text?
@@ -2106,22 +2106,20 @@ havoc_stage:
if (temp_len < 64) {
- stack_max = 4;
+ --stack_max_pow;
- } else if (temp_len < 512) {
+ } else if (temp_len <= 8096) {
- stack_max = 8;
-
- } else if (temp_len < 8096) {
-
- stack_max = 16;
+ ++stack_max_pow;
} else {
- stack_max = 32;
+ ++stack_max_pow;
}
+ stack_max = 1 << stack_max_pow;
+
// + (afl->extras_cnt ? 2 : 0) + (afl->a_extras_cnt ? 2 : 0);
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
--
cgit 1.4.1
From e313180e4d3f7ba44b773e43af40d4af21088576 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 5 Apr 2023 10:32:37 +0200
Subject: fix for clang
---
include/afl-mutations.h | 10 ++++++----
src/afl-fuzz-one.c | 9 ++++++---
2 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 9188a37f..cc913fb0 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -1231,7 +1231,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
for (u32 step = 0; step < steps; ++step) {
- retry_havoc_step:
+ retry_havoc_step : {
u32 r = rand_below(afl, MUT_STRATEGY_ARRAY_SIZE), item;
@@ -1667,10 +1667,10 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
if (unlikely(len < 4)) { break; } // no retry
- u32 len = choose_block_len(afl, len - 1);
- u32 off = rand_below(afl, len - len + 1);
+ u32 blen = choose_block_len(afl, len - 1);
+ u32 off = rand_below(afl, len - blen + 1);
- for (u32 i = len - 1; i > 0; i--) {
+ for (u32 i = blen - 1; i > 0; i--) {
u32 j;
do {
@@ -2030,6 +2030,8 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
}
+ }
+
return len;
}
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 48aa6eb0..e6ff1d1a 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2139,8 +2139,8 @@ havoc_stage:
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
- if (el->stacked_custom &&
- rand_below(afl, 100) < el->stacked_custom_prob) {
+ if (unlikely(el->stacked_custom &&
+ rand_below(afl, 100) < el->stacked_custom_prob)) {
u8 *custom_havoc_buf = NULL;
size_t new_len = el->afl_custom_havoc_mutation(
@@ -2170,7 +2170,8 @@ havoc_stage:
}
- retry_havoc_step:
+ retry_havoc_step : {
+
u32 r = rand_below(afl, MUT_STRATEGY_ARRAY_SIZE), item;
switch (mutation_array[r]) {
@@ -3250,6 +3251,8 @@ havoc_stage:
}
+ }
+
if (common_fuzz_stuff(afl, out_buf, temp_len)) { goto abandon_entry; }
/* out_buf might have been mangled a bit, so let's restore it to its
--
cgit 1.4.1
From a74561b0e7434282ad214ca634b5c19c2f345e8e Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 5 Apr 2023 12:12:05 +0200
Subject: implement switch mode
---
include/afl-fuzz.h | 6 +++---
src/afl-fuzz-bitmap.c | 12 ++++++++++++
src/afl-fuzz-state.c | 2 +-
src/afl-fuzz.c | 30 ++++++++++++++++++++++++++----
4 files changed, 42 insertions(+), 8 deletions(-)
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 6573eabf..23a04f42 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -491,8 +491,7 @@ typedef struct afl_state {
*infoexec; /* Command to execute on a new crash */
u32 hang_tmout, /* Timeout used for hang det (ms) */
- stats_update_freq, /* Stats update frequency (execs) */
- switch_fuzz_mode; /* auto or fixed fuzz mode */
+ stats_update_freq; /* Stats update frequency (execs) */
u8 havoc_stack_pow2, /* HAVOC_STACK_POW2 */
no_unlink, /* do not unlink cur_input */
@@ -592,7 +591,8 @@ typedef struct afl_state {
last_hang_time, /* Time for most recent hang (ms) */
longest_find_time, /* Longest time taken for a find */
exit_on_time, /* Delay to exit if no new paths */
- sync_time; /* Sync time (ms) */
+ sync_time, /* Sync time (ms) */
+ switch_fuzz_mode; /* auto or fixed fuzz mode */
u32 slowest_exec_ms, /* Slowest testcase non hang in ms */
subseq_tmouts; /* Number of timeouts in a row */
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index d9c792d1..a937c96d 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -529,6 +529,18 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
close(fd);
add_to_queue(afl, queue_fn, len, 0);
+ if (unlikely(afl->fuzz_mode) && likely(afl->switch_fuzz_mode)) {
+
+ if (afl->afl_env.afl_no_ui) {
+
+ ACTF("New coverage found, switching back to exploration mode.");
+
+ }
+
+ afl->fuzz_mode = 0;
+
+ }
+
#ifdef INTROSPECTION
if (afl->custom_mutators_count && afl->current_custom_fuzz) {
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 907861e9..9dc258b1 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -108,7 +108,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
afl->cmplog_lvl = 2;
afl->min_length = 1;
afl->max_length = MAX_FILE;
- afl->switch_fuzz_mode = STRATEGY_SWITCH_TIME;
+ afl->switch_fuzz_mode = STRATEGY_SWITCH_TIME * 1000;
#ifndef NO_SPLICING
afl->use_splicing = 1;
#endif
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 315107d7..c50b271b 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -577,7 +577,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (!stricmp(optarg, "explore") || !stricmp(optarg, "exploration")) {
afl->fuzz_mode = 0;
- afl->switch_fuzz_mode = 1;
+ afl->switch_fuzz_mode = 0;
} else if (!stricmp(optarg, "exploit") ||
@@ -588,12 +588,16 @@ int main(int argc, char **argv_orig, char **envp) {
} else {
- if ((s32)(afl->switch_fuzz_mode = (u32)atoi(optarg)) < 1) {
+ if ((afl->switch_fuzz_mode = (u32)atoi(optarg)) > INT_MAX) {
FATAL(
"Parameter for option -P must be \"explore\", \"exploit\" or a "
"number!");
+ } else {
+
+ afl->switch_fuzz_mode *= 1000;
+
}
}
@@ -2689,13 +2693,31 @@ int main(int argc, char **argv_orig, char **envp) {
} while (skipped_fuzz && afl->queue_cur && !afl->stop_soon);
+ u64 cur_time = get_cur_time();
+
+ if (likely(afl->switch_fuzz_mode && afl->fuzz_mode == 0) &&
+ unlikely(cur_time > afl->last_find_time + afl->switch_fuzz_mode)) {
+
+ if (afl->afl_env.afl_no_ui) {
+
+ ACTF(
+ "No new coverage found for %llu seconds, switching to exploitation "
+ "strategy.",
+ afl->switch_fuzz_mode / 1000);
+
+ }
+
+ afl->fuzz_mode = 1;
+
+ }
+
if (likely(!afl->stop_soon && afl->sync_id)) {
if (likely(afl->skip_deterministic)) {
if (unlikely(afl->is_main_node)) {
- if (unlikely(get_cur_time() >
+ if (unlikely(cur_time >
(afl->sync_time >> 1) + afl->last_sync_time)) {
if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) {
@@ -2708,7 +2730,7 @@ int main(int argc, char **argv_orig, char **envp) {
} else {
- if (unlikely(get_cur_time() > afl->sync_time + afl->last_sync_time)) {
+ if (unlikely(cur_time > afl->sync_time + afl->last_sync_time)) {
if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); }
--
cgit 1.4.1
From fcb5eda5d0eb38b1a9678ee75890f2fccf936bd9 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 5 Apr 2023 16:34:08 +0200
Subject: nit
---
src/afl-fuzz.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index c50b271b..bc44367a 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -562,7 +562,7 @@ int main(int argc, char **argv_orig, char **envp) {
afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing
- // still available: aHjJkKPqruvwz
+ // still available: HjJkKqruvwz
while ((opt = getopt(argc, argv,
"+aAb:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:"
"T:UV:WXx:YZ")) > 0) {
--
cgit 1.4.1
From 400c5e92cb5ed304a2c14a79597100850cf9f82c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 7 Apr 2023 09:41:22 +0200
Subject: renaming
---
include/afl-mutations.h | 166 ++++++++++++++++++++++++------------------------
src/afl-fuzz-one.c | 30 +++++----
2 files changed, 99 insertions(+), 97 deletions(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index cc913fb0..8d40855d 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -52,8 +52,8 @@ enum {
/* 14 */ MUT_ARITH32,
/* 15 */ MUT_ARITH32BE,
/* 16 */ MUT_RAND8,
- /* 17 */ MUT_CLONE_OVERWRITE,
- /* 18 */ MUT_CLONE_INSERT,
+ /* 17 */ MUT_CLONE_COPY,
+ /* 18 */ MUT_CLONE_FIXED,
/* 19 */ MUT_OVERWRITE_COPY,
/* 20 */ MUT_OVERWRITE_FIXED,
/* 21 */ MUT_BYTEADD,
@@ -176,29 +176,29 @@ u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_RAND8,
MUT_RAND8,
MUT_RAND8,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
@@ -446,28 +446,28 @@ u32 mutation_strategy_exploration_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_RAND8,
MUT_RAND8,
MUT_RAND8,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
@@ -716,23 +716,23 @@ u32 mutation_strategy_exploitation_text[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_RAND8,
MUT_RAND8,
MUT_RAND8,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
@@ -979,23 +979,23 @@ u32 mutation_strategy_exploitation_binary[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_RAND8,
MUT_RAND8,
MUT_RAND8,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_OVERWRITE,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
- MUT_CLONE_INSERT,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
MUT_OVERWRITE_COPY,
@@ -1455,7 +1455,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
}
- case MUT_CLONE_OVERWRITE: {
+ case MUT_CLONE_COPY: {
if (likely(len + HAVOC_BLK_XL < max_len)) {
@@ -1494,7 +1494,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
}
- case MUT_CLONE_INSERT: {
+ case MUT_CLONE_FIXED: {
if (likely(len + HAVOC_BLK_XL < max_len)) {
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index e6ff1d1a..f5ddea0e 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2481,7 +2481,7 @@ havoc_stage:
}
- case MUT_CLONE_OVERWRITE: {
+ case MUT_CLONE_COPY: {
if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) {
@@ -2493,7 +2493,7 @@ havoc_stage:
#ifdef INTROSPECTION
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s_%u_%u_%u",
- "overwrite", clone_from, clone_to, clone_len);
+ "COPY", clone_from, clone_to, clone_len);
strcat(afl->mutation, afl->m_tmp);
#endif
u8 *new_buf =
@@ -2530,7 +2530,7 @@ havoc_stage:
}
- case MUT_CLONE_INSERT: {
+ case MUT_CLONE_FIXED: {
if (likely(temp_len + HAVOC_BLK_XL < MAX_FILE)) {
@@ -2544,7 +2544,7 @@ havoc_stage:
#ifdef INTROSPECTION
snprintf(afl->m_tmp, sizeof(afl->m_tmp), " CLONE-%s_%u_%u_%u",
- "insert", strat, clone_to, clone_len);
+ "FIXED", strat, clone_to, clone_len);
strcat(afl->mutation, afl->m_tmp);
#endif
u8 *new_buf =
@@ -2587,20 +2587,22 @@ havoc_stage:
if (unlikely(temp_len < 2)) { break; } // no retry
- u32 copy_len = choose_block_len(afl, temp_len - 1);
- u32 copy_from = rand_below(afl, temp_len - copy_len + 1);
- u32 copy_to = rand_below(afl, temp_len - copy_len + 1);
+ u32 copy_from, copy_to,
+ copy_len = choose_block_len(afl, temp_len - 1);
+
+ do {
- if (likely(copy_from != copy_to)) {
+ copy_from = rand_below(afl, temp_len - copy_len + 1);
+ copy_to = rand_below(afl, temp_len - copy_len + 1);
+
+ } while (unlikely(copy_from == copy_to));
#ifdef INTROSPECTION
- snprintf(afl->m_tmp, sizeof(afl->m_tmp), " OVERWRITE-COPY_%u_%u_%u",
- copy_from, copy_to, copy_len);
- strcat(afl->mutation, afl->m_tmp);
+ snprintf(afl->m_tmp, sizeof(afl->m_tmp), " OVERWRITE-COPY_%u_%u_%u",
+ copy_from, copy_to, copy_len);
+ strcat(afl->mutation, afl->m_tmp);
#endif
- memmove(out_buf + copy_to, out_buf + copy_from, copy_len);
-
- }
+ memmove(out_buf + copy_to, out_buf + copy_from, copy_len);
break;
--
cgit 1.4.1
From 3e84d6a2ae7df5f6b9073a91ccc6acef50b45aab Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 27 Apr 2023 11:49:00 +0200
Subject: afl++ -> AFL++
---
Dockerfile | 4 ++--
GNUmakefile | 12 ++++++------
GNUmakefile.gcc_plugin | 6 +++---
GNUmakefile.llvm | 6 +++---
afl-cmin | 2 +-
docs/Changelog.md | 2 +-
docs/INSTALL.md | 2 +-
include/alloc-inl.h | 2 +-
instrumentation/SanitizerCoverageLTO.so.cc | 30 +++++++++++++++---------------
instrumentation/afl-llvm-common.cc | 2 +-
instrumentation/afl-llvm-dict2file.so.cc | 2 +-
qemu_mode/build_qemu_support.sh | 4 ++--
src/afl-cc.c | 2 +-
src/afl-forkserver.c | 6 +++---
src/afl-fuzz.c | 10 +++++-----
src/afl-ld-lto.c | 4 ++--
test/test-dlopen.c | 2 +-
test/test-gcc-plugin.sh | 2 +-
test/test-performance.sh | 4 ++--
test/test-pre.sh | 2 +-
unicorn_mode/build_unicorn_support.sh | 2 +-
21 files changed, 54 insertions(+), 54 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 4e53de40..1b5ffd28 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -6,7 +6,7 @@
#
FROM ubuntu:22.04 AS aflplusplus
-LABEL "maintainer"="afl++ team "
+LABEL "maintainer"="AFL++ team "
LABEL "about"="AFLplusplus container image"
### Comment out to enable these features
@@ -94,4 +94,4 @@ RUN sed -i.bak 's/^ -/ /g' GNUmakefile && \
RUN echo "set encoding=utf-8" > /root/.vimrc && \
echo ". /etc/bash_completion" >> ~/.bashrc && \
echo 'alias joe="joe --wordwrap --joe_state -nobackup"' >> ~/.bashrc && \
- echo "export PS1='"'[afl++ \h] \w \$ '"'" >> ~/.bashrc
+ echo "export PS1='"'[AFL++ \h] \w \$ '"'" >> ~/.bashrc
diff --git a/GNUmakefile b/GNUmakefile
index 23cae65d..5900ad61 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -39,7 +39,7 @@ ASAN_OPTIONS=detect_leaks=0
SYS = $(shell uname -s)
ARCH = $(shell uname -m)
-$(info [*] Compiling afl++ for OS $(SYS) on ARCH $(ARCH))
+$(info [*] Compiling AFL++ for OS $(SYS) on ARCH $(ARCH))
ifdef NO_SPLICING
override CFLAGS_OPT += -DNO_SPLICING
@@ -359,7 +359,7 @@ performance-test: source-only
help:
@echo "HELP --- the following make targets exist:"
@echo "=========================================="
- @echo "all: the main afl++ binaries and llvm/gcc instrumentation"
+ @echo "all: the main AFL++ binaries and llvm/gcc instrumentation"
@echo "binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode, qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator, libtokencap"
@echo "source-only: everything for source code fuzzing: nyx_mode, libdislocator, libtokencap"
@echo "distrib: everything (for both binary-only and source code fuzzing)"
@@ -367,7 +367,7 @@ help:
@echo "install: installs everything you have compiled with the build option above"
@echo "clean: cleans everything compiled (not downloads when on a checkout)"
@echo "deepclean: cleans everything including downloads"
- @echo "uninstall: uninstall afl++ from the system"
+ @echo "uninstall: uninstall AFL++ from the system"
@echo "code-format: format the code, do this before you commit and send a PR please!"
@echo "tests: this runs the test framework. It is more catered for the developers, but if you run into problems this helps pinpointing the problem"
@echo "unit: perform unit tests (based on cmocka and GNU linker)"
@@ -749,7 +749,7 @@ endif
@echo
%.8: %
- @echo .TH $* 8 $(BUILD_DATE) "afl++" > $@
+ @echo .TH $* 8 $(BUILD_DATE) "AFL++" > $@
@echo .SH NAME >> $@
@echo .B $* >> $@
@echo >> $@
@@ -761,8 +761,8 @@ endif
@./$* -hh 2>&1 | tail -n +4 >> $@
@echo >> $@
@echo .SH AUTHOR >> $@
- @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> $@
- @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> $@
+ @echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Dominik Maier , Andrea Fioraldi and Heiko \"hexcoder-\" Eissfeldt " >> $@
+ @echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> $@
@echo >> $@
@echo .SH LICENSE >> $@
@echo Apache License Version 2.0, January 2004 >> $@
diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin
index 4c4e10c4..41face4c 100644
--- a/GNUmakefile.gcc_plugin
+++ b/GNUmakefile.gcc_plugin
@@ -175,7 +175,7 @@ all_done: test_build
.NOTPARALLEL: clean
%.8: %
- @echo .TH $* 8 `date "+%Y-%m-%d"` "afl++" > ./$@
+ @echo .TH $* 8 `date "+%Y-%m-%d"` "AFL++" > ./$@
@echo .SH NAME >> ./$@
@echo .B $* >> ./$@
@echo >> ./$@
@@ -187,8 +187,8 @@ all_done: test_build
@./$* -h 2>&1 | tail -n +4 >> ./$@
@echo >> ./$@
@echo .SH AUTHOR >> ./$@
- @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ./$@
- @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
+ @echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Dominik Maier , Andrea Fioraldi and Heiko \"hexcoder-\" Eissfeldt " >> ./$@
+ @echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
@echo >> ./$@
@echo .SH LICENSE >> ./$@
@echo Apache License Version 2.0, January 2004 >> ./$@
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index a053403b..c1b006ba 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -510,7 +510,7 @@ install: all
install -m 644 instrumentation/README.*.md $${DESTDIR}$(DOC_PATH)/
%.8: %
- @echo .TH $* 8 $(BUILD_DATE) "afl++" > ./$@
+ @echo .TH $* 8 $(BUILD_DATE) "AFL++" > ./$@
@echo .SH NAME >> ./$@
@printf "%s" ".B $* \- " >> ./$@
@./$* -h 2>&1 | head -n 1 | sed -e "s/$$(printf '\e')[^m]*m//g" >> ./$@
@@ -524,8 +524,8 @@ install: all
@./$* -h 2>&1 | tail -n +4 >> ./$@
@echo >> ./$@
@echo .SH AUTHOR >> ./$@
- @echo "afl++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Heiko \"hexcoder-\" Eissfeldt , Andrea Fioraldi and Dominik Maier " >> ./$@
- @echo The homepage of afl++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
+ @echo "AFL++ was written by Michal \"lcamtuf\" Zalewski and is maintained by Marc \"van Hauser\" Heuse , Dominik Maier , Andrea Fioraldi and Heiko \"hexcoder-\" Eissfeldt " >> ./$@
+ @echo The homepage of AFL++ is: https://github.com/AFLplusplus/AFLplusplus >> ./$@
@echo >> ./$@
@echo .SH LICENSE >> ./$@
@echo Apache License Version 2.0, January 2004 >> ./$@
diff --git a/afl-cmin b/afl-cmin
index 63cfdd7e..ae723c1b 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -149,7 +149,7 @@ BEGIN {
redirected = 0
}
- print "corpus minimization tool for afl++ (awk version)\n"
+ print "corpus minimization tool for AFL++ (awk version)\n"
# defaults
extra_par = ""
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 20b915fa..cd5ed9fc 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -229,7 +229,7 @@
afl-showmap and other tools.
- afl-cc:
- detect overflow reads on initial input buffer for asan
- - new cmplog mode (incompatible with older afl++ versions)
+ - new cmplog mode (incompatible with older AFL++ versions)
- support llvm IR select instrumentation for default PCGUARD and LTO
- fix for shared linking on MacOS
- better selective instrumentation AFL_LLVM_{ALLOW|DENY}LIST
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 591b7ded..c54cb9ad 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -51,7 +51,7 @@ make source-only
These build targets exist:
-* all: the main afl++ binaries and llvm/gcc instrumentation
+* all: the main AFL++ binaries and llvm/gcc instrumentation
* binary-only: everything for binary-only fuzzing: frida_mode, nyx_mode,
qemu_mode, frida_mode, unicorn_mode, coresight_mode, libdislocator,
libtokencap
diff --git a/include/alloc-inl.h b/include/alloc-inl.h
index ae37028e..bbb42e88 100644
--- a/include/alloc-inl.h
+++ b/include/alloc-inl.h
@@ -42,7 +42,7 @@
// Be careful! _WANT_ORIGINAL_AFL_ALLOC is not compatible with custom mutators
#ifndef _WANT_ORIGINAL_AFL_ALLOC
- // afl++ stuff without memory corruption checks - for speed
+ // AFL++ stuff without memory corruption checks - for speed
/* User-facing macro to sprintf() to a dynamically allocated buffer. */
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 42583f9e..6a719737 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1,4 +1,4 @@
-/* SanitizeCoverage.cpp ported to afl++ LTO :-) */
+/* SanitizeCoverage.cpp ported to AFL++ LTO :-) */
#define AFL_LLVM_PASS
@@ -234,7 +234,7 @@ class ModuleSanitizerCoverageLTO
SanitizerCoverageOptions Options;
- // afl++ START
+ // AFL++ START
// const SpecialCaseList * Allowlist;
// const SpecialCaseList * Blocklist;
uint32_t autodictionary = 1;
@@ -260,7 +260,7 @@ class ModuleSanitizerCoverageLTO
Value *MapPtrFixed = NULL;
std::ofstream dFile;
size_t found = 0;
- // afl++ END
+ // AFL++ END
};
@@ -404,7 +404,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
Int8Ty = IRB.getInt8Ty();
Int1Ty = IRB.getInt1Ty();
- /* afl++ START */
+ /* AFL++ START */
char *ptr;
LLVMContext &Ctx = M.getContext();
Ct = &Ctx;
@@ -978,7 +978,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
}
- // afl++ END
+ // AFL++ END
SanCovTracePCIndir =
M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy);
@@ -1002,7 +1002,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
for (auto &F : M)
instrumentFunction(F, DTCallback, PDTCallback);
- // afl++ START
+ // AFL++ START
if (dFile.is_open()) dFile.close();
if (!getenv("AFL_LLVM_LTO_SKIPINIT") &&
@@ -1156,7 +1156,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
}
- // afl++ END
+ // AFL++ END
// We don't reference these arrays directly in any of our runtime functions,
// so we need to prevent them from being dead stripped.
@@ -1213,10 +1213,10 @@ static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
// (catchswitch blocks).
if (BB->getFirstInsertionPt() == BB->end()) return false;
- // afl++ START
+ // AFL++ START
if (!Options.NoPrune && &F.getEntryBlock() == BB && F.size() > 1)
return false;
- // afl++ END
+ // AFL++ END
if (Options.NoPrune || &F.getEntryBlock() == BB) return true;
@@ -1258,10 +1258,10 @@ void ModuleSanitizerCoverageLTO::instrumentFunction(
// if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName()))
// return;
- // afl++ START
+ // AFL++ START
if (!F.size()) return;
if (!isInInstrumentList(&F, FMNAME)) return;
- // afl++ END
+ // AFL++ END
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
SplitAllCriticalEdges(
@@ -1559,7 +1559,7 @@ bool ModuleSanitizerCoverageLTO::InjectCoverage(
for (size_t i = 0, N = AllBlocks.size(); i < N; i++) {
- // afl++ START
+ // AFL++ START
if (BlockList.size()) {
int skip = 0;
@@ -1581,7 +1581,7 @@ bool ModuleSanitizerCoverageLTO::InjectCoverage(
}
- // afl++ END
+ // AFL++ END
InjectCoverageAtBlock(F, *AllBlocks[i], i, IsLeafFunc);
@@ -1647,7 +1647,7 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F,
if (Options.TracePCGuard) {
- // afl++ START
+ // AFL++ START
++afl_global_id;
if (dFile.is_open()) {
@@ -1711,7 +1711,7 @@ void ModuleSanitizerCoverageLTO::InjectCoverageAtBlock(Function &F,
// done :)
inst++;
- // afl++ END
+ // AFL++ END
/*
XXXXXXXXXXXXXXXXXXX
diff --git a/instrumentation/afl-llvm-common.cc b/instrumentation/afl-llvm-common.cc
index 5d82aa25..7f17b02d 100644
--- a/instrumentation/afl-llvm-common.cc
+++ b/instrumentation/afl-llvm-common.cc
@@ -584,7 +584,7 @@ bool isInInstrumentList(llvm::Function *F, std::string Filename) {
}
// Calculate the number of average collisions that would occur if all
-// location IDs would be assigned randomly (like normal afl/afl++).
+// location IDs would be assigned randomly (like normal afl/AFL++).
// This uses the "balls in bins" algorithm.
unsigned long long int calculateCollisions(uint32_t edges) {
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index 97f1d47f..cf368e35 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -744,7 +744,7 @@ static void registerAFLdict2filePass(const PassManagerBuilder &,
}
static RegisterPass X("afl-dict2file",
- "afl++ dict2file instrumentation pass",
+ "AFL++ dict2file instrumentation pass",
false, false);
static RegisterStandardPasses RegisterAFLdict2filePass(
diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh
index a064fe58..f59cba78 100755
--- a/qemu_mode/build_qemu_support.sh
+++ b/qemu_mode/build_qemu_support.sh
@@ -356,7 +356,7 @@ fi
if ! command -v "$CROSS" > /dev/null ; then
if [ "$CPU_TARGET" = "$(uname -m)" ] ; then
- echo "[+] Building afl++ qemu support libraries with CC=$CC"
+ echo "[+] Building AFL++ qemu support libraries with CC=$CC"
echo "[+] Building libcompcov ..."
make -C libcompcov && echo "[+] libcompcov ready"
echo "[+] Building unsigaction ..."
@@ -371,7 +371,7 @@ if ! command -v "$CROSS" > /dev/null ; then
echo "[!] Cross compiler $CROSS could not be found, cannot compile libcompcov libqasan and unsigaction"
fi
else
- echo "[+] Building afl++ qemu support libraries with CC=\"$CROSS $CROSS_FLAGS\""
+ echo "[+] Building AFL++ qemu support libraries with CC=\"$CROSS $CROSS_FLAGS\""
echo "[+] Building libcompcov ..."
make -C libcompcov CC="$CROSS $CROSS_FLAGS" && echo "[+] libcompcov ready"
echo "[+] Building unsigaction ..."
diff --git a/src/afl-cc.c b/src/afl-cc.c
index d1001187..99ce39d4 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -642,7 +642,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
//#if LLVM_MAJOR >= 13
- // // Use the old pass manager in LLVM 14 which the afl++ passes still
+ // // Use the old pass manager in LLVM 14 which the AFL++ passes still
// use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager";
//#endif
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index aa8c8622..30c8901c 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -489,7 +489,7 @@ static void report_error_and_exit(int error) {
break;
case FS_ERROR_OLD_CMPLOG:
FATAL(
- "the -c cmplog target was instrumented with an too old afl++ "
+ "the -c cmplog target was instrumented with an too old AFL++ "
"version, you need to recompile it.");
break;
case FS_ERROR_OLD_CMPLOG_QEMU:
@@ -987,7 +987,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
- // workaround for recent afl++ versions
+ // workaround for recent AFL++ versions
if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND)
status = (status & 0xf0ffffff);
@@ -1059,7 +1059,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
FATAL(
"Target's coverage map size of %u is larger than the one this "
- "afl++ is set with (%u). Either set AFL_MAP_SIZE=%u and restart "
+ "AFL++ is set with (%u). Either set AFL_MAP_SIZE=%u and restart "
" afl-fuzz, or change MAP_SIZE_POW2 in config.h and recompile "
"afl-fuzz",
tmp_map_size, fsrv->map_size, tmp_map_size);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 71d2afd8..646dc50b 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1280,16 +1280,16 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260;
- OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
- "Eiรfeldt, Andrea Fioraldi and Dominik Maier");
- OKF("afl++ is open source, get it at "
+ OKF("AFL++ is maintained by Marc \"van Hauser\" Heuse, Dominik Maier, Andrea "
+ "Fioraldi and Heiko \"hexcoder\" Eiรfeldt");
+ OKF("AFL++ is open source, get it at "
"https://github.com/AFLplusplus/AFLplusplus");
- OKF("NOTE: afl++ >= v3 has changed defaults and behaviours - see README.md");
+ OKF("NOTE: AFL++ >= v3 has changed defaults and behaviours - see README.md");
#ifdef __linux__
if (afl->fsrv.nyx_mode) {
- OKF("afl++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
+ OKF("AFL++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
OKF("Nyx is open source, get it at https://github.com/Nyx-Fuzz");
}
diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c
index 5438bd9f..420dd817 100644
--- a/src/afl-ld-lto.c
+++ b/src/afl-ld-lto.c
@@ -2,7 +2,7 @@
american fuzzy lop++ - wrapper for llvm 11+ lld
-----------------------------------------------
- Written by Marc Heuse for afl++
+ Written by Marc Heuse for AFL++
Maintained by Marc Heuse ,
Heiko Eiรfeldt
@@ -210,7 +210,7 @@ static void edit_params(int argc, char **argv) {
if (strcmp(argv[i], "--afl") == 0) {
- if (!be_quiet) OKF("afl++ test command line flag detected, exiting.");
+ if (!be_quiet) OKF("AFL++ test command line flag detected, exiting.");
exit(0);
}
diff --git a/test/test-dlopen.c b/test/test-dlopen.c
index b81bab13..39442f93 100644
--- a/test/test-dlopen.c
+++ b/test/test-dlopen.c
@@ -28,7 +28,7 @@ int main(int argc, char **argv) {
}
- // must use deferred forkserver as otherwise afl++ instrumentation aborts
+ // must use deferred forkserver as otherwise AFL++ instrumentation aborts
// because all dlopen() of instrumented libs must be before the forkserver
__AFL_INIT();
diff --git a/test/test-gcc-plugin.sh b/test/test-gcc-plugin.sh
index 54e6987f..3690a80a 100755
--- a/test/test-gcc-plugin.sh
+++ b/test/test-gcc-plugin.sh
@@ -23,7 +23,7 @@ test -e ../afl-gcc-fast -a -e ../afl-compiler-rt.o && {
$ECHO "$GREEN[+] gcc_plugin run reported $TUPLES instrumented locations which is fine"
} || {
$ECHO "$RED[!] gcc_plugin instrumentation produces a weird numbers: $TUPLES"
- $ECHO "$YELLOW[-] this is a known issue in gcc, not afl++. It is not flagged as an error because travis builds would all fail otherwise :-("
+ $ECHO "$YELLOW[-] this is a known issue in gcc, not AFL++. It is not flagged as an error because travis builds would all fail otherwise :-("
#CODE=1
}
test "$TUPLES" -lt 2 && SKIP=1
diff --git a/test/test-performance.sh b/test/test-performance.sh
index d61e2f2a..50957141 100755
--- a/test/test-performance.sh
+++ b/test/test-performance.sh
@@ -7,7 +7,7 @@ FILE=$AFL_PERFORMANCE_FILE
test -z "$FILE" && FILE=.afl_performance
test -e $FILE || {
- echo Warning: This script measure the performance of afl++ and saves the result for future comparisons into $FILE
+ echo Warning: This script measure the performance of AFL++ and saves the result for future comparisons into $FILE
echo Press ENTER to continue or CONTROL-C to abort
read IN
}
@@ -74,7 +74,7 @@ afl-system-config > /dev/null 2>&1
echo Performance settings applied.
echo
-$ECHO "${RESET}${GREY}[*] starting afl++ performance test framework ..."
+$ECHO "${RESET}${GREY}[*] starting AFL++ performance test framework ..."
$ECHO "$BLUE[*] Testing: ${AFL_GCC}"
GCC=x
diff --git a/test/test-pre.sh b/test/test-pre.sh
index b8b286e5..1ca9dfb5 100755
--- a/test/test-pre.sh
+++ b/test/test-pre.sh
@@ -133,7 +133,7 @@ MEM_LIMIT=none
export PATH="${PATH}:/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin"
-$ECHO "${RESET}${GREY}[*] starting afl++ test framework ..."
+$ECHO "${RESET}${GREY}[*] starting AFL++ test framework ..."
test -z "$SYS" && $ECHO "$YELLOW[-] uname -m did not succeed"
diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh
index 53ec2481..d3d16ad5 100755
--- a/unicorn_mode/build_unicorn_support.sh
+++ b/unicorn_mode/build_unicorn_support.sh
@@ -182,7 +182,7 @@ git pull
sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null
git checkout "$UNICORNAFL_VERSION" || exit 1
-echo "[*] making sure afl++ header files match"
+echo "[*] making sure AFL++ header files match"
cp "../../include/config.h" "./include" || exit 1
echo "[*] Configuring Unicorn build..."
--
cgit 1.4.1
From a25439cfa1521065ff9775c2314ed80a31fba6f2 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 27 Apr 2023 11:50:12 +0200
Subject: update readme
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index c012c400..863c2fce 100644
--- a/README.md
+++ b/README.md
@@ -12,9 +12,9 @@ Repository:
AFL++ is maintained by:
* Marc "van Hauser" Heuse
-* Heiko "hexcoder-" Eiรfeldt
* Andrea Fioraldi
* Dominik Maier
+* Heiko "hexcoder-" Eiรfeldt
* Documentation: Jana Aydinbas
Originally developed by Michaล "lcamtuf" Zalewski.
--
cgit 1.4.1
From e983e2e9cfb9e4c8489dc35f28bca502ec241c27 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 27 Apr 2023 16:24:43 +0200
Subject: more debug
---
src/afl-fuzz-init.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index bd591c8f..baf56a5f 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -716,6 +716,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
}
+ // if (getenv("MYTEST")) afl->in_place_resume = 1;
+
if (nl_cnt) {
u32 done = 0;
@@ -827,6 +829,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
}
+ // if (getenv("MYTEST")) afl->in_place_resume = 0;
+
free(nl); /* not tracked */
if (!afl->queued_items && directory == NULL) {
@@ -908,8 +912,10 @@ void perform_dry_run(afl_state_t *afl) {
if (res == afl->crash_mode || res == FSRV_RUN_NOBITS) {
- SAYF(cGRA " len = %u, map size = %u, exec speed = %llu us\n" cRST,
- q->len, q->bitmap_size, q->exec_us);
+ SAYF(cGRA
+ " len = %u, map size = %u, exec speed = %llu us, hash = "
+ "%016llx\n" cRST,
+ q->len, q->bitmap_size, q->exec_us, q->exec_cksum);
}
@@ -1164,14 +1170,14 @@ void perform_dry_run(afl_state_t *afl) {
u32 duplicates = 0, i;
- for (idx = 0; idx < afl->queued_items; idx++) {
+ for (idx = 0; idx < afl->queued_items - 1; idx++) {
q = afl->queue_buf[idx];
if (!q || q->disabled || q->cal_failed || !q->exec_cksum) { continue; }
-
u32 done = 0;
+
for (i = idx + 1;
- i < afl->queued_items && !done && likely(afl->queue_buf[i]); i++) {
+ likely(i < afl->queued_items && afl->queue_buf[i] && !done); ++i) {
struct queue_entry *p = afl->queue_buf[i];
if (p->disabled || p->cal_failed || !p->exec_cksum) { continue; }
@@ -1194,6 +1200,13 @@ void perform_dry_run(afl_state_t *afl) {
p->disabled = 1;
p->perf_score = 0;
+ if (afl->debug) {
+
+ WARNF("Same coverage - %s is kept active, %s is disabled.",
+ q->fname, p->fname);
+
+ }
+
} else {
if (!q->was_fuzzed) {
@@ -1207,7 +1220,14 @@ void perform_dry_run(afl_state_t *afl) {
q->disabled = 1;
q->perf_score = 0;
- done = 1;
+ if (afl->debug) {
+
+ WARNF("Same coverage - %s is kept active, %s is disabled.",
+ p->fname, q->fname);
+
+ }
+
+ done = 1; // end inner loop because outer loop entry is disabled now
}
--
cgit 1.4.1
From a2daef29f9c323c0a6a7a64013aadb79ffd3e534 Mon Sep 17 00:00:00 2001
From: van Hauser
Date: Thu, 27 Apr 2023 17:57:22 +0200
Subject: slightly different weighting algo (#1719)
* better seed selection
* slightly different weighting calculation
* remove unnecessary memset
---
include/afl-fuzz.h | 4 +--
src/afl-fuzz-queue.c | 92 +++++++++++++++++++++++++++++++++++-----------------
2 files changed, 65 insertions(+), 31 deletions(-)
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 831a0dbc..8fb7ecb1 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -1223,7 +1223,7 @@ double rand_next_percent(afl_state_t *afl);
static inline u32 rand_below(afl_state_t *afl, u32 limit) {
- if (limit <= 1) return 0;
+ if (unlikely(limit <= 1)) return 0;
/* The boundary not being necessarily a power of 2,
we need to ensure the result uniformity. */
@@ -1256,7 +1256,7 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) {
expand havoc mode */
static inline u32 rand_below_datalen(afl_state_t *afl, u32 limit) {
- if (limit <= 1) return 0;
+ if (unlikely(limit <= 1)) return 0;
switch (rand_below(afl, 3)) {
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 8ad7cd97..b10bf749 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -49,11 +49,13 @@ inline u32 select_next_queue_entry(afl_state_t *afl) {
u32 s = rand_below(afl, afl->queued_items);
double p = rand_next_percent(afl);
+
/*
fprintf(stderr, "select: p=%f s=%u ... p < prob[s]=%f ? s=%u : alias[%u]=%u"
" ==> %u\n", p, s, afl->alias_probability[s], s, s, afl->alias_table[s], p <
afl->alias_probability[s] ? s : afl->alias_table[s]);
*/
+
return (p < afl->alias_probability[s] ? s : afl->alias_table[s]);
}
@@ -87,25 +89,28 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q,
void create_alias_table(afl_state_t *afl) {
- u32 n = afl->queued_items, i = 0, a, g;
+ u32 n = afl->queued_items, i = 0, nSmall = 0, nLarge = n - 1;
double sum = 0;
+ double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double));
+ u32 *Small = (int *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32));
+ u32 *Large = (int *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32));
+
afl->alias_table =
(u32 *)afl_realloc((void **)&afl->alias_table, n * sizeof(u32));
afl->alias_probability = (double *)afl_realloc(
(void **)&afl->alias_probability, n * sizeof(double));
- double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double));
- int *S = (int *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32));
- int *L = (int *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32));
- if (!P || !S || !L || !afl->alias_table || !afl->alias_probability) {
+ if (!P || !Small || !Large || !afl->alias_table || !afl->alias_probability) {
FATAL("could not acquire memory for alias table");
}
- memset((void *)afl->alias_table, 0, n * sizeof(u32));
memset((void *)afl->alias_probability, 0, n * sizeof(double));
+ memset((void *)afl->alias_table, 0, n * sizeof(u32));
+ memset((void *)Small, 0, n * sizeof(u32));
+ memset((void *)Large, 0, n * sizeof(u32));
if (likely(afl->schedule < RARE)) {
@@ -166,7 +171,15 @@ void create_alias_table(afl_state_t *afl) {
for (i = 0; i < n; i++) {
// weight is always 0 for disabled entries
- P[i] = (afl->queue_buf[i]->weight * n) / sum;
+ if (unlikely(afl->queue_buf[i]->disabled)) {
+
+ P[i] = 0;
+
+ } else {
+
+ P[i] = (afl->queue_buf[i]->weight * n) / sum;
+
+ }
}
@@ -176,60 +189,81 @@ void create_alias_table(afl_state_t *afl) {
struct queue_entry *q = afl->queue_buf[i];
- if (likely(!q->disabled)) { q->perf_score = calculate_score(afl, q); }
+ if (likely(!q->disabled)) {
+
+ q->perf_score = calculate_score(afl, q);
+ sum += q->perf_score;
- sum += q->perf_score;
+ }
}
for (i = 0; i < n; i++) {
// perf_score is always 0 for disabled entries
- P[i] = (afl->queue_buf[i]->perf_score * n) / sum;
+ if (unlikely(afl->queue_buf[i]->disabled)) {
+
+ P[i] = 0;
+
+ } else {
+
+ P[i] = (afl->queue_buf[i]->perf_score * n) / sum;
+
+ }
}
}
- int nS = 0, nL = 0, s;
- for (s = (s32)n - 1; s >= 0; --s) {
+ // Done collecting weightings in P, now create the arrays.
+
+ for (s32 j = (s32)(n - 1); j >= 0; j--) {
- if (P[s] < 1) {
+ if (P[j] < 1) {
- S[nS++] = s;
+ Small[nSmall++] = (u32)j;
} else {
- L[nL++] = s;
+ Large[nLarge--] = (u32)j;
}
}
- while (nS && nL) {
+ while (nSmall && nLarge != n - 1) {
+
+ u32 small = Small[--nSmall];
+ u32 large = Large[++nLarge];
+
+ afl->alias_probability[small] = P[small];
+ afl->alias_table[small] = large;
- a = S[--nS];
- g = L[--nL];
- afl->alias_probability[a] = P[a];
- afl->alias_table[a] = g;
- P[g] = P[g] + P[a] - 1;
- if (P[g] < 1) {
+ P[large] = P[large] - (1 - P[small]);
- S[nS++] = g;
+ if (P[large] < 1) {
+
+ Small[nSmall++] = large;
} else {
- L[nL++] = g;
+ Large[nLarge--] = large;
}
}
- while (nL)
- afl->alias_probability[L[--nL]] = 1;
+ while (nSmall) {
+
+ afl->alias_probability[Small[--nSmall]] = 1;
+
+ }
- while (nS)
- afl->alias_probability[S[--nS]] = 1;
+ while (nLarge != n - 1) {
+
+ afl->alias_probability[Large[++nLarge]] = 1;
+
+ }
afl->reinit_table = 0;
@@ -264,7 +298,7 @@ void create_alias_table(afl_state_t *afl) {
*/
/*
fprintf(stderr, " entry alias probability perf_score weight
- filename\n"); for (u32 i = 0; i < n; ++i) fprintf(stderr, " %5u %5u %11u
+ filename\n"); for (i = 0; i < n; ++i) fprintf(stderr, " %5u %5u %11u
%0.9f %0.9f %s\n", i, afl->alias_table[i], afl->alias_probability[i],
afl->queue_buf[i]->perf_score, afl->queue_buf[i]->weight,
afl->queue_buf[i]->fname);
--
cgit 1.4.1
From 6172bc7312f85276101edbf78d2dd702f9ddfb49 Mon Sep 17 00:00:00 2001
From: fxlb
Date: Thu, 27 Apr 2023 16:00:26 +0000
Subject: Add "Hangs saved" to afl-whatsup (#1717)
The hangs could show long or infinite loops. This is important.
Co-authored-by: van Hauser
---
afl-whatsup | 3 +++
1 file changed, 3 insertions(+)
diff --git a/afl-whatsup b/afl-whatsup
index cec1ae28..6f29ab24 100755
--- a/afl-whatsup
+++ b/afl-whatsup
@@ -88,6 +88,7 @@ TOTAL_TIME=0
TOTAL_EXECS=0
TOTAL_EPS=0
TOTAL_CRASHES=0
+TOTAL_HANGS=0
TOTAL_PFAV=0
TOTAL_PENDING=0
@@ -190,6 +191,7 @@ for i in `find . -maxdepth 2 -iname fuzzer_stats | sort`; do
TOTAL_EPS=$((TOTAL_EPS + EXEC_SEC))
TOTAL_EXECS=$((TOTAL_EXECS + execs_done))
TOTAL_CRASHES=$((TOTAL_CRASHES + saved_crashes))
+ TOTAL_HANGS=$((TOTAL_HANGS + saved_hangs))
TOTAL_PENDING=$((TOTAL_PENDING + pending_total))
TOTAL_PFAV=$((TOTAL_PFAV + pending_favs))
@@ -301,6 +303,7 @@ if [ "$ALIVE_CNT" -gt "1" ]; then
fi
echo " Crashes saved : $TOTAL_CRASHES"
+echo " Hangs saved : $TOTAL_HANGS"
echo "Cycles without finds : $TOTAL_WCOP"
echo " Time without finds : $TOTAL_LAST_FIND"
echo
--
cgit 1.4.1
From 6cad585bdc5c335cc2894c97e9aaf6d5fff88e1f Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 27 Apr 2023 18:57:28 +0200
Subject: nits
---
src/afl-showmap.c | 2 +-
test/test-llvm.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index d0e01cb1..f60acb2d 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -1287,7 +1287,7 @@ int main(int argc, char **argv_orig, char **envp) {
break;
- case 'Y': // fallthough
+ case 'Y': // fallthrough
#ifdef __linux__
case 'X': /* NYX mode */
diff --git a/test/test-llvm.sh b/test/test-llvm.sh
index 0e66cc97..714bda93 100755
--- a/test/test-llvm.sh
+++ b/test/test-llvm.sh
@@ -263,7 +263,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
{
mkdir -p in
echo 00000000000000000000000000000000 > in/in
- AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -m none -V15 -i in -o out -c./test-cmplog -- ./test-c >>errors 2>&1
+ AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -m none -V30 -i in -o out -c./test-cmplog -- ./test-c >>errors 2>&1
} >>errors 2>&1
test -n "$( ls out/default/crashes/id:000000* out/default/hangs/id:000000* 2>/dev/null )" && {
$ECHO "$GREEN[+] afl-fuzz is working correctly with llvm_mode cmplog"
--
cgit 1.4.1
From 41b0fe7280372031753fc5f11b9a03b214189155 Mon Sep 17 00:00:00 2001
From: Nick Potenski
Date: Thu, 27 Apr 2023 11:57:55 -0500
Subject: afl-showmap: Start a only a single fork server (#1718)
A forkserver is started by afl_fsrv_get_mapsize() when dynamically
finding the map size. When an input directory option is specified a
second fork server was also started. This commit re-arranges the inits
for several forkserver struct members so that we can re-use the server
started by the get_mapsize() call when not in coresight/qemu/unicorn
modes and just start the server otherwise.
---
src/afl-showmap.c | 29 ++++++++++++++++-------------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index f60acb2d..9c029035 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -1421,6 +1421,14 @@ int main(int argc, char **argv_orig, char **envp) {
// If @@ are in the target args, replace them and also set use_stdin=false.
detect_file_args(argv + optind, stdin_file, &fsrv->use_stdin);
+ fsrv->dev_null_fd = open("/dev/null", O_RDWR);
+ if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
+
+ fsrv->out_file = stdin_file;
+ fsrv->out_fd =
+ open(stdin_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
+ if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", stdin_file); }
+
} else {
// If @@ are in the target args, replace them and also set use_stdin=false.
@@ -1588,6 +1596,14 @@ int main(int argc, char **argv_orig, char **envp) {
fsrv->map_size = map_size;
+ } else {
+
+ afl_fsrv_start(fsrv, use_argv, &stop_soon,
+ (get_afl_env("AFL_DEBUG_CHILD") ||
+ get_afl_env("AFL_DEBUG_CHILD_OUTPUT"))
+ ? 1
+ : 0);
+
}
if (in_dir || in_filelist) {
@@ -1617,9 +1633,6 @@ int main(int argc, char **argv_orig, char **envp) {
if (getenv("AFL_DEBUG_GDB")) wait_for_gdb = true;
- fsrv->dev_null_fd = open("/dev/null", O_RDWR);
- if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
-
if (in_filelist) {
if (!be_quiet) ACTF("Reading from file list '%s'...", in_filelist);
@@ -1666,10 +1679,6 @@ int main(int argc, char **argv_orig, char **envp) {
}
atexit(at_exit_handler);
- fsrv->out_file = stdin_file;
- fsrv->out_fd =
- open(stdin_file, O_RDWR | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
- if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }
if (get_afl_env("AFL_DEBUG")) {
@@ -1685,12 +1694,6 @@ int main(int argc, char **argv_orig, char **envp) {
}
- afl_fsrv_start(fsrv, use_argv, &stop_soon,
- (get_afl_env("AFL_DEBUG_CHILD") ||
- get_afl_env("AFL_DEBUG_CHILD_OUTPUT"))
- ? 1
- : 0);
-
map_size = fsrv->map_size;
if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz)
--
cgit 1.4.1
From e956f23a77b776a5c11344889503c833adbf1052 Mon Sep 17 00:00:00 2001
From: "Christian Holler (:decoder)"
Date: Fri, 28 Apr 2023 11:35:22 +0200
Subject: Source Code Coverage support for Nyx (Part 1) (#1720)
* Additional source code reformatting in afl-compiler-rt
* Add source code coverage support to afl-compiler-rt (for use with Nyx)
---
GNUmakefile.llvm | 5 +
instrumentation/README.llvm.md | 24 ++++
instrumentation/afl-compiler-rt.o.c | 261 +++++++++++++++++++++++++++++++++++-
src/afl-cc.c | 26 +++-
4 files changed, 308 insertions(+), 8 deletions(-)
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index c1b006ba..2bb4e7f8 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -274,6 +274,11 @@ ifndef LLVM_DEBUG
CFLAGS_SAFE += -Wno-deprecated
endif
+ifdef CODE_COVERAGE
+ override CFLAGS_SAFE += -D__AFL_CODE_COVERAGE=1
+ override LDFLAGS += -ldl
+endif
+
override CFLAGS += $(CFLAGS_SAFE)
ifdef AFL_TRACE_PC
diff --git a/instrumentation/README.llvm.md b/instrumentation/README.llvm.md
index c0677474..126cf1a2 100644
--- a/instrumentation/README.llvm.md
+++ b/instrumentation/README.llvm.md
@@ -280,3 +280,27 @@ Please note that the default counter implementations are not thread safe!
Support for thread safe counters in mode LLVM CLASSIC can be activated with
setting `AFL_LLVM_THREADSAFE_INST=1`.
+
+## 8) Source code coverage through instrumentation
+
+Measuring source code coverage is a common task in fuzzing, but it is very
+difficut to do in some situations (e.g. when using snapshot fuzzing).
+
+When using the `AFL_LLVM_INSTRUMENT=llvm-codecov` option, afl-cc will use
+native trace-pc-guard instrumentation but additionally select options that
+are required to utilize the instrumentation for source code coverage.
+
+In particular, it will switch the instrumentation to be per basic block
+instead of instrumenting edges, disable all guard pruning and enable the
+experimental pc-table support that allows the runtime to gather 100% of
+instrumented basic blocks at start, including their locations.
+
+Note: You must compile AFL with the `CODE_COVERAGE=1` option to enable the
+respective parts in the AFL compiler runtime. Support is currently only
+implemented for Nyx, but can in theory also work without Nyx.
+
+Note: You might have to adjust `MAP_SIZE_POW2` in include/config.h to ensure
+that your coverage map is large enough to hold all basic blocks of your
+target program without any collisions.
+
+More documentation on how to utilize this with Nyx will follow.
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 0912e52b..3f8b519b 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -14,6 +14,16 @@
*/
+#ifdef __AFL_CODE_COVERAGE
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+ #endif
+ #ifndef __USE_GNU
+ #define __USE_GNU
+ #endif
+ #include
+#endif
+
#ifdef __ANDROID__
#include "android-ashmem.h"
#endif
@@ -105,6 +115,44 @@ u32 __afl_dictionary_len;
u64 __afl_map_addr;
u32 __afl_first_final_loc;
+#ifdef __AFL_CODE_COVERAGE
+typedef struct afl_module_info_t afl_module_info_t;
+
+struct afl_module_info_t {
+
+ // A unique id starting with 0
+ u32 id;
+
+ // Name and base address of the module
+ char *name;
+ uintptr_t base_address;
+
+ // PC Guard start/stop
+ u32 start;
+ u32 stop;
+
+ // PC Table begin/end
+ const uintptr_t *pcs_beg;
+ const uintptr_t *pcs_end;
+
+ u8 mapped;
+
+ afl_module_info_t *next;
+
+};
+
+typedef struct {
+
+ uintptr_t PC, PCFlags;
+
+} PCTableEntry;
+
+afl_module_info_t *__afl_module_info = NULL;
+
+u32 __afl_pcmap_size = 0;
+uintptr_t *__afl_pcmap_ptr = NULL;
+#endif // __AFL_CODE_COVERAGE
+
/* 1 if we are running in afl, and the forkserver was started, else 0 */
u32 __afl_connected = 0;
@@ -496,11 +544,12 @@ static void __afl_map_shm(void) {
if (__afl_map_size && __afl_map_size > MAP_SIZE) {
- u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
- if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
+ u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
+ if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
- send_forkserver_error(FS_ERROR_MAP_SIZE);
- _exit(1);
+ fprintf(stderr, "FS_ERROR_MAP_SIZE\n");
+ send_forkserver_error(FS_ERROR_MAP_SIZE);
+ _exit(1);
}
@@ -512,13 +561,13 @@ static void __afl_map_shm(void) {
if (!__afl_area_ptr || __afl_area_ptr == (void *)-1) {
- if (__afl_map_addr)
+ if (__afl_map_addr)
send_forkserver_error(FS_ERROR_MAP_ADDR);
else
send_forkserver_error(FS_ERROR_SHMAT);
perror("shmat for map");
- _exit(1);
+ _exit(1);
}
@@ -678,6 +727,27 @@ static void __afl_map_shm(void) {
}
+#ifdef __AFL_CODE_COVERAGE
+ char *pcmap_id_str = getenv("__AFL_PCMAP_SHM_ID");
+
+ if (pcmap_id_str) {
+
+ __afl_pcmap_size = __afl_map_size * sizeof(void *);
+ u32 shm_id = atoi(pcmap_id_str);
+
+ __afl_pcmap_ptr = (uintptr_t *)shmat(shm_id, NULL, 0);
+
+ if (__afl_debug) {
+
+ fprintf(stderr, "DEBUG: Received %p via shmat for pcmap\n",
+ __afl_pcmap_ptr);
+
+ }
+
+ }
+
+#endif // __AFL_CODE_COVERAGE
+
}
/* unmap SHM. */
@@ -686,6 +756,17 @@ static void __afl_unmap_shm(void) {
if (!__afl_already_initialized_shm) return;
+#ifdef __AFL_CODE_COVERAGE
+ if (__afl_pcmap_size) {
+
+ shmdt((void *)__afl_pcmap_ptr);
+ __afl_pcmap_ptr = NULL;
+ __afl_pcmap_size = 0;
+
+ }
+
+#endif // __AFL_CODE_COVERAGE
+
char *id_str = getenv(SHM_ENV_VAR);
if (id_str) {
@@ -1507,6 +1588,102 @@ void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
}
+#ifdef __AFL_CODE_COVERAGE
+void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
+ const uintptr_t *pcs_end) {
+
+ if (__afl_debug) {
+
+ fprintf(stderr, "DEBUG: __sanitizer_cov_pcs_init called\n");
+
+ }
+
+ // If for whatever reason, we cannot get dlinfo here, then pc_guard_init also
+ // couldn't get it and we'd end up attributing to the wrong module.
+ Dl_info dlinfo;
+ if (!dladdr(__builtin_return_address(0), &dlinfo)) {
+
+ fprintf(stderr,
+ "WARNING: Ignoring __sanitizer_cov_pcs_init callback due to "
+ "missing module info\n");
+ return;
+
+ }
+
+ afl_module_info_t *last_module_info = __afl_module_info;
+ while (last_module_info && last_module_info->next) {
+
+ last_module_info = last_module_info->next;
+
+ }
+
+ if (!last_module_info) {
+
+ fprintf(stderr,
+ "ERROR: __sanitizer_cov_pcs_init called with no module info?!\n");
+ abort();
+
+ }
+
+ last_module_info->pcs_beg = pcs_beg;
+ last_module_info->pcs_end = pcs_end;
+
+ // Now update the pcmap. If this is the last module coming in, after all
+ // pre-loaded code, then this will also map all of our delayed previous
+ // modules.
+
+ if (!__afl_pcmap_ptr) { return; }
+
+ for (afl_module_info_t *mod_info = __afl_module_info; mod_info;
+ mod_info = mod_info->next) {
+
+ if (mod_info->mapped) { continue; }
+
+ PCTableEntry *start = (PCTableEntry *)(mod_info->pcs_beg);
+ PCTableEntry *end = (PCTableEntry *)(mod_info->pcs_end);
+
+ u32 in_module_index = 0;
+
+ while (start < end) {
+
+ if (mod_info->start + in_module_index >= __afl_map_size) {
+
+ fprintf(stderr, "ERROR: __sanitizer_cov_pcs_init out of bounds?!\n");
+ abort();
+
+ }
+
+ uintptr_t PC = start->PC;
+
+ // This is what `GetPreviousInstructionPc` in sanitizer runtime does
+ // for x86/x86-64. Needs more work for ARM and other archs.
+ PC = PC - 1;
+
+ // Calculate relative offset in module
+ PC = PC - mod_info->base_address;
+
+ __afl_pcmap_ptr[mod_info->start + in_module_index] = PC;
+
+ start++;
+ in_module_index++;
+
+ }
+
+ mod_info->mapped = 1;
+
+ if (__afl_debug) {
+
+ fprintf(stderr, "DEBUG: __sanitizer_cov_pcs_init initialized %u PCs\n",
+ in_module_index);
+
+ }
+
+ }
+
+}
+
+#endif // __AFL_CODE_COVERAGE
+
/* Init callback. Populates instrumentation IDs. Note that we're using
ID of 0 as a special value to indicate non-instrumented bits. That may
still touch the bitmap, but in a fairly harmless way. */
@@ -1538,6 +1715,62 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
if (start == stop || *start) { return; }
+#ifdef __AFL_CODE_COVERAGE
+ u32 *orig_start = start;
+ afl_module_info_t *mod_info = NULL;
+
+ Dl_info dlinfo;
+ if (dladdr(__builtin_return_address(0), &dlinfo)) {
+
+ if (__afl_already_initialized_forkserver) {
+
+ fprintf(stderr, "[pcmap] Error: Module was not preloaded: %s\n",
+ dlinfo.dli_fname);
+
+ } else {
+
+ afl_module_info_t *last_module_info = __afl_module_info;
+ while (last_module_info && last_module_info->next) {
+
+ last_module_info = last_module_info->next;
+
+ }
+
+ mod_info = malloc(sizeof(afl_module_info_t));
+
+ mod_info->id = last_module_info ? last_module_info->id + 1 : 0;
+ mod_info->name = strdup(dlinfo.dli_fname);
+ mod_info->base_address = (uintptr_t)dlinfo.dli_fbase;
+ mod_info->start = 0;
+ mod_info->stop = 0;
+ mod_info->pcs_beg = NULL;
+ mod_info->pcs_end = NULL;
+ mod_info->mapped = 0;
+ mod_info->next = NULL;
+
+ if (last_module_info) {
+
+ last_module_info->next = mod_info;
+
+ } else {
+
+ __afl_module_info = mod_info;
+
+ }
+
+ fprintf(stderr, "[pcmap] Module: %s Base Address: %p\n", dlinfo.dli_fname,
+ dlinfo.dli_fbase);
+
+ }
+
+ } else {
+
+ fprintf(stderr, "[pcmap] dladdr call failed\n");
+
+ }
+
+#endif // __AFL_CODE_COVERAGE
+
x = getenv("AFL_INST_RATIO");
if (x) {
@@ -1625,6 +1858,22 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
}
+#ifdef __AFL_CODE_COVERAGE
+ if (mod_info) {
+
+ mod_info->start = *orig_start;
+ mod_info->stop = *(stop - 1);
+ if (__afl_debug) {
+
+ fprintf(stderr, "DEBUG: [pcmap] Start Index: %u Stop Index: %u\n",
+ mod_info->start, mod_info->stop);
+
+ }
+
+ }
+
+#endif // __AFL_CODE_COVERAGE
+
if (__afl_debug) {
fprintf(stderr,
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 99ce39d4..b11a041d 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -76,6 +76,7 @@ enum {
INSTRUMENT_OPT_NGRAM = 16,
INSTRUMENT_OPT_CALLER = 32,
INSTRUMENT_OPT_CTX_K = 64,
+ INSTRUMENT_OPT_CODECOV = 128,
};
@@ -751,7 +752,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else if (instrument_mode == INSTRUMENT_LLVMNATIVE) {
#if LLVM_MAJOR >= 4
- cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
+ if (instrument_opt_mode & INSTRUMENT_OPT_CODECOV) {
+ #if LLVM_MAJOR >= 6
+ cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table";
+ #else
+ FATAL("pcguard instrumentation with pc-table requires llvm 6.0.1+");
+ #endif
+ } else {
+ cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
+ }
#else
FATAL("pcguard instrumentation requires llvm 4.0.1+");
#endif
@@ -1682,6 +1691,18 @@ int main(int argc, char **argv, char **envp) {
}
+ if (strncasecmp(ptr2, "llvmcodecov", strlen("llvmcodecov")) == 0 ||
+ strncasecmp(ptr2, "llvm-codecov", strlen("llvm-codecov")) == 0) {
+
+ if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE) {
+ instrument_mode = INSTRUMENT_LLVMNATIVE;
+ instrument_opt_mode |= INSTRUMENT_OPT_CODECOV;
+ } else
+ FATAL("main instrumentation mode already set with %s",
+ instrument_mode_string[instrument_mode]);
+
+ }
+
if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 ||
strncasecmp(ptr2, "instrim", strlen("instrim")) == 0) {
@@ -2241,7 +2262,8 @@ int main(int argc, char **argv, char **envp) {
"(requires LLVM 11 or higher)");
#endif
- if (instrument_opt_mode && instrument_mode != INSTRUMENT_CLASSIC)
+ if (instrument_opt_mode && instrument_opt_mode != INSTRUMENT_OPT_CODECOV &&
+ instrument_mode != INSTRUMENT_CLASSIC)
FATAL(
"CALLER, CTX and NGRAM instrumentation options can only be used with "
"the LLVM CLASSIC instrumentation mode.");
--
cgit 1.4.1
From 5813a4319c88848b2a1c47c12fe27f5e14dcad44 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 28 Apr 2023 11:42:21 +0200
Subject: doc, code format
---
GNUmakefile | 3 ++-
docs/INSTALL.md | 10 ++++------
instrumentation/afl-compiler-rt.o.c | 14 +++++++-------
src/afl-cc.c | 31 +++++++++++++++++++++++--------
4 files changed, 36 insertions(+), 22 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 5900ad61..56b8bb42 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -379,6 +379,7 @@ help:
@echo Known build environment options:
@echo "=========================================="
@echo STATIC - compile AFL++ static
+ @echo CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)
@echo ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
@echo UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
@echo DEBUG - no optimization, -ggdb3, all warnings and -Werror
@@ -394,7 +395,7 @@ help:
@echo AFL_NO_X86 - if compiling on non-intel/amd platforms
@echo "LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)"
@echo "=========================================="
- @echo e.g.: make ASAN_BUILD=1
+ @echo e.g.: make LLVM_CONFIG=llvm-config-16
.PHONY: test_x86
ifndef AFL_NO_X86
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index c54cb9ad..637e8658 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -79,22 +79,20 @@ make STATIC=1
These build options exist:
* STATIC - compile AFL++ static
+* CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)
* ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
-* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for
- debug purposes
+* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
* DEBUG - no optimization, -ggdb3, all warnings and -Werror
* LLVM_DEBUG - shows llvm deprecation warnings
* PROFILING - compile afl-fuzz with profiling information
* INTROSPECTION - compile afl-fuzz with mutation introspection
* NO_PYTHON - disable python support
-* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for
- normal fuzzing
+* NO_SPLICING - disables splicing mutation in afl-fuzz, not recommended for normal fuzzing
* NO_NYX - disable building nyx mode dependencies
* NO_CORESIGHT - disable building coresight (arm64 only)
* NO_UNICORN_ARM64 - disable building unicorn on arm64
* AFL_NO_X86 - if compiling on non-intel/amd platforms
-* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config
- (e.g., Debian)
+* LLVM_CONFIG - if your distro doesn't use the standard name for llvm-config (e.g., Debian)
e.g.: `make LLVM_CONFIG=llvm-config-14`
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 3f8b519b..5372fae0 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -544,12 +544,12 @@ static void __afl_map_shm(void) {
if (__afl_map_size && __afl_map_size > MAP_SIZE) {
- u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
- if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
+ u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
+ if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
- fprintf(stderr, "FS_ERROR_MAP_SIZE\n");
- send_forkserver_error(FS_ERROR_MAP_SIZE);
- _exit(1);
+ fprintf(stderr, "FS_ERROR_MAP_SIZE\n");
+ send_forkserver_error(FS_ERROR_MAP_SIZE);
+ _exit(1);
}
@@ -561,13 +561,13 @@ static void __afl_map_shm(void) {
if (!__afl_area_ptr || __afl_area_ptr == (void *)-1) {
- if (__afl_map_addr)
+ if (__afl_map_addr)
send_forkserver_error(FS_ERROR_MAP_ADDR);
else
send_forkserver_error(FS_ERROR_SHMAT);
perror("shmat for map");
- _exit(1);
+ _exit(1);
}
diff --git a/src/afl-cc.c b/src/afl-cc.c
index b11a041d..19314555 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -752,15 +752,21 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else if (instrument_mode == INSTRUMENT_LLVMNATIVE) {
#if LLVM_MAJOR >= 4
- if (instrument_opt_mode & INSTRUMENT_OPT_CODECOV) {
+ if (instrument_opt_mode & INSTRUMENT_OPT_CODECOV) {
+
#if LLVM_MAJOR >= 6
- cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table";
+ cc_params[cc_par_cnt++] =
+ "-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table";
#else
FATAL("pcguard instrumentation with pc-table requires llvm 6.0.1+");
#endif
- } else {
+
+ } else {
+
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
- }
+
+ }
+
#else
FATAL("pcguard instrumentation requires llvm 4.0.1+");
#endif
@@ -1660,13 +1666,17 @@ int main(int argc, char **argv, char **envp) {
instrument_mode = INSTRUMENT_CLASSIC;
lto_mode = 1;
- } else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL)
+ } else if (!instrument_mode || instrument_mode == INSTRUMENT_AFL) {
instrument_mode = INSTRUMENT_AFL;
- else
+
+ } else {
+
FATAL("main instrumentation mode already set with %s",
instrument_mode_string[instrument_mode]);
+ }
+
}
if (strncasecmp(ptr2, "pc-guard", strlen("pc-guard")) == 0 ||
@@ -1695,12 +1705,17 @@ int main(int argc, char **argv, char **envp) {
strncasecmp(ptr2, "llvm-codecov", strlen("llvm-codecov")) == 0) {
if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE) {
+
instrument_mode = INSTRUMENT_LLVMNATIVE;
- instrument_opt_mode |= INSTRUMENT_OPT_CODECOV;
- } else
+ instrument_opt_mode |= INSTRUMENT_OPT_CODECOV;
+
+ } else {
+
FATAL("main instrumentation mode already set with %s",
instrument_mode_string[instrument_mode]);
+ }
+
}
if (strncasecmp(ptr2, "cfg", strlen("cfg")) == 0 ||
--
cgit 1.4.1
From 00c86b7cb155a266c84c9a62b33697fa3f367386 Mon Sep 17 00:00:00 2001
From: vH
Date: Fri, 28 Apr 2023 14:56:52 +0200
Subject: llvm 17 changes
---
instrumentation/SanitizerCoverageLTO.so.cc | 6 ++++--
instrumentation/SanitizerCoveragePCGUARD.so.cc | 2 +-
instrumentation/afl-llvm-common.h | 2 ++
instrumentation/afl-llvm-dict2file.so.cc | 4 +++-
instrumentation/cmplog-routines-pass.cc | 4 +++-
instrumentation/cmplog-switches-pass.cc | 4 +++-
6 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 6a719737..1ee85234 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -19,8 +19,8 @@
#include "llvm/ADT/SmallVector.h"
#if LLVM_VERSION_MAJOR < 17
#include "llvm/ADT/Triple.h"
+ #include "llvm/Analysis/EHPersonalities.h"
#endif
-#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ValueTracking.h"
#include "llvm/IR/BasicBlock.h"
@@ -49,7 +49,9 @@
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Instrumentation.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#if LLVM_VERSION_MAJOR < 17
+ #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#endif
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 85b1ddd5..8be9e329 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -15,8 +15,8 @@
#include "llvm/ADT/SmallVector.h"
#if LLVM_VERSION_MAJOR < 17
#include "llvm/ADT/Triple.h"
+ #include "llvm/Analysis/EHPersonalities.h"
#endif
-#include "llvm/Analysis/EHPersonalities.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constant.h"
diff --git a/instrumentation/afl-llvm-common.h b/instrumentation/afl-llvm-common.h
index 16a13da5..c9324460 100644
--- a/instrumentation/afl-llvm-common.h
+++ b/instrumentation/afl-llvm-common.h
@@ -22,7 +22,9 @@ typedef long double max_align_t;
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
+#if LLVM_VERSION_MAJOR < 17
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#endif
#if LLVM_VERSION_MAJOR > 3 || \
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 4)
diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc
index cf368e35..8ee13010 100644
--- a/instrumentation/afl-llvm-dict2file.so.cc
+++ b/instrumentation/afl-llvm-dict2file.so.cc
@@ -53,7 +53,9 @@
#include "llvm/IR/Verifier.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#if LLVM_VERSION_MAJOR < 17
+ #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#endif
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/ValueTracking.h"
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index 0498156d..39db5aa4 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -38,7 +38,9 @@
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#if LLVM_VERSION_MAJOR < 17
+ #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#endif
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/ValueTracking.h"
diff --git a/instrumentation/cmplog-switches-pass.cc b/instrumentation/cmplog-switches-pass.cc
index cd0ae76d..38de669d 100644
--- a/instrumentation/cmplog-switches-pass.cc
+++ b/instrumentation/cmplog-switches-pass.cc
@@ -39,7 +39,9 @@
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#if LLVM_VERSION_MAJOR < 17
+ #include "llvm/Transforms/IPO/PassManagerBuilder.h"
+#endif
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Pass.h"
#include "llvm/Analysis/ValueTracking.h"
--
cgit 1.4.1
From f567a89dae29afb2e421d649f0e750e77913f08c Mon Sep 17 00:00:00 2001
From: vH
Date: Fri, 28 Apr 2023 15:39:01 +0200
Subject: more llvm 17
---
instrumentation/SanitizerCoverageLTO.so.cc | 2 ++
instrumentation/SanitizerCoveragePCGUARD.so.cc | 2 ++
2 files changed, 4 insertions(+)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 1ee85234..b3b0d2cd 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -20,6 +20,8 @@
#if LLVM_VERSION_MAJOR < 17
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/EHPersonalities.h"
+#else
+ #include "llvm/IR/EHPersonalities.h"
#endif
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/ValueTracking.h"
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 8be9e329..41c38283 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -16,6 +16,8 @@
#if LLVM_VERSION_MAJOR < 17
#include "llvm/ADT/Triple.h"
#include "llvm/Analysis/EHPersonalities.h"
+#else
+ #include "llvm/IR/EHPersonalities.h"
#endif
#include "llvm/Analysis/PostDominators.h"
#include "llvm/IR/CFG.h"
--
cgit 1.4.1
From ed96f9b209ceed9e0295bd0bce452bd74e797f1f Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 28 Apr 2023 16:02:09 +0200
Subject: add frida mode tutorial
---
docs/tutorials.md | 4 ++++
frida_mode/README.md | 2 ++
2 files changed, 6 insertions(+)
diff --git a/docs/tutorials.md b/docs/tutorials.md
index 758fddab..342080fd 100644
--- a/docs/tutorials.md
+++ b/docs/tutorials.md
@@ -20,6 +20,10 @@ training, then we can highly recommend the following:
* [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101)
+Here is good workflow description for frida_mode:
+
+* [https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html](https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html)
+
If you are interested in fuzzing structured data (where you define what the
structure is), these links have you covered (some are outdated though):
diff --git a/frida_mode/README.md b/frida_mode/README.md
index 49a1fe38..bfca443c 100644
--- a/frida_mode/README.md
+++ b/frida_mode/README.md
@@ -7,6 +7,8 @@ variables.
In FRIDA mode, binary programs are instrumented, similarly to QEMU mode.
+A tutorial can be found at [https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html](https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html)
+
## Current progress
As FRIDA mode is new, it is missing a lot of features. The design is such that
--
cgit 1.4.1
From 9065d4ba86ecdafeade50e5235ee1e99f4179692 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 1 May 2023 08:38:13 +0200
Subject: fix effector map
---
src/afl-fuzz-one.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index ee562f96..442240a9 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -842,6 +842,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len));
if (unlikely(!eff_map)) { PFATAL("alloc"); }
+ memset(eff_map, 0, sizeof(len));
eff_map[0] = 1;
if (EFF_APOS(len - 1) != 0) {
@@ -3570,6 +3571,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len));
if (unlikely(!eff_map)) { PFATAL("alloc"); }
+ memset(eff_map, 0, sizeof(len));
eff_map[0] = 1;
if (EFF_APOS(len - 1) != 0) {
--
cgit 1.4.1
From fcab3ec99026e92b688a69de476a0763942a9d67 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 1 May 2023 08:55:37 +0200
Subject: docs
---
docs/FAQ.md | 8 ++++++++
docs/best_practices.md | 5 +++++
2 files changed, 13 insertions(+)
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 76350c79..8178db46 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -171,6 +171,14 @@ If you find an interesting or important question missing, submit it via
The more "unstable" edges there are, the harder it is for AFL++ to identify
valid new paths.
+ If you fuzz in persistent mode (`AFL_LOOP` or `LLVMFuzzerTestOneInput()`
+ harnesses, a large number of unstable edges can mean that the target keeps
+ internal state and therefore it is possible that crashes cannot be replayed.
+ In such a case do either **not** fuzz in persistent mode (remove `AFL_LOOP()`
+ from your harness or call `LLVMFuzzerTestOneInput()` harnesses with `@@`),
+ or set a low `AFL_LOOP` value, e.g. 100, and enable `AFL_PERSISTENT_RECORD`
+ in `config.h` with the same value.
+
A value above 90% is usually fine and a value above 80% is also still ok, and
even a value above 20% can still result in successful finds of bugs. However,
it is recommended that for values below 90% or 80% you should take
diff --git a/docs/best_practices.md b/docs/best_practices.md
index 133c645e..459fcaf7 100644
--- a/docs/best_practices.md
+++ b/docs/best_practices.md
@@ -131,6 +131,11 @@ jitter, or is a hash map function etc., then it should not be instrumented.
To be able to exclude these functions (based on AFL++'s measured stability), the
following process will allow to identify functions with variable edges.
+Note that this is only useful for non-persistent targets!
+If a persistent target is unstable whereas when run non-persistent is fine,
+then this means that the target is keeping internal state, which is bad for
+fuzzing. Fuzz such targets **without** persistent mode.
+
Four steps are required to do this and it also requires quite some knowledge of
coding and/or disassembly and is effectively possible only with `afl-clang-fast`
`PCGUARD` and `afl-clang-lto` `LTO` instrumentation.
--
cgit 1.4.1
From 2cd07abca9c7b843bbd2085e0e4d852d41169092 Mon Sep 17 00:00:00 2001
From: lazymio
Date: Mon, 1 May 2023 13:12:05 +0200
Subject: Should memset EFF_ALEN(len) of eff_map (#1722)
---
src/afl-fuzz-one.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 442240a9..a9902087 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -842,7 +842,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len));
if (unlikely(!eff_map)) { PFATAL("alloc"); }
- memset(eff_map, 0, sizeof(len));
+ memset(eff_map, 0, EFF_ALEN(len));
eff_map[0] = 1;
if (EFF_APOS(len - 1) != 0) {
@@ -3571,7 +3571,7 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
eff_map = afl_realloc(AFL_BUF_PARAM(eff), EFF_ALEN(len));
if (unlikely(!eff_map)) { PFATAL("alloc"); }
- memset(eff_map, 0, sizeof(len));
+ memset(eff_map, 0, EFF_ALEN(len));
eff_map[0] = 1;
if (EFF_APOS(len - 1) != 0) {
--
cgit 1.4.1
From 22db79aefafb48fed48199a86a39babdee795870 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 1 May 2023 15:07:49 +0200
Subject: fix reallocs
---
include/alloc-inl.h | 7 +++----
src/afl-fuzz.c | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+), 4 deletions(-)
diff --git a/include/alloc-inl.h b/include/alloc-inl.h
index bbb42e88..1e9a192b 100644
--- a/include/alloc-inl.h
+++ b/include/alloc-inl.h
@@ -704,12 +704,11 @@ static inline void *afl_realloc(void **buf, size_t size_needed) {
*buf = NULL;
return NULL;
- } else {
-
- new_buf = newer_buf;
-
}
+ new_buf = newer_buf;
+ memset(((u8 *)new_buf) + current_size, 0, next_size - current_size);
+
new_buf->complete_size = next_size;
*buf = (void *)(new_buf->buf);
return *buf;
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 646dc50b..c02479cf 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1979,6 +1979,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->non_instrumented_mode || afl->fsrv.qemu_mode ||
afl->fsrv.frida_mode || afl->fsrv.cs_mode || afl->unicorn_mode) {
+ u32 old_map_size = map_size;
map_size = afl->fsrv.real_map_size = afl->fsrv.map_size = MAP_SIZE;
afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size);
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size);
@@ -1990,6 +1991,18 @@ int main(int argc, char **argv_orig, char **envp) {
afl->first_trace = ck_realloc(afl->first_trace, map_size);
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size);
+ if (old_map_size < map_size) {
+
+ memset(afl->var_bytes + old_map_size, 0, map_size - old_map_size);
+ memset(afl->top_rated + old_map_size, 0, map_size - old_map_size);
+ memset(afl->clean_trace + old_map_size, 0, map_size - old_map_size);
+ memset(afl->clean_trace_custom + old_map_size, 0,
+ map_size - old_map_size);
+ memset(afl->first_trace + old_map_size, 0, map_size - old_map_size);
+ memset(afl->map_tmp_buf + old_map_size, 0, map_size - old_map_size);
+
+ }
+
}
afl->argv = use_argv;
@@ -2017,6 +2030,7 @@ int main(int argc, char **argv_orig, char **envp) {
OKF("Re-initializing maps to %u bytes", new_map_size);
+ u32 old_map_size = map_size;
afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
@@ -2029,6 +2043,18 @@ int main(int argc, char **argv_orig, char **envp) {
afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
+ if (old_map_size < new_map_size) {
+
+ memset(afl->var_bytes + old_map_size, 0, new_map_size - old_map_size);
+ memset(afl->top_rated + old_map_size, 0, new_map_size - old_map_size);
+ memset(afl->clean_trace + old_map_size, 0, new_map_size - old_map_size);
+ memset(afl->clean_trace_custom + old_map_size, 0,
+ new_map_size - old_map_size);
+ memset(afl->first_trace + old_map_size, 0, new_map_size - old_map_size);
+ memset(afl->map_tmp_buf + old_map_size, 0, new_map_size - old_map_size);
+
+ }
+
afl_fsrv_kill(&afl->fsrv);
afl_shm_deinit(&afl->shm);
afl->fsrv.map_size = new_map_size;
@@ -2079,6 +2105,7 @@ int main(int argc, char **argv_orig, char **envp) {
OKF("Re-initializing maps to %u bytes due cmplog", new_map_size);
+ u32 old_map_size = map_size;
afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
@@ -2091,6 +2118,18 @@ int main(int argc, char **argv_orig, char **envp) {
afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
+ if (old_map_size < new_map_size) {
+
+ memset(afl->var_bytes + old_map_size, 0, new_map_size - old_map_size);
+ memset(afl->top_rated + old_map_size, 0, new_map_size - old_map_size);
+ memset(afl->clean_trace + old_map_size, 0, new_map_size - old_map_size);
+ memset(afl->clean_trace_custom + old_map_size, 0,
+ new_map_size - old_map_size);
+ memset(afl->first_trace + old_map_size, 0, new_map_size - old_map_size);
+ memset(afl->map_tmp_buf + old_map_size, 0, new_map_size - old_map_size);
+
+ }
+
afl_fsrv_kill(&afl->fsrv);
afl_fsrv_kill(&afl->cmplog_fsrv);
afl_shm_deinit(&afl->shm);
--
cgit 1.4.1
From a7b7f3cde9b3a420ea5ac32f7309e8a856a01e94 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 2 May 2023 18:25:56 +0200
Subject: fix afl-system-config for macos
---
afl-system-config | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/afl-system-config b/afl-system-config
index bf6397fa..b50bb06e 100755
--- a/afl-system-config
+++ b/afl-system-config
@@ -110,7 +110,7 @@ if [ "$PLATFORM" = "Darwin" ] ; then
sysctl kern.sysv.shmall=131072000
echo Settings applied.
echo
- if [ $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') ] ; then
+ if $(launchctl list 2>/dev/null | grep -q '\.ReportCrash$') ; then
echo
echo Unloading the default crash reporter
SL=/System/Library; PL=com.apple.ReportCrash
@@ -119,6 +119,7 @@ if [ "$PLATFORM" = "Darwin" ] ; then
echo
fi
echo It is recommended to disable System Integrity Protection for increased performance.
+ echo See: https://developer.apple.com/documentation/security/disabling_and_enabling_system_integrity_protection
echo
DONE=1
fi
--
cgit 1.4.1
From f516926f006545d45162eaef723d786a427721f8 Mon Sep 17 00:00:00 2001
From: Moshe Kaplan
Date: Thu, 4 May 2023 11:23:30 -0400
Subject: afl-fuzz.c: Document -i - in --help (#1725)
afl-fuzz.c: Document `-i -` in `--help`, to write that `-i` can be passed '-' to resume the prior fuzzing job. Also reference AFL_AUTORESUME so users know they can set that parameter to sidestep the issue entirely.
---
src/afl-fuzz.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index c02479cf..c5206282 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -124,7 +124,7 @@ static void usage(u8 *argv0, int more_help) {
"\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n"
"Required parameters:\n"
- " -i dir - input directory with test cases\n"
+ " -i dir - input directory with test cases (or '-' to resume, also see AFL_AUTORESUME)\n"
" -o dir - output directory for fuzzer findings\n\n"
"Execution control settings:\n"
--
cgit 1.4.1
From 396157dedae2049f830c49eb81ef9617275333ee Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 5 May 2023 13:52:54 +0200
Subject: tritondse custom mutator attempt
---
custom_mutators/aflpp_tritondse/README.md | 17 ++++
custom_mutators/aflpp_tritondse/aflpp_tritondse.py | 106 +++++++++++++++++++++
src/afl-fuzz-one.c | 16 ++--
3 files changed, 132 insertions(+), 7 deletions(-)
create mode 100644 custom_mutators/aflpp_tritondse/README.md
create mode 100644 custom_mutators/aflpp_tritondse/aflpp_tritondse.py
diff --git a/custom_mutators/aflpp_tritondse/README.md b/custom_mutators/aflpp_tritondse/README.md
new file mode 100644
index 00000000..8a5dd02b
--- /dev/null
+++ b/custom_mutators/aflpp_tritondse/README.md
@@ -0,0 +1,17 @@
+# An AFL++ custom mutator using TritonDSE
+
+## Installing the requirements
+
+`pip3 install tritondse`
+
+## How to run with an example
+
+```
+../../afl-cc -o ../../test-instr ../../test-instr.c
+mkdir -p in
+echo aaaa > in/in
+TRITON_DSE_TARGET=../../test-instr AFL_CUSTOM_MUTATOR_ONLY=1 AFL_SYNC_TIME=1 AFL_PYTHON_MODULE=aflpp_tritondse PYTHONPATH=. ../../afl-fuzz -i in -o out -- ../../test-instr
+```
+
+Note that this custom mutator works differently, new finds are synced
+after 10-60 seconds to the fuzzing instance.
diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
new file mode 100644
index 00000000..33bf8a9f
--- /dev/null
+++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
@@ -0,0 +1,106 @@
+import sys
+import os
+import logging
+
+from tritondse import Config
+from tritondse import CoverageStrategy
+from tritondse import ProcessState
+from tritondse import Program
+from tritondse import Seed
+from tritondse import SeedFormat
+from tritondse import SymbolicExecutor
+from tritondse import SymbolicExplorator
+
+
+#logging.basicConfig(level=logging.INFO)
+
+is_debug = False
+out_path = "out/tritondse/queue"
+input_file = None
+prog = None
+config = None
+dse = None
+cycle = 0
+count = 0
+hashes = set()
+
+def pre_exec_hook(se: SymbolicExecutor, state: ProcessState):
+ #logging.info(f"[PRE-EXEC] Processing seed: {se.seed.hash}, \
+ # ({repr(se.seed.content)})")
+ global count
+ global hasshes
+ if se.seed.hash not in hashes:
+ hashes.add(se.seed.hash)
+ filename = out_path + "/id:" + f"{count:06}" + "," + se.seed.hash
+ if not os.path.exists(filename):
+ with open(filename, 'wb') as file:
+ file.write(se.seed.content)
+ count += 1
+ if input_file:
+ with open(input_file, 'wb') as file:
+ file.write(se.seed.content)
+
+
+def init(seed):
+ global prog
+ global config
+ global dse
+ global input_file
+ global is_debug
+ # Load the program (LIEF-based program loader).
+ prog = Program(os.environ['TRITON_DSE_TARGET'])
+ # Set the configuration.
+ argv = None
+ try:
+ foo = os.environ['AFL_DEBUG']
+ is_debug = True
+ except KeyError:
+ pass
+ try:
+ argv_list = os.environ['TRITON_DSE_TARGET_ARGV']
+ argv = argv_list.split()
+ except KeyError:
+ pass
+ try:
+ foo = os.environ['TRITON_DSE_TARGET_INPUT']
+ input_file = foo
+ except KeyError:
+ pass
+ config = Config(coverage_strategy = CoverageStrategy.PATH,
+ debug = is_debug,
+ pipe_stdout = is_debug,
+ pipe_stderr = is_debug,
+ execution_timeout = 1,
+ program_argv = argv,
+ smt_timeout= 50,
+ seed_format = SeedFormat.RAW)
+ # Create an instance of the Symbolic Explorator
+ dse = SymbolicExplorator(config, prog)
+ # Add callbacks.
+ dse.callback_manager.register_pre_execution_callback(pre_exec_hook)
+ # Create the output directory
+ os.makedirs(out_path, exist_ok=True)
+
+
+#def fuzz(buf, add_buf, max_size):
+# return b""
+
+
+def queue_new_entry(filename_new_queue, filename_orig_queue):
+ global dse
+ global cycle
+ # Add seed to the worklist.
+ with open(filename_new_queue, "rb") as file:
+ seed = file.read()
+ seed = Seed(seed)
+ dse.add_input_seed(seed)
+ if is_debug:
+ print("NEW FILE " + filename_new_queue + " count " + str(cycle))
+ cycle += 1
+ # Start exploration!
+ #dse.step()
+ dse.explore()
+ pass
+
+def splice_optout():
+ pass
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index a9902087..c6e9a295 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2048,20 +2048,22 @@ custom_mutator_stage:
afl->queue_cur->stats_mutated += afl->stage_max;
#endif
- if (likely(afl->custom_only)) {
+ /****************
+ * RANDOM HAVOC *
+ ****************/
+
+havoc_stage:
+
+ if (unlikely(afl->custom_only)) {
+ /* Force UI update */
+ show_stats(afl);
/* Skip other stages */
ret_val = 0;
goto abandon_entry;
}
- /****************
- * RANDOM HAVOC *
- ****************/
-
-havoc_stage:
-
afl->stage_cur_byte = -1;
/* The havoc stage mutation code is also invoked when splicing files; if the
--
cgit 1.4.1
From f585f262669c14d8b7037d4a34eaa9eb7aef38c5 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 5 May 2023 14:04:53 +0200
Subject: tritondse fixes
---
custom_mutators/aflpp_tritondse/aflpp_tritondse.py | 20 ++++++++++++--------
1 file changed, 12 insertions(+), 8 deletions(-)
diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
index 33bf8a9f..49f67d75 100644
--- a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
+++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
@@ -1,6 +1,7 @@
import sys
import os
import logging
+import hashlib
from tritondse import Config
from tritondse import CoverageStrategy
@@ -92,14 +93,17 @@ def queue_new_entry(filename_new_queue, filename_orig_queue):
# Add seed to the worklist.
with open(filename_new_queue, "rb") as file:
seed = file.read()
- seed = Seed(seed)
- dse.add_input_seed(seed)
- if is_debug:
- print("NEW FILE " + filename_new_queue + " count " + str(cycle))
- cycle += 1
- # Start exploration!
- #dse.step()
- dse.explore()
+ hash = hashlib.md5(seed).hexdigest()
+ if hash not in hashes:
+ hashes.add(hash)
+ if is_debug:
+ print("NEW FILE " + filename_new_queue + " hash " + hash + " count " + str(cycle))
+ cycle += 1
+ seed = Seed(seed)
+ dse.add_input_seed(seed)
+ # Start exploration!
+ #dse.step()
+ dse.explore()
pass
def splice_optout():
--
cgit 1.4.1
From 2c421d48fa668d23a20d06bf974fe05be14e5591 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 5 May 2023 14:08:01 +0200
Subject: update libnyx (#1727)
---
nyx_mode/LIBNYX_VERSION | 2 +-
nyx_mode/libnyx | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/nyx_mode/LIBNYX_VERSION b/nyx_mode/LIBNYX_VERSION
index 86b32eec..ed88ec10 100644
--- a/nyx_mode/LIBNYX_VERSION
+++ b/nyx_mode/LIBNYX_VERSION
@@ -1 +1 @@
-2da7f08
+c8a72dc
diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx
index 2da7f08b..c8a72dc3 160000
--- a/nyx_mode/libnyx
+++ b/nyx_mode/libnyx
@@ -1 +1 @@
-Subproject commit 2da7f08b6e0267ccfe64e1320b24cdb29223459c
+Subproject commit c8a72dc3b302b4037b03738454e1dc8e2bb18796
--
cgit 1.4.1
From 001d9d3d20890941120cc16e9109b4c561da39d1 Mon Sep 17 00:00:00 2001
From: Moshe Kaplan
Date: Fri, 5 May 2023 10:02:00 -0400
Subject: GNUmakefile: Update LLVM instructions (#1728)
Update LLVM instructions, because versions higher than 14 are supported and to be explicit that LLD is also required
---
GNUmakefile | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/GNUmakefile b/GNUmakefile
index 56b8bb42..794ebeab 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -316,7 +316,7 @@ all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_bu
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
@test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
@test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
- @test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM 11-14. More information at instrumentation/README.lto.md on how to build it"
+ @test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM and LLD 11+. More information at instrumentation/README.lto.md on how to build it"
ifneq "$(SYS)" "Darwin"
@test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
endif
--
cgit 1.4.1
From c092892488a1ed8e5213b9dcdf3d4da617fe0dd2 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 6 May 2023 09:26:24 +0200
Subject: disable macos in the ci, works fine for me
---
.github/workflows/ci.yml | 40 ++++++++++++++++++++--------------------
nyx_mode/libnyx | 2 +-
2 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 03e4151d..fdf618b9 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -36,23 +36,23 @@ jobs:
run: make distrib ASAN_BUILD=1 NO_NYX=1
- name: run tests
run: sudo -E ./afl-system-config; make tests
- macos:
- runs-on: macOS-latest
- env:
- AFL_MAP_SIZE: 65536
- AFL_SKIP_CPUFREQ: 1
- AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
- steps:
- - uses: actions/checkout@v3
- - name: install
- run: brew install make gcc llvm
- - name: fix install
- run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
- - name: build
- run: export PATH=/usr/local/Cellar/llvm/*/":$PATH"; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; sudo -E ./afl-system-config; gmake ASAN_BUILD=1
- - name: frida
- run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake
- - name: run tests
- run: sudo -E ./afl-system-config; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export PATH=/usr/local/Cellar/llvm/*/":/usr/local/bin:$PATH"; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; gmake tests
- - name: force frida test for MacOS
- run: export AFL_PATH=`pwd`; /usr/local/bin/gcc -o test-instr test-instr.c; mkdir in; echo > in/in; AFL_NO_UI=1 ./afl-fuzz -O -i in -o out -V 5 -- ./test-instr
+ # macos:
+ # runs-on: macOS-latest
+ # env:
+ # AFL_MAP_SIZE: 65536
+ # AFL_SKIP_CPUFREQ: 1
+ # AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: 1
+ # steps:
+ # - uses: actions/checkout@v3
+ # - name: install
+ # run: brew install make gcc llvm
+ # - name: fix install
+ # run: cd /usr/local/bin; ln -s gcc-11 gcc; ln -s g++-11 g++; which gcc; gcc -v
+ # - name: build
+ # run: export PATH=/usr/local/Cellar/llvm/*/":$PATH"; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; sudo -E ./afl-system-config; gmake ASAN_BUILD=1
+ # - name: frida
+ # run: export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; cd frida_mode; gmake
+ # - name: run tests
+ # run: sudo -E ./afl-system-config; export CC=/usr/local/Cellar/llvm/*/bin/clang; export CXX="$CC"++; export PATH=/usr/local/Cellar/llvm/*/":/usr/local/bin:$PATH"; export LLVM_CONFIG=/usr/local/Cellar/llvm/*/bin/llvm-config; gmake tests
+ # - name: force frida test for MacOS
+ # run: export AFL_PATH=`pwd`; /usr/local/bin/gcc -o test-instr test-instr.c; mkdir in; echo > in/in; AFL_NO_UI=1 ./afl-fuzz -O -i in -o out -V 5 -- ./test-instr
diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx
index c8a72dc3..2da7f08b 160000
--- a/nyx_mode/libnyx
+++ b/nyx_mode/libnyx
@@ -1 +1 @@
-Subproject commit c8a72dc3b302b4037b03738454e1dc8e2bb18796
+Subproject commit 2da7f08b6e0267ccfe64e1320b24cdb29223459c
--
cgit 1.4.1
From c97caa6e1095a4bce8f0c32108e6e33f7ac240e4 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 9 May 2023 14:17:09 +0200
Subject: fix makefile
---
GNUmakefile | 2 +-
src/afl-fuzz.c | 3 ++-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 794ebeab..31374c10 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -379,7 +379,7 @@ help:
@echo Known build environment options:
@echo "=========================================="
@echo STATIC - compile AFL++ static
- @echo CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)
+ @echo "CODE_COVERAGE - compile the target for code coverage (see docs/instrumentation/README.llvm.md)"
@echo ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
@echo UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
@echo DEBUG - no optimization, -ggdb3, all warnings and -Werror
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index c5206282..f982258f 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -124,7 +124,8 @@ static void usage(u8 *argv0, int more_help) {
"\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n"
"Required parameters:\n"
- " -i dir - input directory with test cases (or '-' to resume, also see AFL_AUTORESUME)\n"
+ " -i dir - input directory with test cases (or '-' to resume, "
+ "also see AFL_AUTORESUME)\n"
" -o dir - output directory for fuzzer findings\n\n"
"Execution control settings:\n"
--
cgit 1.4.1
From 70da0c2e405102dc044cb4bed0f4f1e847c90d0b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 10 May 2023 16:09:18 +0200
Subject: better tritondse support
---
custom_mutators/aflpp_tritondse/aflpp_tritondse.py | 54 ++++++++++---
docs/custom_mutators.md | 28 +++++++
include/envs.h | 4 +
src/afl-fuzz.c | 91 ++++++++++++++++------
4 files changed, 145 insertions(+), 32 deletions(-)
diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
index 49f67d75..9584b368 100644
--- a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
+++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
@@ -7,6 +7,7 @@ from tritondse import Config
from tritondse import CoverageStrategy
from tritondse import ProcessState
from tritondse import Program
+from tritondse import CleLoader
from tritondse import Seed
from tritondse import SeedFormat
from tritondse import SymbolicExecutor
@@ -16,7 +17,7 @@ from tritondse import SymbolicExplorator
#logging.basicConfig(level=logging.INFO)
is_debug = False
-out_path = "out/tritondse/queue"
+out_path = ""
input_file = None
prog = None
config = None
@@ -29,28 +30,38 @@ def pre_exec_hook(se: SymbolicExecutor, state: ProcessState):
#logging.info(f"[PRE-EXEC] Processing seed: {se.seed.hash}, \
# ({repr(se.seed.content)})")
global count
- global hasshes
+ global hashes
+ print('DEBUG - prehook')
if se.seed.hash not in hashes:
hashes.add(se.seed.hash)
filename = out_path + "/id:" + f"{count:06}" + "," + se.seed.hash
if not os.path.exists(filename):
+ if is_debug:
+ print('Creating queue input ' + filename)
with open(filename, 'wb') as file:
file.write(se.seed.content)
count += 1
+ else:
+ print('has hash: ' + se.seed.hash)
if input_file:
+ if is_debug:
+ print('Writing to ' + input_file + ' the content: ' + str(se.seed.content))
with open(input_file, 'wb') as file:
file.write(se.seed.content)
+ else:
+ print('no input!')
def init(seed):
global prog
global config
global dse
+ global out_path
global input_file
global is_debug
# Load the program (LIEF-based program loader).
- prog = Program(os.environ['TRITON_DSE_TARGET'])
- # Set the configuration.
+ prog = CleLoader(os.environ['AFL_CUSTOM_INFO_PROGRAM'])
+ # Process other configuration environment variables.
argv = None
try:
foo = os.environ['AFL_DEBUG']
@@ -58,15 +69,42 @@ def init(seed):
except KeyError:
pass
try:
- argv_list = os.environ['TRITON_DSE_TARGET_ARGV']
- argv = argv_list.split()
+ foo = os.environ['AFL_CUSTOM_INFO_OUT']
+ out_path = foo + '/../tritondse/queue'
except KeyError:
pass
try:
- foo = os.environ['TRITON_DSE_TARGET_INPUT']
+ foo = os.environ['AFL_CUSTOM_INFO_PROGRAM_INPUT']
input_file = foo
except KeyError:
pass
+ try:
+ argv_list = os.environ['AFL_CUSTOM_INFO_PROGRAM_ARGV']
+ argv_tmp = [ os.environ['AFL_CUSTOM_INFO_PROGRAM'] ]
+ argv_tmp += argv_list.split()
+ argv = []
+ # now check for @@
+ for item in argv_tmp:
+ if "@@" in item:
+ input_file = out_path + '/../.input'
+ argv.append(input_file)
+ else:
+ argv.append(item)
+ except KeyError:
+ pass
+ # Create the output directory
+ os.makedirs(out_path, exist_ok=True)
+ # Debug
+ if is_debug:
+ print('DEBUG target: ' + os.environ['AFL_CUSTOM_INFO_PROGRAM'])
+ if argv:
+ print('DEBUG argv: ')
+ print(argv)
+ if input_file:
+ print('DEBUG input_file: ' + input_file)
+ print('DEBUG out_path: ' + out_path)
+ print('')
+ # Now set up TritonDSE
config = Config(coverage_strategy = CoverageStrategy.PATH,
debug = is_debug,
pipe_stdout = is_debug,
@@ -79,8 +117,6 @@ def init(seed):
dse = SymbolicExplorator(config, prog)
# Add callbacks.
dse.callback_manager.register_pre_execution_callback(pre_exec_hook)
- # Create the output directory
- os.makedirs(out_path, exist_ok=True)
#def fuzz(buf, add_buf, max_size):
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index a1de479e..3f7e9e6e 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -304,6 +304,34 @@ Note: for some distributions, you might also need the package `python[3]-apt`.
In case your setup is different, set the necessary variables like this:
`PYTHON_INCLUDE=/path/to/python/include LDFLAGS=-L/path/to/python/lib make`.
+### Helpers
+
+For C/C++ custom mutators you get a pointer to `afl_state_t *afl` in the
+`afl_custom_init()` which contains all information that you need.
+Note that if you access it, you need to recompile your custom mutator if
+you update AFL++ because the structure might have changed!
+
+For mutators written in Python, Rust, GO, etc. there are a few environment
+variables set to help you to get started:
+
+`AFL_CUSTOM_INFO_PROGRAM` - the program name of the target that is executed.
+If your custom mutator is used with modes like Qemu (`-Q`), this will still
+contain the target program, not afl-qemu-trace.
+
+`AFL_CUSTOM_INFO_PROGRAM_INPUT` - if the `-f` parameter is used with afl-fuzz
+then this value is found in this environment variable.
+
+`AFL_CUSTOM_INFO_PROGRAM_ARGV` - this contains the parameters given to the
+target program and still has the `@@` identifier in there.
+
+Note: If `AFL_CUSTOM_INFO_PROGRAM_INPUT` is empty and `AFL_CUSTOM_INFO_PROGRAM_ARGV`
+is either empty or does not contain `@@` then the target gets the input via
+`stdin`.
+
+`AFL_CUSTOM_INFO_OUT` - This is the output directory for this fuzzer instance,
+so if `afl-fuzz` was called with `-o out -S foobar`, then this will be set to
+`out/foobar`.
+
### Custom Mutator Preparation
For C/C++ mutators, the source code must be compiled as a shared object:
diff --git a/include/envs.h b/include/envs.h
index fe5ee0e3..edfd06e4 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -37,6 +37,10 @@ static char *afl_environment_variables[] = {
"AFL_CRASH_EXITCODE",
"AFL_CUSTOM_MUTATOR_LIBRARY",
"AFL_CUSTOM_MUTATOR_ONLY",
+ "AFL_CUSTOM_INFO_PROGRAM",
+ "AFL_CUSTOM_INFO_PROGRAM_ARGV",
+ "AFL_CUSTOM_INFO_PROGRAM_INPUT",
+ "AFL_CUSTOM_INFO_OUT",
"AFL_CXX",
"AFL_CYCLE_SCHEDULES",
"AFL_DEBUG",
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index f982258f..4339ddd2 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1530,29 +1530,6 @@ int main(int argc, char **argv_orig, char **envp) {
}
- if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
-
- if (afl->custom_only) {
-
- FATAL("Custom mutators are incompatible with MOpt (-L)");
-
- }
-
- u32 custom_fuzz = 0;
- LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
-
- if (el->afl_custom_fuzz) { custom_fuzz = 1; }
-
- });
-
- if (custom_fuzz) {
-
- WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
-
- }
-
- }
-
if (afl->afl_env.afl_max_det_extras) {
s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
@@ -1827,8 +1804,76 @@ int main(int argc, char **argv_orig, char **envp) {
printf("DEBUG: rand %06d is %u\n", counter, rand_below(afl, 65536));
#endif
+ if (!getenv("AFL_CUSTOM_INFO_PROGRAM")) {
+
+ setenv("AFL_CUSTOM_INFO_PROGRAM", argv[optind], 1);
+
+ }
+
+ if (!getenv("AFL_CUSTOM_INFO_PROGRAM_INPUT") && afl->fsrv.out_file) {
+
+ setenv("AFL_CUSTOM_INFO_PROGRAM_INPUT", afl->fsrv.out_file, 1);
+
+ }
+
+ {
+
+ u8 envbuf[8096] = "", tmpbuf[8096] = "";
+ for (s32 i = optind + 1; i < argc; ++i) {
+
+ strcpy(tmpbuf, envbuf);
+ if (strchr(argv[i], ' ') && !strchr(argv[i], '"') &&
+ !strchr(argv[i], '\'')) {
+
+ if (!strchr(argv[i], '\'')) {
+
+ snprintf(envbuf, sizeof(tmpbuf), "%s '%s'", tmpbuf, argv[i]);
+
+ } else {
+
+ snprintf(envbuf, sizeof(tmpbuf), "%s \"%s\"", tmpbuf, argv[i]);
+
+ }
+
+ } else {
+
+ snprintf(envbuf, sizeof(tmpbuf), "%s %s", tmpbuf, argv[i]);
+
+ }
+
+ }
+
+ setenv("AFL_CUSTOM_INFO_PROGRAM_ARGV", envbuf + 1, 1);
+
+ }
+
+ setenv("AFL_CUSTOM_INFO_OUT", afl->out_dir, 1); // same as __AFL_OUT_DIR
+
setup_custom_mutators(afl);
+ if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
+
+ if (afl->custom_only) {
+
+ FATAL("Custom mutators are incompatible with MOpt (-L)");
+
+ }
+
+ u32 custom_fuzz = 0;
+ LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
+
+ if (el->afl_custom_fuzz) { custom_fuzz = 1; }
+
+ });
+
+ if (custom_fuzz) {
+
+ WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
+
+ }
+
+ }
+
write_setup_file(afl, argc, argv);
setup_cmdline_file(afl, argv + optind);
--
cgit 1.4.1
From eaf59d5a194f5e5469a86158aeb0e936111ad790 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 11 May 2023 07:55:17 +0200
Subject: next steps for tritondse
---
custom_mutators/aflpp_tritondse/aflpp_tritondse.py | 50 +++++++++++-----------
1 file changed, 26 insertions(+), 24 deletions(-)
diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
index 9584b368..e0219f0b 100644
--- a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
+++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
@@ -3,19 +3,17 @@ import os
import logging
import hashlib
+from tritondse import CleLoader
+from tritondse import CompositeData
from tritondse import Config
from tritondse import CoverageStrategy
from tritondse import ProcessState
from tritondse import Program
-from tritondse import CleLoader
from tritondse import Seed
from tritondse import SeedFormat
from tritondse import SymbolicExecutor
from tritondse import SymbolicExplorator
-
-#logging.basicConfig(level=logging.INFO)
-
is_debug = False
out_path = ""
input_file = None
@@ -25,13 +23,11 @@ dse = None
cycle = 0
count = 0
hashes = set()
+format = SeedFormat.RAW
def pre_exec_hook(se: SymbolicExecutor, state: ProcessState):
- #logging.info(f"[PRE-EXEC] Processing seed: {se.seed.hash}, \
- # ({repr(se.seed.content)})")
global count
global hashes
- print('DEBUG - prehook')
if se.seed.hash not in hashes:
hashes.add(se.seed.hash)
filename = out_path + "/id:" + f"{count:06}" + "," + se.seed.hash
@@ -39,26 +35,26 @@ def pre_exec_hook(se: SymbolicExecutor, state: ProcessState):
if is_debug:
print('Creating queue input ' + filename)
with open(filename, 'wb') as file:
- file.write(se.seed.content)
+ if input_file:
+ file.write(se.seed.content.files[input_file])
+ else:
+ file.write(se.seed.content)
count += 1
- else:
- print('has hash: ' + se.seed.hash)
- if input_file:
- if is_debug:
- print('Writing to ' + input_file + ' the content: ' + str(se.seed.content))
- with open(input_file, 'wb') as file:
- file.write(se.seed.content)
- else:
- print('no input!')
+ #if input_file:
+ # if is_debug:
+ # print('Writing to ' + input_file + ' the content: ' + str(se.seed.content))
+ # with open(input_file, 'wb') as file:
+ # file.write(se.seed.content)
def init(seed):
- global prog
global config
global dse
- global out_path
+ global format
global input_file
global is_debug
+ global out_path
+ global prog
# Load the program (LIEF-based program loader).
prog = CleLoader(os.environ['AFL_CUSTOM_INFO_PROGRAM'])
# Process other configuration environment variables.
@@ -104,6 +100,8 @@ def init(seed):
print('DEBUG input_file: ' + input_file)
print('DEBUG out_path: ' + out_path)
print('')
+ if input_file:
+ format = SeedFormat.COMPOSITE
# Now set up TritonDSE
config = Config(coverage_strategy = CoverageStrategy.PATH,
debug = is_debug,
@@ -112,7 +110,7 @@ def init(seed):
execution_timeout = 1,
program_argv = argv,
smt_timeout= 50,
- seed_format = SeedFormat.RAW)
+ seed_format = format)
# Create an instance of the Symbolic Explorator
dse = SymbolicExplorator(config, prog)
# Add callbacks.
@@ -124,18 +122,22 @@ def init(seed):
def queue_new_entry(filename_new_queue, filename_orig_queue):
- global dse
global cycle
+ global dse
# Add seed to the worklist.
with open(filename_new_queue, "rb") as file:
- seed = file.read()
- hash = hashlib.md5(seed).hexdigest()
+ data = file.read()
+ hash = hashlib.md5(data).hexdigest()
if hash not in hashes:
hashes.add(hash)
if is_debug:
print("NEW FILE " + filename_new_queue + " hash " + hash + " count " + str(cycle))
cycle += 1
- seed = Seed(seed)
+ if input_file:
+ seed = Seed(CompositeData(files={"stdin": b"", # nothing on stdin
+ input_file: data}))
+ else:
+ seed = Seed(data)
dse.add_input_seed(seed)
# Start exploration!
#dse.step()
--
cgit 1.4.1
From 3a98d7af18e6ebf12e7cce2eb78bdb9b9927be3e Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Thu, 11 May 2023 21:02:46 +0200
Subject: qemuafl: Persistent mode for PPC32 targets
---
docs/Changelog.md | 2 ++
qemu_mode/QEMUAFL_VERSION | 2 +-
qemu_mode/qemuafl | 2 +-
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index cd5ed9fc..1fe714e8 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,6 +18,8 @@
- add `-I filelist` option, an alternative to `-i in_dir`
- afl-cmin + afl-cmin.bash:
- `-T threads` parallel task support, can be a huge speedup!
+ - qemuafl:
+ - Persistent mode support for ppc32 tragets by @worksbutnottested
- a new grammar custom mutator atnwalk was submitted by @voidptr127 !
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index fa44d173..043a9f82 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-0569eff8a1
+b0abbe2
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index 0569eff8..b0abbe2e 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit 0569eff8a12dec73642b96757f6b5b51a618a03a
+Subproject commit b0abbe2e74ed74ff6ff25b5ea3110d27ba978001
--
cgit 1.4.1
From a752b159212db458d77cd13c46fdfbde01045d91 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 12 May 2023 08:29:31 +0200
Subject: update qemu_mode
---
docs/Changelog.md | 4 ++--
qemu_mode/QEMUAFL_VERSION | 2 +-
qemu_mode/qemuafl | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 1fe714e8..e85de763 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,8 +18,8 @@
- add `-I filelist` option, an alternative to `-i in_dir`
- afl-cmin + afl-cmin.bash:
- `-T threads` parallel task support, can be a huge speedup!
- - qemuafl:
- - Persistent mode support for ppc32 tragets by @worksbutnottested
+ - qemu_mode:
+ - Persistent mode +QASAN support for ppc32 tragets by @worksbutnottested
- a new grammar custom mutator atnwalk was submitted by @voidptr127 !
diff --git a/qemu_mode/QEMUAFL_VERSION b/qemu_mode/QEMUAFL_VERSION
index 043a9f82..44ea5345 100644
--- a/qemu_mode/QEMUAFL_VERSION
+++ b/qemu_mode/QEMUAFL_VERSION
@@ -1 +1 @@
-b0abbe2
+a1321713c7
diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl
index b0abbe2e..a1321713 160000
--- a/qemu_mode/qemuafl
+++ b/qemu_mode/qemuafl
@@ -1 +1 @@
-Subproject commit b0abbe2e74ed74ff6ff25b5ea3110d27ba978001
+Subproject commit a1321713c7502c152dd7527555e0f8a800d55225
--
cgit 1.4.1
From 93c821aaa3df0cf20f892ce72447ff022161c8ab Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 12 May 2023 08:39:11 +0200
Subject: afl-clang-lto incomptable with -flto=thin
---
docs/Changelog.md | 1 +
src/afl-cc.c | 9 +++++++++
2 files changed, 10 insertions(+)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index e85de763..799c13af 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -13,6 +13,7 @@
- afl-cc:
- new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM
(https://github.com/fgsect/WAFL) project
+ - error and print help if afl-clan-lto is used with lto=thin
- afl-showmap:
- added custom mutator post_process and send support
- add `-I filelist` option, an alternative to `-i in_dir`
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 19314555..13ca751e 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -853,6 +853,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
if (cur[0] != '-') { non_dash = 1; }
if (!strncmp(cur, "--afl", 5)) continue;
+
+ if (lto_mode && !strncmp(cur, "-flto=thin", 10)) {
+
+ FATAL(
+ "afl-clang-lto cannot work with -flto=thin. Switch to -flto=full or "
+ "use afl-clang-fast!");
+
+ }
+
if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
if (!strncmp(cur, "-fno-unroll", 11)) continue;
--
cgit 1.4.1
From 7f636dbfc247fbe75910fa8fb681ea55d230ba79 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 12 May 2023 15:58:20 +0200
Subject: add @responsefile support for afl-cc
---
docs/Changelog.md | 1 +
src/afl-cc.c | 460 +++++++++++++++++++++++++++++++++++-------------------
2 files changed, 300 insertions(+), 161 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 799c13af..3602af50 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -11,6 +11,7 @@
- new env `AFL_IGNORE_PROBLEMS_COVERAGE` to ignore coverage from
loaded libs after forkserver initialization (required by Mozilla)
- afl-cc:
+ - added @responsefile support
- new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM
(https://github.com/fgsect/WAFL) project
- error and print help if afl-clan-lto is used with lto=thin
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 13ca751e..972ac8cd 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -31,6 +31,8 @@
#include
#include
#include
+#include
+#include
#if (LLVM_MAJOR - 0 == 0)
#undef LLVM_MAJOR
@@ -376,15 +378,304 @@ void parse_fsanitize(char *string) {
}
+static u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0,
+ shared_linking = 0, preprocessor_only = 0, have_unroll = 0,
+ have_o = 0, have_pic = 0, have_c = 0, partial_linking = 0,
+ non_dash = 0;
+
+static void process_params(u32 argc, char **argv) {
+
+ if (cc_par_cnt + argc >= 1024) { FATAL("Too many command line parameters"); }
+
+ if (lto_mode && argc > 1) {
+
+ u32 idx;
+ for (idx = 1; idx < argc; idx++) {
+
+ if (!strncasecmp(argv[idx], "-fpic", 5)) have_pic = 1;
+
+ }
+
+ }
+
+ // for (u32 x = 0; x < argc; ++x) fprintf(stderr, "[%u] %s\n", x, argv[x]);
+
+ /* Process the argument list. */
+
+ u8 skip_next = 0;
+ while (--argc) {
+
+ u8 *cur = *(++argv);
+
+ if (skip_next) {
+
+ skip_next = 0;
+ continue;
+
+ }
+
+ if (cur[0] != '-') { non_dash = 1; }
+ if (!strncmp(cur, "--afl", 5)) continue;
+
+ if (lto_mode && !strncmp(cur, "-flto=thin", 10)) {
+
+ FATAL(
+ "afl-clang-lto cannot work with -flto=thin. Switch to -flto=full or "
+ "use afl-clang-fast!");
+
+ }
+
+ if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
+ if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
+ if (!strncmp(cur, "-fno-unroll", 11)) continue;
+ if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue;
+ if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") ||
+ !strcmp(cur, "--no-undefined")) {
+
+ continue;
+
+ }
+
+ if (compiler_mode == GCC_PLUGIN && !strcmp(cur, "-pipe")) { continue; }
+
+ if (!strcmp(cur, "-z") || !strcmp(cur, "-Wl,-z")) {
+
+ u8 *param = *(argv + 1);
+ if (!strcmp(param, "defs") || !strcmp(param, "-Wl,defs")) {
+
+ skip_next = 1;
+ continue;
+
+ }
+
+ }
+
+ if ((compiler_mode == GCC || compiler_mode == GCC_PLUGIN) &&
+ !strncmp(cur, "-stdlib=", 8)) {
+
+ if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
+ continue;
+
+ }
+
+ if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) {
+
+ have_instr_list = 1;
+
+ }
+
+ if (!strncmp(cur, "-fsanitize=", strlen("-fsanitize=")) &&
+ strchr(cur, ',')) {
+
+ parse_fsanitize(cur);
+ if (!cur || strlen(cur) <= strlen("-fsanitize=")) { continue; }
+
+ } else if ((!strncmp(cur, "-fsanitize=fuzzer-",
+
+ strlen("-fsanitize=fuzzer-")) ||
+ !strncmp(cur, "-fsanitize-coverage",
+ strlen("-fsanitize-coverage"))) &&
+ (strncmp(cur, "sanitize-coverage-allow",
+ strlen("sanitize-coverage-allow")) &&
+ strncmp(cur, "sanitize-coverage-deny",
+ strlen("sanitize-coverage-deny")) &&
+ instrument_mode != INSTRUMENT_LLVMNATIVE)) {
+
+ if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
+ continue;
+
+ }
+
+ if (need_aflpplib || !strcmp(cur, "-fsanitize=fuzzer")) {
+
+ u8 *afllib = find_object("libAFLDriver.a", argv[0]);
+
+ if (!be_quiet) {
+
+ OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
+
+ }
+
+ if (!afllib) {
+
+ if (!be_quiet) {
+
+ WARNF(
+ "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
+ "the flags - this will fail!");
+
+ }
+
+ } else {
+
+ cc_params[cc_par_cnt++] = afllib;
+
+#ifdef __APPLE__
+ cc_params[cc_par_cnt++] = "-undefined";
+ cc_params[cc_par_cnt++] = "dynamic_lookup";
+#endif
+
+ }
+
+ if (need_aflpplib) {
+
+ need_aflpplib = 0;
+
+ } else {
+
+ continue;
+
+ }
+
+ }
+
+ if (!strcmp(cur, "-m32")) bit_mode = 32;
+ if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32;
+ if (!strcmp(cur, "-m64")) bit_mode = 64;
+
+ if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
+ asan_set = 1;
+
+ if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
+
+ if (!strcmp(cur, "-x")) x_set = 1;
+ if (!strcmp(cur, "-E")) preprocessor_only = 1;
+ if (!strcmp(cur, "-shared")) shared_linking = 1;
+ if (!strcmp(cur, "-dynamiclib")) shared_linking = 1;
+ if (!strcmp(cur, "--target=wasm32-wasi")) passthrough = 1;
+ if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
+ if (!strcmp(cur, "-Wl,-i")) partial_linking = 1;
+ if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1;
+ if (!strcmp(cur, "-r")) partial_linking = 1;
+ if (!strcmp(cur, "--relocatable")) partial_linking = 1;
+ if (!strcmp(cur, "-c")) have_c = 1;
+
+ if (!strncmp(cur, "-O", 2)) have_o = 1;
+ if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1;
+
+ if (*cur == '@') {
+
+ // response file support.
+ // we have two choices - move everything to the command line or
+ // rewrite the response files to temporary files and delete them
+ // afterwards. We choose the first for easiness.
+ // We do *not* support quotes in the rsp files to cope with spaces in
+ // filenames etc! If you need that then send a patch!
+ u8 *filename = cur + 1;
+ if (debug) { DEBUGF("response file=%s\n", filename); }
+ FILE *f = fopen(filename, "r");
+ struct stat st;
+
+ // Check not found or empty? let the compiler complain if so.
+ if (!f || fstat(fileno(f), &st) < 0 || st.st_size < 1) {
+
+ cc_params[cc_par_cnt++] = cur;
+ continue;
+
+ }
+
+ u8 *tmpbuf = malloc(st.st_size + 1), *ptr;
+ char **args = malloc(sizeof(char *) * (st.st_size >> 1));
+ int count = 1, cont = 0, cont_act = 0;
+
+ while (fgets(tmpbuf, st.st_size, f)) {
+
+ ptr = tmpbuf;
+ // no leading whitespace
+ while (isspace(*ptr)) {
+
+ ++ptr;
+ cont_act = 0;
+
+ }
+
+ // no comments, no empty lines
+ if (*ptr == '#' || *ptr == '\n' || !*ptr) { continue; }
+ // remove LF
+ if (ptr[strlen(ptr) - 1] == '\n') { ptr[strlen(ptr) - 1] = 0; }
+ // remove CR
+ if (*ptr && ptr[strlen(ptr) - 1] == '\r') { ptr[strlen(ptr) - 1] = 0; }
+ // handle \ at end of line
+ if (*ptr && ptr[strlen(ptr) - 1] == '\\') {
+
+ cont = 1;
+ ptr[strlen(ptr) - 1] = 0;
+
+ }
+
+ // remove whitespace at end
+ while (*ptr && isspace(ptr[strlen(ptr) - 1])) {
+
+ ptr[strlen(ptr) - 1] = 0;
+ cont = 0;
+
+ }
+
+ if (*ptr) {
+
+ do {
+
+ u8 *value = ptr;
+ while (*ptr && !isspace(*ptr)) {
+
+ ++ptr;
+
+ }
+
+ while (*ptr && isspace(*ptr)) {
+
+ *ptr++ = 0;
+
+ }
+
+ if (cont_act) {
+
+ u32 len = strlen(args[count - 1]) + strlen(value) + 1;
+ u8 *tmp = malloc(len);
+ snprintf(tmp, len, "%s%s", args[count - 1], value);
+ free(args[count - 1]);
+ args[count - 1] = tmp;
+ cont_act = 0;
+
+ } else {
+
+ args[count++] = strdup(value);
+
+ }
+
+ } while (*ptr);
+
+ }
+
+ if (cont) {
+
+ cont_act = 1;
+ cont = 0;
+
+ }
+
+ }
+
+ if (count) { process_params(count, args); }
+
+ // we cannot free args[]
+ free(tmpbuf);
+
+ continue;
+
+ }
+
+ cc_params[cc_par_cnt++] = cur;
+
+ }
+
+}
+
/* Copy argv to cc_params, making the necessary edits. */
static void edit_params(u32 argc, char **argv, char **envp) {
- u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0, shared_linking = 0,
- preprocessor_only = 0, have_unroll = 0, have_o = 0, have_pic = 0,
- have_c = 0, partial_linking = 0;
-
- cc_params = ck_alloc((argc + 128) * sizeof(u8 *));
+ cc_params = ck_alloc(1024 * sizeof(u8 *));
if (lto_mode) {
@@ -831,168 +1122,15 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- if (!have_pic) cc_params[cc_par_cnt++] = "-fPIC";
-
}
}
- /* Detect stray -v calls from ./configure scripts. */
-
- u8 skip_next = 0, non_dash = 0;
- while (--argc) {
-
- u8 *cur = *(++argv);
-
- if (skip_next) {
-
- skip_next = 0;
- continue;
-
- }
-
- if (cur[0] != '-') { non_dash = 1; }
- if (!strncmp(cur, "--afl", 5)) continue;
-
- if (lto_mode && !strncmp(cur, "-flto=thin", 10)) {
-
- FATAL(
- "afl-clang-lto cannot work with -flto=thin. Switch to -flto=full or "
- "use afl-clang-fast!");
-
- }
-
- if (lto_mode && !strncmp(cur, "-fuse-ld=", 9)) continue;
- if (lto_mode && !strncmp(cur, "--ld-path=", 10)) continue;
- if (!strncmp(cur, "-fno-unroll", 11)) continue;
- if (strstr(cur, "afl-compiler-rt") || strstr(cur, "afl-llvm-rt")) continue;
- if (!strcmp(cur, "-Wl,-z,defs") || !strcmp(cur, "-Wl,--no-undefined") ||
- !strcmp(cur, "--no-undefined")) {
-
- continue;
-
- }
+ /* Inspect the command line parameters. */
- if (compiler_mode == GCC_PLUGIN && !strcmp(cur, "-pipe")) { continue; }
-
- if (!strcmp(cur, "-z") || !strcmp(cur, "-Wl,-z")) {
+ process_params(argc, argv);
- u8 *param = *(argv + 1);
- if (!strcmp(param, "defs") || !strcmp(param, "-Wl,defs")) {
-
- skip_next = 1;
- continue;
-
- }
-
- }
-
- if ((compiler_mode == GCC || compiler_mode == GCC_PLUGIN) &&
- !strncmp(cur, "-stdlib=", 8)) {
-
- if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
- continue;
-
- }
-
- if (!strncmp(cur, "-fsanitize-coverage-", 20) && strstr(cur, "list=")) {
-
- have_instr_list = 1;
-
- }
-
- if (!strncmp(cur, "-fsanitize=", strlen("-fsanitize=")) &&
- strchr(cur, ',')) {
-
- parse_fsanitize(cur);
- if (!cur || strlen(cur) <= strlen("-fsanitize=")) { continue; }
-
- } else if ((!strncmp(cur, "-fsanitize=fuzzer-",
-
- strlen("-fsanitize=fuzzer-")) ||
- !strncmp(cur, "-fsanitize-coverage",
- strlen("-fsanitize-coverage"))) &&
- (strncmp(cur, "sanitize-coverage-allow",
- strlen("sanitize-coverage-allow")) &&
- strncmp(cur, "sanitize-coverage-deny",
- strlen("sanitize-coverage-deny")) &&
- instrument_mode != INSTRUMENT_LLVMNATIVE)) {
-
- if (!be_quiet) { WARNF("Found '%s' - stripping!", cur); }
- continue;
-
- }
-
- if (need_aflpplib || !strcmp(cur, "-fsanitize=fuzzer")) {
-
- u8 *afllib = find_object("libAFLDriver.a", argv[0]);
-
- if (!be_quiet) {
-
- OKF("Found '-fsanitize=fuzzer', replacing with libAFLDriver.a");
-
- }
-
- if (!afllib) {
-
- if (!be_quiet) {
-
- WARNF(
- "Cannot find 'libAFLDriver.a' to replace '-fsanitize=fuzzer' in "
- "the flags - this will fail!");
-
- }
-
- } else {
-
- cc_params[cc_par_cnt++] = afllib;
-
-#ifdef __APPLE__
- cc_params[cc_par_cnt++] = "-undefined";
- cc_params[cc_par_cnt++] = "dynamic_lookup";
-#endif
-
- }
-
- if (need_aflpplib) {
-
- need_aflpplib = 0;
-
- } else {
-
- continue;
-
- }
-
- }
-
- if (!strcmp(cur, "-m32")) bit_mode = 32;
- if (!strcmp(cur, "armv7a-linux-androideabi")) bit_mode = 32;
- if (!strcmp(cur, "-m64")) bit_mode = 64;
-
- if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
- asan_set = 1;
-
- if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
-
- if (!strcmp(cur, "-x")) x_set = 1;
- if (!strcmp(cur, "-E")) preprocessor_only = 1;
- if (!strcmp(cur, "-shared")) shared_linking = 1;
- if (!strcmp(cur, "-dynamiclib")) shared_linking = 1;
- if (!strcmp(cur, "--target=wasm32-wasi")) passthrough = 1;
- if (!strcmp(cur, "-Wl,-r")) partial_linking = 1;
- if (!strcmp(cur, "-Wl,-i")) partial_linking = 1;
- if (!strcmp(cur, "-Wl,--relocatable")) partial_linking = 1;
- if (!strcmp(cur, "-r")) partial_linking = 1;
- if (!strcmp(cur, "--relocatable")) partial_linking = 1;
- if (!strcmp(cur, "-c")) have_c = 1;
-
- if (!strncmp(cur, "-O", 2)) have_o = 1;
- if (!strncmp(cur, "-funroll-loop", 13)) have_unroll = 1;
-
- cc_params[cc_par_cnt++] = cur;
-
- }
+ if (!have_pic) { cc_params[cc_par_cnt++] = "-fPIC"; }
// in case LLVM is installed not via a package manager or "make install"
// e.g. compiled download or compiled from github then its ./lib directory
--
cgit 1.4.1
From d1ec5dc089ff29e596083a90fa64dcd77060e6bc Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 15 May 2023 15:11:16 +0200
Subject: standalone mutator
---
custom_mutators/aflpp/standalone/Makefile | 10 ++
custom_mutators/aflpp/standalone/README.md | 10 ++
.../aflpp/standalone/aflpp-standalone.c | 167 +++++++++++++++++++++
3 files changed, 187 insertions(+)
create mode 100644 custom_mutators/aflpp/standalone/Makefile
create mode 100644 custom_mutators/aflpp/standalone/README.md
create mode 100644 custom_mutators/aflpp/standalone/aflpp-standalone.c
diff --git a/custom_mutators/aflpp/standalone/Makefile b/custom_mutators/aflpp/standalone/Makefile
new file mode 100644
index 00000000..f1e99445
--- /dev/null
+++ b/custom_mutators/aflpp/standalone/Makefile
@@ -0,0 +1,10 @@
+
+CFLAGS = -O3 -funroll-loops -fPIC
+
+all: aflpp-standalone
+
+aflpp-standalone: aflpp-standalone.c
+ $(CC) $(CFLAGS) -I../../../include -I. -o aflpp-standalone aflpp-standalone.c ../../../src/afl-performance.c
+
+clean:
+ rm -f *.o *~ aflpp-standalone core
diff --git a/custom_mutators/aflpp/standalone/README.md b/custom_mutators/aflpp/standalone/README.md
new file mode 100644
index 00000000..f5f94c5f
--- /dev/null
+++ b/custom_mutators/aflpp/standalone/README.md
@@ -0,0 +1,10 @@
+# AFL++ standalone mutator
+
+this is the AFL++ havoc mutator as a standalone mutator
+
+just type `make` to build.
+
+```
+aflpp-standalone inputfile outputfile
+```
+
diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c
new file mode 100644
index 00000000..337b7937
--- /dev/null
+++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c
@@ -0,0 +1,167 @@
+#include "afl-mutations.h"
+
+s8 interesting_8[] = {INTERESTING_8};
+s16 interesting_16[] = {INTERESTING_8, INTERESTING_16};
+s32 interesting_32[] = {INTERESTING_8, INTERESTING_16, INTERESTING_32};
+
+typedef struct my_mutator {
+
+ afl_state_t *afl;
+ u8 *buf;
+ u32 buf_size;
+
+} my_mutator_t;
+
+my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
+
+ (void)seed;
+
+ my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
+ if (!data) {
+
+ perror("afl_custom_init alloc");
+ return NULL;
+
+ }
+
+ if ((data->buf = malloc(1024*1024)) == NULL) {
+
+ perror("afl_custom_init alloc");
+ return NULL;
+
+ } else {
+
+ data->buf_size = 1024*1024;
+
+ }
+
+ /* fake AFL++ state */
+ data->afl = calloc(1, sizeof(afl_state_t));
+ data->afl->queue_cycle = 1;
+ data->afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
+ rand_set_seed(data->afl, getpid());
+
+ return data;
+
+}
+
+/* here we run the AFL++ mutator, which is the best! */
+
+size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
+ u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
+ size_t max_size) {
+
+ if (max_size > data->buf_size) {
+
+ u8 *ptr = realloc(data->buf, max_size);
+
+ if (ptr) {
+
+ return 0;
+
+ } else {
+
+ data->buf = ptr;
+ data->buf_size = max_size;
+
+ }
+
+ }
+
+ u32 havoc_steps = 1 + rand_below(data->afl, 16);
+
+ /* set everything up, costly ... :( */
+ memcpy(data->buf, buf, buf_size);
+
+ /* the mutation */
+ u32 out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps,
+ false, true, add_buf, add_buf_size, max_size);
+
+ /* return size of mutated data */
+ *out_buf = data->buf;
+ return out_buf_len;
+
+}
+
+int main(int argc, char *argv[]) {
+
+ if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) {
+
+ printf("Syntax: $0 [-v] [inputfile [outputfile [splicefile]]]\n\n", argv[0]);
+ printf("Reads a testcase from stdin when no input file (or '-') is specified,\n");
+ printf("mutates according to AFL++'s mutation engine, and write to stdout when '-' or\n");
+ printf("no output filename is given. As an optional third parameter you can give a file\n");
+ printf("for splicing. Maximum input and output length is 1MB.\n");
+ printf("The -v verbose option prints debug output to stderr\n");
+ return 0;
+
+ }
+
+ FILE *in = stdin, *out = stdout, *splice = NULL;
+ unsigned char *inbuf = malloc(1024 * 1024), *outbuf, *splicebuf = NULL;
+ int verbose = 0, splicelen = 0;
+
+ if (argc > 1 && strcmp(argv[1], "-v") == 0) {
+ verbose = 1;
+ argc--;
+ argv++;
+ fprintf(stderr, "Verbose active\n");
+ }
+
+ my_mutator_t *data = afl_custom_init(NULL, 0);
+
+ if (argc > 1 && strcmp(argv[1], "-") != 0) {
+ if ((in = fopen(argv[1], "r")) == NULL) {
+ perror(argv[1]);
+ return -1;
+ }
+ if (verbose) fprintf(stderr, "Input: %s\n", argv[1]);
+ }
+
+ size_t inlen = fread(inbuf, 1, 1024*1024, in);
+
+ if (!inlen) {
+ fprintf(stderr, "Error: empty file %s\n", argv[1] ? argv[1] : "stdin");
+ return -1;
+ }
+
+ if (argc > 2 && strcmp(argv[2], "-") != 0) {
+ if ((out = fopen(argv[2], "w")) == NULL) {
+ perror(argv[2]);
+ return -1;
+ }
+ if (verbose) fprintf(stderr, "Output: %s\n", argv[2]);
+ }
+
+ if (argc > 3) {
+ if ((splice = fopen(argv[3], "r")) == NULL) {
+ perror(argv[3]);
+ return -1;
+ }
+ if (verbose) fprintf(stderr, "Splice: %s\n", argv[3]);
+ splicebuf = malloc(1024*1024);
+ size_t splicelen = fread(splicebuf, 1, 1024*1024, splice);
+ if (!splicelen) {
+ fprintf(stderr, "Error: empty file %s\n", argv[3]);
+ return -1;
+ }
+ if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen);
+ }
+
+ if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen);
+ unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf, splicelen, 1024*1024);
+
+ if (outlen == 0 || !outbuf) {
+ fprintf(stderr, "Error: no mutation data returned.\n");
+ return -1;
+ }
+
+ if (verbose) fprintf(stderr, "Mutation output length: %zu\n", outlen);
+
+ if (fwrite(outbuf, 1, outlen, out) != outlen) {
+ fprintf(stderr, "Warning: incomplete write.\n");
+ return -1;
+ }
+
+ return 0;
+}
--
cgit 1.4.1
From ab148aeed81d755399e257c0c17fe4cbb9be3d48 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 15 May 2023 15:12:26 +0200
Subject: standalone mutator
---
custom_mutators/aflpp/standalone/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/custom_mutators/aflpp/standalone/README.md b/custom_mutators/aflpp/standalone/README.md
index f5f94c5f..a1ffb5f9 100644
--- a/custom_mutators/aflpp/standalone/README.md
+++ b/custom_mutators/aflpp/standalone/README.md
@@ -5,6 +5,6 @@ this is the AFL++ havoc mutator as a standalone mutator
just type `make` to build.
```
-aflpp-standalone inputfile outputfile
+aflpp-standalone inputfile outputfile [splicefile]
```
--
cgit 1.4.1
From 9a55bbdb44c1508a0b08728db2dacaebc9c43277 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 15 May 2023 15:17:33 +0200
Subject: fix
---
custom_mutators/aflpp/standalone/aflpp-standalone.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c
index 337b7937..91bac4a8 100644
--- a/custom_mutators/aflpp/standalone/aflpp-standalone.c
+++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c
@@ -86,15 +86,13 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
int main(int argc, char *argv[]) {
if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) {
-
- printf("Syntax: $0 [-v] [inputfile [outputfile [splicefile]]]\n\n", argv[0]);
+ printf("Syntax: %s [-v] [inputfile [outputfile [splicefile]]]\n\n", argv[0]);
printf("Reads a testcase from stdin when no input file (or '-') is specified,\n");
printf("mutates according to AFL++'s mutation engine, and write to stdout when '-' or\n");
printf("no output filename is given. As an optional third parameter you can give a file\n");
printf("for splicing. Maximum input and output length is 1MB.\n");
- printf("The -v verbose option prints debug output to stderr\n");
+ printf("The -v verbose option prints debug output to stderr.\n");
return 0;
-
}
FILE *in = stdin, *out = stdout, *splice = NULL;
--
cgit 1.4.1
From 6d23df2c7c5246eb2e3da393b99a9c06bac972c1 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 15 May 2023 17:13:20 +0200
Subject: add target_intelligence
---
utils/target_intelligence/README.md | 61 +++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
create mode 100644 utils/target_intelligence/README.md
diff --git a/utils/target_intelligence/README.md b/utils/target_intelligence/README.md
new file mode 100644
index 00000000..086c9e20
--- /dev/null
+++ b/utils/target_intelligence/README.md
@@ -0,0 +1,61 @@
+# Target Intelligence
+
+These are some ideas you can do so that your target that you are fuzzing can
+give helpful feedback to AFL++.
+
+## Add to the AFL++ dictionary from your target
+
+For this you target must be compiled for CMPLOG (`AFL_LLVM_CMPLOG=1`).
+
+Add in your source code:
+
+```
+__attribute__((weak)) void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len);
+__attribute__((weak)) void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2, uint8_t attr);
+__attribute__((weak)) void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2, uint8_t attr);
+__attribute__((weak)) void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2, uint8_t attr);
+__attribute__((weak)) void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2, uint8_t attr);
+
+int in_your_function(...) {
+
+ // to add two strings to the AFL++ dictionary:
+ if (__cmplog_rtn_hook_strn)
+ __cmplog_rtn_hook_strn(string1, length_of_string1, string2, length_of_string2);
+
+ // to add two 32 bit integers to the AFL++ dictionary:
+ if (__cmplog_ins_hook4)
+ __cmplog_ins_hook4(first_32_bit_var, second_32_bit_var, 0);
+
+}
+```
+
+Note that this only makes sense if these values are in-depth processed in the
+target in a way that AFL++ CMPLOG cannot uncover these, e.g. if these values
+are transformed by a matrix computation.
+
+Fixed values are always better to give to afl-fuzz via a `-x dictionary`.
+
+## Add inputs to AFL++ dictionary from your target
+
+If for whatever reason you want your target to propose new inputs to AFL++,
+then this is actually very easy.
+The environment variable `AFL_CUSTOM_INFO_OUT` contains the output directory
+of this run - including the fuzzer instance name (e.g. `default`), so if you
+run `afl-fuzz -o out -S foobar`, the value would be `out/foobar`).
+
+To show afl-fuzz an input it should consider just do the following:
+
+1. create the directory `$AFL_CUSTOM_INFO_OUT/../target/queue`
+2. create any new inputs you want afl-fuzz to notice in that directory with the
+ following naming convention: `id:NUMBER-OF-LENGTH-SIX-WITH-LEADING-ZEROES,whatever`
+ where that number has to be increasing.
+ e.g.:
+```
+ id:000000,first_file
+ id:000001,second_file
+ id:000002,third_file
+ etc.
+```
+
+Note that this will not work in nyx_mode because afl-fuzz cannot see inside the
+virtual machine.
--
cgit 1.4.1
From 1ad63a6a32d966f1ac05ff40163ef7f747011307 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 16 May 2023 12:20:58 +0200
Subject: fix tritondse
---
custom_mutators/aflpp_tritondse/aflpp_tritondse.py | 68 +++++++++++++++++++++-
1 file changed, 65 insertions(+), 3 deletions(-)
diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
index e0219f0b..48367bc7 100644
--- a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
+++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
@@ -22,14 +22,17 @@ config = None
dse = None
cycle = 0
count = 0
+finding = 0
hashes = set()
format = SeedFormat.RAW
def pre_exec_hook(se: SymbolicExecutor, state: ProcessState):
global count
global hashes
+ global finding
if se.seed.hash not in hashes:
hashes.add(se.seed.hash)
+ finding = 1
filename = out_path + "/id:" + f"{count:06}" + "," + se.seed.hash
if not os.path.exists(filename):
if is_debug:
@@ -47,6 +50,59 @@ def pre_exec_hook(se: SymbolicExecutor, state: ProcessState):
# file.write(se.seed.content)
+#def rtn_open(se: SymbolicExecutor, pstate: ProcessState, pc):
+# """
+# The open behavior.
+# """
+# logging.debug('open hooked')
+#
+# # Get arguments
+# arg0 = pstate.get_argument_value(0) # const char *pathname
+# flags = pstate.get_argument_value(1) # int flags
+# mode = pstate.get_argument_value(2) # int mode
+# arg0s = pstate.memory.read_string(arg0)
+#
+# # Concretize the whole path name
+# pstate.concretize_memory_bytes(arg0, len(arg0s)+1) # Concretize the whole string + \0
+#
+# # We use flags as concrete value
+# pstate.concretize_argument(1)
+#
+# # Use the flags to open the file in the write mode.
+# mode = ""
+# if (flags & 0xFF) == 0x00: # O_RDONLY
+# mode = "r"
+# elif (flags & 0xFF) == 0x01: # O_WRONLY
+# mode = "w"
+# elif (flags & 0xFF) == 0x02: # O_RDWR
+# mode = "r+"
+#
+# if (flags & 0x0100): # O_CREAT
+# mode += "x"
+# if (flags & 0x0200): # O_APPEND
+# mode = "a" # replace completely value
+#
+# if se.seed.is_file_defined(arg0s) and "r" in mode: # input file and opened in reading
+# logging.info(f"opening an input file: {arg0s}")
+# # Program is opening an input
+# data = se.seed.get_file_input(arg0s)
+# filedesc = pstate.create_file_descriptor(arg0s, io.BytesIO(data))
+# fd = filedesc.id
+# else:
+# # Try to open it as a regular file
+# try:
+# fd = open(arg0s, mode) # use the mode here
+# filedesc = pstate.create_file_descriptor(arg0s, fd)
+# fd = filedesc.id
+# except Exception as e:
+# logging.debug(f"Failed to open {arg0s} {e}")
+# fd = pstate.minus_one
+#
+# pstate.write_register("rax", fd) # write the return value
+# pstate.cpu.program_counter = pstate.pop_stack_value() # pop the return value
+# se.skip_instruction() # skip the current instruction so that the engine go straight fetching the next instruction
+
+
def init(seed):
global config
global dse
@@ -115,10 +171,16 @@ def init(seed):
dse = SymbolicExplorator(config, prog)
# Add callbacks.
dse.callback_manager.register_pre_execution_callback(pre_exec_hook)
+ #dse.callback_manager.register_function_callback("open", rtn_open)
-#def fuzz(buf, add_buf, max_size):
-# return b""
+def fuzz(buf, add_buf, max_size):
+ global finding
+ finding = 1
+ while finding == 1:
+ finding = 0
+ dse.step()
+ return b""
def queue_new_entry(filename_new_queue, filename_orig_queue):
@@ -141,7 +203,7 @@ def queue_new_entry(filename_new_queue, filename_orig_queue):
dse.add_input_seed(seed)
# Start exploration!
#dse.step()
- dse.explore()
+ #dse.explore()
pass
def splice_optout():
--
cgit 1.4.1
From 49997e60cba8dc260d45cc0ce68fa810588e2f23 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 16 May 2023 12:33:58 +0200
Subject: fix
---
custom_mutators/aflpp_tritondse/aflpp_tritondse.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
index 48367bc7..cef28f34 100644
--- a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
+++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
@@ -206,5 +206,11 @@ def queue_new_entry(filename_new_queue, filename_orig_queue):
#dse.explore()
pass
+
+# we simulate just doing one single fuzz in the custom mutator
+def fuzz_count(buf):
+ return 1
+
+
def splice_optout():
pass
--
cgit 1.4.1
From dfdc6fd12cdae1fe2dab1183f20d3c312a7f2f6d Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 16 May 2023 14:54:02 +0200
Subject: add missing envs in the docs
---
docs/env_variables.md | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/docs/env_variables.md b/docs/env_variables.md
index b1f23159..0f0869d2 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -619,6 +619,14 @@ The QEMU wrapper used to instrument binary-only code supports several settings:
- Setting `AFL_INST_LIBS` causes the translator to also instrument the code
inside any dynamically linked libraries (notably including glibc).
+ - You can use `AFL_QEMU_INST_RANGES=0xaaaa-0xbbbb,0xcccc-0xdddd` to just
+ instrument specific memory locations, e.g. a specific library.
+ Excluding ranges takes priority over any included ranges or `AFL_INST_LIBS`.
+
+ - You can use `AFL_QEMU_EXCLUDE_RANGES=0xaaaa-0xbbbb,0xcccc-0xdddd` to **NOT**
+ instrument specific memory locations, e.g. a specific library.
+ Excluding ranges takes priority over any included ranges or `AFL_INST_LIBS`.
+
- It is possible to set `AFL_INST_RATIO` to skip the instrumentation on some
of the basic blocks, which can be useful when dealing with very complex
binaries.
--
cgit 1.4.1
From 1d0694df86a3ce70ffac2846f36605eac9300abe Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 17 May 2023 15:25:26 +0200
Subject: add symqemu custom mutator
---
custom_mutators/symcc/README.md | 2 +
custom_mutators/symqemu/Makefile | 14 ++
custom_mutators/symqemu/README.md | 11 +
custom_mutators/symqemu/symqemu.c | 446 ++++++++++++++++++++++++++++++++++++++
docs/Changelog.md | 3 +
instrumentation/afl-llvm-common.h | 2 +-
test-instr.c | 9 +-
7 files changed, 483 insertions(+), 4 deletions(-)
create mode 100644 custom_mutators/symqemu/Makefile
create mode 100644 custom_mutators/symqemu/README.md
create mode 100644 custom_mutators/symqemu/symqemu.c
diff --git a/custom_mutators/symcc/README.md b/custom_mutators/symcc/README.md
index 364a348e..a6839a37 100644
--- a/custom_mutators/symcc/README.md
+++ b/custom_mutators/symcc/README.md
@@ -5,6 +5,8 @@ This uses the symcc to find new paths into the target.
Note that this is a just a proof of concept example! It is better to use
the fuzzing helpers of symcc, symqemu, Fuzzolic, etc. rather than this.
+Also the symqemu custom mutator is better than this.
+
To use this custom mutator follow the steps in the symcc repository
[https://github.com/eurecom-s3/symcc/](https://github.com/eurecom-s3/symcc/)
on how to build symcc and how to instrument a target binary (the same target
diff --git a/custom_mutators/symqemu/Makefile b/custom_mutators/symqemu/Makefile
new file mode 100644
index 00000000..3361ab0f
--- /dev/null
+++ b/custom_mutators/symqemu/Makefile
@@ -0,0 +1,14 @@
+
+ifdef DEBUG
+ CFLAGS += -DDEBUG
+endif
+
+all: symqemu-mutator.so
+
+CFLAGS += -O3 -funroll-loops
+
+symqemu-mutator.so: symqemu.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -g -I../../include -shared -fPIC -o symqemu-mutator.so symqemu.c
+
+clean:
+ rm -f symqemu-mutator.so *.o *~ core
diff --git a/custom_mutators/symqemu/README.md b/custom_mutators/symqemu/README.md
new file mode 100644
index 00000000..0d5cd4d7
--- /dev/null
+++ b/custom_mutators/symqemu/README.md
@@ -0,0 +1,11 @@
+# custum mutator: symqemu
+
+This uses the symcc to find new paths into the target.
+
+To use this custom mutator follow the steps in the symqemu repository
+[https://github.com/eurecom-s3/symqemu/](https://github.com/eurecom-s3/symqemu/)
+on how to build symqemu-x86_x64 and put it in your `PATH`.
+
+just type `make` to build this custom mutator.
+
+```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/symqemu/symqemu-mutator.so AFL_SYNC_TIME=1 afl-fuzz ...```
diff --git a/custom_mutators/symqemu/symqemu.c b/custom_mutators/symqemu/symqemu.c
new file mode 100644
index 00000000..9030397b
--- /dev/null
+++ b/custom_mutators/symqemu/symqemu.c
@@ -0,0 +1,446 @@
+#define _GNU_SOURCE
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "config.h"
+#include "debug.h"
+#include "afl-fuzz.h"
+#include "common.h"
+
+afl_state_t *afl_struct;
+static u32 debug = 0;
+
+#define DBG(x...) \
+ if (debug) { fprintf(stderr, x); }
+
+typedef struct my_mutator {
+
+ afl_state_t *afl;
+ u8 *mutator_buf;
+ u8 *out_dir;
+ u8 *queue_dir;
+ u8 *target;
+ u8 *symqemu;
+ u8 *input_file;
+ u32 counter;
+ u32 seed;
+ u32 argc;
+ u8 **argv;
+
+} my_mutator_t;
+
+my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
+
+ if (getenv("AFL_DEBUG")) debug = 1;
+
+ my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
+ if (!data) {
+
+ perror("afl_custom_init alloc");
+ return NULL;
+
+ }
+
+ char *path = getenv("PATH");
+ char *exec_name = "symqemu-x86_64";
+ char *token = strtok(path, ":");
+ char exec_path[4096];
+
+ while (token != NULL && data->symqemu == NULL) {
+
+ snprintf(exec_path, sizeof(exec_path), "%s/%s", token, exec_name);
+ if (access(exec_path, X_OK) == 0) {
+
+ data->symqemu = (u8 *)strdup(exec_path);
+ break;
+
+ }
+
+ token = strtok(NULL, ":");
+
+ }
+
+ if (!data->symqemu) FATAL("symqemu binary %s not found", exec_name);
+ DBG("Found %s\n", data->symqemu);
+
+ if (getenv("AFL_CUSTOM_MUTATOR_ONLY"))
+ FATAL("the symqemu module cannot be used with AFL_CUSTOM_MUTATOR_ONLY.");
+
+ if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
+
+ free(data);
+ perror("mutator_buf alloc");
+ return NULL;
+
+ }
+
+ data->target = getenv("AFL_CUSTOM_INFO_PROGRAM");
+
+ u8 *path_tmp = getenv("AFL_CUSTOM_INFO_OUT");
+ u32 len = strlen(path_tmp) + 32;
+ u8 *symqemu_path = malloc(len);
+ data->out_dir = malloc(len);
+ data->queue_dir = malloc(len);
+ snprintf(symqemu_path, len, "%s/../symqemu", path_tmp);
+ snprintf(data->out_dir, len, "%s/../symqemu/out", path_tmp);
+ snprintf(data->queue_dir, len, "%s/../symqemu/queue", path_tmp);
+
+ mkdir(symqemu_path, 0755);
+ mkdir(data->out_dir, 0755);
+ mkdir(data->queue_dir, 0755);
+
+ setenv("SYMCC_OUTPUT_DIR", data->out_dir, 1);
+
+ data->input_file = getenv("AFL_CUSTOM_INFO_PROGRAM_INPUT");
+
+ u8 *tmp = NULL;
+ if ((tmp = getenv("AFL_CUSTOM_INFO_PROGRAM_ARGV")) && *tmp) {
+
+ int argc = 0, index = 2;
+ for (u32 i = 0; i < strlen(tmp); ++i)
+ if (isspace(tmp[i])) ++argc;
+
+ data->argv = (u8 **)malloc((argc + 4) * sizeof(u8 **));
+ u8 *p = strdup(tmp);
+
+ do {
+
+ data->argv[index] = p;
+ while (*p && !isspace(*p))
+ ++p;
+ if (*p) {
+
+ *p++ = 0;
+ while (isspace(*p))
+ ++p;
+
+ }
+
+ if (strcmp(data->argv[index], "@@") == 0) {
+
+ if (!data->input_file) {
+
+ u32 ilen = strlen(symqemu_path) + 32;
+ data->input_file = malloc(ilen);
+ snprintf(data->input_file, ilen, "%s/.input", symqemu_path);
+
+ }
+
+ data->argv[index] = data->input_file;
+
+ }
+
+ DBG("%d: %s\n", index, data->argv[index]);
+ index++;
+
+ } while (*p);
+
+ data->argv[index] = NULL;
+ data->argc = index;
+
+ } else {
+
+ data->argv = (u8 **)malloc(8 * sizeof(u8 **));
+ data->argc = 2;
+ data->argv[2] = NULL;
+
+ }
+
+ data->argv[0] = data->symqemu;
+ data->argv[1] = data->target;
+
+ DBG("out_dir=%s, queue_dir=%s, target=%s, input_file=%s, argc=%u\n",
+ data->out_dir, data->queue_dir, data->target,
+ data->input_file ? (char *)data->input_file : (char *)"",
+ data->argc);
+
+ if (data->input_file) { setenv("SYMCC_INPUT_FILE", data->input_file, 1); }
+
+ data->afl = afl;
+ data->seed = seed;
+ afl_struct = afl;
+
+ if (debug) {
+
+ fprintf(stderr, "[");
+ for (u32 i = 0; i <= data->argc; ++i)
+ fprintf(stderr, " \"%s\"",
+ data->argv[i] ? (char *)data->argv[i] : "");
+ fprintf(stderr, " ]\n");
+
+ }
+
+ OKF("Custom mutator symqemu loaded - note that the initial startup of "
+ "afl-fuzz will be delayed the more starting seeds are present. This is "
+ "fine, do not worry!");
+
+ return data;
+
+}
+
+/* When a new queue entry is added we run this input with the symqemu
+ instrumented binary */
+uint8_t afl_custom_queue_new_entry(my_mutator_t *data,
+ const uint8_t *filename_new_queue,
+ const uint8_t *filename_orig_queue) {
+
+ int pipefd[2];
+ struct stat st;
+ if (data->afl->afl_env.afl_no_ui)
+ ACTF("Sending to symqemu: %s", filename_new_queue);
+ u8 *fn = alloc_printf("%s", filename_new_queue);
+ if (!(stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size)) {
+
+ ck_free(fn);
+ PFATAL("Couldn't find enqueued file: %s", fn);
+
+ }
+
+ if (afl_struct->fsrv.use_stdin) {
+
+ if (pipe(pipefd) == -1) {
+
+ ck_free(fn);
+ PFATAL(
+ "Couldn't create a pipe for interacting with symqemu child process");
+
+ }
+
+ }
+
+ int fd = open(fn, O_RDONLY);
+ if (fd < 0) return 0;
+ ssize_t r = read(fd, data->mutator_buf, MAX_FILE);
+ DBG("fn=%s, fd=%d, size=%ld\n", fn, fd, r);
+ ck_free(fn);
+ close(fd);
+
+ if (data->input_file) {
+
+ fd = open(data->input_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ ssize_t s = write(fd, data->mutator_buf, r);
+ close(fd);
+ DBG("wrote %zd/%zd to %s\n", s, r, data->input_file);
+
+ }
+
+ int pid = fork();
+
+ if (pid == -1) return 0;
+
+ if (pid) {
+
+ if (!data->input_file || afl_struct->fsrv.use_stdin) {
+
+ close(pipefd[0]);
+
+ if (fd >= 0) {
+
+ if (r <= 0) {
+
+ close(pipefd[1]);
+ return 0;
+
+ }
+
+ if (r > fcntl(pipefd[1], F_GETPIPE_SZ))
+ fcntl(pipefd[1], F_SETPIPE_SZ, MAX_FILE);
+ ck_write(pipefd[1], data->mutator_buf, r, filename_new_queue);
+
+ } else {
+
+ ck_free(fn);
+ close(pipefd[1]);
+ PFATAL(
+ "Something happened to the enqueued file before sending its "
+ "contents to symqemu binary");
+
+ }
+
+ close(pipefd[1]);
+
+ }
+
+ pid = waitpid(pid, NULL, 0);
+ DBG("symqemu finished executing!\n");
+
+ // At this point we need to transfer files to output dir, since their names
+ // collide and symqemu will just overwrite them
+
+ struct dirent **nl;
+ int32_t items = scandir(data->out_dir, &nl, NULL, NULL);
+ u8 *origin_name = basename(filename_new_queue);
+ u8 source_name[4096], destination_name[4096];
+ int32_t i;
+
+ if (items > 0) {
+
+ for (i = 0; i < (u32)items; ++i) {
+
+ // symqemu output files start with a digit
+ if (!isdigit(nl[i]->d_name[0])) continue;
+
+ struct stat st;
+ snprintf(source_name, sizeof(source_name), "%s/%s", data->out_dir,
+ nl[i]->d_name);
+ DBG("file=%s\n", source_name);
+
+ if (stat(source_name, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
+
+ snprintf(destination_name, sizeof(destination_name), "%s/id:%06u,%s",
+ data->queue_dir, data->counter++, nl[i]->d_name);
+ DBG("src=%s dst=%s\n", source_name, destination_name);
+ rename(source_name, destination_name);
+
+ }
+
+ free(nl[i]);
+
+ }
+
+ free(nl);
+
+ }
+
+ DBG("Done!\n");
+
+ } else /* (pid == 0) */ { // child
+
+ if (afl_struct->fsrv.use_stdin) {
+
+ close(pipefd[1]);
+ dup2(pipefd[0], 0);
+
+ }
+
+ DBG("exec=%s\n", data->target);
+ if (!debug) {
+
+ close(1);
+ close(2);
+ dup2(afl_struct->fsrv.dev_null_fd, 1);
+ dup2(afl_struct->fsrv.dev_null_fd, 2);
+
+ }
+
+ execvp((char *)data->argv[0], (char **)data->argv);
+ fprintf(stderr, "Executing: [");
+ for (u32 i = 0; i <= data->argc; ++i)
+ fprintf(stderr, " \"%s\"",
+ data->argv[i] ? (char *)data->argv[i] : "");
+ fprintf(stderr, " ]\n");
+ FATAL("Failed to execute %s %s\n", data->argv[0], data->argv[1]);
+ exit(-1);
+
+ }
+
+ return 0;
+
+}
+
+/*
+uint32_t afl_custom_fuzz_count(my_mutator_t *data, const u8 *buf,
+ size_t buf_size) {
+
+ uint32_t count = 0, i;
+ struct dirent **nl;
+ int32_t items = scandir(data->out_dir, &nl, NULL, NULL);
+
+ if (items > 0) {
+
+ for (i = 0; i < (u32)items; ++i) {
+
+ struct stat st;
+ u8 * fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name);
+ DBG("test=%s\n", fn);
+ if (stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
+
+ DBG("found=%s\n", fn);
+ count++;
+
+ }
+
+ ck_free(fn);
+ free(nl[i]);
+
+ }
+
+ free(nl);
+
+ }
+
+ DBG("dir=%s, count=%u\n", data->out_dir, count);
+ return count;
+
+}
+
+*/
+
+// here we actually just read the files generated from symqemu
+/*
+size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
+ u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
+ size_t max_size) {
+
+ struct dirent **nl;
+ int32_t i, done = 0, items = scandir(data->out_dir, &nl, NULL, NULL);
+ ssize_t size = 0;
+
+ if (items <= 0) return 0;
+
+ for (i = 0; i < (u32)items; ++i) {
+
+ struct stat st;
+ u8 * fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name);
+
+ if (done == 0) {
+
+ if (stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
+
+ int fd = open(fn, O_RDONLY);
+
+ if (fd >= 0) {
+
+ size = read(fd, data->mutator_buf, max_size);
+ *out_buf = data->mutator_buf;
+
+ close(fd);
+ done = 1;
+
+ }
+
+ }
+
+ unlink(fn);
+
+ }
+
+ ck_free(fn);
+ free(nl[i]);
+
+ }
+
+ free(nl);
+ DBG("FUZZ size=%lu\n", size);
+ return (uint32_t)size;
+
+}
+
+*/
+
+/**
+ * Deinitialize everything
+ *
+ * @param data The data ptr from afl_custom_init
+ */
+void afl_custom_deinit(my_mutator_t *data) {
+
+ free(data->mutator_buf);
+ free(data);
+
+}
+
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 3602af50..e99747f6 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -23,6 +23,9 @@
- qemu_mode:
- Persistent mode +QASAN support for ppc32 tragets by @worksbutnottested
- a new grammar custom mutator atnwalk was submitted by @voidptr127 !
+ - two new custom mutators are now available:
+ - TritonDSE in custom_mutators/aflpp_tritondse
+ - SymQEMU in custom_mutators/symqemu
### Version ++4.06c (release)
diff --git a/instrumentation/afl-llvm-common.h b/instrumentation/afl-llvm-common.h
index c9324460..23f67179 100644
--- a/instrumentation/afl-llvm-common.h
+++ b/instrumentation/afl-llvm-common.h
@@ -23,7 +23,7 @@ typedef long double max_align_t;
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#if LLVM_VERSION_MAJOR < 17
-#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+ #include "llvm/Transforms/IPO/PassManagerBuilder.h"
#endif
#if LLVM_VERSION_MAJOR > 3 || \
diff --git a/test-instr.c b/test-instr.c
index 1d9f2e6e..eda5189c 100644
--- a/test-instr.c
+++ b/test-instr.c
@@ -24,7 +24,7 @@
int main(int argc, char **argv) {
- int fd = 0;
+ int fd = 0, cnt;
char buff[8];
char *buf = buff;
@@ -32,7 +32,6 @@ int main(int argc, char **argv) {
if (argc == 2) {
buf = argv[1];
- printf("Input %s - ", buf);
} else {
@@ -47,15 +46,19 @@ int main(int argc, char **argv) {
}
- if (read(fd, buf, sizeof(buf)) < 1) {
+ if ((cnt = read(fd, buf, sizeof(buf) - 1)) < 1) {
printf("Hum?\n");
return 1;
}
+ buf[cnt] = 0;
+
}
+ if (getenv("AFL_DEBUG")) fprintf(stderr, "test-instr: %s\n", buf);
+
// we support three input cases (plus a 4th if stdin is used but there is no
// input)
switch (buf[0]) {
--
cgit 1.4.1
From 3e3adb4d377dcfa1e878ab00f061a894923bd642 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 17 May 2023 18:39:54 +0200
Subject: enforce python setting detection
---
GNUmakefile | 34 +++++++++++++++++-----------------
custom_mutators/symqemu/README.md | 2 +-
2 files changed, 18 insertions(+), 18 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 31374c10..bfc2aa03 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -180,13 +180,13 @@ AFL_FUZZ_FILES = $(wildcard src/afl-fuzz*.c)
ifneq "$(shell command -v python3m 2>/dev/null)" ""
ifneq "$(shell command -v python3m-config 2>/dev/null)" ""
- PYTHON_INCLUDE ?= $(shell python3m-config --includes)
- PYTHON_VERSION ?= $(strip $(shell python3m --version 2>&1))
+ PYTHON_INCLUDE := $(shell python3m-config --includes)
+ PYTHON_VERSION := $(strip $(shell python3m --version 2>&1))
# Starting with python3.8, we need to pass the `embed` flag. Earlier versions didn't know this flag.
ifeq "$(shell python3m-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1"
- PYTHON_LIB ?= $(shell python3m-config --libs --embed --ldflags)
+ PYTHON_LIB := $(shell python3m-config --libs --embed --ldflags)
else
- PYTHON_LIB ?= $(shell python3m-config --ldflags)
+ PYTHON_LIB := $(shell python3m-config --ldflags)
endif
endif
endif
@@ -194,13 +194,13 @@ endif
ifeq "$(PYTHON_INCLUDE)" ""
ifneq "$(shell command -v python3 2>/dev/null)" ""
ifneq "$(shell command -v python3-config 2>/dev/null)" ""
- PYTHON_INCLUDE ?= $(shell python3-config --includes)
- PYTHON_VERSION ?= $(strip $(shell python3 --version 2>&1))
+ PYTHON_INCLUDE := $(shell python3-config --includes)
+ PYTHON_VERSION := $(strip $(shell python3 --version 2>&1))
# Starting with python3.8, we need to pass the `embed` flag. Earlier versions didn't know this flag.
ifeq "$(shell python3-config --embed --libs 2>/dev/null | grep -q lpython && echo 1 )" "1"
- PYTHON_LIB ?= $(shell python3-config --libs --embed --ldflags)
+ PYTHON_LIB := $(shell python3-config --libs --embed --ldflags)
else
- PYTHON_LIB ?= $(shell python3-config --ldflags)
+ PYTHON_LIB := $(shell python3-config --ldflags)
endif
endif
endif
@@ -209,9 +209,9 @@ endif
ifeq "$(PYTHON_INCLUDE)" ""
ifneq "$(shell command -v python 2>/dev/null)" ""
ifneq "$(shell command -v python-config 2>/dev/null)" ""
- PYTHON_INCLUDE ?= $(shell python-config --includes)
- PYTHON_LIB ?= $(shell python-config --ldflags)
- PYTHON_VERSION ?= $(strip $(shell python --version 2>&1))
+ PYTHON_INCLUDE := $(shell python-config --includes)
+ PYTHON_LIB := $(shell python-config --ldflags)
+ PYTHON_VERSION := $(strip $(shell python --version 2>&1))
endif
endif
endif
@@ -220,9 +220,9 @@ endif
ifeq "$(PYTHON_INCLUDE)" ""
ifneq "$(shell command -v python3.7 2>/dev/null)" ""
ifneq "$(shell command -v python3.7-config 2>/dev/null)" ""
- PYTHON_INCLUDE ?= $(shell python3.7-config --includes)
- PYTHON_LIB ?= $(shell python3.7-config --ldflags)
- PYTHON_VERSION ?= $(strip $(shell python3.7 --version 2>&1))
+ PYTHON_INCLUDE := $(shell python3.7-config --includes)
+ PYTHON_LIB := $(shell python3.7-config --ldflags)
+ PYTHON_VERSION := $(strip $(shell python3.7 --version 2>&1))
endif
endif
endif
@@ -231,9 +231,9 @@ endif
ifeq "$(PYTHON_INCLUDE)" ""
ifneq "$(shell command -v python2.7 2>/dev/null)" ""
ifneq "$(shell command -v python2.7-config 2>/dev/null)" ""
- PYTHON_INCLUDE ?= $(shell python2.7-config --includes)
- PYTHON_LIB ?= $(shell python2.7-config --ldflags)
- PYTHON_VERSION ?= $(strip $(shell python2.7 --version 2>&1))
+ PYTHON_INCLUDE := $(shell python2.7-config --includes)
+ PYTHON_LIB := $(shell python2.7-config --ldflags)
+ PYTHON_VERSION := $(strip $(shell python2.7 --version 2>&1))
endif
endif
endif
diff --git a/custom_mutators/symqemu/README.md b/custom_mutators/symqemu/README.md
index 0d5cd4d7..55ce05c5 100644
--- a/custom_mutators/symqemu/README.md
+++ b/custom_mutators/symqemu/README.md
@@ -8,4 +8,4 @@ on how to build symqemu-x86_x64 and put it in your `PATH`.
just type `make` to build this custom mutator.
-```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/symqemu/symqemu-mutator.so AFL_SYNC_TIME=1 afl-fuzz ...```
+```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/symqemu/symqemu-mutator.so AFL_SYNC_TIME=1 AFL_DISABLE_TRIM=1 afl-fuzz ...```
--
cgit 1.4.1
From f664eb58c50ab9b6b130139613a35ff7a7297f1b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 17 May 2023 19:21:41 +0200
Subject: fix debug build
---
GNUmakefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index bfc2aa03..4ecdae52 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -139,13 +139,13 @@ endif
ifdef DEBUG
$(info Compiling DEBUG version of binaries)
- override CFLAGS += -ggdb3 -O0 -Wall -Wextra -Werror $(CFLAGS_OPT)
+ override CFLAGS += -ggdb3 -O0 -Wall -Wextra -Werror -Wno-error=format-truncation= $(CFLAGS_OPT)
else
CFLAGS ?= -O2 $(CFLAGS_OPT) # -funroll-loops is slower on modern compilers
endif
override CFLAGS += -g -Wno-pointer-sign -Wno-variadic-macros -Wall -Wextra -Wno-pointer-arith \
- -fPIC -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
+ -fPIC -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" -Wno-format-truncation \
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
# -fstack-protector
--
cgit 1.4.1
From abd6eace9d767e4db6019e8eb69080d2352015c9 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 18 May 2023 10:32:15 +0200
Subject: improved symqemu custom mutator
---
custom_mutators/symqemu/README.md | 2 +-
custom_mutators/symqemu/symqemu.c | 239 +++++++++++++++-----------------------
include/afl-fuzz.h | 1 +
src/afl-fuzz-one.c | 1 +
4 files changed, 98 insertions(+), 145 deletions(-)
diff --git a/custom_mutators/symqemu/README.md b/custom_mutators/symqemu/README.md
index 55ce05c5..b7702c06 100644
--- a/custom_mutators/symqemu/README.md
+++ b/custom_mutators/symqemu/README.md
@@ -8,4 +8,4 @@ on how to build symqemu-x86_x64 and put it in your `PATH`.
just type `make` to build this custom mutator.
-```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/symqemu/symqemu-mutator.so AFL_SYNC_TIME=1 AFL_DISABLE_TRIM=1 afl-fuzz ...```
+```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/symqemu/symqemu-mutator.so AFL_DISABLE_TRIM=1 afl-fuzz ...```
diff --git a/custom_mutators/symqemu/symqemu.c b/custom_mutators/symqemu/symqemu.c
index 9030397b..163ae240 100644
--- a/custom_mutators/symqemu/symqemu.c
+++ b/custom_mutators/symqemu/symqemu.c
@@ -13,6 +13,9 @@
afl_state_t *afl_struct;
static u32 debug = 0;
+static u32 found_items = 0;
+
+#define SYMQEMU_LOCATION "symqemu"
#define DBG(x...) \
if (debug) { fprintf(stderr, x); }
@@ -22,7 +25,6 @@ typedef struct my_mutator {
afl_state_t *afl;
u8 *mutator_buf;
u8 *out_dir;
- u8 *queue_dir;
u8 *target;
u8 *symqemu;
u8 *input_file;
@@ -67,8 +69,13 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
if (!data->symqemu) FATAL("symqemu binary %s not found", exec_name);
DBG("Found %s\n", data->symqemu);
- if (getenv("AFL_CUSTOM_MUTATOR_ONLY"))
- FATAL("the symqemu module cannot be used with AFL_CUSTOM_MUTATOR_ONLY.");
+ if (getenv("AFL_CUSTOM_MUTATOR_ONLY")) {
+
+ WARNF(
+ "the symqemu module is not very effective with "
+ "AFL_CUSTOM_MUTATOR_ONLY.");
+
+ }
if ((data->mutator_buf = malloc(MAX_FILE)) == NULL) {
@@ -84,14 +91,11 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
u32 len = strlen(path_tmp) + 32;
u8 *symqemu_path = malloc(len);
data->out_dir = malloc(len);
- data->queue_dir = malloc(len);
- snprintf(symqemu_path, len, "%s/../symqemu", path_tmp);
- snprintf(data->out_dir, len, "%s/../symqemu/out", path_tmp);
- snprintf(data->queue_dir, len, "%s/../symqemu/queue", path_tmp);
+ snprintf(symqemu_path, len, "%s/%s", path_tmp, SYMQEMU_LOCATION);
+ snprintf(data->out_dir, len, "%s/out", symqemu_path, path_tmp);
- mkdir(symqemu_path, 0755);
- mkdir(data->out_dir, 0755);
- mkdir(data->queue_dir, 0755);
+ (void)mkdir(symqemu_path, 0755);
+ (void)mkdir(data->out_dir, 0755);
setenv("SYMCC_OUTPUT_DIR", data->out_dir, 1);
@@ -153,8 +157,8 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
data->argv[0] = data->symqemu;
data->argv[1] = data->target;
- DBG("out_dir=%s, queue_dir=%s, target=%s, input_file=%s, argc=%u\n",
- data->out_dir, data->queue_dir, data->target,
+ DBG("out_dir=%s, target=%s, input_file=%s, argc=%u\n", data->out_dir,
+ data->target,
data->input_file ? (char *)data->input_file : (char *)"",
data->argc);
@@ -174,29 +178,39 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
}
- OKF("Custom mutator symqemu loaded - note that the initial startup of "
- "afl-fuzz will be delayed the more starting seeds are present. This is "
- "fine, do not worry!");
-
return data;
}
-/* When a new queue entry is added we run this input with the symqemu
- instrumented binary */
-uint8_t afl_custom_queue_new_entry(my_mutator_t *data,
- const uint8_t *filename_new_queue,
- const uint8_t *filename_orig_queue) {
+/* No need to receive a splicing item */
+void afl_custom_splice_optout(void *data) {
+
+ (void)(data);
+
+}
+
+u32 afl_custom_fuzz_count(my_mutator_t *data, const u8 *buf, size_t buf_size) {
+
+ if (likely(!afl_struct->queue_cur->favored ||
+ afl_struct->queue_cur->was_fuzzed)) {
+
+ return 0;
+
+ }
int pipefd[2];
struct stat st;
- if (data->afl->afl_env.afl_no_ui)
- ACTF("Sending to symqemu: %s", filename_new_queue);
- u8 *fn = alloc_printf("%s", filename_new_queue);
- if (!(stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size)) {
- ck_free(fn);
- PFATAL("Couldn't find enqueued file: %s", fn);
+ if (afl_struct->afl_env.afl_no_ui) {
+
+ ACTF("Sending to symqemu: %s", afl_struct->queue_cur->fname);
+
+ }
+
+ if (!(stat(afl_struct->queue_cur->fname, &st) == 0 && S_ISREG(st.st_mode) &&
+ st.st_size)) {
+
+ PFATAL("Couldn't find enqueued file: %s", afl_struct->queue_cur->fname);
}
@@ -204,7 +218,6 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t *data,
if (pipe(pipefd) == -1) {
- ck_free(fn);
PFATAL(
"Couldn't create a pipe for interacting with symqemu child process");
@@ -212,19 +225,12 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t *data,
}
- int fd = open(fn, O_RDONLY);
- if (fd < 0) return 0;
- ssize_t r = read(fd, data->mutator_buf, MAX_FILE);
- DBG("fn=%s, fd=%d, size=%ld\n", fn, fd, r);
- ck_free(fn);
- close(fd);
-
if (data->input_file) {
- fd = open(data->input_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
- ssize_t s = write(fd, data->mutator_buf, r);
+ int fd = open(data->input_file, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+ ssize_t s = write(fd, buf, buf_size);
close(fd);
- DBG("wrote %zd/%zd to %s\n", s, r, data->input_file);
+ DBG("wrote %zd/%zd to %s\n", s, buf_size, data->input_file);
}
@@ -232,35 +238,20 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t *data,
if (pid == -1) return 0;
- if (pid) {
+ if (likely(pid)) {
if (!data->input_file || afl_struct->fsrv.use_stdin) {
close(pipefd[0]);
- if (fd >= 0) {
-
- if (r <= 0) {
-
- close(pipefd[1]);
- return 0;
-
- }
+ if (fcntl(pipefd[1], F_GETPIPE_SZ)) {
- if (r > fcntl(pipefd[1], F_GETPIPE_SZ))
- fcntl(pipefd[1], F_SETPIPE_SZ, MAX_FILE);
- ck_write(pipefd[1], data->mutator_buf, r, filename_new_queue);
-
- } else {
-
- ck_free(fn);
- close(pipefd[1]);
- PFATAL(
- "Something happened to the enqueued file before sending its "
- "contents to symqemu binary");
+ fcntl(pipefd[1], F_SETPIPE_SZ, MAX_FILE);
}
+ ck_write(pipefd[1], buf, buf_size, data->input_file);
+
close(pipefd[1]);
}
@@ -268,46 +259,6 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t *data,
pid = waitpid(pid, NULL, 0);
DBG("symqemu finished executing!\n");
- // At this point we need to transfer files to output dir, since their names
- // collide and symqemu will just overwrite them
-
- struct dirent **nl;
- int32_t items = scandir(data->out_dir, &nl, NULL, NULL);
- u8 *origin_name = basename(filename_new_queue);
- u8 source_name[4096], destination_name[4096];
- int32_t i;
-
- if (items > 0) {
-
- for (i = 0; i < (u32)items; ++i) {
-
- // symqemu output files start with a digit
- if (!isdigit(nl[i]->d_name[0])) continue;
-
- struct stat st;
- snprintf(source_name, sizeof(source_name), "%s/%s", data->out_dir,
- nl[i]->d_name);
- DBG("file=%s\n", source_name);
-
- if (stat(source_name, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
-
- snprintf(destination_name, sizeof(destination_name), "%s/id:%06u,%s",
- data->queue_dir, data->counter++, nl[i]->d_name);
- DBG("src=%s dst=%s\n", source_name, destination_name);
- rename(source_name, destination_name);
-
- }
-
- free(nl[i]);
-
- }
-
- free(nl);
-
- }
-
- DBG("Done!\n");
-
} else /* (pid == 0) */ { // child
if (afl_struct->fsrv.use_stdin) {
@@ -338,33 +289,31 @@ uint8_t afl_custom_queue_new_entry(my_mutator_t *data,
}
- return 0;
-
-}
-
-/*
-uint32_t afl_custom_fuzz_count(my_mutator_t *data, const u8 *buf,
- size_t buf_size) {
+ /* back in mother process */
- uint32_t count = 0, i;
struct dirent **nl;
- int32_t items = scandir(data->out_dir, &nl, NULL, NULL);
+ s32 i, items = scandir(data->out_dir, &nl, NULL, NULL);
+ found_items = 0;
+ char source_name[4096];
if (items > 0) {
for (i = 0; i < (u32)items; ++i) {
+ // symqemu output files start with a digit
+ if (!isdigit(nl[i]->d_name[0])) continue;
+
struct stat st;
- u8 * fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name);
- DBG("test=%s\n", fn);
- if (stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
+ snprintf(source_name, sizeof(source_name), "%s/%s", data->out_dir,
+ nl[i]->d_name);
+ DBG("file=%s\n", source_name);
+
+ if (stat(source_name, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
- DBG("found=%s\n", fn);
- count++;
+ ++found_items;
}
- ck_free(fn);
free(nl[i]);
}
@@ -373,65 +322,67 @@ uint32_t afl_custom_fuzz_count(my_mutator_t *data, const u8 *buf,
}
- DBG("dir=%s, count=%u\n", data->out_dir, count);
- return count;
+ DBG("Done, found %u items!\n", found_items);
-}
+ return found_items;
-*/
+}
-// here we actually just read the files generated from symqemu
-/*
-size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
- u8 **out_buf, uint8_t *add_buf, size_t add_buf_size,
+size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size,
+ u8 **out_buf, u8 *add_buf, size_t add_buf_size,
size_t max_size) {
struct dirent **nl;
- int32_t i, done = 0, items = scandir(data->out_dir, &nl, NULL, NULL);
- ssize_t size = 0;
+ s32 done = 0, i, items = scandir(data->out_dir, &nl, NULL, NULL);
+ char source_name[4096];
- if (items <= 0) return 0;
+ if (items > 0) {
- for (i = 0; i < (u32)items; ++i) {
+ for (i = 0; i < (u32)items; ++i) {
- struct stat st;
- u8 * fn = alloc_printf("%s/%s", data->out_dir, nl[i]->d_name);
+ // symqemu output files start with a digit
+ if (!isdigit(nl[i]->d_name[0])) continue;
- if (done == 0) {
+ struct stat st;
+ snprintf(source_name, sizeof(source_name), "%s/%s", data->out_dir,
+ nl[i]->d_name);
+ DBG("file=%s\n", source_name);
- if (stat(fn, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
+ if (stat(source_name, &st) == 0 && S_ISREG(st.st_mode) && st.st_size) {
- int fd = open(fn, O_RDONLY);
+ int fd = open(source_name, O_RDONLY);
+ if (fd < 0) { goto got_an_issue; }
- if (fd >= 0) {
+ ssize_t r = read(fd, data->mutator_buf, MAX_FILE);
+ close(fd);
- size = read(fd, data->mutator_buf, max_size);
- *out_buf = data->mutator_buf;
+ DBG("fn=%s, fd=%d, size=%ld\n", source_name, fd, r);
- close(fd);
- done = 1;
+ if (r < 1) { goto got_an_issue; }
- }
+ done = 1;
+ --found_items;
+ unlink(source_name);
+
+ *out_buf = data->mutator_buf;
+ return (u32)r;
}
- unlink(fn);
+ free(nl[i]);
}
- ck_free(fn);
- free(nl[i]);
+ free(nl);
}
- free(nl);
- DBG("FUZZ size=%lu\n", size);
- return (uint32_t)size;
+got_an_issue:
+ *out_buf = NULL;
+ return 0;
}
-*/
-
/**
* Deinitialize everything
*
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 8fb7ecb1..beb2de2a 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -184,6 +184,7 @@ struct queue_entry {
handicap, /* Number of queue cycles behind */
depth, /* Path depth */
exec_cksum, /* Checksum of the execution trace */
+ custom, /* Marker for custom mutators */
stats_mutated; /* stats: # of mutations performed */
u8 *trace_mini; /* Trace bytes, if kept */
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index c6e9a295..5c71fc59 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -1912,6 +1912,7 @@ custom_mutator_stage:
afl->stage_name = "custom mutator";
afl->stage_short = "custom";
+ afl->stage_cur = 0;
afl->stage_val_type = STAGE_VAL_NONE;
bool has_custom_fuzz = false;
u32 shift = unlikely(afl->custom_only) ? 7 : 8;
--
cgit 1.4.1
From 401d7617efbd2f38d9132eabfd1b1152abceda52 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 18 May 2023 10:50:10 +0200
Subject: symqemu mutator options
---
custom_mutators/aflpp_tritondse/README.md | 7 +++--
custom_mutators/symqemu/README.md | 10 ++++++-
custom_mutators/symqemu/symqemu.c | 44 +++++++++++++++++++++++++------
src/afl-common.c | 2 +-
4 files changed, 51 insertions(+), 12 deletions(-)
diff --git a/custom_mutators/aflpp_tritondse/README.md b/custom_mutators/aflpp_tritondse/README.md
index 8a5dd02b..608c2624 100644
--- a/custom_mutators/aflpp_tritondse/README.md
+++ b/custom_mutators/aflpp_tritondse/README.md
@@ -10,8 +10,11 @@
../../afl-cc -o ../../test-instr ../../test-instr.c
mkdir -p in
echo aaaa > in/in
-TRITON_DSE_TARGET=../../test-instr AFL_CUSTOM_MUTATOR_ONLY=1 AFL_SYNC_TIME=1 AFL_PYTHON_MODULE=aflpp_tritondse PYTHONPATH=. ../../afl-fuzz -i in -o out -- ../../test-instr
+AFL_DISABLE_TRIM=1 AFL_CUSTOM_MUTATOR_ONLY=1 AFL_SYNC_TIME=1 AFL_PYTHON_MODULE=aflpp_tritondse PYTHONPATH=. ../../afl-fuzz -i in -o out -- ../../test-instr
```
Note that this custom mutator works differently, new finds are synced
-after 10-60 seconds to the fuzzing instance.
+after 10-60 seconds to the fuzzing instance. This is necessary because only
+C/C++ mutators have access to the internal AFL++ state.
+
+Hence the symqemu customer mutator is more effective.
diff --git a/custom_mutators/symqemu/README.md b/custom_mutators/symqemu/README.md
index b7702c06..c3071afc 100644
--- a/custom_mutators/symqemu/README.md
+++ b/custom_mutators/symqemu/README.md
@@ -2,10 +2,18 @@
This uses the symcc to find new paths into the target.
+## How to build and use
+
To use this custom mutator follow the steps in the symqemu repository
[https://github.com/eurecom-s3/symqemu/](https://github.com/eurecom-s3/symqemu/)
on how to build symqemu-x86_x64 and put it in your `PATH`.
-just type `make` to build this custom mutator.
+Just type `make` to build this custom mutator.
```AFL_CUSTOM_MUTATOR_LIBRARY=custom_mutators/symqemu/symqemu-mutator.so AFL_DISABLE_TRIM=1 afl-fuzz ...```
+
+## Options
+
+`SYMQEMU_ALL=1` - use concolic solving on **all** queue items, not only interesting/favorite ones.
+
+`SYMQEMU_LATE=1` - use concolic solving only after there have been no finds for 5 minutes.
diff --git a/custom_mutators/symqemu/symqemu.c b/custom_mutators/symqemu/symqemu.c
index 163ae240..e2b07af6 100644
--- a/custom_mutators/symqemu/symqemu.c
+++ b/custom_mutators/symqemu/symqemu.c
@@ -23,6 +23,8 @@ static u32 found_items = 0;
typedef struct my_mutator {
afl_state_t *afl;
+ u32 all;
+ u32 late;
u8 *mutator_buf;
u8 *out_dir;
u8 *target;
@@ -156,18 +158,19 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
data->argv[0] = data->symqemu;
data->argv[1] = data->target;
+ data->afl = afl;
+ data->seed = seed;
+ afl_struct = afl;
+
+ if (getenv("SYMQEMU_ALL")) { data->all = 1; }
+ if (getenv("SYMQEMU_LATE")) { data->late = 1; }
+ if (data->input_file) { setenv("SYMCC_INPUT_FILE", data->input_file, 1); }
DBG("out_dir=%s, target=%s, input_file=%s, argc=%u\n", data->out_dir,
data->target,
data->input_file ? (char *)data->input_file : (char *)"",
data->argc);
- if (data->input_file) { setenv("SYMCC_INPUT_FILE", data->input_file, 1); }
-
- data->afl = afl;
- data->seed = seed;
- afl_struct = afl;
-
if (debug) {
fprintf(stderr, "[");
@@ -189,15 +192,40 @@ void afl_custom_splice_optout(void *data) {
}
+/* Get unix time in milliseconds */
+
+inline u64 get_cur_time(void) {
+
+ struct timeval tv;
+ struct timezone tz;
+
+ gettimeofday(&tv, &tz);
+
+ return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000);
+
+}
+
u32 afl_custom_fuzz_count(my_mutator_t *data, const u8 *buf, size_t buf_size) {
- if (likely(!afl_struct->queue_cur->favored ||
- afl_struct->queue_cur->was_fuzzed)) {
+ if (likely((!afl_struct->queue_cur->favored ||
+ afl_struct->queue_cur->was_fuzzed) &&
+ !data->all)) {
return 0;
}
+ if (likely(data->late)) {
+
+ if (unlikely(get_cur_time() - afl_struct->last_find_time <=
+ 10 * 60 * 1000)) {
+
+ return 0;
+
+ }
+
+ }
+
int pipefd[2];
struct stat st;
diff --git a/src/afl-common.c b/src/afl-common.c
index a5c48e80..84ddefd8 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -949,7 +949,7 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) {
/* Get unix time in milliseconds */
-u64 get_cur_time(void) {
+inline u64 get_cur_time(void) {
struct timeval tv;
struct timezone tz;
--
cgit 1.4.1
From eec2c38a6891ea317a287498ce1da2f2c8f6f9ff Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 18 May 2023 12:29:43 +0200
Subject: symqemu fix
---
custom_mutators/symqemu/symqemu.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/custom_mutators/symqemu/symqemu.c b/custom_mutators/symqemu/symqemu.c
index e2b07af6..73a1640a 100644
--- a/custom_mutators/symqemu/symqemu.c
+++ b/custom_mutators/symqemu/symqemu.c
@@ -207,9 +207,8 @@ inline u64 get_cur_time(void) {
u32 afl_custom_fuzz_count(my_mutator_t *data, const u8 *buf, size_t buf_size) {
- if (likely((!afl_struct->queue_cur->favored ||
- afl_struct->queue_cur->was_fuzzed) &&
- !data->all)) {
+ if (likely((!afl_struct->queue_cur->favored && !data->all) ||
+ afl_struct->queue_cur->was_fuzzed)) {
return 0;
--
cgit 1.4.1
From 53a869b757287e8bebdfcbc96b8abe1729955171 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 18 May 2023 14:45:45 +0200
Subject: act on invalid AFL_CUSTOM_MUTATOR_ONLY usage
---
src/afl-fuzz.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 4339ddd2..e2d8dea5 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1748,6 +1748,23 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->afl_env.afl_custom_mutator_only) {
+ if (!afl->custom_mutators_count) {
+
+ if (afl->shm.cmplog_mode) {
+
+ WARNF(
+ "No custom mutator loaded, using AFL_CUSTOM_MUTATOR_ONLY is "
+ "pointless and only allowed now to allow experiments with CMPLOG.");
+
+ } else {
+
+ FATAL(
+ "No custom mutator loaded but AFL_CUSTOM_MUTATOR_ONLY specified.");
+
+ }
+
+ }
+
/* This ensures we don't proceed to havoc/splice */
afl->custom_only = 1;
--
cgit 1.4.1
From 9a6c0ec0c0af42d33e4350ee2958b58fef1c39dd Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 21 May 2023 13:04:17 +0200
Subject: make AFL_CUSTOM_INFO overridable
---
custom_mutators/symqemu/Makefile | 2 +-
src/afl-fuzz.c | 8 ++++++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/custom_mutators/symqemu/Makefile b/custom_mutators/symqemu/Makefile
index 3361ab0f..958aec19 100644
--- a/custom_mutators/symqemu/Makefile
+++ b/custom_mutators/symqemu/Makefile
@@ -8,7 +8,7 @@ all: symqemu-mutator.so
CFLAGS += -O3 -funroll-loops
symqemu-mutator.so: symqemu.c
- $(CC) $(CFLAGS) $(CPPFLAGS) -g -I../../include -shared -fPIC -o symqemu-mutator.so symqemu.c
+ $(CC) -g $(CFLAGS) $(CPPFLAGS) -g -I../../include -shared -fPIC -o symqemu-mutator.so symqemu.c
clean:
rm -f symqemu-mutator.so *.o *~ core
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index e2d8dea5..a61718a7 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1833,7 +1833,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
- {
+ if (!getenv("AFL_CUSTOM_INFO_PROGRAM_ARGV")) {
u8 envbuf[8096] = "", tmpbuf[8096] = "";
for (s32 i = optind + 1; i < argc; ++i) {
@@ -1864,7 +1864,11 @@ int main(int argc, char **argv_orig, char **envp) {
}
- setenv("AFL_CUSTOM_INFO_OUT", afl->out_dir, 1); // same as __AFL_OUT_DIR
+ if (!getenv("AFL_CUSTOM_INFO_OUT") {
+
+ setenv("AFL_CUSTOM_INFO_OUT", afl->out_dir, 1); // same as __AFL_OUT_DIR
+
+ }
setup_custom_mutators(afl);
--
cgit 1.4.1
From d4085314c1c1d4e8bbe4159216f8cb83e0804ea7 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 21 May 2023 13:44:07 +0200
Subject: fix
---
src/afl-fuzz.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index a61718a7..559a7326 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1864,7 +1864,7 @@ int main(int argc, char **argv_orig, char **envp) {
}
- if (!getenv("AFL_CUSTOM_INFO_OUT") {
+ if (!getenv("AFL_CUSTOM_INFO_OUT")) {
setenv("AFL_CUSTOM_INFO_OUT", afl->out_dir, 1); // same as __AFL_OUT_DIR
--
cgit 1.4.1
From 1416fea1604a19408554678d7c9fb35b67da302b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 21 May 2023 14:49:24 +0200
Subject: cleaner tritondse
---
custom_mutators/aflpp_tritondse/README.md | 6 ++++--
custom_mutators/aflpp_tritondse/aflpp_tritondse.py | 4 ++++
2 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/custom_mutators/aflpp_tritondse/README.md b/custom_mutators/aflpp_tritondse/README.md
index 608c2624..033655d2 100644
--- a/custom_mutators/aflpp_tritondse/README.md
+++ b/custom_mutators/aflpp_tritondse/README.md
@@ -15,6 +15,8 @@ AFL_DISABLE_TRIM=1 AFL_CUSTOM_MUTATOR_ONLY=1 AFL_SYNC_TIME=1 AFL_PYTHON_MODULE=a
Note that this custom mutator works differently, new finds are synced
after 10-60 seconds to the fuzzing instance. This is necessary because only
-C/C++ mutators have access to the internal AFL++ state.
+C/C++ custom mutators have access to the internal AFL++ state.
-Hence the symqemu customer mutator is more effective.
+Note that you should run first with `AFL_DEBUG` for 5-10 minutes and see if
+all important libraries and syscalls are hooked (look at `WARNING` and `CRITICAL`
+output during the run, best use with `AFL_NO_UI=1`)
diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
index cef28f34..58b506b6 100644
--- a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
+++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
@@ -120,6 +120,10 @@ def init(seed):
is_debug = True
except KeyError:
pass
+ if is_debug:
+ logging.basicConfig(level=logging.WARNING)
+ else:
+ logging.basicConfig(level=logging.CRITICAL)
try:
foo = os.environ['AFL_CUSTOM_INFO_OUT']
out_path = foo + '/../tritondse/queue'
--
cgit 1.4.1
From 029e039cbcbf9e30f35eb255162679b8d609d25d Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 21 May 2023 17:49:14 +0200
Subject: code format
---
.custom-format.py | 2 +-
frida_mode/src/lib/lib_apple.c | 4 +--
include/config.h | 2 +-
instrumentation/SanitizerCoverageLTO.so.cc | 4 +--
instrumentation/SanitizerCoveragePCGUARD.so.cc | 4 +--
instrumentation/afl-compiler-rt.o.c | 14 +++++-----
instrumentation/afl-llvm-lto-instrumentlist.so.cc | 2 +-
instrumentation/cmplog-routines-pass.cc | 4 +--
instrumentation/compare-transform-pass.so.cc | 2 +-
instrumentation/split-compares-pass.so.cc | 2 +-
qemu_mode/libcompcov/libcompcov.so.c | 6 ++++-
src/afl-cc.c | 8 +++---
src/afl-fuzz-redqueen.c | 32 +++++++++++------------
utils/afl_untracer/afl-untracer.c | 2 +-
utils/libtokencap/libtokencap.so.c | 6 ++++-
utils/socket_fuzzing/socketfuzz.c | 3 ++-
16 files changed, 53 insertions(+), 44 deletions(-)
diff --git a/.custom-format.py b/.custom-format.py
index 1295ce55..1d5c8839 100755
--- a/.custom-format.py
+++ b/.custom-format.py
@@ -24,7 +24,7 @@ import importlib.metadata
# string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # TODO: for future use
-CURRENT_LLVM = os.getenv('LLVM_VERSION', 14)
+CURRENT_LLVM = os.getenv('LLVM_VERSION', 15)
CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN", "")
diff --git a/frida_mode/src/lib/lib_apple.c b/frida_mode/src/lib/lib_apple.c
index 634e0e30..d29d0303 100644
--- a/frida_mode/src/lib/lib_apple.c
+++ b/frida_mode/src/lib/lib_apple.c
@@ -17,8 +17,8 @@ static gboolean lib_get_main_module(const GumModuleDetails *details,
GumDarwinModule **ret = (GumDarwinModule **)user_data;
GumDarwinModule *module = gum_darwin_module_new_from_memory(
- details->path, mach_task_self(), details->range->base_address,
- GUM_DARWIN_MODULE_FLAGS_NONE, NULL);
+ details->path, mach_task_self(), details->range->base_address,
+ GUM_DARWIN_MODULE_FLAGS_NONE, NULL);
FVERBOSE("Found main module: %s", module->name);
diff --git a/include/config.h b/include/config.h
index 764c29dc..194786f7 100644
--- a/include/config.h
+++ b/include/config.h
@@ -81,7 +81,7 @@
will be kept and written to the crash/ directory as RECORD:... files.
Note that every crash will be written, not only unique ones! */
-//#define AFL_PERSISTENT_RECORD
+// #define AFL_PERSISTENT_RECORD
/* console output colors: There are three ways to configure its behavior
* 1. default: colored outputs fixed on: defined USE_COLOR && defined
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index b3b0d2cd..d7b03634 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1478,8 +1478,8 @@ GlobalVariable *ModuleSanitizerCoverageLTO::CreateFunctionLocalArrayInSection(
ArrayType *ArrayTy = ArrayType::get(Ty, NumElements);
auto Array = new GlobalVariable(
- *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
- Constant::getNullValue(ArrayTy), "__sancov_gen_");
+ *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
+ Constant::getNullValue(ArrayTy), "__sancov_gen_");
#if LLVM_VERSION_MAJOR >= 13
if (TargetTriple.supportsCOMDAT() &&
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 41c38283..8fed2042 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -714,8 +714,8 @@ GlobalVariable *ModuleSanitizerCoverageAFL::CreateFunctionLocalArrayInSection(
ArrayType *ArrayTy = ArrayType::get(Ty, NumElements);
auto Array = new GlobalVariable(
- *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
- Constant::getNullValue(ArrayTy), "__sancov_gen_");
+ *CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
+ Constant::getNullValue(ArrayTy), "__sancov_gen_");
#if LLVM_VERSION_MAJOR >= 13
if (TargetTriple.supportsCOMDAT() &&
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 5372fae0..3f8b519b 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -544,12 +544,12 @@ static void __afl_map_shm(void) {
if (__afl_map_size && __afl_map_size > MAP_SIZE) {
- u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
- if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
+ u8 *map_env = (u8 *)getenv("AFL_MAP_SIZE");
+ if (!map_env || atoi((char *)map_env) < MAP_SIZE) {
- fprintf(stderr, "FS_ERROR_MAP_SIZE\n");
- send_forkserver_error(FS_ERROR_MAP_SIZE);
- _exit(1);
+ fprintf(stderr, "FS_ERROR_MAP_SIZE\n");
+ send_forkserver_error(FS_ERROR_MAP_SIZE);
+ _exit(1);
}
@@ -561,13 +561,13 @@ static void __afl_map_shm(void) {
if (!__afl_area_ptr || __afl_area_ptr == (void *)-1) {
- if (__afl_map_addr)
+ if (__afl_map_addr)
send_forkserver_error(FS_ERROR_MAP_ADDR);
else
send_forkserver_error(FS_ERROR_SHMAT);
perror("shmat for map");
- _exit(1);
+ _exit(1);
}
diff --git a/instrumentation/afl-llvm-lto-instrumentlist.so.cc b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
index db5bd55e..61f97d77 100644
--- a/instrumentation/afl-llvm-lto-instrumentlist.so.cc
+++ b/instrumentation/afl-llvm-lto-instrumentlist.so.cc
@@ -45,7 +45,7 @@
#include "llvm/IR/Module.h"
#include "llvm/Pass.h"
#include "llvm/Support/Debug.h"
-//#include "llvm/Transforms/IPO/PassManagerBuilder.h"
+// #include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Passes/PassPlugin.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/IR/PassManager.h"
diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc
index 39db5aa4..c3fbed8d 100644
--- a/instrumentation/cmplog-routines-pass.cc
+++ b/instrumentation/cmplog-routines-pass.cc
@@ -542,7 +542,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
Value *v3Pbitcast = IRB.CreateBitCast(
- v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
+ v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
Value *v3Pcasted =
IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false);
args.push_back(v1Pcasted);
@@ -608,7 +608,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
Value *v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value *v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
Value *v3Pbitcast = IRB.CreateBitCast(
- v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
+ v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
Value *v3Pcasted =
IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false);
args.push_back(v1Pcasted);
diff --git a/instrumentation/compare-transform-pass.so.cc b/instrumentation/compare-transform-pass.so.cc
index efc99d20..5dd705cf 100644
--- a/instrumentation/compare-transform-pass.so.cc
+++ b/instrumentation/compare-transform-pass.so.cc
@@ -623,7 +623,7 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
IRBuilder<> cur_lenchk_IRB(&*(cur_lenchk_bb->getFirstInsertionPt()));
Value *icmp = cur_lenchk_IRB.CreateICmpEQ(
- sizedValue, ConstantInt::get(sizedValue->getType(), i));
+ sizedValue, ConstantInt::get(sizedValue->getType(), i));
cur_lenchk_IRB.CreateCondBr(icmp, end_bb, cur_cmp_bb);
cur_lenchk_bb->getTerminator()->eraseFromParent();
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 8a07610c..aec6758e 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -60,7 +60,7 @@ using namespace llvm;
// uncomment this toggle function verification at each step. horribly slow, but
// helps to pinpoint a potential problem in the splitting code.
-//#define VERIFY_TOO_MUCH 1
+// #define VERIFY_TOO_MUCH 1
namespace {
diff --git a/qemu_mode/libcompcov/libcompcov.so.c b/qemu_mode/libcompcov/libcompcov.so.c
index b6ee0019..b57e9701 100644
--- a/qemu_mode/libcompcov/libcompcov.so.c
+++ b/qemu_mode/libcompcov/libcompcov.so.c
@@ -68,7 +68,11 @@ static int debug_fd = -1;
#define MAX_MAPPINGS 1024
-static struct mapping { void *st, *en; } __compcov_ro[MAX_MAPPINGS];
+static struct mapping {
+
+ void *st, *en;
+
+} __compcov_ro[MAX_MAPPINGS];
static u32 __compcov_ro_cnt;
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 972ac8cd..e3cc04dd 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -933,10 +933,10 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
- //#if LLVM_MAJOR >= 13
- // // Use the old pass manager in LLVM 14 which the AFL++ passes still
- // use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager";
- //#endif
+ // #if LLVM_MAJOR >= 13
+ // // Use the old pass manager in LLVM 14 which the AFL++ passes still
+ // use. cc_params[cc_par_cnt++] = "-flegacy-pass-manager";
+ // #endif
if (lto_mode && !have_c) {
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 6e4a655b..d9dc50df 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -28,8 +28,8 @@
#include "afl-fuzz.h"
#include "cmplog.h"
-//#define _DEBUG
-//#define CMPLOG_INTROSPECTION
+// #define _DEBUG
+// #define CMPLOG_INTROSPECTION
// CMP attribute enum
enum {
@@ -571,7 +571,7 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) {
}
-//#ifdef CMPLOG_SOLVE_TRANSFORM
+// #ifdef CMPLOG_SOLVE_TRANSFORM
static int strntoll(const char *str, size_t sz, char **end, int base,
long long *out) {
@@ -771,7 +771,7 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
#endif
-//#endif
+// #endif
static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u64 pattern, u64 repl, u64 o_pattern,
@@ -803,8 +803,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
// o_pattern, pattern, repl, changed_val, idx, taint_len,
// hshape, attr);
- //#ifdef CMPLOG_SOLVE_TRANSFORM
- // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3
+ // #ifdef CMPLOG_SOLVE_TRANSFORM
+ // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3
if (afl->cmplog_enable_transform && (lvl & LVL3)) {
u8 *endptr;
@@ -1120,7 +1120,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
- //#endif
+ // #endif
// we only allow this for ascii2integer (above) so leave if this is the case
if (unlikely(pattern == o_pattern)) { return 0; }
@@ -1275,7 +1275,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
// 16 = modified float, 32 = modified integer (modified = wont match
// in original buffer)
- //#ifdef CMPLOG_SOLVE_ARITHMETIC
+ // #ifdef CMPLOG_SOLVE_ARITHMETIC
if (!afl->cmplog_enable_arith || lvl < LVL3 || attr == IS_TRANSFORM) {
return 0;
@@ -1440,8 +1440,8 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
- //#endif /*
- // CMPLOG_SOLVE_ARITHMETIC
+ // #endif /*
+ // CMPLOG_SOLVE_ARITHMETIC
return 0;
@@ -1948,9 +1948,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
#ifndef CMPLOG_COMBINE
(void)(cbuf);
#endif
- //#ifndef CMPLOG_SOLVE_TRANSFORM
- // (void)(changed_val);
- //#endif
+ // #ifndef CMPLOG_SOLVE_TRANSFORM
+ // (void)(changed_val);
+ // #endif
if (afl->fsrv.total_execs - last_update > screen_update) {
@@ -2418,7 +2418,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- //#endif
+ // #endif
return 0;
@@ -2818,9 +2818,9 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
} else if ((lvl & LVL1)
- //#ifdef CMPLOG_SOLVE_TRANSFORM
+ // #ifdef CMPLOG_SOLVE_TRANSFORM
|| ((lvl & LVL3) && afl->cmplog_enable_transform)
- //#endif
+ // #endif
) {
if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) {
diff --git a/utils/afl_untracer/afl-untracer.c b/utils/afl_untracer/afl-untracer.c
index a18e314e..e1038212 100644
--- a/utils/afl_untracer/afl-untracer.c
+++ b/utils/afl_untracer/afl-untracer.c
@@ -288,7 +288,7 @@ library_list_t *find_library(char *name) {
#pragma GCC optimize("O0")
void breakpoint(void) {
- if (debug) fprintf(stderr, "Breakpoint function \"breakpoint\" reached.\n");
+ if (debug) fprintf(stderr, "Breakpoint function \"breakpoint\" reached.\n");
}
diff --git a/utils/libtokencap/libtokencap.so.c b/utils/libtokencap/libtokencap.so.c
index 299056ab..b21f3068 100644
--- a/utils/libtokencap/libtokencap.so.c
+++ b/utils/libtokencap/libtokencap.so.c
@@ -81,7 +81,11 @@ void *(*__libc_memmem)(const void *haystack, size_t haystack_len,
#define MAX_MAPPINGS 1024
-static struct mapping { void *st, *en; } __tokencap_ro[MAX_MAPPINGS];
+static struct mapping {
+
+ void *st, *en;
+
+} __tokencap_ro[MAX_MAPPINGS];
static u32 __tokencap_ro_cnt;
static u8 __tokencap_ro_loaded;
diff --git a/utils/socket_fuzzing/socketfuzz.c b/utils/socket_fuzzing/socketfuzz.c
index 3ec8383b..7497519e 100644
--- a/utils/socket_fuzzing/socketfuzz.c
+++ b/utils/socket_fuzzing/socketfuzz.c
@@ -23,7 +23,8 @@
#include
#include
#include
-//#include "logging.h" // switche from preeny_info() to fprintf(stderr, "Info: "
+// #include "logging.h" // switched from preeny_info() to fprintf(stderr, "Info:
+// "
//
// originals
--
cgit 1.4.1
From d5e3223f0340181e74d352db3def2c98cf14d628 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 23 May 2023 09:01:49 +0200
Subject: fix custom mutator only check
---
src/afl-fuzz.c | 54 +++++++++++++++++++++++++++---------------------------
1 file changed, 27 insertions(+), 27 deletions(-)
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 559a7326..4134b99e 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1746,33 +1746,6 @@ int main(int argc, char **argv_orig, char **envp) {
check_if_tty(afl);
if (afl->afl_env.afl_force_ui) { afl->not_on_tty = 0; }
- if (afl->afl_env.afl_custom_mutator_only) {
-
- if (!afl->custom_mutators_count) {
-
- if (afl->shm.cmplog_mode) {
-
- WARNF(
- "No custom mutator loaded, using AFL_CUSTOM_MUTATOR_ONLY is "
- "pointless and only allowed now to allow experiments with CMPLOG.");
-
- } else {
-
- FATAL(
- "No custom mutator loaded but AFL_CUSTOM_MUTATOR_ONLY specified.");
-
- }
-
- }
-
- /* This ensures we don't proceed to havoc/splice */
- afl->custom_only = 1;
-
- /* Ensure we also skip all deterministic steps */
- afl->skip_deterministic = 1;
-
- }
-
get_core_count(afl);
atexit(at_exit);
@@ -1872,6 +1845,33 @@ int main(int argc, char **argv_orig, char **envp) {
setup_custom_mutators(afl);
+ if (afl->afl_env.afl_custom_mutator_only) {
+
+ if (!afl->custom_mutators_count) {
+
+ if (afl->shm.cmplog_mode) {
+
+ WARNF(
+ "No custom mutator loaded, using AFL_CUSTOM_MUTATOR_ONLY is "
+ "pointless and only allowed now to allow experiments with CMPLOG.");
+
+ } else {
+
+ FATAL(
+ "No custom mutator loaded but AFL_CUSTOM_MUTATOR_ONLY specified.");
+
+ }
+
+ }
+
+ /* This ensures we don't proceed to havoc/splice */
+ afl->custom_only = 1;
+
+ /* Ensure we also skip all deterministic steps */
+ afl->skip_deterministic = 1;
+
+ }
+
if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
if (afl->custom_only) {
--
cgit 1.4.1
From dd736126dc9da78d6828cdf76f7eb8b389af7ed3 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 23 May 2023 09:06:29 +0200
Subject: allow llvm_instrument native
---
src/afl-cc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/afl-cc.c b/src/afl-cc.c
index e3cc04dd..64c0ce66 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -1838,7 +1838,8 @@ int main(int argc, char **argv, char **envp) {
}
if (strncasecmp(ptr2, "llvmnative", strlen("llvmnative")) == 0 ||
- strncasecmp(ptr2, "llvm-native", strlen("llvm-native")) == 0) {
+ strncasecmp(ptr2, "llvm-native", strlen("llvm-native")) == 0 ||
+ strncasecmp(ptr2, "native", strlen("native")) == 0) {
if (!instrument_mode || instrument_mode == INSTRUMENT_LLVMNATIVE)
instrument_mode = INSTRUMENT_LLVMNATIVE;
--
cgit 1.4.1
From 22837b5ad2d1cc6313c706ac9cb7fcd005cd3c2c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 23 May 2023 12:14:58 +0200
Subject: response file fix
---
src/afl-cc.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 64c0ce66..84fe70ec 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -574,14 +574,15 @@ static void process_params(u32 argc, char **argv) {
}
- u8 *tmpbuf = malloc(st.st_size + 1), *ptr;
+ u8 *tmpbuf = malloc(st.st_size + 2), *ptr;
char **args = malloc(sizeof(char *) * (st.st_size >> 1));
int count = 1, cont = 0, cont_act = 0;
- while (fgets(tmpbuf, st.st_size, f)) {
+ while (fgets(tmpbuf, st.st_size + 1, f)) {
ptr = tmpbuf;
- // no leading whitespace
+ // fprintf(stderr, "1: %s\n", ptr);
+ // no leading whitespace
while (isspace(*ptr)) {
++ptr;
@@ -603,6 +604,8 @@ static void process_params(u32 argc, char **argv) {
}
+ // fprintf(stderr, "2: %s\n", ptr);
+
// remove whitespace at end
while (*ptr && isspace(ptr[strlen(ptr) - 1])) {
@@ -611,6 +614,7 @@ static void process_params(u32 argc, char **argv) {
}
+ // fprintf(stderr, "3: %s\n", ptr);
if (*ptr) {
do {
--
cgit 1.4.1
From 8985524d3a7e9991ededcd2e7f01a112b3107871 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 23 May 2023 14:15:36 +0200
Subject: todo
---
TODO.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/TODO.md b/TODO.md
index 2efcefea..d6a2e6fd 100644
--- a/TODO.md
+++ b/TODO.md
@@ -2,6 +2,7 @@
## Should
+ - redo PCGUARD + LTO for llvm 15+
- splicing selection weighted?
- support persistent and deferred fork server in afl-showmap?
- better autodetection of shifting runtime timeout values
--
cgit 1.4.1
From 501226c992e5c47672907c5dde7f968f4e8fb001 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 23 May 2023 14:41:59 +0200
Subject: correct rtn cmplog map size
---
include/cmplog.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/cmplog.h b/include/cmplog.h
index 6e16e6b0..e4821444 100644
--- a/include/cmplog.h
+++ b/include/cmplog.h
@@ -34,7 +34,7 @@
#define CMP_MAP_W 65536
#define CMP_MAP_H 32
-#define CMP_MAP_RTN_H (CMP_MAP_H / 4)
+#define CMP_MAP_RTN_H (CMP_MAP_H / 2)
#define SHAPE_BYTES(x) (x + 1)
--
cgit 1.4.1
From eeed38c5f8335b5a2b69d85b950aa33682a2c079 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 23 May 2023 18:31:34 +0200
Subject: fix gnumakefile for non-gcc
---
GNUmakefile | 11 ++++++++---
src/afl-fuzz-redqueen.c | 12 ++++++------
2 files changed, 14 insertions(+), 9 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 4ecdae52..6962d28a 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -100,8 +100,13 @@ else
LDFLAGS += $(SDK_LD)
endif
+COMPILER_TYPE=$(shell $(CC) --version|grep "Free Software Foundation")
+ifneq ($(COMPILER_TYPE), "")
+ # $(info gcc is being used)
+ CFLAGS_OPT += -Wno-error=format-truncation -Wno-format-truncation
+endif
+
ifeq "$(SYS)" "SunOS"
- CFLAGS_OPT += -Wno-format-truncation
LDFLAGS = -lkstat -lrt -lsocket -lnsl
endif
@@ -139,13 +144,13 @@ endif
ifdef DEBUG
$(info Compiling DEBUG version of binaries)
- override CFLAGS += -ggdb3 -O0 -Wall -Wextra -Werror -Wno-error=format-truncation= $(CFLAGS_OPT)
+ override CFLAGS += -ggdb3 -O0 -Wall -Wextra -Werror $(CFLAGS_OPT)
else
CFLAGS ?= -O2 $(CFLAGS_OPT) # -funroll-loops is slower on modern compilers
endif
override CFLAGS += -g -Wno-pointer-sign -Wno-variadic-macros -Wall -Wextra -Wno-pointer-arith \
- -fPIC -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" -Wno-format-truncation \
+ -fPIC -I include/ -DAFL_PATH=\"$(HELPER_PATH)\" \
-DBIN_PATH=\"$(BIN_PATH)\" -DDOC_PATH=\"$(DOC_PATH)\"
# -fstack-protector
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index d9dc50df..7f42db3f 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -379,7 +379,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
}
- if (++afl->stage_cur % screen_update == 0) { show_stats(afl); };
+ if (unlikely(++afl->stage_cur % screen_update == 0)) { show_stats(afl); };
}
@@ -790,7 +790,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u32 its_len = MIN(len - idx, taint_len);
- if (afl->fsrv.total_execs - last_update > screen_update) {
+ if (unlikely(afl->fsrv.total_execs - last_update > screen_update)) {
show_stats(afl);
last_update = afl->fsrv.total_execs;
@@ -1455,7 +1455,7 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h,
u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf,
u32 len, u8 do_reverse, u8 lvl, u8 *status) {
- if (afl->fsrv.total_execs - last_update > screen_update) {
+ if (unlikely(afl->fsrv.total_execs - last_update > screen_update)) {
show_stats(afl);
last_update = afl->fsrv.total_execs;
@@ -1952,7 +1952,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
// (void)(changed_val);
// #endif
- if (afl->fsrv.total_execs - last_update > screen_update) {
+ if (unlikely(afl->fsrv.total_execs - last_update > screen_update)) {
show_stats(afl);
last_update = afl->fsrv.total_execs;
@@ -2002,10 +2002,10 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- u8 lmax = MAX(l0, ol0);
+ u8 lmin = MIN(l0, ol0);
u8 save[40];
u32 saved_idx = idx, pre, from = 0, to = 0, i, j;
- u32 its_len = MIN(MIN(lmax, hshape), len - idx);
+ u32 its_len = MIN(MIN(lmin, hshape), len - idx);
its_len = MIN(its_len, taint_len);
u32 saved_its_len = its_len;
--
cgit 1.4.1
From b10a0914083911591a8ac816bd4bada6602bf8b5 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 23 May 2023 18:48:03 +0200
Subject: real gcc gnumakefile fix
---
GNUmakefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 6962d28a..715e7386 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -101,8 +101,8 @@ else
endif
COMPILER_TYPE=$(shell $(CC) --version|grep "Free Software Foundation")
-ifneq ($(COMPILER_TYPE), "")
- # $(info gcc is being used)
+ifneq "$(COMPILER_TYPE)" ""
+ #$(info gcc is being used)
CFLAGS_OPT += -Wno-error=format-truncation -Wno-format-truncation
endif
--
cgit 1.4.1
From c323e0dc63e97299da4a2f775f6f1639d5e13bf0 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 23 May 2023 19:46:35 +0200
Subject: revert fix
---
src/afl-fuzz-redqueen.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 7f42db3f..41644cb9 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -2002,10 +2002,10 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- u8 lmin = MIN(l0, ol0);
+ u8 lmax = MAX(l0, ol0);
u8 save[40];
u32 saved_idx = idx, pre, from = 0, to = 0, i, j;
- u32 its_len = MIN(MIN(lmin, hshape), len - idx);
+ u32 its_len = MIN(MIN(lmax, hshape), len - idx);
its_len = MIN(its_len, taint_len);
u32 saved_its_len = its_len;
--
cgit 1.4.1
From c9dfc279c78d9eb1b993cf9ee7ebe07d2d688822 Mon Sep 17 00:00:00 2001
From: fanquake
Date: Tue, 30 May 2023 14:47:34 +0100
Subject: doc: fix logo link in README.md
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 863c2fce..0208a9fe 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
# American Fuzzy Lop plus plus (AFL++)
-
+
Release version: [4.06c](https://github.com/AFLplusplus/AFLplusplus/releases)
--
cgit 1.4.1
From b08e6bf8c6433adf7d34d0c0025c5cc5672f61ee Mon Sep 17 00:00:00 2001
From: fanquake
Date: Tue, 30 May 2023 15:57:24 +0100
Subject: doc: recommend llvm/clang-14 in docs
Might as well recommend installing 14, as that's newer, and what's used
in Docker.
Also remove outdated Dockerfile versions, likely easier to remove
versions here entirely, and anyone that wants to see what version is
used, can look in the Dockerfile.
---
docs/INSTALL.md | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/docs/INSTALL.md b/docs/INSTALL.md
index 637e8658..9005a7eb 100644
--- a/docs/INSTALL.md
+++ b/docs/INSTALL.md
@@ -3,9 +3,8 @@
## Linux on x86
An easy way to install AFL++ with everything compiled is available via docker:
-You can use the [Dockerfile](../Dockerfile) (which has gcc-10 and clang-12 -
-hence afl-clang-lto is available) or just pull directly from the Docker Hub
-(for x86_64 and arm64):
+You can use the [Dockerfile](../Dockerfile) or just pull directly from the
+Docker Hub (for x86_64 and arm64):
```shell
docker pull aflplusplus/aflplusplus:
@@ -21,14 +20,14 @@ development state of AFL++.
If you want to build AFL++ yourself, you have many options. The easiest choice
is to build and install everything:
-NOTE: depending on your Debian/Ubuntu/Kali/... release, replace `-12` with
-whatever llvm version is available. We recommend llvm 12, 13 or 14.
+NOTE: depending on your Debian/Ubuntu/Kali/... release, replace `-14` with
+whatever llvm version is available. We recommend llvm 13, 14, 15 or 16.
```shell
sudo apt-get update
sudo apt-get install -y build-essential python3-dev automake cmake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools cargo libgtk-3-dev
-# try to install llvm 12 and install the distro default if that fails
-sudo apt-get install -y lld-12 llvm-12 llvm-12-dev clang-12 || sudo apt-get install -y lld llvm llvm-dev clang
+# try to install llvm 14 and install the distro default if that fails
+sudo apt-get install -y lld-14 llvm-14 llvm-14-dev clang-14 || sudo apt-get install -y lld llvm llvm-dev clang
sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/\..*//'|sed 's/.* //')-dev
sudo apt-get install -y ninja-build # for QEMU mode
git clone https://github.com/AFLplusplus/AFLplusplus
--
cgit 1.4.1
From ad8f7d6eb3be245202ace23d4d1dd9152647a775 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 31 May 2023 11:40:48 +0200
Subject: switch user mailinglist reference to discord
---
TODO.md | 1 +
src/afl-forkserver.c | 8 ++++----
src/afl-fuzz-init.c | 4 ++--
3 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/TODO.md b/TODO.md
index d6a2e6fd..dc02a914 100644
--- a/TODO.md
+++ b/TODO.md
@@ -3,6 +3,7 @@
## Should
- redo PCGUARD + LTO for llvm 15+
+ - test cmplog for less than 16bit
- splicing selection weighted?
- support persistent and deferred fork server in afl-showmap?
- better autodetection of shifting runtime timeout values
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 30c8901c..7322f1ad 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -1226,7 +1226,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
" - Less likely, there is a horrible bug in the fuzzer. If other "
"options\n"
- " fail, poke for troubleshooting "
+ " fail, poke the Awesome Fuzzing Discord for troubleshooting "
"tips.\n");
} else {
@@ -1271,7 +1271,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
" - Less likely, there is a horrible bug in the fuzzer. If other "
"options\n"
- " fail, poke for troubleshooting "
+ " fail, poke the Awesome Fuzzing Discord for troubleshooting "
"tips.\n",
stringify_mem_size(val_buf, sizeof(val_buf), fsrv->mem_limit << 20),
fsrv->mem_limit - 1);
@@ -1321,7 +1321,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
" Retry with setting AFL_MAP_SIZE=10000000.\n\n"
"Otherwise there is a horrible bug in the fuzzer.\n"
- "Poke for troubleshooting tips.\n");
+ "Poke the Awesome Fuzzing Discord for troubleshooting tips.\n");
} else {
@@ -1370,7 +1370,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
" - Less likely, there is a horrible bug in the fuzzer. If other "
"options\n"
- " fail, poke for troubleshooting "
+ " fail, poke the Awesome Fuzzing Discord for troubleshooting "
"tips.\n",
getenv(DEFER_ENV_VAR)
? " - You are using deferred forkserver, but __AFL_INIT() is "
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index baf56a5f..13802f40 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1012,7 +1012,7 @@ void perform_dry_run(afl_state_t *afl) {
" - Least likely, there is a horrible bug in the fuzzer. If "
"other options\n"
- " fail, poke for "
+ " fail, poke the Awesome Fuzzing Discord for "
"troubleshooting tips.\n",
stringify_mem_size(val_buf, sizeof(val_buf),
afl->fsrv.mem_limit << 20),
@@ -1041,7 +1041,7 @@ void perform_dry_run(afl_state_t *afl) {
" - Least likely, there is a horrible bug in the fuzzer. If "
"other options\n"
- " fail, poke for "
+ " fail, poke the Awesome Fuzzing Discord for "
"troubleshooting tips.\n");
}
--
cgit 1.4.1
From e596c9856b636d6c227115655aa74f316d8f27ca Mon Sep 17 00:00:00 2001
From: Your Name
Date: Wed, 31 May 2023 19:15:18 +0100
Subject: Support for instrumentation more than GB away from data structures
---
frida_mode/src/instrument/instrument_arm64.c | 231 ++++++++++++++++++++++-----
frida_mode/test/testinstr/GNUmakefile | 5 +
2 files changed, 198 insertions(+), 38 deletions(-)
diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c
index 4372861d..131eb4c5 100644
--- a/frida_mode/src/instrument/instrument_arm64.c
+++ b/frida_mode/src/instrument/instrument_arm64.c
@@ -76,6 +76,45 @@ typedef struct {
} afl_log_code_asm_t;
+typedef struct {
+
+ uint32_t b_imm8; /* br #XX (end) */
+
+ uint32_t restoration_prolog; /* ldp x16, x17, [sp], #0x90 */
+
+ uint32_t stp_x0_x1; /* stp x0, x1, [sp, #-0xa0] */
+
+ uint32_t ldr_x0_p_prev_loc_1; /* ldr x0, #0xXXXX */
+ uint32_t ldr_x1_ptr_x0; /* ldr x1, [x0] */
+
+ uint32_t ldr_x0_p_area_offset; /* ldr x0, #0xXXXX */
+ uint32_t eor_x0_x1_x0; /* eor x0, x1, x0 */
+ uint32_t ldr_x1_p_area_ptr; /* ldr x1, #0xXXXX */
+ uint32_t add_x0_x1_x0; /* add x0, x1, x0 */
+
+ uint32_t ldrb_w1_x0; /* ldrb w1, [x0] */
+ uint32_t add_w1_w1_1; /* add w1, w1, #1 */
+ uint32_t add_w1_w1_w1_lsr_8; /* add x1, x1, x1, lsr #8 */
+
+ uint32_t strb_w1_ptr_x0; /* strb w1, [x0] */
+
+ uint32_t ldr_x0_p_prev_loc_2; /* ldr x0, #0xXXXX */
+ uint32_t ldr_x1_p_area_offset_ror; /* ldr x1, #0xXXXX */
+ uint32_t str_x1_ptr_x0; /* str x1, [x0] */
+
+ uint32_t ldp_x0_x1; /* ldp x0, x1, [sp, #-0xa0] */
+
+ uint32_t b_end; /* skip the data */
+
+ uint64_t area_ptr;
+ uint64_t prev_loc_ptr;
+ uint64_t area_offset;
+ uint64_t area_offset_ror;
+
+ uint8_t end[0];
+
+} afl_log_code_asm_long_t;
+
#pragma pack(pop)
typedef union {
@@ -85,6 +124,13 @@ typedef union {
} afl_log_code;
+typedef union {
+
+ afl_log_code_asm_long_t code;
+ uint8_t bytes[0];
+
+} afl_log_code_long;
+
static const afl_log_code_asm_t template =
{
@@ -119,6 +165,46 @@ static const afl_log_code_asm_t template =
;
+static const afl_log_code_asm_long_t template_long =
+ {.b_imm8 = 0x1400001a,
+
+ .restoration_prolog = 0xa8c947f0, /* ldp x16, x17, [sp], #0x90 */
+
+ .stp_x0_x1 = 0xa93607e0, /* stp x0, x1, [sp, #-0xa0] */
+
+ .ldr_x0_p_prev_loc_1 = 0x58000220, /* ldr x0, #0xXXXX */
+ .ldr_x1_ptr_x0 = 0xf9400001, /* ldr x1, [x0] */
+
+ .ldr_x0_p_area_offset = 0x58000220, /* ldr x0, #0xXXXX */
+ .eor_x0_x1_x0 = 0xca000020, /* eor x0, x1, x0 */
+ .ldr_x1_p_area_ptr = 0x58000161, /* ldr x1, #0xXXXX */
+ .add_x0_x1_x0 = 0x8b000020, /* add x0, x1, x0 */
+
+ .ldrb_w1_x0 = 0x39400001, /* ldrb w1, [x0] */
+ .add_w1_w1_1 = 0x11000421, /* add w1, w1, #1 */
+ .add_w1_w1_w1_lsr_8 = 0x8b412021, /* add x1, x1, x1, lsr #8 */
+
+ .strb_w1_ptr_x0 = 0x39000001, /* strb w1, [x0] */
+
+ .ldr_x0_p_prev_loc_2 = 0x580000e0, /* ldr x0, #0xXXXX */
+ .ldr_x1_p_area_offset_ror = 0x58000141, /* ldr x1, #0xXXXX */
+ .str_x1_ptr_x0 = 0xf9000001, /* str x1, [x0] */
+
+ .ldp_x0_x1 = 0xa97607e0, /* ldp x0, x1, [sp, #-0xa0] */
+
+ .b_end = 0x14000009, /* skip the data */
+
+ .area_ptr = 0x0,
+ .prev_loc_ptr = 0x0,
+ .area_offset = 0x0,
+ .area_offset_ror = 0x0,
+
+ .end = {}
+
+}
+
+;
+
gboolean instrument_is_coverage_optimize_supported(void) {
return true;
@@ -266,16 +352,22 @@ static gboolean instrument_coverage_in_range(gssize offset) {
}
-static void instrument_patch_ardp(guint32 *patch, GumAddress insn,
+static bool instrument_patch_ardp(guint32 *patch, GumAddress insn,
GumAddress target) {
- if (!PAGE_ALIGNED(target)) { FATAL("Target not page aligned"); }
+ if (!PAGE_ALIGNED(target)) {
+
+ FWARNF("Target not page aligned");
+ return false;
+
+ }
gssize distance = target - (GUM_ADDRESS(insn) & PAGE_MASK);
if (!instrument_coverage_in_range(distance)) {
- FATAL("Patch out of range 0x%016lX->0x%016lX = 0x%016lX", insn, target,
- distance);
+ FVERBOSE("Patch out of range 0x%016lX->0x%016lX = 0x%016lX", insn, target,
+ distance);
+ return false;
}
@@ -283,6 +375,95 @@ static void instrument_patch_ardp(guint32 *patch, GumAddress insn,
guint32 imm_high = ((distance >> 14) & 0x7FFFF) << 5;
*patch |= imm_low;
*patch |= imm_high;
+ return true;
+
+}
+
+bool instrument_write_inline(GumArm64Writer *cw, GumAddress code_addr,
+ guint64 area_offset, gsize area_offset_ror) {
+
+ afl_log_code code = {0};
+ code.code = template;
+
+ /*
+ * Given our map is allocated on a 64KB boundary and our map is a multiple of
+ * 64KB in size, then it should also end on a 64 KB boundary. It is followed
+ * by our previous_pc, so this too should be 64KB aligned.
+ */
+ g_assert(PAGE_ALIGNED(instrument_previous_pc_addr));
+ g_assert(PAGE_ALIGNED(__afl_area_ptr));
+
+ if (!instrument_patch_ardp(
+ &code.code.adrp_x0_prev_loc1,
+ code_addr + offsetof(afl_log_code, code.adrp_x0_prev_loc1),
+ GUM_ADDRESS(instrument_previous_pc_addr))) {
+
+ return false;
+
+ }
+
+ code.code.mov_x0_curr_loc |= area_offset << 5;
+
+ if (!instrument_patch_ardp(
+ &code.code.adrp_x1_area_ptr,
+ code_addr + offsetof(afl_log_code, code.adrp_x1_area_ptr),
+ GUM_ADDRESS(__afl_area_ptr))) {
+
+ return false;
+
+ }
+
+ if (!instrument_patch_ardp(
+ &code.code.adrp_x0_prev_loc2,
+ code_addr + offsetof(afl_log_code, code.adrp_x0_prev_loc2),
+ GUM_ADDRESS(instrument_previous_pc_addr))) {
+
+ return false;
+
+ }
+
+ code.code.mov_x1_curr_loc_shr_1 |= (area_offset_ror << 5);
+
+ if (instrument_suppress) {
+
+ gum_arm64_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
+
+ } else {
+
+ size_t offset = offsetof(afl_log_code, code.stp_x0_x1);
+ gum_arm64_writer_put_bytes(cw, &code.bytes[offset],
+ sizeof(afl_log_code) - offset);
+
+ }
+
+ return true;
+
+}
+
+bool instrument_write_inline_long(GumArm64Writer *cw, GumAddress code_addr,
+ guint64 area_offset, gsize area_offset_ror) {
+
+ afl_log_code_long code = {0};
+ code.code = template_long;
+
+ code.code.area_ptr = GUM_ADDRESS(__afl_area_ptr);
+ code.code.prev_loc_ptr = GUM_ADDRESS(instrument_previous_pc_addr);
+ code.code.area_offset = area_offset;
+ code.code.area_offset_ror = GUM_ADDRESS(area_offset_ror);
+
+ if (instrument_suppress) {
+
+ gum_arm64_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code_long));
+
+ } else {
+
+ size_t offset = offsetof(afl_log_code_long, code.stp_x0_x1);
+ gum_arm64_writer_put_bytes(cw, &code.bytes[offset],
+ sizeof(afl_log_code_long) - offset);
+
+ }
+
+ return true;
}
@@ -312,6 +493,8 @@ void instrument_coverage_optimize(const cs_insn *instr,
}
// gum_arm64_writer_put_brk_imm(cw, 0x0);
+ // uint32_t jmp_dot = 0x14000000;
+ // gum_arm64_writer_put_bytes(cw, (guint8 *)&jmp_dot, sizeof(jmp_dot));
if (instrument_suppress) { instrument_coverage_suppress_init(); }
@@ -343,47 +526,19 @@ void instrument_coverage_optimize(const cs_insn *instr,
}
- code.code = template;
-
- /*
- * Given our map is allocated on a 64KB boundary and our map is a multiple of
- * 64KB in size, then it should also end on a 64 KB boundary. It is followed
- * by our previous_pc, so this too should be 64KB aligned.
- */
- g_assert(PAGE_ALIGNED(instrument_previous_pc_addr));
- g_assert(PAGE_ALIGNED(__afl_area_ptr));
-
- instrument_patch_ardp(
- &code.code.adrp_x0_prev_loc1,
- code_addr + offsetof(afl_log_code, code.adrp_x0_prev_loc1),
- GUM_ADDRESS(instrument_previous_pc_addr));
-
- code.code.mov_x0_curr_loc |= area_offset << 5;
-
- instrument_patch_ardp(
- &code.code.adrp_x1_area_ptr,
- code_addr + offsetof(afl_log_code, code.adrp_x1_area_ptr),
- GUM_ADDRESS(__afl_area_ptr));
-
map_size_pow2 = util_log2(__afl_map_size);
area_offset_ror = util_rotate(area_offset, 1, map_size_pow2);
- instrument_patch_ardp(
- &code.code.adrp_x0_prev_loc2,
- code_addr + offsetof(afl_log_code, code.adrp_x0_prev_loc2),
- GUM_ADDRESS(instrument_previous_pc_addr));
-
- code.code.mov_x1_curr_loc_shr_1 |= (area_offset_ror << 5);
+ code.code = template;
- if (instrument_suppress) {
+ if (!instrument_write_inline(cw, code_addr, area_offset, area_offset_ror)) {
- gum_arm64_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
+ if (!instrument_write_inline_long(cw, code_addr, area_offset,
+ area_offset_ror)) {
- } else {
+ FATAL("Failed to write inline instrumentation");
- size_t offset = offsetof(afl_log_code, code.stp_x0_x1);
- gum_arm64_writer_put_bytes(cw, &code.bytes[offset],
- sizeof(afl_log_code) - offset);
+ }
}
diff --git a/frida_mode/test/testinstr/GNUmakefile b/frida_mode/test/testinstr/GNUmakefile
index ebc0b2dc..46d9b85f 100644
--- a/frida_mode/test/testinstr/GNUmakefile
+++ b/frida_mode/test/testinstr/GNUmakefile
@@ -67,3 +67,8 @@ debug:
--ex 'set environment LD_PRELOAD=$(ROOT)afl-frida-trace.so' \
--ex 'set disassembly-flavor intel' \
--args $(TESTINSTBIN) $(TESTINSTR_DATA_FILE)
+
+lldb:
+ lldb \
+ -O 'settings set target.env-vars DYLD_INSERT_LIBRARIES=$(ROOT)afl-frida-trace.so' \
+ -- $(TESTINSTBIN) $(TESTINSTR_DATA_FILE)
--
cgit 1.4.1
From 06e1c64745ed37bd826ff6f2c1a42340684998dc Mon Sep 17 00:00:00 2001
From: Your Name
Date: Wed, 31 May 2023 17:34:36 +0100
Subject: Changes to support defered start
---
frida_mode/include/entry.h | 2 --
frida_mode/src/entry.c | 26 +--------------------
frida_mode/src/instrument/instrument.c | 1 -
frida_mode/src/main.c | 41 +++++++++++++++++++++++++++++-----
4 files changed, 37 insertions(+), 33 deletions(-)
diff --git a/frida_mode/include/entry.h b/frida_mode/include/entry.h
index edc41467..949fab71 100644
--- a/frida_mode/include/entry.h
+++ b/frida_mode/include/entry.h
@@ -14,8 +14,6 @@ void entry_init(void);
void entry_start(void);
-void entry_prologue(GumStalkerIterator *iterator, GumStalkerOutput *output);
-
void entry_on_fork(void);
#endif
diff --git a/frida_mode/src/entry.c b/frida_mode/src/entry.c
index 05af7ebb..fc49b4d7 100644
--- a/frida_mode/src/entry.c
+++ b/frida_mode/src/entry.c
@@ -78,31 +78,7 @@ void entry_init(void) {
void entry_start(void) {
- if (persistent_start == 0) {
-
- ranges_exclude();
- stalker_trust();
-
- }
-
- if (entry_point == 0) { entry_launch(); }
-
-}
-
-static void entry_callout(GumCpuContext *cpu_context, gpointer user_data) {
-
- UNUSED_PARAMETER(cpu_context);
- UNUSED_PARAMETER(user_data);
- entry_compiled = TRUE;
- entry_launch();
-
-}
-
-void entry_prologue(GumStalkerIterator *iterator, GumStalkerOutput *output) {
-
- UNUSED_PARAMETER(output);
FVERBOSE("AFL_ENTRYPOINT reached");
-
if (persistent_start == 0) {
ranges_exclude();
@@ -110,7 +86,7 @@ void entry_prologue(GumStalkerIterator *iterator, GumStalkerOutput *output) {
}
- gum_stalker_iterator_put_callout(iterator, entry_callout, NULL, NULL);
+ entry_launch();
}
diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c
index a6aac666..db73d845 100644
--- a/frida_mode/src/instrument/instrument.c
+++ b/frida_mode/src/instrument/instrument.c
@@ -169,7 +169,6 @@ static void instrument_basic_block(GumStalkerIterator *iterator,
if (unlikely(begin)) { instrument_debug_start(instr->address, output); }
- if (instr->address == entry_point) { entry_prologue(iterator, output); }
if (instr->address == persistent_start) { persistent_prologue(output); }
if (instr->address == persistent_ret) { persistent_epilogue(output); }
diff --git a/frida_mode/src/main.c b/frida_mode/src/main.c
index c8c50b37..f11c4b25 100644
--- a/frida_mode/src/main.c
+++ b/frida_mode/src/main.c
@@ -197,7 +197,7 @@ static void afl_print_env(void) {
}
-__attribute__((visibility("default"))) void afl_frida_start(void) {
+void afl_frida_config(void) {
FOKF(cRED "**********************");
FOKF(cRED "* " cYEL "******************" cRED " *");
@@ -225,9 +225,7 @@ __attribute__((visibility("default"))) void afl_frida_start(void) {
js_start();
- /* Initialize */
output_init();
-
embedded_init();
entry_init();
instrument_init();
@@ -240,12 +238,35 @@ __attribute__((visibility("default"))) void afl_frida_start(void) {
ranges_init();
stats_init();
- /* Start */
+}
+
+void afl_frida_run(void) {
+
stalker_start();
entry_start();
}
+__attribute__((visibility("default"))) void afl_frida_start(void) {
+
+ afl_frida_config();
+ afl_frida_run();
+
+}
+
+typedef void *(*entry_func_t)(size_t a1, size_t a2, size_t a3, size_t a4,
+ size_t a5, size_t a6);
+
+static void *on_entry(size_t a1, size_t a2, size_t a3, size_t a4, size_t a5,
+ size_t a6) {
+
+ intercept_unhook(GSIZE_TO_POINTER(entry_point));
+ afl_frida_run();
+ entry_func_t entry = (entry_func_t)entry_point;
+ return entry(a1, a2, a3, a4, a5, a6);
+
+}
+
static int on_main(int argc, char **argv, char **envp) {
int ret;
@@ -254,7 +275,17 @@ static int on_main(int argc, char **argv, char **envp) {
intercept_unhook_self();
- afl_frida_start();
+ afl_frida_config();
+
+ if (entry_point == 0) {
+
+ afl_frida_run();
+
+ } else {
+
+ intercept_hook(GSIZE_TO_POINTER(entry_point), on_entry, NULL);
+
+ }
if (js_main_hook != NULL) {
--
cgit 1.4.1
From 9324f3f6289c62451e2add1f7553a7eda0d7d642 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 1 Jun 2023 12:19:45 +0200
Subject: rewrote PCGUARD
---
GNUmakefile.llvm | 4 +-
TODO.md | 2 -
afl-cmin.bash | 4 +-
docs/Changelog.md | 5 +-
instrumentation/SanitizerCoveragePCGUARD.so.cc | 603 +++++++++----------------
src/afl-cc.c | 31 +-
6 files changed, 249 insertions(+), 400 deletions(-)
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index 2bb4e7f8..6c68f1f3 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -49,7 +49,7 @@ LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[
LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[5-9]' && echo 1 || echo 0 )
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[0-9]' && echo 1 || echo 0 )
LLVM_NEWER_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[6-9]' && echo 1 || echo 0 )
-LLVM_10_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[1-9]|^10\.[1-9]|^10\.0.[1-9]' && echo 1 || echo 0 )
+LLVM_13_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[3-9]' && echo 1 || echo 0 )
LLVM_HAVE_LTO = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[1-9]' && echo 1 || echo 0 )
LLVM_BINDIR = $(shell $(LLVM_CONFIG) --bindir 2>/dev/null)
LLVM_LIBDIR = $(shell $(LLVM_CONFIG) --libdir 2>/dev/null)
@@ -422,7 +422,7 @@ endif
$(CXX) $(CLANG_CPPFL) -Wdeprecated -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) instrumentation/afl-llvm-common.o
./SanitizerCoveragePCGUARD.so: instrumentation/SanitizerCoveragePCGUARD.so.cc instrumentation/afl-llvm-common.o | test_deps
-ifeq "$(LLVM_10_OK)" "1"
+ifeq "$(LLVM_13_OK)" "1"
-$(CXX) $(CLANG_CPPFL) -fno-rtti -fPIC -std=$(LLVM_STDCXX) -shared $< -o $@ $(CLANG_LFL) -Wno-deprecated-copy-dtor -Wdeprecated instrumentation/afl-llvm-common.o
endif
diff --git a/TODO.md b/TODO.md
index dc02a914..2b7e8fcf 100644
--- a/TODO.md
+++ b/TODO.md
@@ -2,9 +2,7 @@
## Should
- - redo PCGUARD + LTO for llvm 15+
- test cmplog for less than 16bit
- - splicing selection weighted?
- support persistent and deferred fork server in afl-showmap?
- better autodetection of shifting runtime timeout values
- Update afl->pending_not_fuzzed for MOpt
diff --git a/afl-cmin.bash b/afl-cmin.bash
index d390ff65..dc6d5342 100755
--- a/afl-cmin.bash
+++ b/afl-cmin.bash
@@ -206,7 +206,7 @@ fi
# Check for obvious errors.
-if [ ! "$T_ARG" = "" -a ! "$F_ARG" = "" -a ! "$NYX_MODE" == 1 ]; then
+if [ ! "$T_ARG" = "" -a -n "$F_ARG" -a ! "$NYX_MODE" == 1 ]; then
echo "[-] Error: -T and -f can not be used together." 1>&2
exit 1
fi
@@ -323,7 +323,7 @@ if [ ! "$T_ARG" = "" ]; then
fi
fi
else
- if [ "$F_ARG" = ""]; then
+ if [ -z "$F_ARG" ]; then
echo "[*] Are you aware of the '-T all' parallelize option that massively improves the speed?"
fi
fi
diff --git a/docs/Changelog.md b/docs/Changelog.md
index e99747f6..facf2196 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -15,13 +15,16 @@
- new env `AFL_LLVM_LTO_SKIPINIT` to support the AFL++ based WASM
(https://github.com/fgsect/WAFL) project
- error and print help if afl-clan-lto is used with lto=thin
+ - rewrote our PCGUARD pass to be compatible with LLVM 15+ shenanigans,
+ requires LLVM 13+ now instead of 10.0.1+
+ - fallback to native LLVM PCGUARD if our PCGUARD is unavailable
- afl-showmap:
- added custom mutator post_process and send support
- add `-I filelist` option, an alternative to `-i in_dir`
- afl-cmin + afl-cmin.bash:
- `-T threads` parallel task support, can be a huge speedup!
- qemu_mode:
- - Persistent mode +QASAN support for ppc32 tragets by @worksbutnottested
+ - Persistent mode + QASAN support for ppc32 targets by @worksbutnottested
- a new grammar custom mutator atnwalk was submitted by @voidptr127 !
- two new custom mutators are now available:
- TritonDSE in custom_mutators/aflpp_tritondse
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 8fed2042..2abc58ec 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -13,42 +13,64 @@
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
+#if LLVM_VERSION_MAJOR >= 15
+ #if LLVM_VERSION_MAJOR < 17
+ #include "llvm/ADT/Triple.h"
+ #endif
+#endif
#if LLVM_VERSION_MAJOR < 17
- #include "llvm/ADT/Triple.h"
#include "llvm/Analysis/EHPersonalities.h"
-#else
- #include "llvm/IR/EHPersonalities.h"
#endif
#include "llvm/Analysis/PostDominators.h"
-#include "llvm/IR/CFG.h"
+#if LLVM_VERSION_MAJOR < 15
+ #include "llvm/IR/CFG.h"
+#endif
#include "llvm/IR/Constant.h"
#include "llvm/IR/DataLayout.h"
-#include "llvm/IR/DebugInfo.h"
+#if LLVM_VERSION_MAJOR < 15
+ #include "llvm/IR/DebugInfo.h"
+#endif
#include "llvm/IR/Dominators.h"
+#if LLVM_VERSION_MAJOR >= 17
+ #include "llvm/Analysis/EHPersonalities.h"
+#endif
#include "llvm/IR/Function.h"
-#include "llvm/IR/GlobalVariable.h"
+#if LLVM_VERSION_MAJOR >= 16
+ #include "llvm/IR/GlobalVariable.h"
+#endif
#include "llvm/IR/IRBuilder.h"
-#include "llvm/IR/InlineAsm.h"
+#if LLVM_VERSION_MAJOR < 15
+ #include "llvm/IR/InlineAsm.h"
+#endif
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
-#include "llvm/IR/MDBuilder.h"
-#include "llvm/IR/Mangler.h"
+#if LLVM_VERSION_MAJOR < 15
+ #include "llvm/IR/MDBuilder.h"
+ #include "llvm/IR/Mangler.h"
+#endif
#include "llvm/IR/Module.h"
#include "llvm/IR/PassManager.h"
+#include "llvm/Passes/PassBuilder.h"
+#include "llvm/Passes/PassPlugin.h"
#include "llvm/IR/Type.h"
-#include "llvm/InitializePasses.h"
+#if LLVM_VERSION_MAJOR < 17
+ #include "llvm/InitializePasses.h"
+#endif
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/SpecialCaseList.h"
#include "llvm/Support/VirtualFileSystem.h"
-#include "llvm/Support/raw_ostream.h"
-#include "llvm/Transforms/Instrumentation.h"
+#if LLVM_VERSION_MAJOR < 15
+ #include "llvm/Support/raw_ostream.h"
+#endif
+#if LLVM_VERSION_MAJOR < 17
+ #include "llvm/Transforms/Instrumentation.h"
+#else
+ #include "llvm/TargetParser/Triple.h"
+#endif
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Transforms/Utils/ModuleUtils.h"
-#include "llvm/Passes/PassPlugin.h"
-#include "llvm/Passes/PassBuilder.h"
-#include "llvm/IR/PassManager.h"
#include "config.h"
#include "debug.h"
@@ -58,7 +80,8 @@ using namespace llvm;
#define DEBUG_TYPE "sancov"
-const char SanCovTracePCIndirName[] = "__sanitizer_cov_trace_pc_indir";
+static const uint64_t SanCtorAndDtorPriority = 2;
+
const char SanCovTracePCName[] = "__sanitizer_cov_trace_pc";
const char SanCovTraceCmp1[] = "__sanitizer_cov_trace_cmp1";
const char SanCovTraceCmp2[] = "__sanitizer_cov_trace_cmp2";
@@ -68,22 +91,13 @@ const char SanCovTraceConstCmp1[] = "__sanitizer_cov_trace_const_cmp1";
const char SanCovTraceConstCmp2[] = "__sanitizer_cov_trace_const_cmp2";
const char SanCovTraceConstCmp4[] = "__sanitizer_cov_trace_const_cmp4";
const char SanCovTraceConstCmp8[] = "__sanitizer_cov_trace_const_cmp8";
-const char SanCovTraceDiv4[] = "__sanitizer_cov_trace_div4";
-const char SanCovTraceDiv8[] = "__sanitizer_cov_trace_div8";
-const char SanCovTraceGep[] = "__sanitizer_cov_trace_gep";
const char SanCovTraceSwitchName[] = "__sanitizer_cov_trace_switch";
+
const char SanCovModuleCtorTracePcGuardName[] =
"sancov.module_ctor_trace_pc_guard";
-const char SanCovModuleCtor8bitCountersName[] =
- "sancov.module_ctor_8bit_counters";
-const char SanCovModuleCtorBoolFlagName[] = "sancov.module_ctor_bool_flag";
-static const uint64_t SanCtorAndDtorPriority = 2;
+const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init";
const char SanCovTracePCGuardName[] = "__sanitizer_cov_trace_pc_guard";
-const char SanCovTracePCGuardInitName[] = "__sanitizer_cov_trace_pc_guard_init";
-const char SanCov8bitCountersInitName[] = "__sanitizer_cov_8bit_counters_init";
-const char SanCovBoolFlagInitName[] = "__sanitizer_cov_bool_flag_init";
-const char SanCovPCsInitName[] = "__sanitizer_cov_pcs_init";
const char SanCovGuardsSectionName[] = "sancov_guards";
const char SanCovCountersSectionName[] = "sancov_cntrs";
@@ -99,27 +113,9 @@ namespace {
SanitizerCoverageOptions OverrideFromCL(SanitizerCoverageOptions Options) {
- // Sets CoverageType and IndirectCalls.
- // SanitizerCoverageOptions CLOpts = getOptions(ClCoverageLevel);
- Options.CoverageType =
- SanitizerCoverageOptions::SCK_Edge; // std::max(Options.CoverageType,
- // CLOpts.CoverageType);
- Options.IndirectCalls = false; // CLOpts.IndirectCalls;
- Options.TraceCmp = false; //|= ClCMPTracing;
- Options.TraceDiv = false; //|= ClDIVTracing;
- Options.TraceGep = false; //|= ClGEPTracing;
- Options.TracePC = false; //|= ClTracePC;
- Options.TracePCGuard = true; // |= ClTracePCGuard;
- Options.Inline8bitCounters = 0; //|= ClInline8bitCounters;
- // Options.InlineBoolFlag = 0; //|= ClInlineBoolFlag;
- Options.PCTable = false; //|= ClCreatePCTable;
- Options.NoPrune = false; //|= !ClPruneBlocks;
- Options.StackDepth = false; //|= ClStackDepth;
- if (!Options.TracePCGuard && !Options.TracePC &&
- !Options.Inline8bitCounters && !Options.StackDepth /*&&
- !Options.InlineBoolFlag*/)
- Options.TracePCGuard = true; // TracePCGuard is default.
-
+ Options.CoverageType = SanitizerCoverageOptions::SCK_Edge;
+ // Options.NoPrune = true;
+ Options.TracePCGuard = true; // TracePCGuard is default.
return Options;
}
@@ -139,20 +135,13 @@ class ModuleSanitizerCoverageAFL
}
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
-
- bool instrumentModule(Module &M, DomTreeCallback DTCallback,
- PostDomTreeCallback PDTCallback);
+ bool instrumentModule(Module &M, DomTreeCallback DTCallback,
+ PostDomTreeCallback PDTCallback);
private:
void instrumentFunction(Function &F, DomTreeCallback DTCallback,
PostDomTreeCallback PDTCallback);
- void InjectCoverageForIndirectCalls(Function &F,
- ArrayRef IndirCalls);
void InjectTraceForCmp(Function &F, ArrayRef CmpTraceTargets);
- void InjectTraceForDiv(Function &F,
- ArrayRef DivTraceTargets);
- void InjectTraceForGep(Function &F,
- ArrayRef GepTraceTargets);
void InjectTraceForSwitch(Function &F,
ArrayRef SwitchTraceTargets);
bool InjectCoverage(Function &F, ArrayRef AllBlocks,
@@ -173,20 +162,23 @@ class ModuleSanitizerCoverageAFL
void SetNoSanitizeMetadata(Instruction *I) {
+#if LLVM_VERSION_MAJOR == 15
+ I->setMetadata(LLVMContext::MD_nosanitize, MDNode::get(*C, None));
+#elif LLVM_VERSION_MAJOR >= 16
+ I->setMetadata(LLVMContext::MD_nosanitize, MDNode::get(*C, std::nullopt));
+#else
I->setMetadata(I->getModule()->getMDKindID("nosanitize"),
MDNode::get(*C, None));
+#endif
}
std::string getSectionName(const std::string &Section) const;
std::string getSectionStart(const std::string &Section) const;
std::string getSectionEnd(const std::string &Section) const;
- FunctionCallee SanCovTracePCIndir;
FunctionCallee SanCovTracePC, SanCovTracePCGuard;
FunctionCallee SanCovTraceCmpFunction[4];
FunctionCallee SanCovTraceConstCmpFunction[4];
- FunctionCallee SanCovTraceDivFunction[2];
- FunctionCallee SanCovTraceGepFunction;
FunctionCallee SanCovTraceSwitchFunction;
GlobalVariable *SanCovLowestStack;
Type *IntptrTy, *IntptrPtrTy, *Int64Ty, *Int64PtrTy, *Int32Ty, *Int32PtrTy,
@@ -215,18 +207,16 @@ class ModuleSanitizerCoverageAFL
} // namespace
-#if LLVM_VERSION_MAJOR >= 11 /* use new pass manager */
-
extern "C" ::llvm::PassPluginLibraryInfo LLVM_ATTRIBUTE_WEAK
llvmGetPassPluginInfo() {
- return {LLVM_PLUGIN_API_VERSION, "SanitizerCoveragePCGUARD", "v0.1",
+ return {LLVM_PLUGIN_API_VERSION, "SanitizerCoveragePCGUARD", "v0.2",
/* lambda to insert our pass into the pass pipeline. */
[](PassBuilder &PB) {
- #if LLVM_VERSION_MAJOR <= 13
+#if LLVM_VERSION_MAJOR == 13
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
- #endif
+#endif
PB.registerOptimizerLastEPCallback(
[](ModulePassManager &MPM, OptimizationLevel OL) {
@@ -238,8 +228,7 @@ llvmGetPassPluginInfo() {
}
-#endif
-
+#if LLVM_VERSION_MAJOR == 1
PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
ModuleAnalysisManager &MAM) {
@@ -257,34 +246,65 @@ PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
};
+ if (!ModuleSancov.instrumentModule(M, DTCallback, PDTCallback))
+ return PreservedAnalyses::all();
+
+ PreservedAnalyses PA = PreservedAnalyses::none();
+ // GlobalsAA is considered stateless and does not get invalidated unless
+ // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
+ // make changes that require GlobalsAA to be invalidated.
+ PA.abandon();
+ return PA;
+
+}
+
+#else
+ #if LLVM_VERSION_MAJOR >= 16
+PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+
+ #else
+PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
+ ModuleAnalysisManager &MAM) {
+
+ #endif
+ ModuleSanitizerCoverageAFL ModuleSancov(Options);
+ auto &FAM = MAM.getResult(M).getManager();
+ auto DTCallback = [&FAM](Function &F) -> const DominatorTree * {
+
+ return &FAM.getResult(F);
+
+ };
+
+ auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree * {
+
+ return &FAM.getResult(F);
+
+ };
+
if (ModuleSancov.instrumentModule(M, DTCallback, PDTCallback))
return PreservedAnalyses::none();
return PreservedAnalyses::all();
}
+#endif
+
std::pair ModuleSanitizerCoverageAFL::CreateSecStartEnd(
Module &M, const char *Section, Type *Ty) {
- GlobalVariable *SecStart =
- new GlobalVariable(M,
-#if LLVM_VERSION_MAJOR >= 15
- Ty,
-#else
- Ty->getPointerElementType(),
-#endif
- false, GlobalVariable::ExternalWeakLinkage, nullptr,
- getSectionStart(Section));
+ // Use ExternalWeak so that if all sections are discarded due to section
+ // garbage collection, the linker will not report undefined symbol errors.
+ // Windows defines the start/stop symbols in compiler-rt so no need for
+ // ExternalWeak.
+ GlobalValue::LinkageTypes Linkage = TargetTriple.isOSBinFormatCOFF()
+ ? GlobalVariable::ExternalLinkage
+ : GlobalVariable::ExternalWeakLinkage;
+ GlobalVariable *SecStart = new GlobalVariable(M, Ty, false, Linkage, nullptr,
+ getSectionStart(Section));
SecStart->setVisibility(GlobalValue::HiddenVisibility);
- GlobalVariable *SecEnd =
- new GlobalVariable(M,
-#if LLVM_VERSION_MAJOR >= 15
- Ty,
-#else
- Ty->getPointerElementType(),
-#endif
- false, GlobalVariable::ExternalWeakLinkage, nullptr,
- getSectionEnd(Section));
+ GlobalVariable *SecEnd = new GlobalVariable(M, Ty, false, Linkage, nullptr,
+ getSectionEnd(Section));
SecEnd->setVisibility(GlobalValue::HiddenVisibility);
IRBuilder<> IRB(M.getContext());
if (!TargetTriple.isOSBinFormatCOFF())
@@ -295,7 +315,8 @@ std::pair ModuleSanitizerCoverageAFL::CreateSecStartEnd(
auto SecStartI8Ptr = IRB.CreatePointerCast(SecStart, Int8PtrTy);
auto GEP = IRB.CreateGEP(Int8Ty, SecStartI8Ptr,
ConstantInt::get(IntptrTy, sizeof(uint64_t)));
- return std::make_pair(IRB.CreatePointerCast(GEP, Ty), SecEnd);
+ return std::make_pair(IRB.CreatePointerCast(GEP, PointerType::getUnqual(Ty)),
+ SecEnd);
}
@@ -307,8 +328,9 @@ Function *ModuleSanitizerCoverageAFL::CreateInitCallsForSections(
auto SecStart = SecStartEnd.first;
auto SecEnd = SecStartEnd.second;
Function *CtorFunc;
+ Type *PtrTy = PointerType::getUnqual(Ty);
std::tie(CtorFunc, std::ignore) = createSanitizerCtorAndInitFunctions(
- M, CtorName, InitFunctionName, {Ty, Ty}, {SecStart, SecEnd});
+ M, CtorName, InitFunctionName, {PtrTy, PtrTy}, {SecStart, SecEnd});
assert(CtorFunc->getName() == CtorName);
if (TargetTriple.supportsCOMDAT()) {
@@ -332,7 +354,6 @@ Function *ModuleSanitizerCoverageAFL::CreateInitCallsForSections(
// to include the sancov constructor. This way the linker can deduplicate
// the constructors but always leave one copy.
CtorFunc->setLinkage(GlobalValue::WeakODRLinkage);
- appendToUsed(M, CtorFunc);
}
@@ -344,37 +365,25 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
Module &M, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
setvbuf(stdout, NULL, _IONBF, 0);
- if (getenv("AFL_DEBUG")) debug = 1;
+
+ if (getenv("AFL_DEBUG")) { debug = 1; }
if ((isatty(2) && !getenv("AFL_QUIET")) || debug) {
SAYF(cCYA "SanitizerCoveragePCGUARD" VERSION cRST "\n");
- } else
+ } else {
be_quiet = 1;
+ }
+
skip_nozero = getenv("AFL_LLVM_SKIP_NEVERZERO");
use_threadsafe_counters = getenv("AFL_LLVM_THREADSAFE_INST");
initInstrumentList();
scanForDangerousFunctions(&M);
- if (debug) {
-
- fprintf(stderr,
- "SANCOV: covtype:%u indirect:%d stack:%d noprune:%d "
- "createtable:%d tracepcguard:%d tracepc:%d\n",
- Options.CoverageType, Options.IndirectCalls == true ? 1 : 0,
- Options.StackDepth == true ? 1 : 0, Options.NoPrune == true ? 1 : 0,
- // Options.InlineBoolFlag == true ? 1 : 0,
- Options.PCTable == true ? 1 : 0,
- Options.TracePCGuard == true ? 1 : 0,
- Options.TracePC == true ? 1 : 0);
-
- }
-
- if (Options.CoverageType == SanitizerCoverageOptions::SCK_None) return false;
C = &(M.getContext());
DL = &M.getDataLayout();
CurModule = &M;
@@ -397,16 +406,14 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
Int16Ty = IRB.getInt16Ty();
Int8Ty = IRB.getInt8Ty();
Int1Ty = IRB.getInt1Ty();
- LLVMContext &Ctx = M.getContext();
+ LLVMContext &Ctx = M.getContext();
AFLMapPtr =
new GlobalVariable(M, PointerType::get(Int8Ty, 0), false,
GlobalValue::ExternalLinkage, 0, "__afl_area_ptr");
One = ConstantInt::get(IntegerType::getInt8Ty(Ctx), 1);
Zero = ConstantInt::get(IntegerType::getInt8Ty(Ctx), 0);
- SanCovTracePCIndir =
- M.getOrInsertFunction(SanCovTracePCIndirName, VoidTy, IntptrTy);
// Make sure smaller parameters are zero-extended to i64 if required by the
// target ABI.
AttributeList SanCovTraceCmpZeroExtAL;
@@ -436,26 +443,13 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
SanCovTraceConstCmpFunction[3] =
M.getOrInsertFunction(SanCovTraceConstCmp8, VoidTy, Int64Ty, Int64Ty);
- {
-
- AttributeList AL;
- AL = AL.addParamAttribute(*C, 0, Attribute::ZExt);
- SanCovTraceDivFunction[0] =
- M.getOrInsertFunction(SanCovTraceDiv4, AL, VoidTy, IRB.getInt32Ty());
-
- }
-
- SanCovTraceDivFunction[1] =
- M.getOrInsertFunction(SanCovTraceDiv8, VoidTy, Int64Ty);
- SanCovTraceGepFunction =
- M.getOrInsertFunction(SanCovTraceGep, VoidTy, IntptrTy);
SanCovTraceSwitchFunction =
M.getOrInsertFunction(SanCovTraceSwitchName, VoidTy, Int64Ty, Int64PtrTy);
Constant *SanCovLowestStackConstant =
M.getOrInsertGlobal(SanCovLowestStackName, IntptrTy);
SanCovLowestStack = dyn_cast(SanCovLowestStackConstant);
- if (!SanCovLowestStack) {
+ if (!SanCovLowestStack || SanCovLowestStack->getValueType() != IntptrTy) {
C->emitError(StringRef("'") + SanCovLowestStackName +
"' should not be declared by the user");
@@ -465,8 +459,6 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
SanCovLowestStack->setThreadLocalMode(
GlobalValue::ThreadLocalMode::InitialExecTLSModel);
- if (Options.StackDepth && !SanCovLowestStack->isDeclaration())
- SanCovLowestStack->setInitializer(Constant::getAllOnesValue(IntptrTy));
SanCovTracePC = M.getOrInsertFunction(SanCovTracePCName, VoidTy);
SanCovTracePCGuard =
@@ -481,40 +473,25 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
Ctor = CreateInitCallsForSections(M, SanCovModuleCtorTracePcGuardName,
SanCovTracePCGuardInitName, Int32PtrTy,
SanCovGuardsSectionName);
- if (Function8bitCounterArray)
- Ctor = CreateInitCallsForSections(M, SanCovModuleCtor8bitCountersName,
- SanCov8bitCountersInitName, Int8PtrTy,
- SanCovCountersSectionName);
- if (FunctionBoolArray) {
-
- Ctor = CreateInitCallsForSections(M, SanCovModuleCtorBoolFlagName,
- SanCovBoolFlagInitName, Int1PtrTy,
- SanCovBoolFlagSectionName);
- }
-
- if (Ctor && Options.PCTable) {
+ if (Ctor && debug) {
- auto SecStartEnd = CreateSecStartEnd(M, SanCovPCsSectionName, IntptrPtrTy);
- FunctionCallee InitFunction = declareSanitizerInitFunction(
- M, SanCovPCsInitName, {IntptrPtrTy, IntptrPtrTy});
- IRBuilder<> IRBCtor(Ctor->getEntryBlock().getTerminator());
- IRBCtor.CreateCall(InitFunction, {SecStartEnd.first, SecStartEnd.second});
+ fprintf(stderr, "SANCOV: installed pcguard_init in ctor\n");
}
- // We don't reference these arrays directly in any of our runtime functions,
- // so we need to prevent them from being dead stripped.
- if (TargetTriple.isOSBinFormatMachO()) appendToUsed(M, GlobalsToAppendToUsed);
+ appendToUsed(M, GlobalsToAppendToUsed);
appendToCompilerUsed(M, GlobalsToAppendToCompilerUsed);
if (!be_quiet) {
- if (!instr)
+ if (!instr) {
+
WARNF("No instrumentation targets found.");
- else {
- char modeline[100];
+ } else {
+
+ char modeline[128];
snprintf(modeline, sizeof(modeline), "%s%s%s%s%s%s",
getenv("AFL_HARDEN") ? "hardened" : "non-hardened",
getenv("AFL_USE_ASAN") ? ", ASAN" : "",
@@ -535,39 +512,36 @@ bool ModuleSanitizerCoverageAFL::instrumentModule(
}
// True if block has successors and it dominates all of them.
-bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
+static bool isFullDominator(const BasicBlock *BB, const DominatorTree *DT) {
- if (succ_begin(BB) == succ_end(BB)) return false;
+ if (succ_empty(BB)) return false;
- for (const BasicBlock *SUCC : make_range(succ_begin(BB), succ_end(BB))) {
+ return llvm::all_of(successors(BB), [&](const BasicBlock *SUCC) {
- if (!DT->dominates(BB, SUCC)) return false;
+ return DT->dominates(BB, SUCC);
- }
-
- return true;
+ });
}
// True if block has predecessors and it postdominates all of them.
-bool isFullPostDominator(const BasicBlock *BB, const PostDominatorTree *PDT) {
+static bool isFullPostDominator(const BasicBlock *BB,
+ const PostDominatorTree *PDT) {
- if (pred_begin(BB) == pred_end(BB)) return false;
+ if (pred_empty(BB)) return false;
- for (const BasicBlock *PRED : make_range(pred_begin(BB), pred_end(BB))) {
+ return llvm::all_of(predecessors(BB), [&](const BasicBlock *PRED) {
- if (!PDT->dominates(BB, PRED)) return false;
+ return PDT->dominates(BB, PRED);
- }
-
- return true;
+ });
}
-bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
- const DominatorTree *DT,
- const PostDominatorTree *PDT,
- const SanitizerCoverageOptions &Options) {
+static bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
+ const DominatorTree *DT,
+ const PostDominatorTree *PDT,
+ const SanitizerCoverageOptions &Options) {
// Don't insert coverage for blocks containing nothing but unreachable: we
// will never call __sanitizer_cov() for them, so counting them in
@@ -582,10 +556,6 @@ bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
if (Options.NoPrune || &F.getEntryBlock() == BB) return true;
- if (Options.CoverageType == SanitizerCoverageOptions::SCK_Function &&
- &F.getEntryBlock() != BB)
- return false;
-
// Do not instrument full dominators, or full post-dominators with multiple
// predecessors.
return !isFullDominator(BB, DT) &&
@@ -597,38 +567,47 @@ bool shouldInstrumentBlock(const Function &F, const BasicBlock *BB,
// A twist here is that we treat From->To as a backedge if
// * To dominates From or
// * To->UniqueSuccessor dominates From
-bool IsBackEdge(BasicBlock *From, BasicBlock *To, const DominatorTree *DT) {
+#if 0
+static bool IsBackEdge(BasicBlock *From, BasicBlock *To,
+ const DominatorTree *DT) {
- if (DT->dominates(To, From)) return true;
+ if (DT->dominates(To, From))
+ return true;
if (auto Next = To->getUniqueSuccessor())
- if (DT->dominates(Next, From)) return true;
+ if (DT->dominates(Next, From))
+ return true;
return false;
}
+#endif
+
// Prunes uninteresting Cmp instrumentation:
// * CMP instructions that feed into loop backedge branch.
//
// Note that Cmp pruning is controlled by the same flag as the
// BB pruning.
-bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT,
- const SanitizerCoverageOptions &Options) {
+#if 0
+static bool IsInterestingCmp(ICmpInst *CMP, const DominatorTree *DT,
+ const SanitizerCoverageOptions &Options) {
if (!Options.NoPrune)
if (CMP->hasOneUse())
if (auto BR = dyn_cast(CMP->user_back()))
for (BasicBlock *B : BR->successors())
- if (IsBackEdge(BR->getParent(), B, DT)) return false;
+ if (IsBackEdge(BR->getParent(), B, DT))
+ return false;
return true;
}
+#endif
+
void ModuleSanitizerCoverageAFL::instrumentFunction(
Function &F, DomTreeCallback DTCallback, PostDomTreeCallback PDTCallback) {
if (F.empty()) return;
if (!isInInstrumentList(&F, FMNAME)) return;
-
if (F.getName().find(".module_ctor") != std::string::npos)
return; // Should not instrument sanitizer init functions.
if (F.getName().startswith("__sanitizer_"))
@@ -647,15 +626,13 @@ void ModuleSanitizerCoverageAFL::instrumentFunction(
if (F.hasPersonalityFn() &&
isAsynchronousEHPersonality(classifyEHPersonality(F.getPersonalityFn())))
return;
+ if (F.hasFnAttribute(Attribute::NoSanitizeCoverage)) return;
if (Options.CoverageType >= SanitizerCoverageOptions::SCK_Edge)
SplitAllCriticalEdges(
F, CriticalEdgeSplittingOptions().setIgnoreUnreachableDests());
- SmallVector IndirCalls;
- SmallVector BlocksToInstrument;
- SmallVector CmpTraceTargets;
- SmallVector SwitchTraceTargets;
- SmallVector DivTraceTargets;
- SmallVector GepTraceTargets;
+ SmallVector BlocksToInstrument;
+ SmallVector CmpTraceTargets;
+ SmallVector SwitchTraceTargets;
const DominatorTree *DT = DTCallback(F);
const PostDominatorTree *PDT = PDTCallback(F);
@@ -665,47 +642,28 @@ void ModuleSanitizerCoverageAFL::instrumentFunction(
if (shouldInstrumentBlock(F, &BB, DT, PDT, Options))
BlocksToInstrument.push_back(&BB);
- for (auto &Inst : BB) {
-
- if (Options.IndirectCalls) {
-
- CallBase *CB = dyn_cast(&Inst);
- if (CB && !CB->getCalledFunction()) IndirCalls.push_back(&Inst);
-
- }
+ /*
+ for (auto &Inst : BB) {
- if (Options.TraceCmp) {
+ if (Options.TraceCmp) {
- if (ICmpInst *CMP = dyn_cast(&Inst))
- if (IsInterestingCmp(CMP, DT, Options))
- CmpTraceTargets.push_back(&Inst);
- if (isa(&Inst)) SwitchTraceTargets.push_back(&Inst);
+ if (ICmpInst *CMP = dyn_cast(&Inst))
+ if (IsInterestingCmp(CMP, DT, Options))
+ CmpTraceTargets.push_back(&Inst);
+ if (isa(&Inst))
+ SwitchTraceTargets.push_back(&Inst);
- }
+ }
- if (Options.TraceDiv)
- if (BinaryOperator *BO = dyn_cast(&Inst))
- if (BO->getOpcode() == Instruction::SDiv ||
- BO->getOpcode() == Instruction::UDiv)
- DivTraceTargets.push_back(BO);
- if (Options.TraceGep)
- if (GetElementPtrInst *GEP = dyn_cast(&Inst))
- GepTraceTargets.push_back(GEP);
- if (Options.StackDepth)
- if (isa(Inst) ||
- (isa(Inst) && !isa(Inst)))
- IsLeafFunc = false;
+ }
- }
+ */
}
InjectCoverage(F, BlocksToInstrument, IsLeafFunc);
- InjectCoverageForIndirectCalls(F, IndirCalls);
- InjectTraceForCmp(F, CmpTraceTargets);
- InjectTraceForSwitch(F, SwitchTraceTargets);
- InjectTraceForDiv(F, DivTraceTargets);
- InjectTraceForGep(F, GepTraceTargets);
+ // InjectTraceForCmp(F, CmpTraceTargets);
+ // InjectTraceForSwitch(F, SwitchTraceTargets);
}
@@ -717,33 +675,30 @@ GlobalVariable *ModuleSanitizerCoverageAFL::CreateFunctionLocalArrayInSection(
*CurModule, ArrayTy, false, GlobalVariable::PrivateLinkage,
Constant::getNullValue(ArrayTy), "__sancov_gen_");
-#if LLVM_VERSION_MAJOR >= 13
if (TargetTriple.supportsCOMDAT() &&
(TargetTriple.isOSBinFormatELF() || !F.isInterposable()))
if (auto Comdat = getOrCreateFunctionComdat(F, TargetTriple))
Array->setComdat(Comdat);
-#else
- if (TargetTriple.supportsCOMDAT() && !F.isInterposable())
- if (auto Comdat =
- GetOrCreateFunctionComdat(F, TargetTriple, CurModuleUniqueId))
- Array->setComdat(Comdat);
-#endif
-
Array->setSection(getSectionName(Section));
-#if (LLVM_VERSION_MAJOR >= 11) || \
- (LLVM_VERSION_MAJOR == 10 && LLVM_VERSION_MINOR >= 1)
- #if LLVM_VERSION_MAJOR >= 16
+#if LLVM_VERSION_MAJOR >= 16
Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedValue()));
- #else
- Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize()));
- #endif
#else
- Array->setAlignment(Align(4)); // cheating
+ Array->setAlignment(Align(DL->getTypeStoreSize(Ty).getFixedSize()));
#endif
- GlobalsToAppendToUsed.push_back(Array);
- GlobalsToAppendToCompilerUsed.push_back(Array);
- MDNode *MD = MDNode::get(F.getContext(), ValueAsMetadata::get(&F));
- Array->addMetadata(LLVMContext::MD_associated, *MD);
+
+ // sancov_pcs parallels the other metadata section(s). Optimizers (e.g.
+ // GlobalOpt/ConstantMerge) may not discard sancov_pcs and the other
+ // section(s) as a unit, so we conservatively retain all unconditionally in
+ // the compiler.
+ //
+ // With comdat (COFF/ELF), the linker can guarantee the associated sections
+ // will be retained or discarded as a unit, so llvm.compiler.used is
+ // sufficient. Otherwise, conservatively make all of them retained by the
+ // linker.
+ if (Array->hasComdat())
+ GlobalsToAppendToCompilerUsed.push_back(Array);
+ else
+ GlobalsToAppendToUsed.push_back(Array);
return Array;
@@ -768,8 +723,12 @@ GlobalVariable *ModuleSanitizerCoverageAFL::CreatePCArray(
PCs.push_back((Constant *)IRB.CreatePointerCast(
BlockAddress::get(AllBlocks[i]), IntptrPtrTy));
+#if LLVM_VERSION_MAJOR >= 16
+ PCs.push_back(Constant::getNullValue(IntptrPtrTy));
+#else
PCs.push_back((Constant *)IRB.CreateIntToPtr(
ConstantInt::get(IntptrTy, 0), IntptrPtrTy));
+#endif
}
@@ -792,21 +751,13 @@ void ModuleSanitizerCoverageAFL::CreateFunctionLocalArrays(
FunctionGuardArray = CreateFunctionLocalArrayInSection(
AllBlocks.size() + special, F, Int32Ty, SanCovGuardsSectionName);
- if (Options.Inline8bitCounters)
- Function8bitCounterArray = CreateFunctionLocalArrayInSection(
- AllBlocks.size(), F, Int8Ty, SanCovCountersSectionName);
- /*
- if (Options.InlineBoolFlag)
- FunctionBoolArray = CreateFunctionLocalArrayInSection(
- AllBlocks.size(), F, Int1Ty, SanCovBoolFlagSectionName);
- */
- if (Options.PCTable) FunctionPCsArray = CreatePCArray(F, AllBlocks);
-
}
bool ModuleSanitizerCoverageAFL::InjectCoverage(
Function &F, ArrayRef AllBlocks, bool IsLeafFunc) {
+ if (AllBlocks.empty()) return false;
+
uint32_t cnt_cov = 0, cnt_sel = 0, cnt_sel_inc = 0;
static uint32_t first = 1;
@@ -855,7 +806,6 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
}
-#if (LLVM_VERSION_MAJOR >= 12)
else if (t->getTypeID() == llvm::Type::FixedVectorTyID) {
FixedVectorType *tt = dyn_cast(t);
@@ -868,16 +818,14 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
}
-#endif
-
}
}
}
- /* Create PCGUARD array */
CreateFunctionLocalArrays(F, AllBlocks, first + cnt_cov + cnt_sel_inc);
+
if (first) { first = 0; }
selects += cnt_sel;
@@ -889,12 +837,6 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
CallInst *callInst = nullptr;
- /*
- std::string errMsg;
- raw_string_ostream os(errMsg);
- IN.print(os);
- fprintf(stderr, "X: %s\n", os.str().c_str());
- */
if ((callInst = dyn_cast(&IN))) {
Function *Callee = callInst->getCalledFunction();
@@ -1033,12 +975,6 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
}
- /*
- std::string errMsg;
- raw_string_ostream os(errMsg);
- x->print(os);
- fprintf(stderr, "X: %s\n", os.str().c_str());
- */
result = IRB.CreateSelect(condition, x, y);
}
@@ -1063,13 +999,6 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
IRB.CreateLoad(PointerType::get(Int8Ty, 0), AFLMapPtr);
ModuleSanitizerCoverageAFL::SetNoSanitizeMetadata(MapPtr);
- /*
- std::string errMsg;
- raw_string_ostream os(errMsg);
- result->print(os);
- fprintf(stderr, "X: %s\n", os.str().c_str());
- */
-
while (1) {
/* Get CurLoc */
@@ -1159,29 +1088,6 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
}
-// On every indirect call we call a run-time function
-// __sanitizer_cov_indir_call* with two parameters:
-// - callee address,
-// - global cache array that contains CacheSize pointers (zero-initialized).
-// The cache is used to speed up recording the caller-callee pairs.
-// The address of the caller is passed implicitly via caller PC.
-// CacheSize is encoded in the name of the run-time function.
-void ModuleSanitizerCoverageAFL::InjectCoverageForIndirectCalls(
- Function &F, ArrayRef IndirCalls) {
-
- if (IndirCalls.empty()) return;
- for (auto I : IndirCalls) {
-
- IRBuilder<> IRB(I);
- CallBase &CB = cast(*I);
- Value *Callee = CB.getCalledOperand();
- if (isa(Callee)) continue;
- IRB.CreateCall(SanCovTracePCIndir, IRB.CreatePointerCast(Callee, IntptrTy));
-
- }
-
-}
-
// For every switch statement we insert a call:
// __sanitizer_cov_trace_switch(CondValue,
// {NumCases, ValueSizeInBits, Case0Value, Case1Value, Case2Value, ... })
@@ -1237,41 +1143,6 @@ void ModuleSanitizerCoverageAFL::InjectTraceForSwitch(
}
-void ModuleSanitizerCoverageAFL::InjectTraceForDiv(
- Function &, ArrayRef DivTraceTargets) {
-
- for (auto BO : DivTraceTargets) {
-
- IRBuilder<> IRB(BO);
- Value *A1 = BO->getOperand(1);
- if (isa(A1)) continue;
- if (!A1->getType()->isIntegerTy()) continue;
- uint64_t TypeSize = DL->getTypeStoreSizeInBits(A1->getType());
- int CallbackIdx = TypeSize == 32 ? 0 : TypeSize == 64 ? 1 : -1;
- if (CallbackIdx < 0) continue;
- auto Ty = Type::getIntNTy(*C, TypeSize);
- IRB.CreateCall(SanCovTraceDivFunction[CallbackIdx],
- {IRB.CreateIntCast(A1, Ty, true)});
-
- }
-
-}
-
-void ModuleSanitizerCoverageAFL::InjectTraceForGep(
- Function &, ArrayRef GepTraceTargets) {
-
- for (auto GEP : GepTraceTargets) {
-
- IRBuilder<> IRB(GEP);
- for (Use &Idx : GEP->indices())
- if (!isa(Idx) && Idx->getType()->isIntegerTy())
- IRB.CreateCall(SanCovTraceGepFunction,
- {IRB.CreateIntCast(Idx, IntptrTy, true)});
-
- }
-
-}
-
void ModuleSanitizerCoverageAFL::InjectTraceForCmp(
Function &, ArrayRef CmpTraceTargets) {
@@ -1321,27 +1192,44 @@ void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function &F,
BasicBlock::iterator IP = BB.getFirstInsertionPt();
bool IsEntryBB = &BB == &F.getEntryBlock();
+ DebugLoc EntryLoc;
if (IsEntryBB) {
- // Keep allocas and llvm.localescape calls in the entry block. Even
+ if (auto SP = F.getSubprogram())
+ EntryLoc = DILocation::get(SP->getContext(), SP->getScopeLine(), 0, SP);
+ // Keep static allocas and llvm.localescape calls in the entry block. Even
// if we aren't splitting the block, it's nice for allocas to be before
// calls.
IP = PrepareToSplitEntryBlock(BB, IP);
+#if LLVM_VERSION_MAJOR < 15
- }
-
- IRBuilder<> IRB(&*IP);
-
- if (Options.TracePC) {
+ } else {
- IRB.CreateCall(SanCovTracePC);
- // ->setCannotMerge(); // gets the PC using GET_CALLER_PC.
+ EntryLoc = IP->getDebugLoc();
+ if (!EntryLoc)
+ if (auto *SP = F.getSubprogram())
+ EntryLoc = DILocation::get(SP->getContext(), 0, 0, SP);
+#endif
}
+#if LLVM_VERSION_MAJOR >= 15
+ InstrumentationIRBuilder IRB(&*IP);
+#else
+ IRBuilder<> IRB(&*IP);
+#endif
+ if (EntryLoc) IRB.SetCurrentDebugLocation(EntryLoc);
if (Options.TracePCGuard) {
+ /*
+ auto GuardPtr = IRB.CreateIntToPtr(
+ IRB.CreateAdd(IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
+ ConstantInt::get(IntptrTy, Idx * 4)),
+ Int32PtrTy);
+ IRB.CreateCall(SanCovTracePCGuard, GuardPtr)->setCannotMerge();
+ */
+
/* Get CurLoc */
Value *GuardPtr = IRB.CreateIntToPtr(
@@ -1399,57 +1287,6 @@ void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function &F,
}
- if (Options.Inline8bitCounters) {
-
- auto CounterPtr = IRB.CreateGEP(
- Function8bitCounterArray->getValueType(), Function8bitCounterArray,
- {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
- auto Load = IRB.CreateLoad(Int8Ty, CounterPtr);
- auto Inc = IRB.CreateAdd(Load, ConstantInt::get(Int8Ty, 1));
- auto Store = IRB.CreateStore(Inc, CounterPtr);
- SetNoSanitizeMetadata(Load);
- SetNoSanitizeMetadata(Store);
-
- }
-
- /*
- if (Options.InlineBoolFlag) {
-
- auto FlagPtr = IRB.CreateGEP(
- FunctionBoolArray->getValueType(), FunctionBoolArray,
- {ConstantInt::get(IntptrTy, 0), ConstantInt::get(IntptrTy, Idx)});
- auto Load = IRB.CreateLoad(Int1Ty, FlagPtr);
- auto ThenTerm =
- SplitBlockAndInsertIfThen(IRB.CreateIsNull(Load), &*IP, false);
- IRBuilder<> ThenIRB(ThenTerm);
- auto Store = ThenIRB.CreateStore(ConstantInt::getTrue(Int1Ty), FlagPtr);
- SetNoSanitizeMetadata(Load);
- SetNoSanitizeMetadata(Store);
-
- }
-
- */
-
- if (Options.StackDepth && IsEntryBB && !IsLeafFunc) {
-
- // Check stack depth. If it's the deepest so far, record it.
- Module *M = F.getParent();
- Function *GetFrameAddr = Intrinsic::getDeclaration(
- M, Intrinsic::frameaddress,
- IRB.getInt8PtrTy(M->getDataLayout().getAllocaAddrSpace()));
- auto FrameAddrPtr =
- IRB.CreateCall(GetFrameAddr, {Constant::getNullValue(Int32Ty)});
- auto FrameAddrInt = IRB.CreatePtrToInt(FrameAddrPtr, IntptrTy);
- auto LowestStack = IRB.CreateLoad(IntptrTy, SanCovLowestStack);
- auto IsStackLower = IRB.CreateICmpULT(FrameAddrInt, LowestStack);
- auto ThenTerm = SplitBlockAndInsertIfThen(IsStackLower, &*IP, false);
- IRBuilder<> ThenIRB(ThenTerm);
- auto Store = ThenIRB.CreateStore(FrameAddrInt, SanCovLowestStack);
- SetNoSanitizeMetadata(LowestStack);
- SetNoSanitizeMetadata(Store);
-
- }
-
}
std::string ModuleSanitizerCoverageAFL::getSectionName(
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 84fe70ec..9e56828c 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -997,7 +997,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
if (instrument_mode == INSTRUMENT_PCGUARD) {
-#if LLVM_MAJOR >= 11
+#if LLVM_MAJOR >= 13
#if defined __ANDROID__ || ANDROID
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
instrument_mode = INSTRUMENT_LLVMNATIVE;
@@ -1014,7 +1014,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
} else {
- #if LLVM_MAJOR >= 11 /* use new pass manager */
+ #if LLVM_MAJOR >= 13 /* use new pass manager */
#if LLVM_MAJOR < 16
cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager";
#endif
@@ -1035,12 +1035,12 @@ static void edit_params(u32 argc, char **argv, char **envp) {
#if LLVM_MAJOR >= 4
if (!be_quiet)
SAYF(
- "Using unoptimized trace-pc-guard, upgrade to llvm 10.0.1+ for "
+ "Using unoptimized trace-pc-guard, upgrade to LLVM 13+ for "
"enhanced version.\n");
cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
instrument_mode = INSTRUMENT_LLVMNATIVE;
#else
- FATAL("pcguard instrumentation requires llvm 4.0.1+");
+ FATAL("pcguard instrumentation requires LLVM 4.0.1+");
#endif
#endif
@@ -1053,7 +1053,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
cc_params[cc_par_cnt++] =
"-fsanitize-coverage=trace-pc-guard,bb,no-prune,pc-table";
#else
- FATAL("pcguard instrumentation with pc-table requires llvm 6.0.1+");
+ FATAL("pcguard instrumentation with pc-table requires LLVM 6.0.1+");
#endif
} else {
@@ -1063,7 +1063,7 @@ static void edit_params(u32 argc, char **argv, char **envp) {
}
#else
- FATAL("pcguard instrumentation requires llvm 4.0.1+");
+ FATAL("pcguard instrumentation requires LLVM 4.0.1+");
#endif
} else {
@@ -2031,7 +2031,7 @@ int main(int argc, char **argv, char **envp) {
if (!compiler_mode) {
// lto is not a default because outside of afl-cc RANLIB and AR have to
- // be set to llvm versions so this would work
+ // be set to LLVM versions so this would work
if (have_llvm)
compiler_mode = LLVM;
else if (have_gcc_plugin)
@@ -2050,6 +2050,17 @@ int main(int argc, char **argv, char **envp) {
}
+ /* if our PCGUARD implementation is not available then silently switch to
+ native LLVM PCGUARD */
+ if (compiler_mode == CLANG &&
+ (instrument_mode == INSTRUMENT_DEFAULT ||
+ instrument_mode == INSTRUMENT_PCGUARD) &&
+ find_object("SanitizerCoveragePCGUARD.so", argv[0]) == NULL) {
+
+ instrument_mode = INSTRUMENT_LLVMNATIVE;
+
+ }
+
if (compiler_mode == GCC) {
if (clang_mode) {
@@ -2096,12 +2107,12 @@ int main(int argc, char **argv, char **envp) {
"-------------|\n"
"MODES: NCC PERSIST DICT LAF "
"CMPLOG SELECT\n"
- " [LTO] llvm LTO: %s%s\n"
+ " [LTO] LLVM LTO: %s%s\n"
" PCGUARD DEFAULT yes yes yes yes yes "
" yes\n"
" CLASSIC yes yes yes yes yes "
" yes\n"
- " [LLVM] llvm: %s%s\n"
+ " [LLVM] LLVM: %s%s\n"
" PCGUARD %s yes yes module yes yes "
"yes\n"
" CLASSIC %s no yes module yes yes "
@@ -2171,7 +2182,7 @@ int main(int argc, char **argv, char **envp) {
" (instrumentation/README.lto.md)\n"
" PERSIST: persistent mode support [code] (huge speed increase!)\n"
" (instrumentation/README.persistent_mode.md)\n"
- " DICT: dictionary in the target [yes=automatic or llvm module "
+ " DICT: dictionary in the target [yes=automatic or LLVM module "
"pass]\n"
" (instrumentation/README.lto.md + "
"instrumentation/README.llvm.md)\n"
--
cgit 1.4.1
From 2b500ce97ee50c4d237702e6121bbd38e56e8ec6 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 1 Jun 2023 12:27:34 +0200
Subject: llvm 15 fixes
---
instrumentation/SanitizerCoverageLTO.so.cc | 2 +-
instrumentation/SanitizerCoveragePCGUARD.so.cc | 4 +---
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index d7b03634..2d17ffd4 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -331,7 +331,7 @@ llvmGetPassPluginInfo() {
#if LLVM_VERSION_MAJOR <= 13
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
#endif
-#if LLVM_VERSION_MAJOR >= 15
+#if LLVM_VERSION_MAJOR >= 16
PB.registerFullLinkTimeOptimizationLastEPCallback(
#else
PB.registerOptimizerLastEPCallback(
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 2abc58ec..29ab1427 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -162,9 +162,7 @@ class ModuleSanitizerCoverageAFL
void SetNoSanitizeMetadata(Instruction *I) {
-#if LLVM_VERSION_MAJOR == 15
- I->setMetadata(LLVMContext::MD_nosanitize, MDNode::get(*C, None));
-#elif LLVM_VERSION_MAJOR >= 16
+#if LLVM_VERSION_MAJOR >= 16
I->setMetadata(LLVMContext::MD_nosanitize, MDNode::get(*C, std::nullopt));
#else
I->setMetadata(I->getModule()->getMDKindID("nosanitize"),
--
cgit 1.4.1
From b644e48f36485c645cbc0dadf0fddb2aa14cc079 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 1 Jun 2023 13:28:07 +0200
Subject: more llvm 15 specialities
---
instrumentation/SanitizerCoveragePCGUARD.so.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 29ab1427..20f54b84 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -1212,7 +1212,7 @@ void ModuleSanitizerCoverageAFL::InjectCoverageAtBlock(Function &F,
}
-#if LLVM_VERSION_MAJOR >= 15
+#if LLVM_VERSION_MAJOR >= 16
InstrumentationIRBuilder IRB(&*IP);
#else
IRBuilder<> IRB(&*IP);
--
cgit 1.4.1
From 28fd9716086f781f548423ea00e0e441e97037bc Mon Sep 17 00:00:00 2001
From: fanquake
Date: Mon, 5 Jun 2023 16:54:23 +0100
Subject: build: fix compiler version in build output
Currently, if I build like with Clang, I'll get:
```bash
make LLVM_CONFIG=llvm-config-15 CC=clang-15 CXX=clang++-15
[+] Everything seems to be working, ready to compile. (gcc version 12.1.0 (Ubuntu 12.1.0-2ubuntu1~22.04) )
clang-15 -O2 -D_FORTIFY_SOURCE=1 ....
```
Which is somewhat confusing. Fix this, and in a way that still outputs
the correct version info for Clang and GCC. Use `--version`, and pick
the first line, as that is where they are consistent in output. `clang
-v` gives the version first, whereas `gcc -v` gives the version on the
last line.
We switch to using $(CC), otherwise we also get incorrect output,
and dropping CCVER altogether, given this is it's only use.
---
GNUmakefile | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 715e7386..55676d97 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -291,8 +291,6 @@ ifeq "$(shell command -v svn >/dev/null && svn proplist . 2>/dev/null && echo 1
IN_REPO=1
endif
-CCVER=$(shell cc -v 2>&1|tail -n 1)
-
ifeq "$(shell echo 'int main() { return 0;}' | $(CC) $(CFLAGS) -fsanitize=address -x c - -o .test2 2>/dev/null && echo 1 || echo 0 ; rm -f .test2 )" "1"
ASAN_CFLAGS=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer -DASAN_BUILD
ASAN_LDFLAGS=-fsanitize=address -fstack-protector-all -fno-omit-frame-pointer
@@ -439,7 +437,7 @@ endif
.PHONY: ready
ready:
- @echo "[+] Everything seems to be working, ready to compile. ($(CCVER))"
+ @echo "[+] Everything seems to be working, ready to compile. ($(shell $(CC) --version 2>&1|head -n 1))"
afl-as: src/afl-as.c include/afl-as.h $(COMM_HDR) | test_x86
$(CC) $(CFLAGS) src/$@.c -o $@ $(LDFLAGS)
--
cgit 1.4.1
From abc26a932a187f4fb84ac178c44326c9e46efca5 Mon Sep 17 00:00:00 2001
From: cocochpie
Date: Mon, 5 Jun 2023 20:33:33 +0000
Subject: Revive f567a89dae29afb2e421d649f0e750e77913f08c
---
instrumentation/SanitizerCoveragePCGUARD.so.cc | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 20f54b84..25851dda 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -20,6 +20,8 @@
#endif
#if LLVM_VERSION_MAJOR < 17
#include "llvm/Analysis/EHPersonalities.h"
+#else
+ #include "llvm/IR/EHPersonalities.h"
#endif
#include "llvm/Analysis/PostDominators.h"
#if LLVM_VERSION_MAJOR < 15
@@ -31,8 +33,10 @@
#include "llvm/IR/DebugInfo.h"
#endif
#include "llvm/IR/Dominators.h"
-#if LLVM_VERSION_MAJOR >= 17
+#if LLVM_VERSION_MAJOR < 17
#include "llvm/Analysis/EHPersonalities.h"
+#else
+ #include "llvm/IR/EHPersonalities.h"
#endif
#include "llvm/IR/Function.h"
#if LLVM_VERSION_MAJOR >= 16
--
cgit 1.4.1
From 9585f5cdfeb7b287ec8614a92f295127eba0a384 Mon Sep 17 00:00:00 2001
From: cocochpie
Date: Tue, 6 Jun 2023 04:07:38 +0000
Subject: change the โ#ifโ to >= 17 instead of < 17
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
instrumentation/SanitizerCoveragePCGUARD.so.cc | 11 +++--------
1 file changed, 3 insertions(+), 8 deletions(-)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 25851dda..7171e7aa 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -18,11 +18,6 @@
#include "llvm/ADT/Triple.h"
#endif
#endif
-#if LLVM_VERSION_MAJOR < 17
- #include "llvm/Analysis/EHPersonalities.h"
-#else
- #include "llvm/IR/EHPersonalities.h"
-#endif
#include "llvm/Analysis/PostDominators.h"
#if LLVM_VERSION_MAJOR < 15
#include "llvm/IR/CFG.h"
@@ -33,10 +28,10 @@
#include "llvm/IR/DebugInfo.h"
#endif
#include "llvm/IR/Dominators.h"
-#if LLVM_VERSION_MAJOR < 17
- #include "llvm/Analysis/EHPersonalities.h"
-#else
+#if LLVM_VERSION_MAJOR >= 17
#include "llvm/IR/EHPersonalities.h"
+#else
+ #include "llvm/Analysis/EHPersonalities.h"
#endif
#include "llvm/IR/Function.h"
#if LLVM_VERSION_MAJOR >= 16
--
cgit 1.4.1
From 234d55ccd547b61839612cc068127dbceaf8a9ec Mon Sep 17 00:00:00 2001
From: fanquake
Date: Tue, 6 Jun 2023 10:29:54 +0100
Subject: build: adjust LLVM development version check
Adjust version check to only warn for LLVM 17.x and newer, which are the
development versions. Otherwise we'll get:
```bash
make LLVM_CONFIG=llvm-config-15 CC=clang-15 CXX=clang++-15
GNUmakefile.llvm:69: you are using an in-development llvm version - this might break llvm_mode!
```
for versions that are supported, and not in development.
---
GNUmakefile.llvm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index 6c68f1f3..6ffac68f 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -46,7 +46,7 @@ LLVMVER = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/git//' | sed 's
LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//' )
LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' )
LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[0-2]\.|^3.[0-7]\.' && echo 1 || echo 0 )
-LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[5-9]' && echo 1 || echo 0 )
+LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[7-9]' && echo 1 || echo 0 )
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[0-9]' && echo 1 || echo 0 )
LLVM_NEWER_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[6-9]' && echo 1 || echo 0 )
LLVM_13_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[3-9]' && echo 1 || echo 0 )
--
cgit 1.4.1
From 8de7f6131d48e27d53e894b65bd11e0dc3817639 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 6 Jun 2023 13:12:31 +0200
Subject: add current mutation strategy to include
---
include/afl-mutations.h | 161 ++++++++++++++++++++++++++++++++++++++++++++++++
src/afl-fuzz-one.c | 7 ++-
2 files changed, 166 insertions(+), 2 deletions(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 8d40855d..08037b09 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -77,6 +77,167 @@ enum {
};
+ #define MUT_NORMAL_ARRAY_SIZE 77
+u32 normal_splice[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_FIXED,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_FIXED,
+ MUT_BYTEADD,
+ MUT_BYTESUB,
+ MUT_FLIP8,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT};
+ #define MUT_SPLICE_ARRAY_SIZE 81
+u32 full_splice_array[MUT_SPLICE_ARRAY_SIZE] = {MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_FIXED,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_FIXED,
+ MUT_BYTEADD,
+ MUT_BYTESUB,
+ MUT_FLIP8,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT};
+
u32 mutation_strategy_exploration_text[MUT_STRATEGY_ARRAY_SIZE] = {
MUT_FLIPBIT,
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index f5ddea0e..312e180d 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2076,7 +2076,7 @@ havoc_stage:
where we take the input file and make random stacked tweaks. */
u32 *mutation_array;
- u32 stack_max, stack_max_pow = afl->havoc_stack_pow2;
+ u32 stack_max; // stack_max_pow = afl->havoc_stack_pow2;
if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text?
@@ -2104,6 +2104,7 @@ havoc_stage:
}
+ /*
if (temp_len < 64) {
--stack_max_pow;
@@ -2118,7 +2119,9 @@ havoc_stage:
}
- stack_max = 1 << stack_max_pow;
+ */
+
+ stack_max = 1 << (1 + rand_below(afl, afl->havoc_stack_pow2));
// + (afl->extras_cnt ? 2 : 0) + (afl->a_extras_cnt ? 2 : 0);
--
cgit 1.4.1
From ee2cab73ac6c72095f781da979094f877291a1d6 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 6 Jun 2023 16:42:42 +0200
Subject: reduce false positive ci failures
---
test/test-cmplog.c | 6 ++----
test/test-llvm.sh | 2 +-
2 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/test/test-cmplog.c b/test/test-cmplog.c
index bd1b73e3..2ab579b0 100644
--- a/test/test-cmplog.c
+++ b/test/test-cmplog.c
@@ -8,16 +8,14 @@
int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t i) {
- if (i < 30) return -1;
+ if (i < 15) return -1;
if (buf[0] != 'A') return 0;
if (buf[1] != 'B') return 0;
if (buf[2] != 'C') return 0;
if (buf[3] != 'D') return 0;
int *icmp = (int *)(buf + 4);
if (*icmp != 0x69694141) return 0;
- if (memcmp(buf + 8, "1234", 4) || memcmp(buf + 12, "EFGH", 4)) return 0;
- if (strncmp(buf + 16, "IJKL", 4) == 0 && strcmp(buf + 20, "DEADBEEF") == 0)
- abort();
+ if (memcmp(buf + 8, "1234EF", 6) == 0) abort();
return 0;
}
diff --git a/test/test-llvm.sh b/test/test-llvm.sh
index 714bda93..19fb7c1a 100755
--- a/test/test-llvm.sh
+++ b/test/test-llvm.sh
@@ -263,7 +263,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
{
mkdir -p in
echo 00000000000000000000000000000000 > in/in
- AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -m none -V30 -i in -o out -c./test-cmplog -- ./test-c >>errors 2>&1
+ AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -l 3 -m none -V30 -i in -o out -c ./test-cmplog -- ./test-c >>errors 2>&1
} >>errors 2>&1
test -n "$( ls out/default/crashes/id:000000* out/default/hangs/id:000000* 2>/dev/null )" && {
$ECHO "$GREEN[+] afl-fuzz is working correctly with llvm_mode cmplog"
--
cgit 1.4.1
From 62bacf4fc82194f1f5592d3d487443cef3c2850c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 6 Jun 2023 16:45:20 +0200
Subject: better cmplog ci
---
test/test-frida-mode.sh | 2 +-
test/test-qemu-mode.sh | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/test-frida-mode.sh b/test/test-frida-mode.sh
index 3ae84656..8c528da5 100755
--- a/test/test-frida-mode.sh
+++ b/test/test-frida-mode.sh
@@ -39,7 +39,7 @@ test -e ../afl-frida-trace.so && {
test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc" -o "$SYS" = "aarch64" -o ! "${SYS%%arm*}" && {
$ECHO "$GREY[*] running afl-fuzz for frida_mode cmplog, this will take approx 10 seconds"
{
- ../afl-fuzz -m none -V07 -O -c 0 -i in -o out -- ./test-compcov >>errors 2>&1
+ ../afl-fuzz -m none -V07 -O -c 0 -l 3 -i in -o out -- ./test-compcov >>errors 2>&1
} >>errors 2>&1
test -n "$( ls out/default/queue/id:000003* 2>/dev/null )" && {
$ECHO "$GREEN[+] afl-fuzz is working correctly with frida_mode cmplog"
diff --git a/test/test-qemu-mode.sh b/test/test-qemu-mode.sh
index 9e268963..8eb7cb67 100755
--- a/test/test-qemu-mode.sh
+++ b/test/test-qemu-mode.sh
@@ -88,7 +88,7 @@ test -e ../afl-qemu-trace && {
test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc" -o "$SYS" = "aarch64" -o ! "${SYS%%arm*}" && {
$ECHO "$GREY[*] running afl-fuzz for qemu_mode cmplog, this will take approx 10 seconds"
{
- ../afl-fuzz -m none -V07 -Q -c 0 -i in -o out -- ./test-compcov >>errors 2>&1
+ ../afl-fuzz -m none -V07 -Q -c 0 -l 3 -i in -o out -- ./test-compcov >>errors 2>&1
} >>errors 2>&1
test -n "$( ls out/default/queue/id:000001* 2>/dev/null )" && {
$ECHO "$GREEN[+] afl-fuzz is working correctly with qemu_mode cmplog"
--
cgit 1.4.1
From 9b2c4a2a5a8e54a80bdb82fee39891fbe42544e8 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 6 Jun 2023 16:54:12 +0200
Subject: nit
---
include/afl-mutations.h | 155 ++++++++++++++++++++++++------------------------
1 file changed, 78 insertions(+), 77 deletions(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 08037b09..a3c9fd59 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -78,83 +78,84 @@ enum {
};
#define MUT_NORMAL_ARRAY_SIZE 77
-u32 normal_splice[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT,
- MUT_FLIPBIT,
- MUT_FLIPBIT,
- MUT_FLIPBIT,
- MUT_INTERESTING8,
- MUT_INTERESTING8,
- MUT_INTERESTING8,
- MUT_INTERESTING8,
- MUT_INTERESTING16,
- MUT_INTERESTING16,
- MUT_INTERESTING16BE,
- MUT_INTERESTING16BE,
- MUT_INTERESTING32,
- MUT_INTERESTING32,
- MUT_INTERESTING32BE,
- MUT_INTERESTING32BE,
- MUT_ARITH8_,
- MUT_ARITH8_,
- MUT_ARITH8_,
- MUT_ARITH8_,
- MUT_ARITH8,
- MUT_ARITH8,
- MUT_ARITH8,
- MUT_ARITH8,
- MUT_ARITH16_,
- MUT_ARITH16_,
- MUT_ARITH16BE_,
- MUT_ARITH16BE_,
- MUT_ARITH16,
- MUT_ARITH16,
- MUT_ARITH16BE,
- MUT_ARITH16BE,
- MUT_ARITH32_,
- MUT_ARITH32_,
- MUT_ARITH32BE_,
- MUT_ARITH32BE_,
- MUT_ARITH32,
- MUT_ARITH32,
- MUT_ARITH32BE,
- MUT_ARITH32BE,
- MUT_RAND8,
- MUT_RAND8,
- MUT_RAND8,
- MUT_RAND8,
- MUT_CLONE_COPY,
- MUT_CLONE_COPY,
- MUT_CLONE_COPY,
- MUT_CLONE_FIXED,
- MUT_OVERWRITE_COPY,
- MUT_OVERWRITE_COPY,
- MUT_OVERWRITE_COPY,
- MUT_OVERWRITE_FIXED,
- MUT_BYTEADD,
- MUT_BYTESUB,
- MUT_FLIP8,
- MUT_SWITCH,
- MUT_SWITCH,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_EXTRA_OVERWRITE,
- MUT_EXTRA_OVERWRITE,
- MUT_EXTRA_INSERT,
- MUT_EXTRA_INSERT,
- MUT_AUTO_EXTRA_OVERWRITE,
- MUT_AUTO_EXTRA_OVERWRITE,
- MUT_AUTO_EXTRA_INSERT,
- MUT_AUTO_EXTRA_INSERT,
- MUT_SPLICE_OVERWRITE,
- MUT_SPLICE_OVERWRITE,
- MUT_SPLICE_INSERT,
- MUT_SPLICE_INSERT};
+u32 normal_splice_array[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_FIXED,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_FIXED,
+ MUT_BYTEADD,
+ MUT_BYTESUB,
+ MUT_FLIP8,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT};
+
#define MUT_SPLICE_ARRAY_SIZE 81
u32 full_splice_array[MUT_SPLICE_ARRAY_SIZE] = {MUT_FLIPBIT,
MUT_FLIPBIT,
--
cgit 1.4.1
From 14e25340fb7b9e13357a9059dd1c128a2d7d9d5b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 6 Jun 2023 16:55:32 +0200
Subject: comparison
---
include/afl-mutations.h | 155 ++++++++++++++++++++++++------------------------
src/afl-fuzz-one.c | 43 +++++++++-----
2 files changed, 107 insertions(+), 91 deletions(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 08037b09..a3c9fd59 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -78,83 +78,84 @@ enum {
};
#define MUT_NORMAL_ARRAY_SIZE 77
-u32 normal_splice[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT,
- MUT_FLIPBIT,
- MUT_FLIPBIT,
- MUT_FLIPBIT,
- MUT_INTERESTING8,
- MUT_INTERESTING8,
- MUT_INTERESTING8,
- MUT_INTERESTING8,
- MUT_INTERESTING16,
- MUT_INTERESTING16,
- MUT_INTERESTING16BE,
- MUT_INTERESTING16BE,
- MUT_INTERESTING32,
- MUT_INTERESTING32,
- MUT_INTERESTING32BE,
- MUT_INTERESTING32BE,
- MUT_ARITH8_,
- MUT_ARITH8_,
- MUT_ARITH8_,
- MUT_ARITH8_,
- MUT_ARITH8,
- MUT_ARITH8,
- MUT_ARITH8,
- MUT_ARITH8,
- MUT_ARITH16_,
- MUT_ARITH16_,
- MUT_ARITH16BE_,
- MUT_ARITH16BE_,
- MUT_ARITH16,
- MUT_ARITH16,
- MUT_ARITH16BE,
- MUT_ARITH16BE,
- MUT_ARITH32_,
- MUT_ARITH32_,
- MUT_ARITH32BE_,
- MUT_ARITH32BE_,
- MUT_ARITH32,
- MUT_ARITH32,
- MUT_ARITH32BE,
- MUT_ARITH32BE,
- MUT_RAND8,
- MUT_RAND8,
- MUT_RAND8,
- MUT_RAND8,
- MUT_CLONE_COPY,
- MUT_CLONE_COPY,
- MUT_CLONE_COPY,
- MUT_CLONE_FIXED,
- MUT_OVERWRITE_COPY,
- MUT_OVERWRITE_COPY,
- MUT_OVERWRITE_COPY,
- MUT_OVERWRITE_FIXED,
- MUT_BYTEADD,
- MUT_BYTESUB,
- MUT_FLIP8,
- MUT_SWITCH,
- MUT_SWITCH,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_DEL,
- MUT_EXTRA_OVERWRITE,
- MUT_EXTRA_OVERWRITE,
- MUT_EXTRA_INSERT,
- MUT_EXTRA_INSERT,
- MUT_AUTO_EXTRA_OVERWRITE,
- MUT_AUTO_EXTRA_OVERWRITE,
- MUT_AUTO_EXTRA_INSERT,
- MUT_AUTO_EXTRA_INSERT,
- MUT_SPLICE_OVERWRITE,
- MUT_SPLICE_OVERWRITE,
- MUT_SPLICE_INSERT,
- MUT_SPLICE_INSERT};
+u32 normal_splice_array[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_FIXED,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_FIXED,
+ MUT_BYTEADD,
+ MUT_BYTESUB,
+ MUT_FLIP8,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT};
+
#define MUT_SPLICE_ARRAY_SIZE 81
u32 full_splice_array[MUT_SPLICE_ARRAY_SIZE] = {MUT_FLIPBIT,
MUT_FLIPBIT,
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index ec348a95..9d4b366e 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2081,33 +2081,48 @@ havoc_stage:
where we take the input file and make random stacked tweaks. */
u32 *mutation_array;
- u32 stack_max; // stack_max_pow = afl->havoc_stack_pow2;
+ u32 stack_max, rand_max; // stack_max_pow = afl->havoc_stack_pow2;
- if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text?
+ if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
- if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ mutation_array = full_splice_array;
+ rand_max = MUT_SPLICE_ARRAY_SIZE;
- mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
+ } else {
- } else { // is exploitation!
+ mutation_array = normal_splice_array;
+ rand_max = MUT_NORMAL_ARRAY_SIZE;
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
+ }
- }
+ /*
+ if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text?
+
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
+
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
+
+ } else { // is exploitation!
- } else { // is binary!
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
- if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ }
+
+ } else { // is binary!
- mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
- } else { // is exploitation!
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
+ } else { // is exploitation!
+
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
+
+ }
}
- }
+ */
/*
if (temp_len < 64) {
@@ -2180,7 +2195,7 @@ havoc_stage:
retry_havoc_step : {
- u32 r = rand_below(afl, MUT_STRATEGY_ARRAY_SIZE), item;
+ u32 r = rand_below(afl, rand_max), item;
switch (mutation_array[r]) {
--
cgit 1.4.1
From c7c6ad1a94810fc4c24fbf05bcdd7f9cf806646e Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 6 Jun 2023 17:04:31 +0200
Subject: no_ui mode
---
src/afl-fuzz-one.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index ec348a95..9685885b 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -402,10 +402,11 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (unlikely(afl->not_on_tty)) {
ACTF(
- "Fuzzing test case #%u (%u total, %llu crashes saved, "
+ "Fuzzing test case #%u (%u total, %llu crashes saved, mode=%s, "
"perf_score=%0.0f, weight=%0.0f, favorite=%u, was_fuzzed=%u, "
"exec_us=%llu, hits=%u, map=%u, ascii=%u)...",
afl->current_entry, afl->queued_items, afl->saved_crashes,
+ afl->fuzz_mode ? "exploit" : "explore",
afl->queue_cur->perf_score, afl->queue_cur->weight,
afl->queue_cur->favored, afl->queue_cur->was_fuzzed,
afl->queue_cur->exec_us,
--
cgit 1.4.1
From f0ccca123ad8f9813ad141ebd243e8c7b96824a1 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 6 Jun 2023 17:32:32 +0200
Subject: fix ci
---
test/test-llvm.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/test-llvm.sh b/test/test-llvm.sh
index 19fb7c1a..95e43b1c 100755
--- a/test/test-llvm.sh
+++ b/test/test-llvm.sh
@@ -257,7 +257,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && {
}
rm -f test-compcov test.out instrumentlist.txt
AFL_LLVM_CMPLOG=1 ../afl-clang-fast -o test-cmplog test-cmplog.c > /dev/null 2>&1
- ../afl-clang-fast -o test-c test-cmplog.c > /dev/null 2>&1
+ ../afl-clang-fast -O0 -o test-c test-cmplog.c > /dev/null 2>&1
test -e test-cmplog && {
$ECHO "$GREY[*] running afl-fuzz for llvm_mode cmplog, this will take approx 10 seconds"
{
--
cgit 1.4.1
From f6471dd256ac04f51c2107533055a2d9c9a18fc7 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 7 Jun 2023 10:57:52 +0200
Subject: fix gcc cmplog crash
---
instrumentation/afl-gcc-cmptrs-pass.so.cc | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/instrumentation/afl-gcc-cmptrs-pass.so.cc b/instrumentation/afl-gcc-cmptrs-pass.so.cc
index dbb408b0..c56263dd 100644
--- a/instrumentation/afl-gcc-cmptrs-pass.so.cc
+++ b/instrumentation/afl-gcc-cmptrs-pass.so.cc
@@ -157,6 +157,9 @@ struct afl_cmptrs_pass : afl_base_pass {
/* We expect it to be a record type. */
if (TREE_CODE(t) != RECORD_TYPE) return false;
+ /* The type has an identifier. */
+ if (!TYPE_IDENTIFIER(t)) return false;
+
/* The type of the template is basic_string. */
if (strcmp(IDENTIFIER_POINTER(TYPE_IDENTIFIER(t)), "basic_string") != 0)
return false;
@@ -201,7 +204,7 @@ struct afl_cmptrs_pass : afl_base_pass {
/* Now go back to the first data member. Its type should be a
record type named _Alloc_hider. */
c = TREE_TYPE(c);
- if (!c || TREE_CODE(c) != RECORD_TYPE ||
+ if (!c || TREE_CODE(c) != RECORD_TYPE || !TYPE_IDENTIFIER(t) ||
strcmp(IDENTIFIER_POINTER(TYPE_IDENTIFIER(c)), "_Alloc_hider") != 0)
return false;
--
cgit 1.4.1
From a4b927241651c645cc1a2f5b185681830e7000f9 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 7 Jun 2023 10:58:10 +0200
Subject: fix gcc cmplog crash
---
docs/Changelog.md | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index facf2196..9ed930b3 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,6 +18,7 @@
- rewrote our PCGUARD pass to be compatible with LLVM 15+ shenanigans,
requires LLVM 13+ now instead of 10.0.1+
- fallback to native LLVM PCGUARD if our PCGUARD is unavailable
+ - fixed a crash in GCC CMPLOG
- afl-showmap:
- added custom mutator post_process and send support
- add `-I filelist` option, an alternative to `-i in_dir`
--
cgit 1.4.1
From 88603a2c2e770b20373c4002cb4aaf4e7b058ae5 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 7 Jun 2023 15:17:46 +0200
Subject: add issue to faq
---
docs/FAQ.md | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 51 insertions(+)
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 8178db46..9275eb94 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -279,3 +279,54 @@ If you find an interesting or important question missing, submit it via
Solution: just do an `export AFL_MAP_SIZE=(the value in the warning)`.
+
+
+ Linker errors.
+
+ If you compile C++ harnesses and see `undefined reference` errors for
+ variables named `__afl_...`, e.g.:
+
+ ```
+ /usr/bin/ld: /tmp/test-d3085f.o: in function `foo::test()':
+ test.cpp:(.text._ZN3fooL4testEv[_ZN3fooL4testEv]+0x35): undefined reference to `foo::__afl_connected'
+ clang: error: linker command failed with exit code 1 (use -v to see invocation)
+ ```
+
+ Then you use AFL++ macros like `__AFL_LOOP` within a namespace and this
+ will not work.
+
+ Solution: Move that harness portion to the global namespace, e.g. before:
+ ```
+ #include
+ namespace foo {
+ static void test() {
+ while(__AFL_LOOP(1000)) {
+ foo::function();
+ }
+ }
+ }
+
+ int main(int argc, char** argv) {
+ foo::test();
+ return 0;
+ }
+ ```
+ after:
+ ```
+ #include
+ static void mytest() {
+ while(__AFL_LOOP(1000)) {
+ foo::function();
+ }
+ }
+ namespace foo {
+ static void test() {
+ mytest();
+ }
+ }
+ int main(int argc, char** argv) {
+ foo::test();
+ return 0;
+ }
+ ```
+
--
cgit 1.4.1
From e71d422b3c9867249dcaac87e40b08010fc43497 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 8 Jun 2023 08:42:23 +0200
Subject: enhance custom mutator docs
---
docs/custom_mutators.md | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index 3f7e9e6e..c5a64622 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -145,12 +145,15 @@ def deinit(): # optional for Python
- `fuzz` (optional):
- This method performs custom mutations on a given input. It also accepts an
- additional test case. Note that this function is optional - but it makes
- sense to use it. You would only skip this if `post_process` is used to fix
- checksums etc. so if you are using it, e.g., as a post processing library.
- Note that a length > 0 *must* be returned!
- The returned output buffer is under **your** memory management!
+ This method performs your custom mutations on a given input.
+ The add_buf is the contents of another queue item that can be used for
+ splicing - or anything else - and can also be ignored. If you are not
+ using this additional data then define `splice_optout` (see above).
+ This function is optional.
+ Returing a length of 0 is valid and is interpreted as skipping this
+ one mutation result.
+ For non-Python: the returned output buffer is under **your** memory
+ management!
- `describe` (optional):
--
cgit 1.4.1
From c28779adc543ffd3c68696867eef0f719ecee9d4 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 8 Jun 2023 12:32:51 +0200
Subject: show fuzzing state
---
include/afl-fuzz.h | 1 +
src/afl-fuzz-one.c | 5 +++--
src/afl-fuzz-stats.c | 46 +++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 47 insertions(+), 5 deletions(-)
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index e1359dc8..c6c45fbd 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -1202,6 +1202,7 @@ u8 check_if_text_buf(u8 *buf, u32 len);
#ifndef AFL_SHOWMAP
void setup_signal_handlers(void);
#endif
+char *get_fuzzing_state(afl_state_t *afl);
/* CmpLog */
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 9685885b..af5e57a0 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -402,11 +402,12 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (unlikely(afl->not_on_tty)) {
ACTF(
- "Fuzzing test case #%u (%u total, %llu crashes saved, mode=%s, "
+ "Fuzzing test case #%u (%u total, %llu crashes saved, state: %s, "
+ "mode=%s, "
"perf_score=%0.0f, weight=%0.0f, favorite=%u, was_fuzzed=%u, "
"exec_us=%llu, hits=%u, map=%u, ascii=%u)...",
afl->current_entry, afl->queued_items, afl->saved_crashes,
- afl->fuzz_mode ? "exploit" : "explore",
+ get_fuzzing_state(afl), afl->fuzz_mode ? "exploit" : "explore",
afl->queue_cur->perf_score, afl->queue_cur->weight,
afl->queue_cur->favored, afl->queue_cur->was_fuzzed,
afl->queue_cur->exec_us,
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 4ffb2536..9a60fd47 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -27,6 +27,45 @@
#include "envs.h"
#include
+static char fuzzing_state[4][12] = {"started :-)", "in progress", "final phase",
+ "finished..."};
+
+char *get_fuzzing_state(afl_state_t *afl) {
+
+ u64 cur_ms = get_cur_time();
+ u64 last_find = cur_ms - afl->last_find_time;
+ u64 cur_run_time = cur_ms - afl->start_time;
+ u64 cur_total_run_time = afl->prev_run_time + cur_run_time;
+
+ if (unlikely(cur_run_time < 60 * 3 * 1000 ||
+ cur_total_run_time < 60 * 5 * 1000)) {
+
+ return fuzzing_state[0];
+
+ } else {
+
+ u64 last_find_100 = 100 * last_find;
+ u64 percent_cur = last_find_100 / cur_run_time;
+ u64 percent_total = last_find_100 / cur_total_run_time;
+
+ if (unlikely(percent_cur >= 90 && percent_total >= 90)) {
+
+ return fuzzing_state[3];
+
+ } else if (unlikely(percent_cur >= 75 && percent_total >= 75)) {
+
+ return fuzzing_state[2];
+
+ } else {
+
+ return fuzzing_state[1];
+
+ }
+
+ }
+
+}
+
/* Write fuzzer setup file */
void write_setup_file(afl_state_t *afl, u32 argc, char **argv) {
@@ -1283,9 +1322,10 @@ void show_stats_normal(afl_state_t *afl) {
/* Last line */
- SAYF(SET_G1 "\n" bSTG bLB bH cCYA bSTOP
- " strategy:%s %s " bSTG bH20 bH10 bH2 bRB bSTOP cRST RESET_G1,
- cPIN, afl->fuzz_mode == 0 ? "explore" : "exploit");
+ SAYF(SET_G1 "\n" bSTG bLB bH cCYA bSTOP " strategy:" cPIN
+ " %s " bSTG bH10 cCYA bSTOP " state:" cPIN
+ " %s " bSTG bH2 bRB bSTOP cRST RESET_G1,
+ afl->fuzz_mode == 0 ? "explore" : "exploit", get_fuzzing_state(afl));
#undef IB
--
cgit 1.4.1
From 6ec70fc0847a0624692e868743080bf4e6935523 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 9 Jun 2023 09:33:33 +0200
Subject: binary mutations
---
src/afl-fuzz-one.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index e722f0c6..816384fd 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2085,6 +2085,8 @@ havoc_stage:
u32 *mutation_array;
u32 stack_max, rand_max; // stack_max_pow = afl->havoc_stack_pow2;
+ /*
+
if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
mutation_array = full_splice_array;
@@ -2097,6 +2099,8 @@ havoc_stage:
}
+ */
+
/*
if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text?
@@ -2112,15 +2116,21 @@ havoc_stage:
} else { // is binary!
- if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ */
- mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
- } else { // is exploitation!
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
- }
+ } else { // is exploitation!
+
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
+
+ }
+
+ /*
}
--
cgit 1.4.1
From bf2727b76366ce4c9cdc723c3f3ccffae3cc3619 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 12 Jun 2023 08:28:47 +0200
Subject: v4.07c release
---
README.md | 4 ++--
TODO.md | 2 ++
docs/Changelog.md | 2 +-
include/config.h | 2 +-
4 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 0208a9fe..97fd3997 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
-Release version: [4.06c](https://github.com/AFLplusplus/AFLplusplus/releases)
+Release version: [4.07c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.07a
+GitHub version: 4.07c
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/TODO.md b/TODO.md
index 2b7e8fcf..26e12cee 100644
--- a/TODO.md
+++ b/TODO.md
@@ -2,6 +2,8 @@
## Should
+ - afl-crash-analysis
+ - show in the UI when fuzzing is "done"
- test cmplog for less than 16bit
- support persistent and deferred fork server in afl-showmap?
- better autodetection of shifting runtime timeout values
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 9ed930b3..c52ddd56 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,7 +3,7 @@
This is the list of all noteworthy changes made in every public
release of the tool. See README.md for the general instruction manual.
-### Version ++4.07a (dev)
+### Version ++4.07c (release)
- afl-fuzz:
- reverse reading the seeds only on restarts (increases performance)
- new env `AFL_POST_PROCESS_KEEP_ORIGINAL` to keep the orignal
diff --git a/include/config.h b/include/config.h
index 194786f7..53be8549 100644
--- a/include/config.h
+++ b/include/config.h
@@ -26,7 +26,7 @@
/* Version string: */
// c = release, a = volatile github dev, e = experimental branch
-#define VERSION "++4.07a"
+#define VERSION "++4.07c"
/******************************************************
* *
--
cgit 1.4.1
From 25eba95bbaf58539c65088fc8bc143ed30ad82b9 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 12 Jun 2023 08:43:30 +0200
Subject: update new feature config
---
include/config.h | 2 +-
src/afl-fuzz-stats.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/include/config.h b/include/config.h
index b767d526..09d8620d 100644
--- a/include/config.h
+++ b/include/config.h
@@ -47,7 +47,7 @@
switches to exploitation mode. It automatically switches back when new
coverage is found.
Default: 300 (seconds) */
-#define STRATEGY_SWITCH_TIME 300
+#define STRATEGY_SWITCH_TIME 600
/* Default file permission umode when creating files (default: 0600) */
#define DEFAULT_PERMISSION 0600
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 9a60fd47..1499a7e4 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -48,11 +48,11 @@ char *get_fuzzing_state(afl_state_t *afl) {
u64 percent_cur = last_find_100 / cur_run_time;
u64 percent_total = last_find_100 / cur_total_run_time;
- if (unlikely(percent_cur >= 90 && percent_total >= 90)) {
+ if (unlikely(percent_cur >= 80 && percent_total >= 80)) {
return fuzzing_state[3];
- } else if (unlikely(percent_cur >= 75 && percent_total >= 75)) {
+ } else if (unlikely(percent_cur >= 55 && percent_total >= 55)) {
return fuzzing_state[2];
--
cgit 1.4.1
From ed97dbacef98c379d7028514a43c799c86050584 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 12 Jun 2023 09:13:24 +0200
Subject: enable text mode
---
src/afl-fuzz-one.c | 33 +++++++++++++--------------------
1 file changed, 13 insertions(+), 20 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 816384fd..4efc661e 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2101,40 +2101,33 @@ havoc_stage:
*/
- /*
- if (unlikely(afl->text_input || afl->queue_cur->is_ascii)) { // is text?
-
- if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
- mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
+ if (unlikely(afl->text_input /*|| afl->queue_cur->is_ascii*/)) { // is text?
- } else { // is exploitation!
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
- }
+ } else { // is exploitation!
- } else { // is binary!
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
- */
-
- rand_max = MUT_STRATEGY_ARRAY_SIZE;
-
- if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ }
- mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
+ } else { // is binary!
- } else { // is exploitation!
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
- }
+ } else { // is exploitation!
- /*
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
}
- */
+ }
/*
if (temp_len < 64) {
--
cgit 1.4.1
From 61b6f4ed9e4dce15c39e4350278a95a41ea2522c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 12 Jun 2023 09:16:15 +0200
Subject: 4.08a init
---
README.md | 2 +-
docs/Changelog.md | 7 +++++++
include/config.h | 2 +-
3 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 97fd3997..05c662c1 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
Release version: [4.07c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.07c
+GitHub version: 4.08a
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index c52ddd56..98d59527 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,6 +3,13 @@
This is the list of all noteworthy changes made in every public
release of the tool. See README.md for the general instruction manual.
+### Version ++4.08a (dev)
+ - new mutation engine: mutations that favor discovery more paths are prefered
+ until no new finds for 10 minutes then switching to mutations that favor
+ triggering crashes. Modes and switch time can be configured wie `-P`.
+ - display the state of the fuzzing run in the UI :-)
+
+
### Version ++4.07c (release)
- afl-fuzz:
- reverse reading the seeds only on restarts (increases performance)
diff --git a/include/config.h b/include/config.h
index 53be8549..d8153a2c 100644
--- a/include/config.h
+++ b/include/config.h
@@ -26,7 +26,7 @@
/* Version string: */
// c = release, a = volatile github dev, e = experimental branch
-#define VERSION "++4.07c"
+#define VERSION "++4.08a"
/******************************************************
* *
--
cgit 1.4.1
From 3ad8e9856cc48a6f69aa701dafd0623f91f31c5c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 12 Jun 2023 09:23:57 +0200
Subject: update changelog
---
docs/Changelog.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 98d59527..70f38d05 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -7,6 +7,9 @@
- new mutation engine: mutations that favor discovery more paths are prefered
until no new finds for 10 minutes then switching to mutations that favor
triggering crashes. Modes and switch time can be configured wie `-P`.
+ - new custom mutator that has the new afl++ engine (so it can easily
+ incorporated into new custom mutators), and also comes with a standalone
+ command line tool! See custom_mutators/aflpp/standalone/
- display the state of the fuzzing run in the UI :-)
--
cgit 1.4.1
From 091d66fa92cd9e4caa5829d579b1b996c49db8c9 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 12 Jun 2023 13:05:35 +0200
Subject: increase strategy switch
---
include/config.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/config.h b/include/config.h
index 5100d88f..8585041e 100644
--- a/include/config.h
+++ b/include/config.h
@@ -47,7 +47,7 @@
switches to exploitation mode. It automatically switches back when new
coverage is found.
Default: 300 (seconds) */
-#define STRATEGY_SWITCH_TIME 600
+#define STRATEGY_SWITCH_TIME 1000
/* Default file permission umode when creating files (default: 0600) */
#define DEFAULT_PERMISSION 0600
--
cgit 1.4.1
From fc1e352965416fc9cc74db39c1fec25c95ef2a64 Mon Sep 17 00:00:00 2001
From: forky2 <63731115+forky2@users.noreply.github.com>
Date: Wed, 14 Jun 2023 08:43:06 +0100
Subject: Fixes #1770: afl-cmin in -T mode doesn't correctly divide inputs
among threads
---
afl-cmin | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/afl-cmin b/afl-cmin
index ae723c1b..de76caf8 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -488,7 +488,7 @@ BEGIN {
if (threads) {
- inputsperfile = in_count / threads
+ inputsperfile = int(in_count / threads)
if (in_count % threads) {
inputsperfile++;
}
--
cgit 1.4.1
From a36034424779d8c9769819ee525b321bfd64a26c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 14 Jun 2023 13:11:44 +0200
Subject: minor cmplog bugfix
---
TODO.md | 1 -
src/afl-fuzz-redqueen.c | 12 +++++++-----
2 files changed, 7 insertions(+), 6 deletions(-)
diff --git a/TODO.md b/TODO.md
index 26e12cee..7968452e 100644
--- a/TODO.md
+++ b/TODO.md
@@ -3,7 +3,6 @@
## Should
- afl-crash-analysis
- - show in the UI when fuzzing is "done"
- test cmplog for less than 16bit
- support persistent and deferred fork server in afl-showmap?
- better autodetection of shifting runtime timeout values
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 41644cb9..73e188e7 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -1988,10 +1988,10 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
if (l0 >= 0x80 || ol0 >= 0x80) {
- l0 -= 0x80;
- l1 -= 0x80;
- ol0 -= 0x80;
- ol1 -= 0x80;
+ if (l0 >= 0x80) { l0 -= 0x80; }
+ if (l1 >= 0x80) { l1 -= 0x80; }
+ if (ol0 >= 0x80) { ol0 -= 0x80; }
+ if (ol1 >= 0x80) { ol1 -= 0x80; }
}
@@ -2059,7 +2059,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
for (i = 0; i < its_len; ++i) {
- if ((pattern[i] != buf[idx + i] && o_pattern[i] != orig_buf[idx + i]) ||
+ if ((pattern[i] != buf[idx + i] || o_pattern[i] != orig_buf[idx + i]) ||
*status == 1) {
break;
@@ -2592,6 +2592,8 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
// shape_len), check_if_text_buf((u8 *)&o->v1, shape_len), v0_len,
// o->v0, v1_len, o->v1);
+ // Note that this check differs from the line 1901, for RTN we are more
+ // opportunistic for adding to the dictionary than cmps
if (!memcmp(o->v0, orig_o->v0, v0_len) ||
(!found_one || check_if_text_buf((u8 *)&o->v0, v0_len) == v0_len))
maybe_add_auto(afl, o->v0, v0_len);
--
cgit 1.4.1
From 4231d33bc086895a15d8f449991ee3b160446d0a Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 14 Jun 2023 13:18:44 +0200
Subject: improve afl-plot plots
---
afl-plot | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/afl-plot b/afl-plot
index 230d3bfe..f1f288a3 100755
--- a/afl-plot
+++ b/afl-plot
@@ -75,8 +75,17 @@ outputdir=`get_abs_path "$2"`
if [ ! -f "$inputdir/plot_data" ]; then
- echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2
- exit 1
+ if [ -f "$inputdir/default/plot_data" ]; then
+
+ echo "[-] Error: input directory is not valid (missing 'plot_data'), likely you mean $inputdir/default?" 1>&2
+ exit 1
+
+ else
+
+ echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2
+ exit 1
+
+ fi
fi
@@ -141,7 +150,7 @@ set output '$outputdir/high_freq.png'
$GNUPLOT_SETUP
plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'corpus count' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\
- '' using 1:3 with filledcurve x1 title 'current fuzz item' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\
+ '' using 1:3 with filledcurve x1 title 'current item' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\
'' using 1:5 with lines title 'pending items' linecolor rgb '#0090ff' linewidth 3, \\
'' using 1:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\
'' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' linewidth 3
--
cgit 1.4.1
From 450e00446dfe23a74b08c4ad88b082d48e1f0b66 Mon Sep 17 00:00:00 2001
From: cuanduo
Date: Fri, 16 Jun 2023 08:28:05 +0800
Subject: fix bug
---
utils/afl_network_proxy/afl-network-server.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/utils/afl_network_proxy/afl-network-server.c b/utils/afl_network_proxy/afl-network-server.c
index 04309ada..7eb3d18e 100644
--- a/utils/afl_network_proxy/afl-network-server.c
+++ b/utils/afl_network_proxy/afl-network-server.c
@@ -173,6 +173,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
}
out_file = alloc_printf("%s/.afl-input-temp-%u", use_dir, getpid());
+ fsrv->out_file = out_file;
}
--
cgit 1.4.1
From 420e36dcd3764921765d6aeb07989e701134513a Mon Sep 17 00:00:00 2001
From: Seoyoung
Date: Fri, 16 Jun 2023 05:49:49 -0400
Subject: SanitizerCoveragePCGUARD: select counter off by one error
---
instrumentation/SanitizerCoveragePCGUARD.so.cc | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 7171e7aa..d87af775 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -892,7 +892,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
ConstantInt::get(
IntptrTy,
- (cnt_cov + ++local_selects + AllBlocks.size()) * 4)),
+ (cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
Int32PtrTy);
auto GuardPtr2 = IRB.CreateIntToPtr(
@@ -900,7 +900,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
ConstantInt::get(
IntptrTy,
- (cnt_cov + ++local_selects + AllBlocks.size()) * 4)),
+ (cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
Int32PtrTy);
result = IRB.CreateSelect(condition, GuardPtr1, GuardPtr2);
@@ -937,7 +937,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
ConstantInt::get(
IntptrTy,
- (cnt_cov + ++local_selects + AllBlocks.size()) * 4)),
+ (cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
Int32PtrTy);
x = IRB.CreateInsertElement(GuardPtr1, val1, (uint64_t)0);
@@ -946,7 +946,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
ConstantInt::get(
IntptrTy,
- (cnt_cov + ++local_selects + AllBlocks.size()) * 4)),
+ (cnt_cov + local_selects++ + AllBlocks.size()) * 4)),
Int32PtrTy);
y = IRB.CreateInsertElement(GuardPtr2, val2, (uint64_t)0);
@@ -955,7 +955,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
val1 = IRB.CreateIntToPtr(
IRB.CreateAdd(
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
- ConstantInt::get(IntptrTy, (cnt_cov + ++local_selects +
+ ConstantInt::get(IntptrTy, (cnt_cov + local_selects++ +
AllBlocks.size()) *
4)),
Int32PtrTy);
@@ -964,7 +964,7 @@ bool ModuleSanitizerCoverageAFL::InjectCoverage(
val2 = IRB.CreateIntToPtr(
IRB.CreateAdd(
IRB.CreatePointerCast(FunctionGuardArray, IntptrTy),
- ConstantInt::get(IntptrTy, (cnt_cov + ++local_selects +
+ ConstantInt::get(IntptrTy, (cnt_cov + local_selects++ +
AllBlocks.size()) *
4)),
Int32PtrTy);
--
cgit 1.4.1
From 7b29f2cd244424c5385605d1302b68be44e432bc Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 20 Jun 2023 19:58:08 +0200
Subject: fix timeout for sessions restart and + usage
---
docs/Changelog.md | 17 ++++++++++-------
src/afl-fuzz-stats.c | 14 ++++++--------
src/afl-fuzz.c | 1 +
3 files changed, 17 insertions(+), 15 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 70f38d05..4454456e 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -4,13 +4,16 @@
release of the tool. See README.md for the general instruction manual.
### Version ++4.08a (dev)
- - new mutation engine: mutations that favor discovery more paths are prefered
- until no new finds for 10 minutes then switching to mutations that favor
- triggering crashes. Modes and switch time can be configured wie `-P`.
- - new custom mutator that has the new afl++ engine (so it can easily
- incorporated into new custom mutators), and also comes with a standalone
- command line tool! See custom_mutators/aflpp/standalone/
- - display the state of the fuzzing run in the UI :-)
+ - afl-fuzz:
+ - new mutation engine: mutations that favor discovery more paths are
+ prefered until no new finds for 10 minutes then switching to mutations
+ that favor triggering crashes. Modes and switch time can be configured
+ with `-P`.
+ - new custom mutator that has the new afl++ engine (so it can easily
+ incorporated into new custom mutators), and also comes with a standalone
+ command line tool! See custom_mutators/aflpp/standalone/
+ - display the state of the fuzzing run in the UI :-)
+ - fix timeout setting if '+' is used or a session is restarted
### Version ++4.07c (release)
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 1499a7e4..389b82fc 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -2303,7 +2303,12 @@ void show_init_stats(afl_state_t *afl) {
stringify_int(IB(0), min_us), stringify_int(IB(1), max_us),
stringify_int(IB(2), avg_us));
- if (afl->timeout_given != 1) {
+ if (afl->timeout_given == 3) {
+
+ ACTF("Applying timeout settings from resumed session (%u ms).",
+ afl->fsrv.exec_tmout);
+
+ } else if (afl->timeout_given != 1) {
/* Figure out the appropriate timeout. The basic idea is: 5x average or
1x max, rounded up to EXEC_TM_ROUND ms and capped at 1 second.
@@ -2345,13 +2350,6 @@ void show_init_stats(afl_state_t *afl) {
afl->timeout_given = 1;
- } else if (afl->timeout_given == 3) {
-
- ACTF("Applying timeout settings from resumed session (%u ms).",
- afl->fsrv.exec_tmout);
-
- } else {
-
ACTF("-t option specified. We'll use an exec timeout of %u ms.",
afl->fsrv.exec_tmout);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index d727fff5..9eabfae1 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -2362,6 +2362,7 @@ int main(int argc, char **argv_orig, char **envp) {
max_ms = afl->queue_buf[entry]->exec_us;
afl->fsrv.exec_tmout = max_ms;
+ afl->timeout_given = 1;
}
--
cgit 1.4.1
From 51ab51ca278dafacfca1131fd339529e9d7dce08 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 21 Jun 2023 09:04:08 +0200
Subject: update tutorial list
---
custom_mutators/README.md | 11 +++++++----
docs/tutorials.md | 5 +++++
2 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/custom_mutators/README.md b/custom_mutators/README.md
index a5a572c0..2d1220b3 100644
--- a/custom_mutators/README.md
+++ b/custom_mutators/README.md
@@ -70,14 +70,17 @@ requires cmake (among other things):
### libprotobuf Mutators
-There are two WIP protobuf projects, that require work to be working though:
+There are three WIP protobuf projects, that require work to be working though:
+
+ASN.1 example:
+[https://github.com/airbus-seclab/AFLplusplus-blogpost/tree/main/src/mutator](https://github.com/airbus-seclab/AFLplusplus-blogpost/tree/main/src/mutator)
transforms protobuf raw:
-https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator
+[https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator)
has a transform function you need to fill for your protobuf format, however
needs to be ported to the updated AFL++ custom mutator API (not much work):
-https://github.com/thebabush/afl-libprotobuf-mutator
+[https://github.com/thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator)
same as above but is for current AFL++:
-https://github.com/P1umer/AFLplusplus-protobuf-mutator
+[https://github.com/P1umer/AFLplusplus-protobuf-mutator](https://github.com/P1umer/AFLplusplus-protobuf-mutator)
\ No newline at end of file
diff --git a/docs/tutorials.md b/docs/tutorials.md
index 342080fd..a5ee3322 100644
--- a/docs/tutorials.md
+++ b/docs/tutorials.md
@@ -8,6 +8,7 @@ Here are some good write-ups to show how to effectively use AFL++:
* [https://aflplus.plus/docs/tutorials/libxml2_tutorial/](https://aflplus.plus/docs/tutorials/libxml2_tutorial/)
* [https://bananamafia.dev/post/gb-fuzz/](https://bananamafia.dev/post/gb-fuzz/)
+* [https://bushido-sec.com/index.php/2023/06/19/the-art-of-fuzzing/](https://bushido-sec.com/index.php/2023/06/19/the-art-of-fuzzing/)
* [https://securitylab.github.com/research/fuzzing-challenges-solutions-1](https://securitylab.github.com/research/fuzzing-challenges-solutions-1)
* [https://securitylab.github.com/research/fuzzing-software-2](https://securitylab.github.com/research/fuzzing-software-2)
* [https://securitylab.github.com/research/fuzzing-sockets-FTP](https://securitylab.github.com/research/fuzzing-sockets-FTP)
@@ -20,6 +21,10 @@ training, then we can highly recommend the following:
* [https://github.com/antonio-morales/Fuzzing101](https://github.com/antonio-morales/Fuzzing101)
+Here is a good forkflow description (and tutorial) for qemu_mode:
+
+* [https://airbus-seclab.github.io/AFLplusplus-blogpost/](https://airbus-seclab.github.io/AFLplusplus-blogpost/)
+
Here is good workflow description for frida_mode:
* [https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html](https://blog.quarkslab.com/android-greybox-fuzzing-with-afl-frida-mode.html)
--
cgit 1.4.1
From 2366c00235692c9ae11921cf38e9f6fe3fb30142 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 21 Jun 2023 09:38:21 +0200
Subject: switch back to normal mutations
---
src/afl-fuzz-one.c | 26 +++++++++++++++++++++++---
1 file changed, 23 insertions(+), 3 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 4efc661e..32c05182 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2103,11 +2103,21 @@ havoc_stage:
rand_max = MUT_STRATEGY_ARRAY_SIZE;
- if (unlikely(afl->text_input /*|| afl->queue_cur->is_ascii*/)) { // is text?
+ if (unlikely(afl->text_input)) { // is text?
if (likely(afl->fuzz_mode == 0)) { // is exploration?
- mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
+ if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
+
+ mutation_array = full_splice_array;
+ rand_max = MUT_SPLICE_ARRAY_SIZE;
+
+ } else {
+
+ mutation_array = normal_splice_array;
+ rand_max = MUT_NORMAL_ARRAY_SIZE;
+
+ }
} else { // is exploitation!
@@ -2119,7 +2129,17 @@ havoc_stage:
if (likely(afl->fuzz_mode == 0)) { // is exploration?
- mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
+ if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
+
+ mutation_array = full_splice_array;
+ rand_max = MUT_SPLICE_ARRAY_SIZE;
+
+ } else {
+
+ mutation_array = normal_splice_array;
+ rand_max = MUT_NORMAL_ARRAY_SIZE;
+
+ }
} else { // is exploitation!
--
cgit 1.4.1
From 936b6dcb5d7a93d2aa211d0812fd26ba0b2c7d3c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 21 Jun 2023 09:57:24 +0200
Subject: nits
---
afl-cmin | 2 +-
src/afl-fuzz-stats.c | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/afl-cmin b/afl-cmin
index de76caf8..3e37dbdb 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -513,7 +513,7 @@ BEGIN {
if (threads > 1) {
- print "[*] Creating " threads " parallel tasks with about " inputsperfile " each."
+ print "[*] Creating " threads " parallel tasks with about " inputsperfile " items each."
for (i = 1; i <= threads; i++) {
if (!stdin_file) {
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 389b82fc..4013370d 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -2350,6 +2350,8 @@ void show_init_stats(afl_state_t *afl) {
afl->timeout_given = 1;
+ } else {
+
ACTF("-t option specified. We'll use an exec timeout of %u ms.",
afl->fsrv.exec_tmout);
--
cgit 1.4.1
From 64b15a00f270f0ac9c00cf13e569481672227635 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 21 Jun 2023 12:20:10 +0200
Subject: fix afl-cmin* for old afl vanilla issue
---
afl-cmin | 35 +++++++++++++++++++++++++++++------
afl-cmin.bash | 4 +++-
docs/Changelog.md | 4 ++++
src/afl-showmap.c | 5 +++--
4 files changed, 39 insertions(+), 9 deletions(-)
diff --git a/afl-cmin b/afl-cmin
index 3e37dbdb..d0bbed2b 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -318,7 +318,9 @@ BEGIN {
if (!nyx_mode && target_bin && !exists_and_is_executable(target_bin)) {
- "command -v "target_bin" 2>/dev/null" | getline tnew
+ cmd = "command -v "target_bin" 2>/dev/null"
+ cmd | getline tnew
+ close(cmd)
if (!tnew || !exists_and_is_executable(tnew)) {
print "[-] Error: binary '"target_bin"' not found or not executable." > "/dev/stderr"
exit 1
@@ -330,6 +332,7 @@ BEGIN {
echo "[!] Trying to obtain the map size of the target ..."
get_map_size = "AFL_DUMP_MAP_SIZE=1 " target_bin
get_map_size | getline mapsize
+ close(get_map_size)
if (mapsize && mapsize > 65535 && mapsize < 100000000) {
AFL_MAP_SIZE = "AFL_MAP_SIZE="mapsize" "
print "[+] Setting "AFL_MAP_SIZE
@@ -359,14 +362,18 @@ BEGIN {
system("rm -rf "trace_dir" 2>/dev/null");
system("rm "out_dir"/id[:_]* 2>/dev/null")
- "ls "out_dir"/* 2>/dev/null | wc -l" | getline noofentries
+ cmd = "ls "out_dir"/* 2>/dev/null | wc -l"
+ cmd | getline noofentries
+ close(cmd)
if (0 == system( "test -d "out_dir" -a "noofentries" -gt 0" )) {
print "[-] Error: directory '"out_dir"' exists and is not empty - delete it first." > "/dev/stderr"
exit 1
}
if (threads) {
- "nproc" | getline nproc
+ cmd = "nproc"
+ cmd | getline nproc
+ close(cmd)
if (threads == "all") {
threads = nproc
} else {
@@ -386,12 +393,14 @@ BEGIN {
if (stdin_file) {
# truncate input file
printf "" > stdin_file
- close( stdin_file )
+ close(stdin_file)
}
# First we look in PATH
if (0 == system("command -v afl-showmap >/dev/null 2>&1")) {
- "command -v afl-showmap 2>/dev/null" | getline showmap
+ cmd = "command -v afl-showmap 2>/dev/null"
+ cmd | getline showmap
+ close(cmd)
} else {
# then we look in the current directory
if (0 == system("test -x ./afl-showmap")) {
@@ -413,7 +422,9 @@ BEGIN {
# yuck, gnu stat is option incompatible to bsd stat
# we use a heuristic to differentiate between
# GNU stat and other stats
- "stat --version 2>/dev/null" | getline statversion
+ cmd = "stat --version 2>/dev/null"
+ cmd | getline statversion
+ close(cmd)
if (statversion ~ /GNU coreutils/) {
stat_format = "-c '%s %n'" # GNU
} else {
@@ -432,6 +443,7 @@ BEGIN {
infilesSmallToBigFullMap[infilesSmallToBigFull[i]] = infilesSmallToBig[i]
i++
}
+ close(cmdline)
in_count = i
first_file = infilesSmallToBigFull[0]
@@ -468,6 +480,7 @@ BEGIN {
while ((getline < runtest) > 0) {
++first_count
}
+ close(runtest)
if (first_count) {
print "[+] OK, "first_count" tuples recorded."
@@ -582,6 +595,15 @@ BEGIN {
else { print " Processing file "cur"/"in_count }
# create path for the trace file from afl-showmap
tracefile_path = trace_dir"/"fn
+ # ensure the file size is not zero
+ cmd = "du -b "tracefile_path
+ "ls -l "tracefile_path
+ cmd | getline output
+ close(cmd)
+ split(output, result, "\t")
+ if (result[1] == 0) {
+ print "[!] WARNING: file "fn" is crashing the target, ignoring..."
+ }
# gather all keys, and count them
while ((getline line < tracefile_path) > 0) {
key = line
@@ -643,6 +665,7 @@ BEGIN {
}
}
close(sortedKeys)
+ print ""
print "[+] Found "tuple_count" unique tuples across "in_count" files."
if (out_count == 1) {
diff --git a/afl-cmin.bash b/afl-cmin.bash
index dc6d5342..1d080491 100755
--- a/afl-cmin.bash
+++ b/afl-cmin.bash
@@ -479,7 +479,7 @@ else
echo "[+] all $THREADS running tasks completed."
rm -f ${TMPFILE}*
- echo trace dir files: $(ls $TRACE_DIR/*|wc -l)
+ #echo trace dir files: $(ls $TRACE_DIR/*|wc -l)
fi
@@ -523,6 +523,8 @@ ls -rS "$IN_DIR" | while read -r fn; do
sed "s#\$# $fn#" "$TRACE_DIR/$fn" >>"$TRACE_DIR/.candidate_list"
+ test -s "$TRACE_DIR/$fn" || echo Warning: $fn is ignored because of crashing the target
+
done
echo
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 4454456e..246c3cac 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -14,6 +14,10 @@
command line tool! See custom_mutators/aflpp/standalone/
- display the state of the fuzzing run in the UI :-)
- fix timeout setting if '+' is used or a session is restarted
+ - afl-cmin/afl-cmin.bash:
+ - fixed a bug inherited from vanilla AFL where a coverage of
+ map[123] = 11 would be the same as map[1123] = 1
+ - warn on crashing inputs
### Version ++4.07c (release)
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 9c029035..13867fda 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -243,7 +243,8 @@ static void analyze_results(afl_forkserver_t *fsrv) {
total += fsrv->trace_bits[i];
if (fsrv->trace_bits[i] > highest) highest = fsrv->trace_bits[i];
- if (!coverage_map[i]) { coverage_map[i] = 1; }
+ // if (!coverage_map[i]) { coverage_map[i] = 1; }
+ coverage_map[i] |= fsrv->trace_bits[i];
}
@@ -328,7 +329,7 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
if (cmin_mode) {
- fprintf(f, "%u%u\n", fsrv->trace_bits[i], i);
+ fprintf(f, "%u%03u\n", i, fsrv->trace_bits[i]);
} else {
--
cgit 1.4.1
From ec4ed66b1efd0953d42e6c7055a2b1cf766ff720 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 21 Jun 2023 13:51:02 +0200
Subject: nits
---
src/afl-fuzz.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 9eabfae1..8cf786af 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -164,7 +164,7 @@ static void usage(u8 *argv0, int more_help) {
"\n"
"Mutator settings:\n"
- " -a - target expects ascii text input\n"
+ " -a - target expects ascii text input (prefer text mutators)\n"
" -g minlength - set min length of generated fuzz input (default: 1)\n"
" -G maxlength - set max length of generated fuzz input (default: "
"%lu)\n"
--
cgit 1.4.1
From 93362c6e672f1d2aba15636b6ba96a771aeb7ead Mon Sep 17 00:00:00 2001
From: mischa
Date: Wed, 21 Jun 2023 16:39:05 +0200
Subject: updated llvm requirements
---
GNUmakefile | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 55676d97..71011858 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -318,7 +318,7 @@ all: test_x86 test_shm test_python ready $(PROGS) afl-as llvm gcc_plugin test_bu
@echo Build Summary:
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
@test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
- @test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
+ @test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-13 and clang-13 or newer, see docs/INSTALL.md"
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM and LLD 11+. More information at instrumentation/README.lto.md on how to build it"
ifneq "$(SYS)" "Darwin"
@test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
@@ -740,7 +740,7 @@ endif
@echo Build Summary:
@test -e afl-fuzz && echo "[+] afl-fuzz and supporting tools successfully built" || echo "[-] afl-fuzz could not be built, please set CC to a working compiler"
@test -e afl-llvm-pass.so && echo "[+] LLVM basic mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
- @test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-11 and clang-11 or newer, see docs/INSTALL.md"
+ @test -e SanitizerCoveragePCGUARD.so && echo "[+] LLVM mode successfully built" || echo "[-] LLVM mode could not be built, please install at least llvm-13 and clang-13 or newer, see docs/INSTALL.md"
@test -e SanitizerCoverageLTO.so && echo "[+] LLVM LTO mode successfully built" || echo "[-] LLVM LTO mode could not be built, it is optional, if you want it, please install LLVM 11-14. More information at instrumentation/README.lto.md on how to build it"
ifneq "$(SYS)" "Darwin"
test -e afl-gcc-pass.so && echo "[+] gcc_mode successfully built" || echo "[-] gcc_mode could not be built, it is optional, install gcc-VERSION-plugin-dev to enable this"
--
cgit 1.4.1
From 90f83c13d08f44fbf50036076a1772909c4d2c86 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 22 Jun 2023 09:24:00 +0200
Subject: remove dead code, code format
---
.custom-format.py | 2 +-
docs/Changelog.md | 3 ++
include/alloc-inl.h | 8 +++---
instrumentation/SanitizerCoveragePCGUARD.so.cc | 39 ++------------------------
qemu_mode/libqasan/dlmalloc.c | 2 +-
src/afl-fuzz-init.c | 8 +++---
src/afl-fuzz.c | 3 +-
utils/afl_network_proxy/afl-network-server.c | 2 +-
8 files changed, 19 insertions(+), 48 deletions(-)
diff --git a/.custom-format.py b/.custom-format.py
index 1d5c8839..3521c05d 100755
--- a/.custom-format.py
+++ b/.custom-format.py
@@ -24,7 +24,7 @@ import importlib.metadata
# string_re = re.compile('(\\"(\\\\.|[^"\\\\])*\\")') # TODO: for future use
-CURRENT_LLVM = os.getenv('LLVM_VERSION', 15)
+CURRENT_LLVM = os.getenv('LLVM_VERSION', 16)
CLANG_FORMAT_BIN = os.getenv("CLANG_FORMAT_BIN", "")
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 246c3cac..c850c43e 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,6 +18,9 @@
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
- warn on crashing inputs
+ - afl-cc
+ - fixed an off-by-one instrumentation of iselect, hurting coverage a bit.
+ Thanks to @amykweon for spotting and fixing!
### Version ++4.07c (release)
diff --git a/include/alloc-inl.h b/include/alloc-inl.h
index 1e9a192b..cff808b2 100644
--- a/include/alloc-inl.h
+++ b/include/alloc-inl.h
@@ -322,7 +322,7 @@ static inline void DFL_ck_free(void *mem) {
static inline void *DFL_ck_realloc(void *orig, u32 size) {
void *ret;
- u32 old_size = 0;
+ u32 old_size = 0;
if (!size) {
@@ -392,7 +392,7 @@ static inline void *DFL_ck_realloc(void *orig, u32 size) {
static inline u8 *DFL_ck_strdup(u8 *str) {
void *ret;
- u32 size;
+ u32 size;
if (!str) return NULL;
@@ -438,14 +438,14 @@ struct TRK_obj {
void *ptr;
char *file, *func;
- u32 line;
+ u32 line;
};
#ifdef AFL_MAIN
struct TRK_obj *TRK[ALLOC_BUCKETS];
-u32 TRK_cnt[ALLOC_BUCKETS];
+u32 TRK_cnt[ALLOC_BUCKETS];
#define alloc_report() TRK_report()
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index d87af775..57b5d128 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -225,49 +225,18 @@ llvmGetPassPluginInfo() {
}
-#if LLVM_VERSION_MAJOR == 1
+#if LLVM_VERSION_MAJOR >= 16
PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
ModuleAnalysisManager &MAM) {
- ModuleSanitizerCoverageAFL ModuleSancov(Options);
- auto &FAM = MAM.getResult(M).getManager();
- auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{
-
- return &FAM.getResult(F);
-
- };
-
- auto PDTCallback = [&FAM](Function &F) -> const PostDominatorTree * {
-
- return &FAM.getResult(F);
-
- };
-
- if (!ModuleSancov.instrumentModule(M, DTCallback, PDTCallback))
- return PreservedAnalyses::all();
-
- PreservedAnalyses PA = PreservedAnalyses::none();
- // GlobalsAA is considered stateless and does not get invalidated unless
- // explicitly invalidated; PreservedAnalyses::none() is not enough. Sanitizers
- // make changes that require GlobalsAA to be invalidated.
- PA.abandon();
- return PA;
-
-}
-
#else
- #if LLVM_VERSION_MAJOR >= 16
-PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
- ModuleAnalysisManager &MAM) {
-
- #else
PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
ModuleAnalysisManager &MAM) {
- #endif
+#endif
ModuleSanitizerCoverageAFL ModuleSancov(Options);
auto &FAM = MAM.getResult(M).getManager();
- auto DTCallback = [&FAM](Function &F) -> const DominatorTree * {
+ auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{
return &FAM.getResult(F);
@@ -285,8 +254,6 @@ PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
}
-#endif
-
std::pair ModuleSanitizerCoverageAFL::CreateSecStartEnd(
Module &M, const char *Section, Type *Ty) {
diff --git a/qemu_mode/libqasan/dlmalloc.c b/qemu_mode/libqasan/dlmalloc.c
index 5d0b65ce..b459eb7b 100644
--- a/qemu_mode/libqasan/dlmalloc.c
+++ b/qemu_mode/libqasan/dlmalloc.c
@@ -1762,7 +1762,7 @@ static FORCEINLINE void *win32direct_mmap(size_t size) {
static FORCEINLINE int win32munmap(void *ptr, size_t size) {
MEMORY_BASIC_INFORMATION minfo;
- char *cptr = (char *)ptr;
+ char *cptr = (char *)ptr;
while (size) {
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 13802f40..24fd7077 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1542,8 +1542,8 @@ double get_runnable_processes(void) {
processes well. */
FILE *f = fopen("/proc/stat", "r");
- u8 tmp[1024];
- u32 val = 0;
+ u8 tmp[1024];
+ u32 val = 0;
if (!f) { return 0; }
@@ -2226,7 +2226,7 @@ void check_crash_handling(void) {
*BSD, so we can just let it slide for now. */
s32 fd = open("/proc/sys/kernel/core_pattern", O_RDONLY);
- u8 fchar;
+ u8 fchar;
if (fd < 0) { return; }
@@ -2365,7 +2365,7 @@ void check_cpu_governor(afl_state_t *afl) {
FATAL("Suboptimal CPU scaling governor");
#elif defined __APPLE__
- u64 min = 0, max = 0;
+ u64 min = 0, max = 0;
size_t mlen = sizeof(min);
if (afl->afl_env.afl_skip_cpufreq) return;
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 8cf786af..79b05da7 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -164,7 +164,8 @@ static void usage(u8 *argv0, int more_help) {
"\n"
"Mutator settings:\n"
- " -a - target expects ascii text input (prefer text mutators)\n"
+ " -a - target expects ascii text input (prefer text "
+ "mutators)\n"
" -g minlength - set min length of generated fuzz input (default: 1)\n"
" -G maxlength - set max length of generated fuzz input (default: "
"%lu)\n"
diff --git a/utils/afl_network_proxy/afl-network-server.c b/utils/afl_network_proxy/afl-network-server.c
index 7eb3d18e..95b0a551 100644
--- a/utils/afl_network_proxy/afl-network-server.c
+++ b/utils/afl_network_proxy/afl-network-server.c
@@ -173,7 +173,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
}
out_file = alloc_printf("%s/.afl-input-temp-%u", use_dir, getpid());
- fsrv->out_file = out_file;
+ fsrv->out_file = out_file;
}
--
cgit 1.4.1
From 9926f070822c35c312b5051ce0be0a40a471f253 Mon Sep 17 00:00:00 2001
From: Your Name
Date: Thu, 22 Jun 2023 17:36:02 +0100
Subject: Support for long form instrumentation on x64
---
frida_mode/src/instrument/instrument_x64.c | 289 ++++++++++++++++++++++++-----
1 file changed, 242 insertions(+), 47 deletions(-)
diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c
index 8338f8e7..3983c3ba 100644
--- a/frida_mode/src/instrument/instrument_x64.c
+++ b/frida_mode/src/instrument/instrument_x64.c
@@ -58,6 +58,7 @@ typedef union {
} jcc_insn;
static GHashTable *coverage_blocks = NULL;
+static GHashTable *coverage_blocks_long = NULL;
gboolean instrument_is_coverage_optimize_supported(void) {
@@ -127,6 +128,64 @@ typedef struct {
} afl_log_code_asm_t;
+typedef struct {
+
+ // cur_location = (block_address >> 4) ^ (block_address << 8);
+ // shared_mem[cur_location ^ prev_location]++;
+ // prev_location = cur_location >> 1;
+
+ // mov QWORD PTR [rsp-0x88],rax
+ // lahf
+ // mov QWORD PTR [rsp-0x90],rax
+ // mov QWORD PTR [rsp-0x98],rbx
+
+ // mov rax, 0xXXXXXXXXXXXXXXXXX /* p_prev_loc */
+ // mov eax, dword ptr [rax] /* prev_loc */
+ // xor eax,0x3f77 /* cur_loc */
+
+ // mov rbx, 0xXXXXXXXXXXXXXXXXX /* map */
+ // add rax,rbx
+
+ // mov bl,BYTE PTR [rax]
+ // add bl,0x1
+ // adc bl,0x0
+ // mov BYTE PTR [rax],bl
+
+ // mov rax, 0xXXXXXXXXXXXXXXXXX /* p_prev_loc */
+ // mov dword ptr [rax], 0xXXXXXXXXX /* prev_loc */
+
+ // mov rbx,QWORD PTR [rsp-0x98]
+ // mov rax,QWORD PTR [rsp-0x90]
+ // sahf
+ // mov rax,QWORD PTR [rsp-0x88]
+
+ uint8_t mov_rax_rsp_88[8];
+ uint8_t lahf;
+ uint8_t mov_rax_rsp_90[8];
+ uint8_t mov_rbx_rsp_98[8];
+
+ uint8_t mov_rax_prev_loc_ptr1[10];
+ uint8_t mov_eax_prev_loc[2];
+ uint8_t xor_eax_curr_loc[5];
+
+ uint8_t mov_rbx_map_ptr[10];
+ uint8_t add_rax_rbx[3];
+
+ uint8_t mov_rbx_ptr_rax[2];
+ uint8_t add_bl_1[3];
+ uint8_t adc_bl_0[3];
+ uint8_t mov_ptr_rax_rbx[2];
+
+ uint8_t mov_rax_prev_loc_ptr2[10];
+ uint8_t mov_prev_loc_curr_loc_shr1[6];
+
+ uint8_t mov_rsp_98_rbx[8];
+ uint8_t mov_rsp_90_rax[8];
+ uint8_t sahf;
+ uint8_t mov_rsp_88_rax[8];
+
+} afl_log_code_asm_long_t;
+
#pragma pack(pop)
static const afl_log_code_asm_t template =
@@ -158,6 +217,41 @@ static const afl_log_code_asm_t template =
;
+static const afl_log_code_asm_long_t template_long =
+ {
+
+ .mov_rax_rsp_88 = {0x48, 0x89, 0x84, 0x24, 0x78, 0xFF, 0xFF, 0xFF},
+ .lahf = 0x9f,
+ .mov_rax_rsp_90 = {0x48, 0x89, 0x84, 0x24, 0x70, 0xFF, 0xFF, 0xFF},
+ .mov_rbx_rsp_98 = {0x48, 0x89, 0x9C, 0x24, 0x68, 0xFF, 0xFF, 0xFF},
+
+ .mov_rax_prev_loc_ptr1 = {0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF},
+ .mov_eax_prev_loc = {0x8b, 0x00},
+ .xor_eax_curr_loc = {0x35},
+
+ .mov_rbx_map_ptr = {0x48, 0xBB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF},
+ .add_rax_rbx = {0x48, 0x01, 0xd8},
+
+ .mov_rbx_ptr_rax = {0x8a, 0x18},
+ .add_bl_1 = {0x80, 0xc3, 0x01},
+ .adc_bl_0 = {0x80, 0xd3, 0x00},
+ .mov_ptr_rax_rbx = {0x88, 0x18},
+
+ .mov_rax_prev_loc_ptr2 = {0x48, 0xB8, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF},
+ .mov_prev_loc_curr_loc_shr1 = {0xc7, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
+
+ .mov_rsp_98_rbx = {0x48, 0x8B, 0x9C, 0x24, 0x68, 0xFF, 0xFF, 0xFF},
+ .mov_rsp_90_rax = {0x48, 0x8B, 0x84, 0x24, 0x70, 0xFF, 0xFF, 0xFF},
+ .sahf = 0x9e,
+ .mov_rsp_88_rax = {0x48, 0x8B, 0x84, 0x24, 0x78, 0xFF, 0xFF, 0xFF},
+
+}
+
+;
+
typedef union {
afl_log_code_asm_t code;
@@ -165,6 +259,13 @@ typedef union {
} afl_log_code;
+typedef union {
+
+ afl_log_code_asm_long_t code;
+ uint8_t bytes[0];
+
+} afl_log_code_long;
+
void instrument_coverage_optimize_init(void) {
FVERBOSE("__afl_area_ptr: %p", __afl_area_ptr);
@@ -182,16 +283,19 @@ static void instrument_coverage_switch_insn(GumStalkerObserver *self,
cs_x86 *x86;
cs_x86_op *op;
+ bool is_short = false;
+ bool is_long = false;
+
if (from_insn == NULL) { return; }
x86 = &from_insn->detail->x86;
op = x86->operands;
- if (!g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target))) {
-
- return;
+ is_short = g_hash_table_contains(coverage_blocks, GSIZE_TO_POINTER(*target));
+ is_long =
+ g_hash_table_contains(coverage_blocks_long, GSIZE_TO_POINTER(*target));
- }
+ if (!is_short && !is_long) { return; }
switch (from_insn->id) {
@@ -212,15 +316,41 @@ static void instrument_coverage_switch_insn(GumStalkerObserver *self,
break;
case X86_INS_RET:
- instrument_cache_insert(start_address,
- (guint8 *)*target + sizeof(afl_log_code));
+ if (is_short) {
+
+ instrument_cache_insert(start_address,
+ (guint8 *)*target + sizeof(afl_log_code));
+
+ } else if (is_long) {
+
+ instrument_cache_insert(start_address,
+ (guint8 *)*target + sizeof(afl_log_code_long));
+
+ } else {
+
+ FATAL("Something has gone wrong here!");
+
+ }
+
break;
default:
return;
}
- *target = (guint8 *)*target + sizeof(afl_log_code);
+ if (is_short) {
+
+ *target = (guint8 *)*target + sizeof(afl_log_code);
+
+ } else if (is_long) {
+
+ *target = (guint8 *)*target + sizeof(afl_log_code_long);
+
+ } else {
+
+ FATAL("Something has gone wrong here!");
+
+ }
}
@@ -270,22 +400,22 @@ static void instrument_coverage_suppress_init(void) {
}
+ coverage_blocks_long = g_hash_table_new(g_direct_hash, g_direct_equal);
+ if (coverage_blocks_long == NULL) {
+
+ FATAL("Failed to g_hash_table_new, errno: %d", errno);
+
+ }
+
}
-static void instrument_coverage_write(GumAddress address,
- GumStalkerOutput *output) {
+bool instrument_write_inline(GumX86Writer *cw, GumAddress code_addr,
+ guint32 area_offset, guint32 area_offset_ror) {
- afl_log_code code = {0};
- GumX86Writer *cw = output->writer.x86;
- guint64 area_offset = instrument_get_offset_hash(address);
- gsize map_size_pow2;
- gsize area_offset_ror;
- GumAddress code_addr = cw->pc;
+ afl_log_code code = {0};
code.code = template;
- /* mov_prev_loc_curr_loc_shr1 */
-
gssize prev_loc_value =
GPOINTER_TO_SIZE(instrument_previous_pc_addr) -
(code_addr + offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) +
@@ -294,11 +424,7 @@ static void instrument_coverage_write(GumAddress address,
offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) +
sizeof(code.code.mov_prev_loc_curr_loc_shr1) - sizeof(gint) -
sizeof(guint32);
- if (!instrument_coverage_in_range(prev_loc_value)) {
-
- FATAL("Patch out of range (current_pc_value1): 0x%016lX", prev_loc_value);
-
- }
+ if (!instrument_coverage_in_range(prev_loc_value)) { return false; }
*((gint *)&code.bytes[prev_loc_value_offset]) = (gint)prev_loc_value;
@@ -311,11 +437,7 @@ static void instrument_coverage_write(GumAddress address,
gssize prev_loc_value_offset2 =
offsetof(afl_log_code, code.mov_eax_prev_loc) +
sizeof(code.code.mov_eax_prev_loc) - sizeof(gint);
- if (!instrument_coverage_in_range(prev_loc_value)) {
-
- FATAL("Patch out of range (current_pc_value1): 0x%016lX", prev_loc_value2);
-
- }
+ if (!instrument_coverage_in_range(prev_loc_value)) { return false; }
*((gint *)&code.bytes[prev_loc_value_offset2]) = (gint)prev_loc_value2;
@@ -338,12 +460,7 @@ static void instrument_coverage_write(GumAddress address,
(code_addr + offsetof(afl_log_code, code.lea_rbx_area_ptr) +
sizeof(code.code.lea_rbx_area_ptr)));
- if (!instrument_coverage_in_range(lea_rbx_area_ptr_value)) {
-
- FATAL("Patch out of range (lea_rbx_area_ptr_value): 0x%016lX",
- lea_rbx_area_ptr_value);
-
- }
+ if (!instrument_coverage_in_range(lea_rbx_area_ptr_value)) { return false; }
*((guint32 *)&code.bytes[lea_rbx_area_ptr_offset]) = lea_rbx_area_ptr_value;
@@ -353,12 +470,100 @@ static void instrument_coverage_write(GumAddress address,
offsetof(afl_log_code, code.mov_prev_loc_curr_loc_shr1) +
sizeof(code.code.mov_prev_loc_curr_loc_shr1) - sizeof(guint32);
- map_size_pow2 = util_log2(__afl_map_size);
- area_offset_ror = util_rotate(area_offset, 1, map_size_pow2);
-
*((guint32 *)&code.bytes[curr_loc_shr_1_offset]) = (guint32)(area_offset_ror);
+ if (instrument_suppress) {
+
+ if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
+
+ FATAL("Failed - g_hash_table_add");
+
+ }
+
+ }
+
gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code));
+ return true;
+
+}
+
+bool instrument_write_inline_long(GumX86Writer *cw, guint32 area_offset,
+ guint32 area_offset_ror) {
+
+ afl_log_code_long code = {0};
+ code.code = template_long;
+
+ /* mov_rax_prev_loc_ptr1 */
+ gssize mov_rax_prev_loc_ptr1_offset =
+ offsetof(afl_log_code_long, code.mov_rax_prev_loc_ptr1) +
+ sizeof(code.code.mov_rax_prev_loc_ptr1) - sizeof(gsize);
+ *((gsize *)&code.bytes[mov_rax_prev_loc_ptr1_offset]) =
+ GPOINTER_TO_SIZE(instrument_previous_pc_addr);
+
+ /* xor_eax_curr_loc */
+ gssize xor_eax_curr_loc_offset =
+ offsetof(afl_log_code_long, code.xor_eax_curr_loc) +
+ sizeof(code.code.xor_eax_curr_loc) - sizeof(guint32);
+ *((guint32 *)&code.bytes[xor_eax_curr_loc_offset]) = area_offset;
+
+ /* mov_rbx_map_ptr */
+ gsize mov_rbx_map_ptr_offset =
+ offsetof(afl_log_code_long, code.mov_rbx_map_ptr) +
+ sizeof(code.code.mov_rbx_map_ptr) - sizeof(gsize);
+ *((gsize *)&code.bytes[mov_rbx_map_ptr_offset]) =
+ GPOINTER_TO_SIZE(__afl_area_ptr);
+
+ /* mov_rax_prev_loc_ptr2 */
+ gssize mov_rax_prev_loc_ptr2_offset =
+ offsetof(afl_log_code_long, code.mov_rax_prev_loc_ptr2) +
+ sizeof(code.code.mov_rax_prev_loc_ptr2) - sizeof(gsize);
+ *((gsize *)&code.bytes[mov_rax_prev_loc_ptr2_offset]) =
+ GPOINTER_TO_SIZE(instrument_previous_pc_addr);
+
+ /* mov_prev_loc_curr_loc_shr1 */
+ gssize mov_prev_loc_curr_loc_shr1_offset =
+ offsetof(afl_log_code_long, code.mov_prev_loc_curr_loc_shr1) +
+ sizeof(code.code.mov_prev_loc_curr_loc_shr1) - sizeof(guint32);
+ *((guint32 *)&code.bytes[mov_prev_loc_curr_loc_shr1_offset]) =
+ (guint32)(area_offset_ror);
+
+ if (instrument_suppress) {
+
+ if (!g_hash_table_add(coverage_blocks_long, GSIZE_TO_POINTER(cw->code))) {
+
+ FATAL("Failed - g_hash_table_add");
+
+ }
+
+ }
+
+ gum_x86_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code_long));
+ return true;
+
+}
+
+static void instrument_coverage_write(GumAddress address,
+ GumStalkerOutput *output) {
+
+ GumX86Writer *cw = output->writer.x86;
+ guint64 area_offset = (guint32)instrument_get_offset_hash(address);
+ gsize map_size_pow2;
+ guint32 area_offset_ror;
+ GumAddress code_addr = cw->pc;
+
+ map_size_pow2 = util_log2(__afl_map_size);
+ area_offset_ror = (guint32)util_rotate(instrument_get_offset_hash(address), 1,
+ map_size_pow2);
+
+ if (!instrument_write_inline(cw, code_addr, area_offset, area_offset_ror)) {
+
+ if (!instrument_write_inline_long(cw, area_offset, area_offset_ror)) {
+
+ FATAL("Failed to write inline instrumentation");
+
+ }
+
+ }
}
@@ -380,17 +585,7 @@ void instrument_coverage_optimize(const cs_insn *instr,
}
- if (instrument_suppress) {
-
- instrument_coverage_suppress_init();
-
- if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) {
-
- FATAL("Failed - g_hash_table_add");
-
- }
-
- }
+ if (instrument_suppress) { instrument_coverage_suppress_init(); }
instrument_coverage_write(GUM_ADDRESS(instr->address), output);
--
cgit 1.4.1
From c2c27349c3d74f79ceb6cd3795862b21d90429ea Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 23 Jun 2023 17:08:21 +0200
Subject: new mutation weighting
---
include/afl-mutations.h | 460 ++++++++++++++++++++++++++++++++++++++++++++++++
src/afl-fuzz-one.c | 30 +---
2 files changed, 466 insertions(+), 24 deletions(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index a3c9fd59..cc4840c8 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -77,6 +77,466 @@ enum {
};
+ #define MUT_TXT_ARRAY_SIZE 200
+u32 text_array[MUT_TXT_ARRAY_SIZE] = {MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT};
+
+ #define MUT_BIN_ARRAY_SIZE 256
+u32 binary_array[MUT_BIN_ARRAY_SIZE] = {MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_FLIPBIT,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING8,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING16BE,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_INTERESTING32BE,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8_,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH8,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16BE_,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH16BE,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32BE_,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_ARITH32BE,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_RAND8,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_COPY,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_CLONE_FIXED,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_COPY,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_OVERWRITE_FIXED,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTEADD,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_BYTESUB,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_FLIP8,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_SWITCH,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_DEL,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_OVERWRITE,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_OVERWRITE,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_AUTO_EXTRA_INSERT,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_OVERWRITE,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT,
+ MUT_SPLICE_INSERT};
+
#define MUT_NORMAL_ARRAY_SIZE 77
u32 normal_splice_array[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT,
MUT_FLIPBIT,
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 32c05182..c6e49653 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2101,27 +2101,17 @@ havoc_stage:
*/
- rand_max = MUT_STRATEGY_ARRAY_SIZE;
-
if (unlikely(afl->text_input)) { // is text?
if (likely(afl->fuzz_mode == 0)) { // is exploration?
- if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
-
- mutation_array = full_splice_array;
- rand_max = MUT_SPLICE_ARRAY_SIZE;
-
- } else {
-
- mutation_array = normal_splice_array;
- rand_max = MUT_NORMAL_ARRAY_SIZE;
-
- }
+ mutation_array = (unsigned int *)&text_array;
+ rand_max = MUT_TXT_ARRAY_SIZE;
} else { // is exploitation!
mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
}
@@ -2129,21 +2119,13 @@ havoc_stage:
if (likely(afl->fuzz_mode == 0)) { // is exploration?
- if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
-
- mutation_array = full_splice_array;
- rand_max = MUT_SPLICE_ARRAY_SIZE;
-
- } else {
-
- mutation_array = normal_splice_array;
- rand_max = MUT_NORMAL_ARRAY_SIZE;
-
- }
+ mutation_array = (unsigned int *)&binary_array;
+ rand_max = MUT_BIN_ARRAY_SIZE;
} else { // is exploitation!
mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
}
--
cgit 1.4.1
From 0616f368c83189ef5559f64d2053129d329aaefe Mon Sep 17 00:00:00 2001
From: "Dongjia \"toka\" Zhang"
Date: Sat, 24 Jun 2023 00:21:45 +0200
Subject: fixing laf
---
instrumentation/split-compares-pass.so.cc | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index aec6758e..3cfd1964 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -463,8 +463,9 @@ bool SplitComparesTransform::simplifyOrEqualsCompare(CmpInst *IcmpInst,
#else
ReplaceInstWithInst(IcmpInst->getParent()->getInstList(), ii, PN);
#endif
-
- worklist.push_back(icmp_np);
+ if (new_pred == CmpInst::ICMP_SGT || new_pred == CmpInst::ICMP_SLT) {
+ simplifySignedCompare(icmp_np, M, worklist);
+ }
worklist.push_back(icmp_eq);
return true;
@@ -740,18 +741,22 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
CmpInst *icmp_inv_cmp = nullptr;
BasicBlock *inv_cmp_bb =
BasicBlock::Create(C, "inv_cmp", end_bb->getParent(), end_bb);
- if (pred == CmpInst::ICMP_UGT || pred == CmpInst::ICMP_SGT ||
- pred == CmpInst::ICMP_UGE || pred == CmpInst::ICMP_SGE) {
+ if (pred == CmpInst::ICMP_UGT) {
icmp_inv_cmp = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_ULT,
op0_high, op1_high);
- } else {
+ } else if (pred == CmpInst::ICMP_ULT) {
icmp_inv_cmp = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT,
op0_high, op1_high);
}
+ else {
+ // Never gonna appen
+ if (!be_quiet)
+ fprintf(stderr, "Error: split-compare: Equals or signed not removed: %d\n", pred);
+ }
#if LLVM_MAJOR >= 16
icmp_inv_cmp->insertInto(inv_cmp_bb, inv_cmp_bb->end());
--
cgit 1.4.1
From edd352612da1f58832cbe84d909a8998ce4fa690 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 24 Jun 2023 09:30:09 +0200
Subject: code format
---
docs/Changelog.md | 6 +++++-
instrumentation/split-compares-pass.so.cc | 12 +++++++++---
2 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index c850c43e..e6b90d3d 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -18,9 +18,13 @@
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
- warn on crashing inputs
- - afl-cc
+ - afl-cc:
- fixed an off-by-one instrumentation of iselect, hurting coverage a bit.
Thanks to @amykweon for spotting and fixing!
+ - @toka fixed a bug in laf-intel signed integer comparison splitting,
+ thanks a lot!!
+ - frida_mode:
+ - support for long form instrumentation on x86_x64 and arm64
### Version ++4.07c (release)
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 3cfd1964..6eafb332 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -464,8 +464,11 @@ bool SplitComparesTransform::simplifyOrEqualsCompare(CmpInst *IcmpInst,
ReplaceInstWithInst(IcmpInst->getParent()->getInstList(), ii, PN);
#endif
if (new_pred == CmpInst::ICMP_SGT || new_pred == CmpInst::ICMP_SLT) {
+
simplifySignedCompare(icmp_np, M, worklist);
+
}
+
worklist.push_back(icmp_eq);
return true;
@@ -751,11 +754,14 @@ bool SplitComparesTransform::splitCompare(CmpInst *cmp_inst, Module &M,
icmp_inv_cmp = CmpInst::Create(Instruction::ICmp, CmpInst::ICMP_UGT,
op0_high, op1_high);
- }
- else {
+ } else {
+
// Never gonna appen
if (!be_quiet)
- fprintf(stderr, "Error: split-compare: Equals or signed not removed: %d\n", pred);
+ fprintf(stderr,
+ "Error: split-compare: Equals or signed not removed: %d\n",
+ pred);
+
}
#if LLVM_MAJOR >= 16
--
cgit 1.4.1
From 1e3890ea7f32866af97614c657afdf970be7168b Mon Sep 17 00:00:00 2001
From: "Dongjia \"toka\" Zhang"
Date: Sat, 24 Jun 2023 15:34:12 +0200
Subject: delete duplicate branches
---
instrumentation/SanitizerCoveragePCGUARD.so.cc | 7 -------
1 file changed, 7 deletions(-)
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 57b5d128..7d614f43 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -225,15 +225,8 @@ llvmGetPassPluginInfo() {
}
-#if LLVM_VERSION_MAJOR >= 16
PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
ModuleAnalysisManager &MAM) {
-
-#else
-PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
- ModuleAnalysisManager &MAM) {
-
-#endif
ModuleSanitizerCoverageAFL ModuleSancov(Options);
auto &FAM = MAM.getResult(M).getManager();
auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{
--
cgit 1.4.1
From cac713ec304b40e815d54e0991adcb14290f8f30 Mon Sep 17 00:00:00 2001
From: "Dongjia \"toka\" Zhang"
Date: Sat, 24 Jun 2023 15:48:23 +0200
Subject: llvm 15
---
instrumentation/SanitizerCoverageLTO.so.cc | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index 2d17ffd4..d7b03634 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -331,7 +331,7 @@ llvmGetPassPluginInfo() {
#if LLVM_VERSION_MAJOR <= 13
using OptimizationLevel = typename PassBuilder::OptimizationLevel;
#endif
-#if LLVM_VERSION_MAJOR >= 16
+#if LLVM_VERSION_MAJOR >= 15
PB.registerFullLinkTimeOptimizationLastEPCallback(
#else
PB.registerOptimizerLastEPCallback(
--
cgit 1.4.1
From 32d5ccb92dd3f646db327d2b7c1ec5fa74b4d656 Mon Sep 17 00:00:00 2001
From: Siqi Chen
Date: Tue, 27 Jun 2023 01:15:54 +0800
Subject: Increase the number of afl-cc supported params
---
src/afl-cc.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 9e56828c..58d44e5d 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -383,9 +383,11 @@ static u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0,
have_o = 0, have_pic = 0, have_c = 0, partial_linking = 0,
non_dash = 0;
+#define MAX_PARAMS_NUM 2048
+
static void process_params(u32 argc, char **argv) {
- if (cc_par_cnt + argc >= 1024) { FATAL("Too many command line parameters"); }
+ if (cc_par_cnt + argc >= MAX_PARAMS_NUM) { FATAL("Too many command line parameters, please increase MAX_PARAMS_NUM."); }
if (lto_mode && argc > 1) {
@@ -679,7 +681,7 @@ static void process_params(u32 argc, char **argv) {
static void edit_params(u32 argc, char **argv, char **envp) {
- cc_params = ck_alloc(1024 * sizeof(u8 *));
+ cc_params = ck_alloc(MAX_PARAMS_NUM * sizeof(u8 *));
if (lto_mode) {
--
cgit 1.4.1
From 3e1d7941077b1457f702988063d6b9fdd9b80740 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 29 Jun 2023 16:57:20 +0200
Subject: update mutation strategy
---
docs/Changelog.md | 4 +++-
include/afl-fuzz.h | 59 +++++++++++++++++++++++++------------------------
include/afl-mutations.h | 6 ++---
src/afl-fuzz-one.c | 56 +++++++++++++++++++++++++++-------------------
src/afl-fuzz.c | 26 +++++++++++++++++-----
5 files changed, 90 insertions(+), 61 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index e6b90d3d..ad58e99e 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -8,7 +8,8 @@
- new mutation engine: mutations that favor discovery more paths are
prefered until no new finds for 10 minutes then switching to mutations
that favor triggering crashes. Modes and switch time can be configured
- with `-P`.
+ with `-P`. Also input mode for the target can be defined with `-a` to
+ be `text` or `binary` (defaults to `generic`)
- new custom mutator that has the new afl++ engine (so it can easily
incorporated into new custom mutators), and also comes with a standalone
command line tool! See custom_mutators/aflpp/standalone/
@@ -23,6 +24,7 @@
Thanks to @amykweon for spotting and fixing!
- @toka fixed a bug in laf-intel signed integer comparison splitting,
thanks a lot!!
+ - more LLVM compatability
- frida_mode:
- support for long form instrumentation on x86_x64 and arm64
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index c6c45fbd..9da5cc03 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -505,36 +505,37 @@ typedef struct afl_state {
is_main_node, /* if this is the main node */
is_secondary_node, /* if this is a secondary instance */
pizza_is_served, /* pizza mode */
- text_input, /* target wants text inputs */
- fuzz_mode, /* current mode: coverage/exploration or crash/exploitation */
+ input_mode, /* target wants text inputs */
+ fuzz_mode, /* coverage/exploration or crash/exploitation mode */
schedule, /* Power schedule (default: EXPLORE)*/
- havoc_max_mult, skip_deterministic, /* Skip deterministic stages? */
- use_splicing, /* Recombine input files? */
- non_instrumented_mode, /* Run in non-instrumented mode? */
- score_changed, /* Scoring for favorites changed? */
- resuming_fuzz, /* Resuming an older fuzzing job? */
- timeout_given, /* Specific timeout given? */
- not_on_tty, /* stdout is not a tty */
- term_too_small, /* terminal dimensions too small */
- no_forkserver, /* Disable forkserver? */
- crash_mode, /* Crash mode! Yeah! */
- in_place_resume, /* Attempt in-place resume? */
- autoresume, /* Resume if afl->out_dir exists? */
- auto_changed, /* Auto-generated tokens changed? */
- no_cpu_meter_red, /* Feng shui on the status screen */
- no_arith, /* Skip most arithmetic ops */
- shuffle_queue, /* Shuffle input queue? */
- bitmap_changed, /* Time to update bitmap? */
- unicorn_mode, /* Running in Unicorn mode? */
- use_wine, /* Use WINE with QEMU mode */
- skip_requested, /* Skip request, via SIGUSR1 */
- run_over10m, /* Run time over 10 minutes? */
- persistent_mode, /* Running in persistent mode? */
- deferred_mode, /* Deferred forkserver mode? */
- fixed_seed, /* do not reseed */
- fast_cal, /* Try to calibrate faster? */
- disable_trim, /* Never trim in fuzz_one */
- shmem_testcase_mode, /* If sharedmem testcases are used */
+ havoc_max_mult, /* havoc multiplier */
+ skip_deterministic, /* Skip deterministic stages? */
+ use_splicing, /* Recombine input files? */
+ non_instrumented_mode, /* Run in non-instrumented mode? */
+ score_changed, /* Scoring for favorites changed? */
+ resuming_fuzz, /* Resuming an older fuzzing job? */
+ timeout_given, /* Specific timeout given? */
+ not_on_tty, /* stdout is not a tty */
+ term_too_small, /* terminal dimensions too small */
+ no_forkserver, /* Disable forkserver? */
+ crash_mode, /* Crash mode! Yeah! */
+ in_place_resume, /* Attempt in-place resume? */
+ autoresume, /* Resume if afl->out_dir exists? */
+ auto_changed, /* Auto-generated tokens changed? */
+ no_cpu_meter_red, /* Feng shui on the status screen */
+ no_arith, /* Skip most arithmetic ops */
+ shuffle_queue, /* Shuffle input queue? */
+ bitmap_changed, /* Time to update bitmap? */
+ unicorn_mode, /* Running in Unicorn mode? */
+ use_wine, /* Use WINE with QEMU mode */
+ skip_requested, /* Skip request, via SIGUSR1 */
+ run_over10m, /* Run time over 10 minutes? */
+ persistent_mode, /* Running in persistent mode? */
+ deferred_mode, /* Deferred forkserver mode? */
+ fixed_seed, /* do not reseed */
+ fast_cal, /* Try to calibrate faster? */
+ disable_trim, /* Never trim in fuzz_one */
+ shmem_testcase_mode, /* If sharedmem testcases are used */
expand_havoc, /* perform expensive havoc after no find */
cycle_schedules, /* cycle power schedules? */
old_seed_selection, /* use vanilla afl seed selection */
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index cc4840c8..0a9bbbf4 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -14,14 +14,14 @@
Parameters:
afl_state_t *afl - the *afl state pointer
u8 *buf - the input buffer to mutate which will be mutated into.
- NOTE: must be able to contain a size of at least max_len (see below)!
+ NOTE: must be able to contain a size of at least max_len!! (see below)
u32 len - the length of the input
u32 steps - how many mutations to perform on the input
bool is_text - is the target expecting text inputs
bool is_exploration - mutate for exploration mode (instead of exploitation)
splice_buf - a buffer from another corpus item to splice with.
- If NULL then no splicing
- splice_len - the length of the splice buffer. If 0 then no splicing
+ If NULL then no splicing is done (obviously).
+ splice_len - the length of the splice buffer. If 0 then no splicing.
u32 max_len - the maximum size the mutated buffer may grow to
*/
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index c6e49653..0d3c29f2 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2085,47 +2085,57 @@ havoc_stage:
u32 *mutation_array;
u32 stack_max, rand_max; // stack_max_pow = afl->havoc_stack_pow2;
- /*
+ switch (afl->input_mode) {
- if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
+ case 1: { // TEXT
- mutation_array = full_splice_array;
- rand_max = MUT_SPLICE_ARRAY_SIZE;
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ mutation_array = (unsigned int *)&binary_array;
+ rand_max = MUT_BIN_ARRAY_SIZE;
- } else {
+ } else { // exploitation mode
- mutation_array = normal_splice_array;
- rand_max = MUT_NORMAL_ARRAY_SIZE;
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
- }
+ }
- */
+ break;
- if (unlikely(afl->text_input)) { // is text?
+ }
- if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ case 2: { // BINARY
- mutation_array = (unsigned int *)&text_array;
- rand_max = MUT_TXT_ARRAY_SIZE;
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_binary;
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
- } else { // is exploitation!
+ } else { // exploitation mode
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
- rand_max = MUT_STRATEGY_ARRAY_SIZE;
+ mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
+
+ }
+
+ break;
}
- } else { // is binary!
+ default: { // DEFAULT/GENERIC
- if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ if (likely(afl->fuzz_mode == 0)) { // is exploration?
+ mutation_array = (unsigned int *)&binary_array;
+ rand_max = MUT_BIN_ARRAY_SIZE;
- mutation_array = (unsigned int *)&binary_array;
- rand_max = MUT_BIN_ARRAY_SIZE;
+ } else { // exploitation mode
- } else { // is exploitation!
+ // this will need to be changed I guess
+ mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
+ rand_max = MUT_STRATEGY_ARRAY_SIZE;
+
+ }
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
- rand_max = MUT_STRATEGY_ARRAY_SIZE;
+ break;
}
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 79b05da7..ab7d6534 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -125,7 +125,8 @@ static void usage(u8 *argv0, int more_help) {
"Required parameters:\n"
" -i dir - input directory with test cases (or '-' to resume, "
- "also see AFL_AUTORESUME)\n"
+ "also see \n"
+ " AFL_AUTORESUME)\n"
" -o dir - output directory for fuzzer findings\n\n"
"Execution control settings:\n"
@@ -164,8 +165,8 @@ static void usage(u8 *argv0, int more_help) {
"\n"
"Mutator settings:\n"
- " -a - target expects ascii text input (prefer text "
- "mutators)\n"
+ " -a - target input format, \"text\" or \"binary\" (default: "
+ "generic)\n"
" -g minlength - set min length of generated fuzz input (default: 1)\n"
" -G maxlength - set max length of generated fuzz input (default: "
"%lu)\n"
@@ -506,13 +507,28 @@ int main(int argc, char **argv_orig, char **envp) {
// still available: HjJkKqruvwz
while ((opt = getopt(argc, argv,
- "+aAb:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:"
+ "+a:Ab:B:c:CdDe:E:f:F:g:G:hi:I:l:L:m:M:nNo:Op:P:QRs:S:t:"
"T:UV:WXx:YZ")) > 0) {
switch (opt) {
case 'a':
- afl->text_input = 1;
+
+ if (!stricmp(optarg, "text") || !stricmp(optarg, "ascii") ||
+ !stricmp(optarg, "txt") || !stricmp(optarg, "asc")) {
+
+ afl->input_mode = 1;
+
+ } else if (!stricmp(optarg, "bin") || !stricmp(optarg, "binary")) {
+
+ afl->input_mode = 2;
+
+ } else {
+
+ FATAL("-a input mode needs to be \"text\" or \"binary\".");
+
+ }
+
break;
case 'P':
--
cgit 1.4.1
From 819ad95f03c06aad7b01c5ec127bd52d89f110e6 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 30 Jun 2023 12:17:57 +0200
Subject: afl-showmap fix
---
src/afl-showmap.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index 13867fda..b82bcd72 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -111,8 +111,9 @@ static sharedmem_t *shm_fuzz;
static const u8 count_class_human[256] = {
- [0] = 0, [1] = 1, [2] = 2, [3] = 3, [4] = 4,
- [8] = 5, [16] = 6, [32] = 7, [128] = 8
+ [0] = 0, [1] = 1, [2] = 2, [3] = 3,
+ [4 ... 7] = 4, [8 ... 15] = 5, [16 ... 31] = 6, [32 ... 127] = 7,
+ [128 ... 255] = 8
};
@@ -424,9 +425,9 @@ static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem,
}
- if (fsrv->trace_bits[0] == 1) {
+ if (fsrv->trace_bits[0]) {
- fsrv->trace_bits[0] = 0;
+ fsrv->trace_bits[0] -= 1;
have_coverage = true;
} else {
@@ -655,9 +656,9 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
}
- if (fsrv->trace_bits[0] == 1) {
+ if (fsrv->trace_bits[0]) {
- fsrv->trace_bits[0] = 0;
+ fsrv->trace_bits[0] -= 1;
have_coverage = true;
} else {
--
cgit 1.4.1
From 03bae6c4fe544f87f07cdb554daa6519d37cdfc8 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 1 Jul 2023 12:19:44 +0200
Subject: switch exploit strategy
---
src/afl-fuzz-one.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 0d3c29f2..942381dd 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2095,8 +2095,8 @@ havoc_stage:
} else { // exploitation mode
- mutation_array = (unsigned int *)&mutation_strategy_exploitation_text;
- rand_max = MUT_STRATEGY_ARRAY_SIZE;
+ mutation_array = (unsigned int *)&text_array;
+ rand_max = MUT_TXT_ARRAY_SIZE;
}
@@ -2129,9 +2129,8 @@ havoc_stage:
} else { // exploitation mode
- // this will need to be changed I guess
- mutation_array = (unsigned int *)&mutation_strategy_exploration_text;
- rand_max = MUT_STRATEGY_ARRAY_SIZE;
+ mutation_array = (unsigned int *)&text_array;
+ rand_max = MUT_TXT_ARRAY_SIZE;
}
--
cgit 1.4.1
From d5184263350335b24daab635f0bcee455302f990 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 2 Jul 2023 14:50:18 +0200
Subject: no_ui: display time
---
include/common.h | 5 +++++
src/afl-common.c | 29 +++++++++++++++++++++++++++++
src/afl-fuzz-one.c | 10 +++++++---
3 files changed, 41 insertions(+), 3 deletions(-)
diff --git a/include/common.h b/include/common.h
index 8d85d201..a9739a7d 100644
--- a/include/common.h
+++ b/include/common.h
@@ -115,6 +115,11 @@ u8 *stringify_mem_size(u8 *buf, size_t len, u64 val);
u8 *stringify_time_diff(u8 *buf, size_t len, u64 cur_ms, u64 event_ms);
+/* Unsafe describe time delta as simple string.
+ Returns a pointer to buf for convenience. */
+
+u8 *u_simplestring_time_diff(u8 *buf, u64 cur_ms, u64 event_ms);
+
/* Unsafe Describe integer. The buf sizes are not checked.
This is unsafe but fast.
Will return buf for convenience. */
diff --git a/src/afl-common.c b/src/afl-common.c
index 84ddefd8..3e1ec09d 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -1298,6 +1298,35 @@ u8 *u_stringify_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
}
+/* Unsafe describe time delta as simple string.
+ Returns a pointer to buf for convenience. */
+
+u8 *u_simplestring_time_diff(u8 *buf, u64 cur_ms, u64 event_ms) {
+
+ if (!event_ms) {
+
+ sprintf(buf, "00:00:00");
+
+ } else {
+
+ u64 delta;
+ s32 t_d, t_h, t_m, t_s;
+
+ delta = cur_ms - event_ms;
+
+ t_d = delta / 1000 / 60 / 60 / 24;
+ t_h = (delta / 1000 / 60 / 60) % 24;
+ t_m = (delta / 1000 / 60) % 60;
+ t_s = (delta / 1000) % 60;
+
+ sprintf(buf, "%d:%02d:%02d:%02d", t_d, t_h, t_m, t_s);
+
+ }
+
+ return buf;
+
+}
+
/* Reads the map size from ENV */
u32 get_map_size(void) {
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 942381dd..e1ca44ab 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -399,20 +399,24 @@ u8 fuzz_one_original(afl_state_t *afl) {
#endif /* ^IGNORE_FINDS */
- if (unlikely(afl->not_on_tty)) {
+ if (likely(afl->not_on_tty)) {
+ u8 time_tmp[64];
+
+ u_simplestring_time_diff(time_tmp, afl->prev_run_time + get_cur_time(),
+ afl->start_time);
ACTF(
"Fuzzing test case #%u (%u total, %llu crashes saved, state: %s, "
"mode=%s, "
"perf_score=%0.0f, weight=%0.0f, favorite=%u, was_fuzzed=%u, "
- "exec_us=%llu, hits=%u, map=%u, ascii=%u)...",
+ "exec_us=%llu, hits=%u, map=%u, ascii=%u, run_time=%s)...",
afl->current_entry, afl->queued_items, afl->saved_crashes,
get_fuzzing_state(afl), afl->fuzz_mode ? "exploit" : "explore",
afl->queue_cur->perf_score, afl->queue_cur->weight,
afl->queue_cur->favored, afl->queue_cur->was_fuzzed,
afl->queue_cur->exec_us,
likely(afl->n_fuzz) ? afl->n_fuzz[afl->queue_cur->n_fuzz_entry] : 0,
- afl->queue_cur->bitmap_size, afl->queue_cur->is_ascii);
+ afl->queue_cur->bitmap_size, afl->queue_cur->is_ascii, time_tmp);
fflush(stdout);
}
--
cgit 1.4.1
From dcbfc88e7d1feae344a5288decc262fa7e8bce83 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 3 Jul 2023 09:17:41 +0200
Subject: comment
---
src/afl-fuzz-one.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index e1ca44ab..8ee50bbf 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2118,6 +2118,9 @@ havoc_stage:
mutation_array = (unsigned int *)&mutation_strategy_exploitation_binary;
rand_max = MUT_STRATEGY_ARRAY_SIZE;
+ // or this one? we do not have enough binary bug benchmarks :-(
+ // mutation_array = (unsigned int *)&binary_array;
+ // rand_max = MUT_BIN_ARRAY_SIZE;
}
--
cgit 1.4.1
From 0966957631c3d537d38ae8f1c5cfdcbcc2779712 Mon Sep 17 00:00:00 2001
From: Eli Kobrin
Date: Mon, 3 Jul 2023 15:03:45 +0300
Subject: Fix max_params define.
---
src/afl-cc.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 58d44e5d..07c2a2d3 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -383,7 +383,9 @@ static u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0,
have_o = 0, have_pic = 0, have_c = 0, partial_linking = 0,
non_dash = 0;
+#ifndef MAX_PARAMS_NUM
#define MAX_PARAMS_NUM 2048
+#endif
static void process_params(u32 argc, char **argv) {
--
cgit 1.4.1
From da3351085519acf73dc8ddde3cf0b526b816551b Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 4 Jul 2023 11:34:13 +0200
Subject: nits
---
src/afl-cc.c | 14 +++++++-------
src/afl-fuzz.c | 4 ++++
2 files changed, 11 insertions(+), 7 deletions(-)
diff --git a/src/afl-cc.c b/src/afl-cc.c
index 07c2a2d3..ec460f17 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -2111,11 +2111,6 @@ int main(int argc, char **argv, char **envp) {
"-------------|\n"
"MODES: NCC PERSIST DICT LAF "
"CMPLOG SELECT\n"
- " [LTO] LLVM LTO: %s%s\n"
- " PCGUARD DEFAULT yes yes yes yes yes "
- " yes\n"
- " CLASSIC yes yes yes yes yes "
- " yes\n"
" [LLVM] LLVM: %s%s\n"
" PCGUARD %s yes yes module yes yes "
"yes\n"
@@ -2125,16 +2120,21 @@ int main(int argc, char **argv, char **envp) {
" - CALLER\n"
" - CTX\n"
" - NGRAM-{2-16}\n"
+ " [LTO] LLVM LTO: %s%s\n"
+ " PCGUARD DEFAULT yes yes yes yes yes "
+ " yes\n"
+ " CLASSIC yes yes yes yes yes "
+ " yes\n"
" [GCC_PLUGIN] gcc plugin: %s%s\n"
" CLASSIC DEFAULT no yes no no no "
"yes\n"
" [GCC/CLANG] simple gcc/clang: %s%s\n"
" CLASSIC DEFAULT no no no no no "
"no\n\n",
- have_lto ? "AVAILABLE" : "unavailable!",
- compiler_mode == LTO ? " [SELECTED]" : "",
have_llvm ? "AVAILABLE" : "unavailable!",
compiler_mode == LLVM ? " [SELECTED]" : "",
+ have_lto ? "AVAILABLE" : "unavailable!",
+ compiler_mode == LTO ? " [SELECTED]" : "",
LLVM_MAJOR >= 7 ? "DEFAULT" : " ",
LLVM_MAJOR >= 7 ? " " : "DEFAULT",
have_gcc_plugin ? "AVAILABLE" : "unavailable!",
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index ab7d6534..70258e33 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1281,6 +1281,10 @@ int main(int argc, char **argv_orig, char **envp) {
}
+ WARNF(
+ "Note that the MOpt mode is not maintained and is not as effective "
+ "normal havoc mode.");
+
} break;
case 'h':
--
cgit 1.4.1
From f37c4c86622c5e0ea10e0a0249e203c412c2db2e Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 5 Jul 2023 13:03:17 +0200
Subject: update llvm recommendations
---
GNUmakefile.llvm | 12 +++++++-----
instrumentation/README.llvm.md | 2 +-
src/afl-cc.c | 17 +++++++++++++++--
src/afl-fuzz.c | 2 +-
4 files changed, 24 insertions(+), 9 deletions(-)
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index 6ffac68f..f298060e 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -47,6 +47,7 @@ LLVM_MAJOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/\..*//' )
LLVM_MINOR = $(shell $(LLVM_CONFIG) --version 2>/dev/null | sed 's/.*\.//' | sed 's/git//' | sed 's/svn//' | sed 's/ .*//' )
LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[0-2]\.|^3.[0-7]\.' && echo 1 || echo 0 )
LLVM_TOO_NEW = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[7-9]' && echo 1 || echo 0 )
+LLVM_TOO_OLD = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^[1-9]\.|^1[012]\.' && echo 1 || echo 0 )
LLVM_NEW_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[0-9]' && echo 1 || echo 0 )
LLVM_NEWER_API = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[6-9]' && echo 1 || echo 0 )
LLVM_13_OK = $(shell $(LLVM_CONFIG) --version 2>/dev/null | grep -E -q '^1[3-9]' && echo 1 || echo 0 )
@@ -69,6 +70,12 @@ ifeq "$(LLVM_TOO_NEW)" "1"
$(warning you are using an in-development llvm version - this might break llvm_mode!)
endif
+ifeq "$(LLVM_TOO_OLD)" "1"
+ $(warning you are using an outdated LLVM version! Please use at least LLVM 13 or newer!)
+ $(shell sleep 2)
+endif
+
+# No switching the meaning of LLVM_TOO_OLD
LLVM_TOO_OLD=1
ifeq "$(LLVM_MAJOR)" "9"
@@ -87,11 +94,6 @@ ifeq "$(LLVM_NEWER_API)" "1"
LLVM_STDCXX = c++17
endif
-ifeq "$(LLVM_TOO_OLD)" "1"
- $(info [!] llvm_mode detected an old version of llvm, upgrade to at least 9 or preferable 11!)
- $(shell sleep 1)
-endif
-
ifeq "$(LLVM_HAVE_LTO)" "1"
$(info [+] llvm_mode detected llvm 11+, enabling afl-lto LTO implementation)
LLVM_LTO = 1
diff --git a/instrumentation/README.llvm.md b/instrumentation/README.llvm.md
index 126cf1a2..34b80c85 100644
--- a/instrumentation/README.llvm.md
+++ b/instrumentation/README.llvm.md
@@ -7,7 +7,7 @@ For the GCC-based instrumentation, see
## 1) Introduction
-! llvm_mode works with llvm versions 3.8 up to 13 !
+! llvm_mode works with llvm versions 3.8 up to 17 - but 13+ is recommended !
The code in this directory allows you to instrument programs for AFL++ using
true compiler-level instrumentation, instead of the more crude assembly-level
diff --git a/src/afl-cc.c b/src/afl-cc.c
index ec460f17..86b81459 100644
--- a/src/afl-cc.c
+++ b/src/afl-cc.c
@@ -384,12 +384,16 @@ static u8 fortify_set = 0, asan_set = 0, x_set = 0, bit_mode = 0,
non_dash = 0;
#ifndef MAX_PARAMS_NUM
-#define MAX_PARAMS_NUM 2048
+ #define MAX_PARAMS_NUM 2048
#endif
static void process_params(u32 argc, char **argv) {
- if (cc_par_cnt + argc >= MAX_PARAMS_NUM) { FATAL("Too many command line parameters, please increase MAX_PARAMS_NUM."); }
+ if (cc_par_cnt + argc >= MAX_PARAMS_NUM) {
+
+ FATAL("Too many command line parameters, please increase MAX_PARAMS_NUM.");
+
+ }
if (lto_mode && argc > 1) {
@@ -2350,6 +2354,15 @@ int main(int argc, char **argv, char **envp) {
"AFL_LLVM_CMPLOG and "
"AFL_LLVM_DICT2FILE+AFL_LLVM_DICT2FILE_NO_MAIN.\n\n");
+ if (LLVM_MAJOR < 13) {
+
+ SAYF(
+ "Warning: It is highly recommended to use at least LLVM version 13 "
+ "(or better, higher) rather than %d!\n\n",
+ LLVM_MAJOR);
+
+ }
+
exit(1);
}
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 70258e33..9afece66 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1283,7 +1283,7 @@ int main(int argc, char **argv_orig, char **envp) {
WARNF(
"Note that the MOpt mode is not maintained and is not as effective "
- "normal havoc mode.");
+ "as normal havoc mode.");
} break;
--
cgit 1.4.1
From 6e5ca0c78c4b982c6d238f66276a9fc4d43b9663 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 6 Jul 2023 14:28:37 +0200
Subject: higher tuples for afl-clang and afl-gcc in tests
---
test/test-basic.sh | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/test/test-basic.sh b/test/test-basic.sh
index 5bb2ca28..61ad4b7c 100755
--- a/test/test-basic.sh
+++ b/test/test-basic.sh
@@ -28,7 +28,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
rm -f test-instr.plain.0 test-instr.plain.1
SKIP=
TUPLES=`echo 1|AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- ./test-instr.plain 2>&1 | grep Captur | awk '{print$3}'`
- test "$TUPLES" -gt 1 -a "$TUPLES" -lt 12 && {
+ test "$TUPLES" -gt 1 -a "$TUPLES" -lt 22 && {
$ECHO "$GREEN[+] ${AFL_GCC} run reported $TUPLES instrumented locations which is fine"
} || {
$ECHO "$RED[!] ${AFL_GCC} instrumentation produces weird numbers: $TUPLES"
@@ -152,7 +152,7 @@ test "$SYS" = "i686" -o "$SYS" = "x86_64" -o "$SYS" = "amd64" -o "$SYS" = "i86pc
}
rm -f test-instr.plain.0 test-instr.plain.1
TUPLES=`echo 1|AFL_QUIET=1 ../afl-showmap -m ${MEM_LIMIT} -o /dev/null -- ./test-instr.plain 2>&1 | grep Captur | awk '{print$3}'`
- test "$TUPLES" -gt 1 -a "$TUPLES" -lt 12 && {
+ test "$TUPLES" -gt 1 -a "$TUPLES" -lt 22 && {
$ECHO "$GREEN[+] ${AFL_CLANG} run reported $TUPLES instrumented locations which is fine"
} || {
$ECHO "$RED[!] ${AFL_CLANG} instrumentation produces weird numbers: $TUPLES"
--
cgit 1.4.1
From 877b2bcab614fdc4a076cf940fda8d0b11b95d42 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 7 Jul 2023 15:03:31 +0200
Subject: add limits.h to afl-ld-lto
---
src/afl-ld-lto.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c
index 420dd817..cb76ba9c 100644
--- a/src/afl-ld-lto.c
+++ b/src/afl-ld-lto.c
@@ -37,6 +37,7 @@
#include
#include
#include
+#include
#include
#include
--
cgit 1.4.1
From e71de2f2b8f4507edef752ce865e49ef2d389e3e Mon Sep 17 00:00:00 2001
From: fuzzah
Date: Fri, 7 Jul 2023 16:57:45 +0300
Subject: remove extra limits.h in afl-ld-lto for BSD
---
src/afl-ld-lto.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c
index cb76ba9c..b306c8d5 100644
--- a/src/afl-ld-lto.c
+++ b/src/afl-ld-lto.c
@@ -46,11 +46,6 @@
#include
-#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || \
- defined(__DragonFly__)
- #include
-#endif
-
#ifdef __APPLE__
#include
#endif
--
cgit 1.4.1
From 20dcb40c53811e36a3ace91a66a70cfddc4b3f1c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sat, 8 Jul 2023 13:31:06 +0200
Subject: fix cmin -T
---
afl-cmin | 5 +++++
afl-cmin.bash | 7 +++++++
docs/Changelog.md | 1 +
3 files changed, 13 insertions(+)
diff --git a/afl-cmin b/afl-cmin
index d0bbed2b..f3ae4304 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -493,6 +493,11 @@ BEGIN {
}
}
+ if (in_count < threads) {
+ threads = in_count
+ print "[!] WARNING: less inputs than threads, reducing threads to "threads" and likely the overhead of threading makes things slower..."
+ }
+
# Let's roll!
#############################
diff --git a/afl-cmin.bash b/afl-cmin.bash
index 1d080491..b326bee8 100755
--- a/afl-cmin.bash
+++ b/afl-cmin.bash
@@ -339,6 +339,13 @@ fi
echo "[*] Are you aware that afl-cmin is faster than this afl-cmin.bash script?"
echo "[+] Found $IN_COUNT files for minimizing."
+if [ -n "$THREADS" ]; then
+ if [ "$IN_COUNT" -lt "$THREADS" ]; then
+ THREADS=$IN_COUNT
+ echo "[!] WARNING: less inputs than threads, reducing threads to $THREADS and likely the overhead of threading makes things slower..."
+ fi
+fi
+
FIRST_FILE=`ls "$IN_DIR" | head -1`
# Make sure that we're not dealing with a directory.
diff --git a/docs/Changelog.md b/docs/Changelog.md
index ad58e99e..032bb774 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -19,6 +19,7 @@
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
- warn on crashing inputs
+ - adjust threads if less inputs than threads specified
- afl-cc:
- fixed an off-by-one instrumentation of iselect, hurting coverage a bit.
Thanks to @amykweon for spotting and fixing!
--
cgit 1.4.1
From a560e42a4d4a41ca132cbc3d7d06c567c1f992a8 Mon Sep 17 00:00:00 2001
From: Your Name
Date: Mon, 10 Jul 2023 07:31:19 +0100
Subject: Increase dummy map size
---
frida_mode/src/instrument/instrument_arm32.c | 2 +-
frida_mode/src/instrument/instrument_arm64.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c
index 51f78a35..2e123247 100644
--- a/frida_mode/src/instrument/instrument_arm32.c
+++ b/frida_mode/src/instrument/instrument_arm32.c
@@ -15,7 +15,7 @@ static GHashTable *coverage_blocks = NULL;
extern __thread guint64 instrument_previous_pc;
-__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_SIZE];
+__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[2UL << 20];
#pragma pack(push, 1)
typedef struct {
diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c
index 131eb4c5..a8d30dc1 100644
--- a/frida_mode/src/instrument/instrument_arm64.c
+++ b/frida_mode/src/instrument/instrument_arm64.c
@@ -22,7 +22,7 @@ gboolean instrument_cache_enabled = FALSE;
gsize instrument_cache_size = 0;
static GHashTable *coverage_blocks = NULL;
-__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_SIZE];
+__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[2UL << 20];
#pragma pack(push, 1)
typedef struct {
--
cgit 1.4.1
From b547a6ab0d0e94fc141b0c013f44c1aa02cb78cc Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 10 Jul 2023 17:43:09 +0200
Subject: nits
---
afl-cmin | 2 +-
instrumentation/SanitizerCoverageLTO.so.cc | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/afl-cmin b/afl-cmin
index f3ae4304..23532b63 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -425,7 +425,7 @@ BEGIN {
cmd = "stat --version 2>/dev/null"
cmd | getline statversion
close(cmd)
- if (statversion ~ /GNU coreutils/) {
+ if (statversion ~ /GNU coreutils/ || statversion ~ /BusyBox/) {
stat_format = "-c '%s %n'" # GNU
} else {
stat_format = "-f '%z %N'" # *BSD, MacOS
diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc
index d7b03634..c70fbd4f 100644
--- a/instrumentation/SanitizerCoverageLTO.so.cc
+++ b/instrumentation/SanitizerCoverageLTO.so.cc
@@ -1081,7 +1081,7 @@ bool ModuleSanitizerCoverageLTO::instrumentModule(
}
if (!be_quiet)
- printf("AUTODICTIONARY: %lu string%s found\n", count,
+ printf("AUTODICTIONARY: %zu string%s found\n", count,
count == 1 ? "" : "s");
if (count) {
--
cgit 1.4.1
From a46d27fad51a8fdd905bb8771bd73eeb2c054895 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Mon, 10 Jul 2023 18:29:21 +0200
Subject: nits
---
instrumentation/split-compares-pass.so.cc | 2 +-
src/afl-common.c | 2 +-
src/afl-forkserver.c | 8 ++++----
test/test-libextensions.sh | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/instrumentation/split-compares-pass.so.cc b/instrumentation/split-compares-pass.so.cc
index 6eafb332..09463fc5 100644
--- a/instrumentation/split-compares-pass.so.cc
+++ b/instrumentation/split-compares-pass.so.cc
@@ -1740,7 +1740,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
if (!be_quiet && !debug) {
errs() << "Split-floatingpoint-compare-pass: " << count
- << " FP comparisons splitted\n";
+ << " FP comparisons split\n";
}
diff --git a/src/afl-common.c b/src/afl-common.c
index 3e1ec09d..a6f83f6d 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -403,7 +403,7 @@ u8 *find_binary(u8 *fname) {
FATAL(
"Unexpected overflow when processing ENV. This should never "
- "happend.");
+ "happened.");
}
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 7322f1ad..ba7cdd66 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -667,13 +667,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
switch (fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner)) {
case Abort:
- NYX_PRE_FATAL(fsrv, "Error: Nyx abort occured...");
+ NYX_PRE_FATAL(fsrv, "Error: Nyx abort occurred...");
break;
case IoError:
NYX_PRE_FATAL(fsrv, "Error: QEMU-Nyx has died...");
break;
case Error:
- NYX_PRE_FATAL(fsrv, "Error: Nyx runtime error has occured...");
+ NYX_PRE_FATAL(fsrv, "Error: Nyx runtime error has occurred...");
break;
default:
break;
@@ -1581,7 +1581,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
FATAL("FixMe: Nyx InvalidWriteToPayload handler is missing");
break;
case Abort:
- FATAL("Error: Nyx abort occured...");
+ FATAL("Error: Nyx abort occurred...");
case IoError:
if (*stop_soon_p) {
@@ -1595,7 +1595,7 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
break;
case Error:
- FATAL("Error: Nyx runtime error has occured...");
+ FATAL("Error: Nyx runtime error has occurred...");
break;
}
diff --git a/test/test-libextensions.sh b/test/test-libextensions.sh
index 40a898c8..f7f86de5 100755
--- a/test/test-libextensions.sh
+++ b/test/test-libextensions.sh
@@ -5,7 +5,7 @@
test -z "$AFL_CC" && unset AFL_CC
$ECHO "$BLUE[*] Testing: shared library extensions"
-cc $CFLAGS -o test-compcov test-compcov.c > /dev/null 2>&1
+cc $CFLAGS -O0 -o test-compcov test-compcov.c > /dev/null 2>&1
test -e ../libtokencap.so && {
AFL_TOKEN_FILE=token.out LD_PRELOAD=../libtokencap.so DYLD_INSERT_LIBRARIES=../libtokencap.so DYLD_FORCE_FLAT_NAMESPACE=1 ./test-compcov foobar > /dev/null 2>&1
grep -q BUGMENOT token.out > /dev/null 2>&1 && {
--
cgit 1.4.1
From 2a34e845072204b29200bf0e480d1d4f2201b332 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Wed, 12 Jul 2023 16:08:22 +0200
Subject: nits
---
include/afl-fuzz.h | 2 +-
include/android-ashmem.h | 4 +++-
src/afl-ld-lto.c | 4 +++-
3 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 9da5cc03..27668da0 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -31,7 +31,7 @@
#define MESSAGES_TO_STDOUT
#ifndef _GNU_SOURCE
- #define _GNU_SOURCE 1
+ #define _GNU_SOURCE
#endif
#ifndef _FILE_OFFSET_BITS
#define _FILE_OFFSET_BITS 64
diff --git a/include/android-ashmem.h b/include/android-ashmem.h
index 1bfd3220..065c213b 100644
--- a/include/android-ashmem.h
+++ b/include/android-ashmem.h
@@ -2,7 +2,9 @@
#ifndef _ANDROID_ASHMEM_H
#define _ANDROID_ASHMEM_H
- #define _GNU_SOURCE
+ #ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+ #endif
#include
#include
#include
diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c
index b306c8d5..b1e6c848 100644
--- a/src/afl-ld-lto.c
+++ b/src/afl-ld-lto.c
@@ -23,7 +23,9 @@
*/
#define AFL_MAIN
-#define _GNU_SOURCE
+#ifndef _GNU_SOURCE
+ #define _GNU_SOURCE
+#endif
#include "config.h"
#include "types.h"
--
cgit 1.4.1
From 534b3eba143c0532e600eb6da08ac2195fa24570 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 13 Jul 2023 10:10:30 +0200
Subject: qemu_get_symbol_addr.sh
---
Dockerfile | 2 +-
docs/Changelog.md | 3 ++
frida_mode/test/bloaty/GNUmakefile | 2 +-
frida_mode/test/cache/GNUmakefile | 2 +-
frida_mode/test/cmov/GNUmakefile | 2 +-
frida_mode/test/deferred/GNUmakefile | 2 +-
frida_mode/test/dynamic/GNUmakefile | 2 +-
frida_mode/test/entry_point/GNUmakefile | 2 +-
frida_mode/test/freetype2/GNUmakefile | 2 +-
frida_mode/test/jpeg/GNUmakefile | 2 +-
frida_mode/test/libpcap/GNUmakefile | 2 +-
frida_mode/test/libxml/GNUmakefile | 2 +-
frida_mode/test/libxslt/GNUmakefile | 2 +-
frida_mode/test/osx-lib/GNUmakefile | 2 +-
frida_mode/test/perf/GNUmakefile | 2 +-
frida_mode/test/persistent_ret/GNUmakefile | 2 +-
frida_mode/test/png/persistent/GNUmakefile | 2 +-
frida_mode/test/png/persistent/hook/GNUmakefile | 2 +-
frida_mode/test/proj4/GNUmakefile | 2 +-
frida_mode/test/re2/GNUmakefile | 2 +-
frida_mode/test/sqlite/GNUmakefile | 2 +-
frida_mode/test/unstable/GNUmakefile | 2 +-
frida_mode/test/vorbis/GNUmakefile | 2 +-
frida_mode/util/frida_get_symbol_addr.sh | 55 +++++++++++++++++++++++++
frida_mode/util/get_symbol_addr.sh | 32 --------------
qemu_mode/util/qemu_get_symbol_addr.sh | 53 ++++++++++++++++++++++++
26 files changed, 133 insertions(+), 54 deletions(-)
create mode 100755 frida_mode/util/frida_get_symbol_addr.sh
delete mode 100755 frida_mode/util/get_symbol_addr.sh
create mode 100755 qemu_mode/util/qemu_get_symbol_addr.sh
diff --git a/Dockerfile b/Dockerfile
index 1b5ffd28..e1616198 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -42,7 +42,7 @@ RUN apt-get update && \
python3 python3-dev python3-pip python-is-python3 \
libtool libtool-bin libglib2.0-dev \
apt-transport-https gnupg dialog \
- gnuplot-nox libpixman-1-dev \
+ gnuplot-nox libpixman-1-dev bc \
gcc-${GCC_VERSION} g++-${GCC_VERSION} gcc-${GCC_VERSION}-plugin-dev gdb lcov \
clang-${LLVM_VERSION} clang-tools-${LLVM_VERSION} libc++1-${LLVM_VERSION} \
libc++-${LLVM_VERSION}-dev libc++abi1-${LLVM_VERSION} libc++abi-${LLVM_VERSION}-dev \
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 032bb774..d61ce8ec 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -28,6 +28,9 @@
- more LLVM compatability
- frida_mode:
- support for long form instrumentation on x86_x64 and arm64
+ - renamed utils/get_symbol_addr.sh to utils/frida_get_symbol_addr.sh
+ - qemu_mode:
+ - added qemu_mode/utils/qemu_get_symbol_addr.sh
### Version ++4.07c (release)
diff --git a/frida_mode/test/bloaty/GNUmakefile b/frida_mode/test/bloaty/GNUmakefile
index 8e767fae..02a0a1e2 100644
--- a/frida_mode/test/bloaty/GNUmakefile
+++ b/frida_mode/test/bloaty/GNUmakefile
@@ -35,7 +35,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/cache/GNUmakefile b/frida_mode/test/cache/GNUmakefile
index 12736a3f..98776193 100644
--- a/frida_mode/test/cache/GNUmakefile
+++ b/frida_mode/test/cache/GNUmakefile
@@ -11,7 +11,7 @@ QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
diff --git a/frida_mode/test/cmov/GNUmakefile b/frida_mode/test/cmov/GNUmakefile
index 96f1ae5b..0712e33b 100644
--- a/frida_mode/test/cmov/GNUmakefile
+++ b/frida_mode/test/cmov/GNUmakefile
@@ -11,7 +11,7 @@ QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
diff --git a/frida_mode/test/deferred/GNUmakefile b/frida_mode/test/deferred/GNUmakefile
index 22aeb2bf..e0b48797 100644
--- a/frida_mode/test/deferred/GNUmakefile
+++ b/frida_mode/test/deferred/GNUmakefile
@@ -10,7 +10,7 @@ TESTINSTSRC:=$(PWD)testinstr.c
QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
ifndef ARCH
diff --git a/frida_mode/test/dynamic/GNUmakefile b/frida_mode/test/dynamic/GNUmakefile
index f43416f7..6c577dff 100644
--- a/frida_mode/test/dynamic/GNUmakefile
+++ b/frida_mode/test/dynamic/GNUmakefile
@@ -17,7 +17,7 @@ FRIDA_OUT:=$(BUILD_DIR)frida-out
AFLPP_FRIDA_DRIVER_HOOK_OBJ=$(ROOT)frida_mode/build/frida_hook.so
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TESTINSTBIN) testinstr $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/entry_point/GNUmakefile b/frida_mode/test/entry_point/GNUmakefile
index 08c660f7..b8c0ecb5 100644
--- a/frida_mode/test/entry_point/GNUmakefile
+++ b/frida_mode/test/entry_point/GNUmakefile
@@ -10,7 +10,7 @@ TESTINSTSRC:=$(PWD)testinstr.c
QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
ifndef ARCH
diff --git a/frida_mode/test/freetype2/GNUmakefile b/frida_mode/test/freetype2/GNUmakefile
index 8c35d5de..23318d52 100644
--- a/frida_mode/test/freetype2/GNUmakefile
+++ b/frida_mode/test/freetype2/GNUmakefile
@@ -64,7 +64,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/jpeg/GNUmakefile b/frida_mode/test/jpeg/GNUmakefile
index a8242081..a4967039 100644
--- a/frida_mode/test/jpeg/GNUmakefile
+++ b/frida_mode/test/jpeg/GNUmakefile
@@ -47,7 +47,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/libpcap/GNUmakefile b/frida_mode/test/libpcap/GNUmakefile
index 1bf9cd7f..745d7057 100644
--- a/frida_mode/test/libpcap/GNUmakefile
+++ b/frida_mode/test/libpcap/GNUmakefile
@@ -56,7 +56,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/libxml/GNUmakefile b/frida_mode/test/libxml/GNUmakefile
index 6fc87585..f1f4a738 100644
--- a/frida_mode/test/libxml/GNUmakefile
+++ b/frida_mode/test/libxml/GNUmakefile
@@ -43,7 +43,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/libxslt/GNUmakefile b/frida_mode/test/libxslt/GNUmakefile
index 655e652b..48bb0b40 100644
--- a/frida_mode/test/libxslt/GNUmakefile
+++ b/frida_mode/test/libxslt/GNUmakefile
@@ -42,7 +42,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/osx-lib/GNUmakefile b/frida_mode/test/osx-lib/GNUmakefile
index 96dbb5ad..fdc9ec04 100644
--- a/frida_mode/test/osx-lib/GNUmakefile
+++ b/frida_mode/test/osx-lib/GNUmakefile
@@ -26,7 +26,7 @@ FRIDA_OUT:=$(BUILD_DIR)frida-out
HARNESS_LDFLAGS:=-Wl,-no_pie
LIB_CFLAGS:=-dynamiclib
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_MAIN_ADDR=$(shell $(GET_SYMBOL_ADDR) $(HARNESS_BIN) main 0x0)
AFL_FRIDA_MAIN_ADDR2=$(shell $(GET_SYMBOL_ADDR) $(HARNESS2_BIN) main 0x0)
AFL_FRIDA_FUZZ_ADDR=$(shell $(GET_SYMBOL_ADDR) $(HARNESS_BIN) LLVMFuzzerTestOneInput 0x0)
diff --git a/frida_mode/test/perf/GNUmakefile b/frida_mode/test/perf/GNUmakefile
index 2d7c0239..6b49c2ba 100644
--- a/frida_mode/test/perf/GNUmakefile
+++ b/frida_mode/test/perf/GNUmakefile
@@ -31,7 +31,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/persistent_ret/GNUmakefile b/frida_mode/test/persistent_ret/GNUmakefile
index 71f6a124..73d710a1 100644
--- a/frida_mode/test/persistent_ret/GNUmakefile
+++ b/frida_mode/test/persistent_ret/GNUmakefile
@@ -23,7 +23,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
ifeq "$(shell uname)" "Darwin"
TEST_BIN_LDFLAGS:=-Wl,-no_pie
diff --git a/frida_mode/test/png/persistent/GNUmakefile b/frida_mode/test/png/persistent/GNUmakefile
index 94e2be38..3dab713e 100644
--- a/frida_mode/test/png/persistent/GNUmakefile
+++ b/frida_mode/test/png/persistent/GNUmakefile
@@ -22,7 +22,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/png/persistent/hook/GNUmakefile b/frida_mode/test/png/persistent/hook/GNUmakefile
index b6a1ca1a..f3d06c87 100644
--- a/frida_mode/test/png/persistent/hook/GNUmakefile
+++ b/frida_mode/test/png/persistent/hook/GNUmakefile
@@ -33,7 +33,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/proj4/GNUmakefile b/frida_mode/test/proj4/GNUmakefile
index debc8a88..17850fa8 100644
--- a/frida_mode/test/proj4/GNUmakefile
+++ b/frida_mode/test/proj4/GNUmakefile
@@ -47,7 +47,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/re2/GNUmakefile b/frida_mode/test/re2/GNUmakefile
index 220e7616..0b79210b 100644
--- a/frida_mode/test/re2/GNUmakefile
+++ b/frida_mode/test/re2/GNUmakefile
@@ -48,7 +48,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/sqlite/GNUmakefile b/frida_mode/test/sqlite/GNUmakefile
index df470af8..6d3c7496 100644
--- a/frida_mode/test/sqlite/GNUmakefile
+++ b/frida_mode/test/sqlite/GNUmakefile
@@ -43,7 +43,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/unstable/GNUmakefile b/frida_mode/test/unstable/GNUmakefile
index 59b49449..3b7b6ddb 100644
--- a/frida_mode/test/unstable/GNUmakefile
+++ b/frida_mode/test/unstable/GNUmakefile
@@ -23,7 +23,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/test/vorbis/GNUmakefile b/frida_mode/test/vorbis/GNUmakefile
index 4cb5d417..b10d059e 100644
--- a/frida_mode/test/vorbis/GNUmakefile
+++ b/frida_mode/test/vorbis/GNUmakefile
@@ -54,7 +54,7 @@ endif
endif
ADDR_BIN:=$(ROOT)frida_mode/build/addr
-GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/get_symbol_addr.sh
+GET_SYMBOL_ADDR:=$(ROOT)frida_mode/util/frida_get_symbol_addr.sh
AFL_FRIDA_BASE_ADDR:=$(shell $(ADDR_BIN))
AFL_FRIDA_PERSISTENT_ADDR=$(shell $(GET_SYMBOL_ADDR) $(TEST_BIN) LLVMFuzzerTestOneInput $(AFL_FRIDA_BASE_ADDR))
diff --git a/frida_mode/util/frida_get_symbol_addr.sh b/frida_mode/util/frida_get_symbol_addr.sh
new file mode 100755
index 00000000..fb0002b7
--- /dev/null
+++ b/frida_mode/util/frida_get_symbol_addr.sh
@@ -0,0 +1,55 @@
+#!/bin/bash
+# Copyright 2023 AFLplusplus
+#
+# 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
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+target="$1"
+symbol="$2"
+base="$3"
+
+test -z "$target" -o -z "$symbol" -o '!' -x "$target" && {
+ echo "Syntax: $0 executable function [baseaddress]"
+ echo
+ echo Help script to calculate the function address of a binary QEMU will load it to.
+ echo function is e.g. LLVMFuzzerTestOneInput, afl_qemu_driver_stdin, etc.
+ echo "baseaddress is tried to be auto-detected, you can use 'AFL_QEMU_DEBUG_MAPS=1 afl-qemu-trace ./executable' to see the maps."
+ exit 1
+}
+
+file=$(file $target|sed 's/.*: //')
+
+arch=$(echo $file|awk -F, '{print$2}'|tr -d ' ')
+bits=$(echo $file|sed 's/-bit .*//'|sed 's/.* //')
+pie=$(echo $file|grep -wqi pie && echo pie)
+
+test $(uname -s) = "Darwin" && symbol=_"$symbol"
+tmp_addr=$(nm "$target" | grep -i "T $symbol" | awk '{print$1}' | tr a-f A-F)
+
+test -z "$tmp_addr" && { echo Error: function $symbol not found 1>&2; exit 1; }
+test -z "$pie" && { echo 0x$tmp_addr; exit 0; }
+
+test -z "$base" && {
+ test "$bits" = 32 -o "$bits" = 64 || { echo "Error: could not identify arch (bits=$bits)" 1>&2 ; exit 1; }
+ # is this true for arm/aarch64/i386 too?
+ base=0x555555554000
+ #test "$arch" = Intel80386 && base=0x5555554000
+ #test "$arch" = x86-64 && base=0x555555554000
+ #test "$arch" = ARMaarch64 && base=0x5500000000
+ # add more here, e.g. "$arch" = ARM
+}
+
+test -z "$base" && { echo "Error: could not identify base address! bits=$bits arch=$arch" 1>&2 ; exit 1; }
+
+hex_base=$(echo "$base" | awk '{sub("^0x","");print $0}' | tr a-f A-F )
+echo $tmp_addr | echo "ibase=16;obase=10;$hex_base + $tmp_addr" | bc | tr A-F a-f | awk '{print "0x"$0}'
+exit 0
diff --git a/frida_mode/util/get_symbol_addr.sh b/frida_mode/util/get_symbol_addr.sh
deleted file mode 100755
index f5d8df91..00000000
--- a/frida_mode/util/get_symbol_addr.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/bash
-# Copyright 2020 Google LLC
-#
-# 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
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-# set -x
-target="$1"
-symbol="$2"
-base="$3"
-
-test -z "$target" -o -z "$symbol" -o '!' -e "$target" && exit 0
-
-test $(uname -s) = "Darwin" && symbol=_"$symbol"
-
-file "$target" | grep -q executable && {
- nm "$target" | grep -i "T $symbol" | awk '{print"0x"$1}'
- exit 0
-}
-
-hex_base=$(echo "$3" | awk '{sub("^0x","");print $0}' | tr a-f A-F )
-nm "$target" | grep -i "T $symbol" | awk '{print$1}' | tr a-f A-F | \
- xargs echo "ibase=16;obase=10;$hex_base + " | bc | tr A-F a-f | awk '{print "0x"$0}'
-exit 0
diff --git a/qemu_mode/util/qemu_get_symbol_addr.sh b/qemu_mode/util/qemu_get_symbol_addr.sh
new file mode 100755
index 00000000..e0a7ae80
--- /dev/null
+++ b/qemu_mode/util/qemu_get_symbol_addr.sh
@@ -0,0 +1,53 @@
+#!/bin/bash
+# Copyright 2023 AFLplusplus
+#
+# 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
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+target="$1"
+symbol="$2"
+base="$3"
+
+test -z "$target" -o -z "$symbol" -o '!' -x "$target" && {
+ echo "Syntax: $0 executable function [baseaddress]"
+ echo
+ echo Help script to calculate the function address of a binary QEMU will load it to.
+ echo function is e.g. LLVMFuzzerTestOneInput, afl_qemu_driver_stdin, etc.
+ echo "baseaddress is tried to be auto-detected, you can use 'AFL_QEMU_DEBUG_MAPS=1 afl-qemu-trace ./executable' to see the maps."
+ exit 1
+}
+
+file=$(file $target|sed 's/.*: //')
+
+arch=$(echo $file|awk -F, '{print$2}'|tr -d ' ')
+bits=$(echo $file|sed 's/-bit .*//'|sed 's/.* //')
+pie=$(echo $file|grep -wqi pie && echo pie)
+
+test $(uname -s) = "Darwin" && symbol=_"$symbol"
+tmp_addr=$(nm "$target" | grep -i "T $symbol" | awk '{print$1}' | tr a-f A-F)
+
+test -z "$tmp_addr" && { echo Error: function $symbol not found 1>&2; exit 1; }
+test -z "$pie" && { echo 0x$tmp_addr; exit 0; }
+
+test -z "$base" && {
+ test "$bits" = 32 -o "$bits" = 64 || { echo "Error: could not identify arch (bits=$bits)" 1>&2 ; exit 1; }
+ test "$arch" = Intel80386 && base=0x40000000
+ test "$arch" = x86-64 && base=0x4000000000
+ test "$arch" = ARMaarch64 && base=0x5500000000
+ # add more here, e.g. "$arch" = ARM
+}
+
+test -z "$base" && { echo "Error: could not identify base address! bits=$bits arch=$arch" 1>&2 ; exit 1; }
+
+hex_base=$(echo "$base" | awk '{sub("^0x","");print $0}' | tr a-f A-F )
+echo $tmp_addr | echo "ibase=16;obase=10;$hex_base + $tmp_addr" | bc | tr A-F a-f | awk '{print "0x"$0}'
+exit 0
--
cgit 1.4.1
From 1132b08d7d3ef6bae712ced57d32ce06abfa973d Mon Sep 17 00:00:00 2001
From: hexcoder
Date: Thu, 13 Jul 2023 13:37:47 +0200
Subject: Update afl-common.c typo
---
src/afl-common.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/afl-common.c b/src/afl-common.c
index a6f83f6d..b4143a1b 100644
--- a/src/afl-common.c
+++ b/src/afl-common.c
@@ -403,7 +403,7 @@ u8 *find_binary(u8 *fname) {
FATAL(
"Unexpected overflow when processing ENV. This should never "
- "happened.");
+ "had happened.");
}
--
cgit 1.4.1
From 127c345161769c513275fed9d64de12536ee979d Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 13 Jul 2023 14:26:26 +0200
Subject: nts
---
frida_mode/src/instrument/instrument_arm32.c | 2 +-
frida_mode/src/instrument/instrument_arm64.c | 2 +-
include/config.h | 8 ++++++++
instrumentation/SanitizerCoveragePCGUARD.so.cc | 1 +
instrumentation/afl-compiler-rt.o.c | 6 ------
5 files changed, 11 insertions(+), 8 deletions(-)
diff --git a/frida_mode/src/instrument/instrument_arm32.c b/frida_mode/src/instrument/instrument_arm32.c
index 2e123247..c1e3f187 100644
--- a/frida_mode/src/instrument/instrument_arm32.c
+++ b/frida_mode/src/instrument/instrument_arm32.c
@@ -15,7 +15,7 @@ static GHashTable *coverage_blocks = NULL;
extern __thread guint64 instrument_previous_pc;
-__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[2UL << 20];
+__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_INITIAL_SIZE];
#pragma pack(push, 1)
typedef struct {
diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c
index a8d30dc1..2256f941 100644
--- a/frida_mode/src/instrument/instrument_arm64.c
+++ b/frida_mode/src/instrument/instrument_arm64.c
@@ -22,7 +22,7 @@ gboolean instrument_cache_enabled = FALSE;
gsize instrument_cache_size = 0;
static GHashTable *coverage_blocks = NULL;
-__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[2UL << 20];
+__attribute__((aligned(0x1000))) static guint8 area_ptr_dummy[MAP_INITIAL_SIZE];
#pragma pack(push, 1)
typedef struct {
diff --git a/include/config.h b/include/config.h
index 8585041e..16f4b613 100644
--- a/include/config.h
+++ b/include/config.h
@@ -446,7 +446,15 @@
after changing this - otherwise, SEGVs may ensue. */
#define MAP_SIZE_POW2 16
+
+/* Do not change this unless you really know what you are doing. */
+
#define MAP_SIZE (1U << MAP_SIZE_POW2)
+#if MAP_SIZE <= 65536
+ #define MAP_INITIAL_SIZE (2 << 20) // = 2097152
+#else
+ #define MAP_INITIAL_SIZE MAP_SIZE
+#endif
/* Maximum allocator request size (keep well under INT_MAX): */
diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc
index 7d614f43..98c5973c 100644
--- a/instrumentation/SanitizerCoveragePCGUARD.so.cc
+++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc
@@ -227,6 +227,7 @@ llvmGetPassPluginInfo() {
PreservedAnalyses ModuleSanitizerCoverageAFL::run(Module &M,
ModuleAnalysisManager &MAM) {
+
ModuleSanitizerCoverageAFL ModuleSancov(Options);
auto &FAM = MAM.getResult(M).getManager();
auto DTCallback = [&FAM](Function &F) -> const DominatorTree *{
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 3f8b519b..dd9aae77 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -87,12 +87,6 @@
is used for instrumentation output before __afl_map_shm() has a chance to
run. It will end up as .comm, so it shouldn't be too wasteful. */
-#if MAP_SIZE <= 65536
- #define MAP_INITIAL_SIZE 2097152
-#else
- #define MAP_INITIAL_SIZE MAP_SIZE
-#endif
-
#if defined(__HAIKU__)
extern ssize_t _kern_write(int fd, off_t pos, const void *buffer,
size_t bufferSize);
--
cgit 1.4.1
From 2b8e528a3b5f44df590b8f727983d142857d0433 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Thu, 13 Jul 2023 17:12:55 +0200
Subject: interesting32_float
---
include/config.h | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/include/config.h b/include/config.h
index 16f4b613..7c29a674 100644
--- a/include/config.h
+++ b/include/config.h
@@ -360,9 +360,10 @@
65535, /* Overflow unsig 16-bit when incremented */ \
65536, /* Overflow unsig 16 bit */ \
100663045, /* Large positive number (endian-agnostic) */ \
+ 2139095040, /* float infinite */ \
2147483647 /* Overflow signed 32-bit when incremented */
-#define INTERESTING_32_LEN 8
+#define INTERESTING_32_LEN 9
/***********************************************************
* *
--
cgit 1.4.1
From 4113b6ccada97c32b3852ece5ffe2fee6dcbc2c8 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Tue, 18 Jul 2023 09:56:28 +0200
Subject: take care of uninstrumented mode for fuzz state and mode
---
README.md | 1 +
src/afl-fuzz-bitmap.c | 3 ++-
src/afl-fuzz-stats.c | 9 +++++++--
src/afl-fuzz.c | 3 ++-
4 files changed, 12 insertions(+), 4 deletions(-)
diff --git a/README.md b/README.md
index 05c662c1..42fcaa0d 100644
--- a/README.md
+++ b/README.md
@@ -15,6 +15,7 @@ AFL++ is maintained by:
* Andrea Fioraldi
* Dominik Maier
* Heiko "hexcoder-" Eiรfeldt
+* frida_mode is maintained by @Worksbutnottested
* Documentation: Jana Aydinbas
Originally developed by Michaล "lcamtuf" Zalewski.
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index fb8a1d4b..87157cad 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -533,7 +533,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
close(fd);
add_to_queue(afl, queue_fn, len, 0);
- if (unlikely(afl->fuzz_mode) && likely(afl->switch_fuzz_mode)) {
+ if (unlikely(afl->fuzz_mode) &&
+ likely(afl->switch_fuzz_mode && !afl->non_instrumented_mode)) {
if (afl->afl_env.afl_no_ui) {
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 4013370d..3d0a9b9a 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -37,8 +37,13 @@ char *get_fuzzing_state(afl_state_t *afl) {
u64 cur_run_time = cur_ms - afl->start_time;
u64 cur_total_run_time = afl->prev_run_time + cur_run_time;
- if (unlikely(cur_run_time < 60 * 3 * 1000 ||
- cur_total_run_time < 60 * 5 * 1000)) {
+ if (unlikely(afl->non_instrumented_mode)) {
+
+ return fuzzing_state[1];
+
+ } else if (unlikely(cur_run_time < 60 * 3 * 1000 ||
+
+ cur_total_run_time < 60 * 5 * 1000)) {
return fuzzing_state[0];
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 9afece66..d8a88f00 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -2755,7 +2755,8 @@ int main(int argc, char **argv_orig, char **envp) {
u64 cur_time = get_cur_time();
- if (likely(afl->switch_fuzz_mode && afl->fuzz_mode == 0) &&
+ if (likely(afl->switch_fuzz_mode && afl->fuzz_mode == 0 &&
+ !afl->non_instrumented_mode) &&
unlikely(cur_time > afl->last_find_time + afl->switch_fuzz_mode)) {
if (afl->afl_env.afl_no_ui) {
--
cgit 1.4.1
From 5f813bbb86e1c9e2480669c44501e9780043728c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 21 Jul 2023 18:02:30 +0200
Subject: improve cmplog level 3
---
docs/Changelog.md | 1 +
include/afl-fuzz.h | 3 +-
include/config.h | 8 +--
src/afl-fuzz-redqueen.c | 171 +++++++++++++++++++++++++-----------------------
src/afl-fuzz.c | 7 +-
5 files changed, 100 insertions(+), 90 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index d61ce8ec..75167172 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -15,6 +15,7 @@
command line tool! See custom_mutators/aflpp/standalone/
- display the state of the fuzzing run in the UI :-)
- fix timeout setting if '+' is used or a session is restarted
+ - -c X option to enable base64 transformation solving
- afl-cmin/afl-cmin.bash:
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 27668da0..e114b0fc 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -674,7 +674,8 @@ typedef struct afl_state {
u32 cmplog_max_filesize;
u32 cmplog_lvl;
u32 colorize_success;
- u8 cmplog_enable_arith, cmplog_enable_transform, cmplog_random_colorization;
+ u8 cmplog_enable_arith, cmplog_enable_transform,
+ cmplog_enable_xtreme_transform, cmplog_random_colorization;
struct afl_pass_stat *pass_stats;
struct cmp_map *orig_cmp_map;
diff --git a/include/config.h b/include/config.h
index 7c29a674..df545583 100644
--- a/include/config.h
+++ b/include/config.h
@@ -60,10 +60,6 @@
*
*/
-/* if TRANSFORM is enabled with '-l T', this additionally enables base64
- encoding/decoding */
-// #define CMPLOG_SOLVE_TRANSFORM_BASE64
-
/* If a redqueen pass finds more than one solution, try to combine them? */
#define CMPLOG_COMBINE
@@ -71,10 +67,10 @@
#define CMPLOG_CORPUS_PERCENT 5U
/* Number of potential positions from which we decide if cmplog becomes
- useless, default 8096 */
+ useless, default 12288 */
#define CMPLOG_POSITIONS_MAX (12 * 1024)
-/* Maximum allowed fails per CMP value. Default: 128 */
+/* Maximum allowed fails per CMP value. Default: 96 */
#define CMPLOG_FAIL_MAX 96
/* -------------------------------------*/
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 73e188e7..5a1f512d 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -571,7 +571,6 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) {
}
-// #ifdef CMPLOG_SOLVE_TRANSFORM
static int strntoll(const char *str, size_t sz, char **end, int base,
long long *out) {
@@ -656,7 +655,6 @@ static int is_hex(const char *str) {
}
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
// tests 4 bytes at location
static int is_base64(const char *str) {
@@ -769,10 +767,6 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
}
-#endif
-
-// #endif
-
static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u64 pattern, u64 repl, u64 o_pattern,
u64 changed_val, u8 attr, u32 idx, u32 taint_len,
@@ -797,42 +791,54 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
- // fprintf(stderr,
- // "Encode: %llx->%llx into %llx(<-%llx) at idx=%u "
- // "taint_len=%u shape=%u attr=%u\n",
- // o_pattern, pattern, repl, changed_val, idx, taint_len,
- // hshape, attr);
+ /*
+ fprintf(stderr,
+ "Encode: %llx->%llx into %llx(<-%llx) at idx=%u "
+ "taint_len=%u shape=%u attr=%u\n",
+ o_pattern, pattern, repl, changed_val, idx, taint_len,
+ hshape, attr);
+ */
- // #ifdef CMPLOG_SOLVE_TRANSFORM
// reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3
if (afl->cmplog_enable_transform && (lvl & LVL3)) {
u8 *endptr;
u8 use_num = 0, use_unum = 0;
- unsigned long long unum;
- long long num;
+ unsigned long long unum = 0;
+ long long num = 0;
+
+ // if (afl->queue_cur->is_ascii) {
+
+ // we first check if our input are ascii numbers that are transformed to
+ // an integer and used for comparison:
- if (afl->queue_cur->is_ascii) {
+ endptr = buf_8;
+ if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) {
- endptr = buf_8;
- if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) {
+ if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum)) {
- if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum))
- use_unum = 1;
+ use_unum = 1;
- } else
+ }
+
+ } else {
- use_num = 1;
+ use_num = 1;
}
+ //}
+
#ifdef _DEBUG
if (idx == 0)
- fprintf(stderr, "ASCII is=%u use_num=%u use_unum=%u idx=%u %llx==%llx\n",
- afl->queue_cur->is_ascii, use_num, use_unum, idx, num, pattern);
+ fprintf(stderr,
+ "ASCII is=%u use_num=%u>%lld use_unum=%u>%llu idx=%u "
+ "pattern=0x%llx\n",
+ afl->queue_cur->is_ascii, use_num, num, use_unum, unum, idx,
+ pattern);
#endif
- // num is likely not pattern as atoi("AAA") will be zero...
+ // atoi("AAA") == 0 so !num means we have to investigate
if (use_num && ((u64)num == pattern || !num)) {
u8 tmp_buf[32];
@@ -961,10 +967,12 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
// test for arithmetic, eg. "if ((user_val - 0x1111) == 0x1234) ..."
s64 diff = pattern - b_val;
s64 o_diff = o_pattern - o_b_val;
- /* fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx,
- hshape, o_pattern, o_b_val, o_diff);
- fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern,
- b_val, diff); */
+ /*
+ fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx,
+ hshape, o_pattern, o_b_val, o_diff);
+ fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern,
+ b_val, diff);
+ */
if (diff == o_diff && diff) {
// this could be an arithmetic transformation
@@ -1275,7 +1283,6 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
// 16 = modified float, 32 = modified integer (modified = wont match
// in original buffer)
- // #ifdef CMPLOG_SOLVE_ARITHMETIC
if (!afl->cmplog_enable_arith || lvl < LVL3 || attr == IS_TRANSFORM) {
return 0;
@@ -2009,8 +2016,12 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
its_len = MIN(its_len, taint_len);
u32 saved_its_len = its_len;
+ if (its_len <= 1) { return 0; }
+
if (lvl & LVL3) {
+ if (memcmp(changed_val, repl, its_len) != 0) { return 0; }
+
u32 max_to = MIN(4U, idx);
if (!(lvl & LVL1) && max_to) { from = 1; }
to = max_to;
@@ -2089,9 +2100,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
if (afl->cmplog_enable_transform && (lvl & LVL3)) {
u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0;
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
u32 tob64 = 0, fromb64 = 0;
-#endif
u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0;
u32 to_0 = 0, to_x = 0, to_slash = 0, to_up = 0;
u8 xor_val[32], arith_val[32], tmp[48];
@@ -2144,7 +2153,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- if (i < 16 && is_hex(repl + (i << 1))) {
+ if (afl->cmplog_enable_xtreme_transform && i < 16 &&
+ is_hex(repl + (i << 1))) {
++tohex;
@@ -2163,7 +2173,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- if ((i % 2)) {
+ if (afl->cmplog_enable_xtreme_transform && (i % 2)) {
if (len > idx + i + 1 && is_hex(orig_buf + idx + i)) {
@@ -2187,20 +2197,21 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- if (i % 3 == 2 && i < 24) {
+ if (afl->cmplog_enable_xtreme_transform) {
- if (is_base64(repl + ((i / 3) << 2))) tob64 += 3;
+ if (i % 3 == 2 && i < 24) {
- }
+ if (is_base64(repl + ((i / 3) << 2))) tob64 += 3;
+
+ }
- if (i % 4 == 3 && i < 24) {
+ if (i % 4 == 3 && i < 24) {
- if (is_base64(orig_buf + idx + i - 3)) fromb64 += 4;
+ if (is_base64(orig_buf + idx + i - 3)) fromb64 += 4;
- }
+ }
-#endif
+ }
if ((o_pattern[i] ^ orig_buf[idx + i]) == xor_val[i] && xor_val[i]) {
@@ -2229,45 +2240,50 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
#ifdef _DEBUG
+ fprintf(stderr, "RTN %s %s %s %s\n", buf, pattern, orig_buf, o_pattern);
fprintf(stderr,
- "RTN idx=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u "
+ "RTN idx=%u len=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u "
"tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u "
"from_0=%u from_slash=%u from_x=%u\n",
- idx, i, xor, arith, tolower, toupper, tohex, fromhex, to_0,
- to_slash, to_x, from_0, from_slash, from_x);
- #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", tob64,
- fromb64);
- #endif
+ idx, its_len, i, xor, arith, tolower, toupper, tohex, fromhex,
+ to_0, to_slash, to_x, from_0, from_slash, from_x);
+ if (afl->cmplog_enable_xtreme_transform) {
+
+ fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", idx, i,
+ tob64, fromb64);
+
+ }
+
#endif
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- // input is base64 and converted to binary? convert repl to base64!
- if ((i % 4) == 3 && i < 24 && fromb64 > i) {
+ if (afl->cmplog_enable_xtreme_transform) {
- to_base64(repl, tmp, i + 1);
- memcpy(buf + idx, tmp, i + 1);
- if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
- // fprintf(stderr, "RTN ATTEMPT fromb64 %u result %u\n", fromb64,
- // *status);
+ // input is base64 and converted to binary? convert repl to base64!
+ if ((i % 4) == 3 && i < 24 && fromb64 > i) {
- }
+ to_base64(repl, tmp, i + 1);
+ memcpy(buf + idx, tmp, i + 1);
+ if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
+ // fprintf(stderr, "RTN ATTEMPT fromb64 %u result %u\n", fromb64,
+ // *status);
+
+ }
- // input is converted to base64? decode repl with base64!
- if ((i % 3) == 2 && i < 24 && tob64 > i) {
+ // input is converted to base64? decode repl with base64!
+ if ((i % 3) == 2 && i < 24 && tob64 > i) {
- u32 olen = from_base64(repl, tmp, i + 1);
- memcpy(buf + idx, tmp, olen);
- if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
- // fprintf(stderr, "RTN ATTEMPT tob64 %u idx=%u result %u\n", tob64,
- // idx, *status);
+ u32 olen = from_base64(repl, tmp, i + 1);
+ memcpy(buf + idx, tmp, olen);
+ if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
+ // fprintf(stderr, "RTN ATTEMPT tob64 %u idx=%u result %u\n", tob64,
+ // idx, *status);
- }
+ }
-#endif
+ }
// input is converted to hex? convert repl to binary!
- if (i < 16 && tohex > i) {
+ if (afl->cmplog_enable_xtreme_transform && i < 16 && tohex > i) {
u32 off;
if (to_slash + to_x + to_0 == 2) {
@@ -2292,8 +2308,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
// input is hex and converted to binary? convert repl to hex!
- if (i && (i % 2) && i < 16 && fromhex &&
- fromhex + from_slash + from_x + from_0 > i) {
+ if (afl->cmplog_enable_xtreme_transform && i && (i % 2) && i < 16 &&
+ fromhex && fromhex + from_slash + from_x + from_0 > i) {
u8 off = 0;
if (from_slash && from_x) {
@@ -2401,11 +2417,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
if ((i >= 7 &&
(i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i >
- (fromhex + from_0 + from_x + from_slash + 1)
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- && i > tob64 + 3 && i > fromb64 + 4
-#endif
- )) ||
+ (fromhex + from_0 + from_x + from_slash + 1) &&
+ (afl->cmplog_enable_xtreme_transform && i > tob64 + 3 &&
+ i > fromb64 + 4))) ||
repl[i] != changed_val[i] || *status == 1) {
break;
@@ -2418,8 +2432,6 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- // #endif
-
return 0;
}
@@ -2818,12 +2830,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
}
- } else if ((lvl & LVL1)
-
- // #ifdef CMPLOG_SOLVE_TRANSFORM
- || ((lvl & LVL3) && afl->cmplog_enable_transform)
- // #endif
- ) {
+ } else if ((lvl & LVL1) || ((lvl & LVL3) && afl->cmplog_enable_transform)) {
if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index d8a88f00..21a8915c 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -185,7 +185,8 @@ static void usage(u8 *argv0, int more_help) {
" 1=small files, 2=larger files (default), 3=all "
"files,\n"
" A=arithmetic solving, T=transformational solving,\n"
- " R=random colorization bytes.\n\n"
+ " X=extreme transform solving, R=random colorization "
+ "bytes.\n\n"
"Fuzzing behavior settings:\n"
" -Z - sequential queue selection instead of weighted "
"random\n"
@@ -1120,6 +1121,10 @@ int main(int argc, char **argv_orig, char **envp) {
case 'T':
afl->cmplog_enable_transform = 1;
break;
+ case 'x':
+ case 'X':
+ afl->cmplog_enable_xtreme_transform = 1;
+ break;
case 'r':
case 'R':
afl->cmplog_random_colorization = 1;
--
cgit 1.4.1
From 705cdf45fc32e6f5fcf3b8e58242ede3b99b8b6e Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 23 Jul 2023 13:05:10 +0200
Subject: temp cmplog fixes
---
GNUmakefile | 6 +-
GNUmakefile.gcc_plugin | 6 +-
GNUmakefile.llvm | 6 +-
src/afl-fuzz-redqueen.c | 190 ++++++++++++++++++++++++++++++------------------
4 files changed, 130 insertions(+), 78 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index 71011858..f6b76a6c 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -91,9 +91,9 @@ ifneq "$(SYS)" "Darwin"
#ifeq "$(HAVE_MARCHNATIVE)" "1"
# SPECIAL_PERFORMANCE += -march=native
#endif
- ifndef DEBUG
- CFLAGS_OPT += -D_FORTIFY_SOURCE=1
- endif
+ #ifndef DEBUG
+ # CFLAGS_OPT += -D_FORTIFY_SOURCE=1
+ #endif
else
# On some odd MacOS system configurations, the Xcode sdk path is not set correctly
SDK_LD = -L$(shell xcrun --show-sdk-path)/usr/lib
diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin
index 41face4c..29d0ed9d 100644
--- a/GNUmakefile.gcc_plugin
+++ b/GNUmakefile.gcc_plugin
@@ -28,14 +28,16 @@ MAN_PATH ?= $(PREFIX)/share/man/man8
VERSION = $(shell grep '^$(HASH)define VERSION ' ./config.h | cut -d '"' -f2)
-CFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=1
+CFLAGS ?= -O3 -g -funroll-loops
+# -D_FORTIFY_SOURCE=1
CFLAGS_SAFE := -Wall -Iinclude -Wno-pointer-sign \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-DGCC_VERSION=\"$(GCCVER)\" -DGCC_BINDIR=\"$(GCCBINDIR)\" \
-Wno-unused-function
override CFLAGS += $(CFLAGS_SAFE)
-CXXFLAGS ?= -O3 -g -funroll-loops -D_FORTIFY_SOURCE=1
+CXXFLAGS ?= -O3 -g -funroll-loops
+# -D_FORTIFY_SOURCE=1
CXXEFLAGS := $(CXXFLAGS) -Wall -std=c++11
CC ?= gcc
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index f298060e..75fb664b 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -262,7 +262,8 @@ else
AFL_CLANG_DEBUG_PREFIX =
endif
-CFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=1
+CFLAGS ?= -O3 -funroll-loops -fPIC
+# -D_FORTIFY_SOURCE=1
CFLAGS_SAFE := -Wall -g -Wno-cast-qual -Wno-variadic-macros -Wno-pointer-sign \
-I ./include/ -I ./instrumentation/ \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
@@ -287,7 +288,8 @@ ifdef AFL_TRACE_PC
$(info Compile option AFL_TRACE_PC is deprecated, just set AFL_LLVM_INSTRUMENT=PCGUARD to activate when compiling targets )
endif
-CXXFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=1
+CXXFLAGS ?= -O3 -funroll-loops -fPIC
+# -D_FORTIFY_SOURCE=1
override CXXFLAGS += -Wall -g -I ./include/ \
-DVERSION=\"$(VERSION)\" -Wno-variadic-macros -Wno-deprecated-copy-with-dtor \
-DLLVM_MINOR=$(LLVM_MINOR) -DLLVM_MAJOR=$(LLVM_MAJOR)
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 5a1f512d..8a652a9f 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -129,7 +129,6 @@ static struct range *pop_biggest_range(struct range **ranges) {
}
#ifdef _DEBUG
-// static int logging = 0;
static void dump(char *txt, u8 *buf, u32 len) {
u32 i;
@@ -140,6 +139,7 @@ static void dump(char *txt, u8 *buf, u32 len) {
}
+/*
static void dump_file(char *path, char *name, u32 counter, u8 *buf, u32 len) {
char fn[4096];
@@ -155,6 +155,8 @@ static void dump_file(char *path, char *name, u32 counter, u8 *buf, u32 len) {
}
+*/
+
#endif
static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) {
@@ -730,12 +732,14 @@ static u32 from_base64(u8 *src, u8 *dst, u32 dst_len) {
}
-static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
+static u32 to_base64(u8 *src, u8 *dst, u32 dst_len) {
u32 i, j, v;
- u32 len = (dst_len >> 2) * 3;
+ // u32 len = (dst_len >> 2) * 3;
+ u32 len = (dst_len / 3) * 4;
+ if (dst_len % 3) len += 4;
- for (i = 0, j = 0; i < len; i += 3, j += 4) {
+ for (i = 0, j = 0; j < len; i += 3, j += 4) {
v = src[i];
v = i + 1 < len ? v << 8 | src[i + 1] : v << 8;
@@ -743,7 +747,8 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
dst[j] = base64_encode_table[(v >> 18) & 0x3F];
dst[j + 1] = base64_encode_table[(v >> 12) & 0x3F];
- if (i + 1 < len) {
+
+ if (i + 1 < dst_len) {
dst[j + 2] = base64_encode_table[(v >> 6) & 0x3F];
@@ -753,7 +758,7 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
}
- if (i + 2 < len) {
+ if (i + 2 < dst_len) {
dst[j + 3] = base64_encode_table[v & 0x3F];
@@ -765,6 +770,9 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
}
+ dst[len] = 0;
+ return len;
+
}
static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
@@ -2016,6 +2024,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
its_len = MIN(its_len, taint_len);
u32 saved_its_len = its_len;
+ // fprintf(stderr, "its_len=%u repl=%s\n", its_len, repl);
+
if (its_len <= 1) { return 0; }
if (lvl & LVL3) {
@@ -2032,27 +2042,32 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
(void)(j);
#ifdef _DEBUG
- fprintf(stderr, "RTN T idx=%u lvl=%02x is_txt=%u shape=%u/%u ", idx, lvl,
- o->v0_len >= 0x80 ? 1 : 0, hshape, l0);
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", orig_buf[idx + j]);
- fprintf(stderr, " -> ");
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", o_pattern[j]);
- fprintf(stderr, " <= ");
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", repl[j]);
- fprintf(stderr, "\n");
- fprintf(stderr, " ");
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", buf[idx + j]);
- fprintf(stderr, " -> ");
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", pattern[j]);
- fprintf(stderr, " <= ");
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", changed_val[j]);
- fprintf(stderr, "\n");
+ if (idx == 0) {
+
+ fprintf(stderr, "RTN T idx=%u lvl=%02x is_txt=%u shape=%u/%u ", idx, lvl,
+ o->v0_len >= 0x80 ? 1 : 0, hshape, l0);
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", orig_buf[idx + j]);
+ fprintf(stderr, " -> ");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", o_pattern[j]);
+ fprintf(stderr, " <= ");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", repl[j]);
+ fprintf(stderr, "\n");
+ fprintf(stderr, " ");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", buf[idx + j]);
+ fprintf(stderr, " -> ");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", pattern[j]);
+ fprintf(stderr, " <= ");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", changed_val[j]);
+ fprintf(stderr, "\n");
+
+ }
+
#endif
// Try to match the replace value up to 4 bytes before the current idx.
@@ -2061,6 +2076,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
// if (memcmp(user_val, "TEST-VALUE") == 0) ...
// We only do this in lvl 3, otherwise we only do direct matching
+ // fprintf(stderr, "XXXX FROMB64 saved_idx=%u its_len=%u from=%u to=%u FROMHEX
+ // repl=%s\n", saved_idx, saved_its_len, from, to, repl);
+
for (pre = from; pre <= to; pre++) {
if (*status != 1 && (!pre || !memcmp(buf + saved_idx - pre, repl, pre))) {
@@ -2173,9 +2191,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- if (afl->cmplog_enable_xtreme_transform && (i % 2)) {
+ if (afl->cmplog_enable_xtreme_transform && (i % 2) == 1) {
- if (len > idx + i + 1 && is_hex(orig_buf + idx + i)) {
+ if (len > idx + i + 1 && is_hex(orig_buf + idx + i - 1)) {
fromhex += 2;
@@ -2205,6 +2223,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
+ // fprintf(stderr, "X FROMB64 idx=%u i=%u repl=%s\n", saved_idx, i,
+ // repl);
if (i % 4 == 3 && i < 24) {
if (is_base64(orig_buf + idx + i - 3)) fromb64 += 4;
@@ -2240,17 +2260,23 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
#ifdef _DEBUG
- fprintf(stderr, "RTN %s %s %s %s\n", buf, pattern, orig_buf, o_pattern);
- fprintf(stderr,
- "RTN idx=%u len=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u "
- "tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u "
- "from_0=%u from_slash=%u from_x=%u\n",
- idx, its_len, i, xor, arith, tolower, toupper, tohex, fromhex,
- to_0, to_slash, to_x, from_0, from_slash, from_x);
- if (afl->cmplog_enable_xtreme_transform) {
+ if (idx == 0) {
+
+ fprintf(stderr, "RTN Z %s %s %s %s repl=%s\n", buf, pattern, orig_buf,
+ o_pattern, repl);
+ fprintf(
+ stderr,
+ "RTN Z idx=%u len=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u "
+ "tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u "
+ "from_0=%u from_slash=%u from_x=%u\n",
+ idx, its_len, i, xor, arith, tolower, toupper, tohex, fromhex, to_0,
+ to_slash, to_x, from_0, from_slash, from_x);
+ if (afl->cmplog_enable_xtreme_transform) {
+
+ fprintf(stderr, "RTN Z idx=%u loop=%u tob64=%u from64=%u\n", idx, i,
+ tob64, fromb64);
- fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", idx, i,
- tob64, fromb64);
+ }
}
@@ -2259,13 +2285,27 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
if (afl->cmplog_enable_xtreme_transform) {
// input is base64 and converted to binary? convert repl to base64!
+ // fprintf(stderr, "FROMB64 idx=%u i=%u %% 4 == 3 && i < 24 &&
+ // fromb64=%u > i, repl=%s\n", saved_idx, i, fromb64, repl);
if ((i % 4) == 3 && i < 24 && fromb64 > i) {
- to_base64(repl, tmp, i + 1);
- memcpy(buf + idx, tmp, i + 1);
- if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
- // fprintf(stderr, "RTN ATTEMPT fromb64 %u result %u\n", fromb64,
- // *status);
+ for (u32 hlen = i; hlen + saved_idx < len && hlen <= its_len;
+ ++hlen) {
+
+ u32 res = to_base64(repl, tmp, hlen);
+ // fprintf(stderr, "FROMB64 GOGO! idx=%u repl=%s tmp[%u]=%s
+ // hlen=%u\n", saved_idx, repl, res, tmp, hlen);
+ if (res + saved_idx < len) {
+
+ memcpy(buf + idx, tmp, res);
+ if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
+ // fprintf(stderr, "RTN ATTEMPT FROMB64 idx=%u fromb64 %u %s %s
+ // result %u\n", saved_idx, fromb64, tmp, repl,
+ // *status);
+
+ }
+
+ }
}
@@ -2308,7 +2348,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
// input is hex and converted to binary? convert repl to hex!
- if (afl->cmplog_enable_xtreme_transform && i && (i % 2) && i < 16 &&
+ if (afl->cmplog_enable_xtreme_transform && (i % 2) == 1 && i < 16 &&
fromhex && fromhex + from_slash + from_x + from_0 > i) {
u8 off = 0;
@@ -2344,31 +2384,36 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- if (to_up == 1) {
+ for (u32 hlen = i; hlen <= (i << 1) && hlen + idx < len; hlen += i) {
- for (j = 0; j <= (i >> 1); j++) {
+ if (to_up == 1) {
- tmp[off + (j << 1)] = hex_table_up[repl[j] >> 4];
- tmp[off + (j << 1) + 1] = hex_table_up[repl[j] % 16];
+ for (j = 0; j <= (hlen >> 1); j++) {
- }
+ tmp[off + (j << 1)] = hex_table_up[repl[j] >> 4];
+ tmp[off + (j << 1) + 1] = hex_table_up[repl[j] % 16];
- } else {
+ }
+
+ } else {
+
+ for (j = 0; j <= (hlen >> 1); j++) {
- for (j = 0; j <= (i >> 1); j++) {
+ tmp[off + (j << 1)] = hex_table_low[repl[j] >> 4];
+ tmp[off + (j << 1) + 1] = hex_table_low[repl[j] % 16];
- tmp[off + (j << 1)] = hex_table_low[repl[j] >> 4];
- tmp[off + (j << 1) + 1] = hex_table_low[repl[j] % 16];
+ }
}
- }
+ memcpy(buf + idx, tmp, hlen + 1 + off);
+ if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
+ tmp[hlen + 1 + off] = 0;
+ // fprintf(stderr, "RTN ATTEMPT idx=%u len=%u fromhex %u %s %s result
+ // %u\n", idx, len, fromhex, tmp, repl, *status);
+ memcpy(buf + idx, save, hlen + 1 + off);
- memcpy(buf + idx, tmp, i + 1 + off);
- if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
- // fprintf(stderr, "RTN ATTEMPT fromhex %u result %u\n", fromhex,
- // *status);
- memcpy(buf + idx, save, i + 1 + off);
+ }
}
@@ -2441,7 +2486,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
struct tainted *t;
struct cmp_header *h = &afl->shm.cmp_map->headers[key];
- u32 i, j, idx, have_taint = 1, taint_len, loggeds;
+ u32 i, idx, have_taint = 1, taint_len, loggeds;
u8 status = 0, found_one = 0;
hshape = SHAPE_BYTES(h->shape);
@@ -2464,19 +2509,22 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
struct cmpfn_operands *orig_o =
&((struct cmpfn_operands *)afl->orig_cmp_map->log[key])[i];
- // opt not in the paper
- for (j = 0; j < i; ++j) {
+ /*
+ // opt not in the paper
+ for (j = 0; j < i; ++j) {
- if (!memcmp(&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[j], o,
- sizeof(struct cmpfn_operands))) {
+ if (!memcmp(&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[j],
+ o, sizeof(struct cmpfn_operands))) {
- goto rtn_fuzz_next_iter;
+ goto rtn_fuzz_next_iter;
- }
+ }
- }
+ }
- /*
+ */
+
+#ifdef _DEBUG
struct cmp_header *hh = &afl->orig_cmp_map->headers[key];
fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits, h->id,
hshape, h->attribute);
@@ -2493,7 +2541,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
for (j = 0; j < 8; j++)
fprintf(stderr, "%02x", orig_o->v1[j]);
fprintf(stderr, "\n");
- */
+#endif
t = taint;
while (t->next) {
@@ -2527,7 +2575,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
status = 0;
#ifdef _DEBUG
- int w;
+ u32 w;
fprintf(stderr, "key=%u idx=%u len=%u o0=", key, idx, hshape);
for (w = 0; w < hshape; ++w)
fprintf(stderr, "%02x", orig_o->v0[w]);
--
cgit 1.4.1
From bd1648e707b85b79d816fd8737909789d7d2a09c Mon Sep 17 00:00:00 2001
From: mark0 <757410129@qq.com>
Date: Fri, 28 Jul 2023 17:32:59 +0800
Subject: fix the file descriptor without determining null
---
custom_mutators/aflpp/standalone/aflpp-standalone.c | 1 +
src/afl-showmap.c | 1 +
test/unittests/unit_rand.c | 1 +
3 files changed, 3 insertions(+)
diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c
index 91bac4a8..361feaba 100644
--- a/custom_mutators/aflpp/standalone/aflpp-standalone.c
+++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c
@@ -39,6 +39,7 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
data->afl = calloc(1, sizeof(afl_state_t));
data->afl->queue_cycle = 1;
data->afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
+ if (data->afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
rand_set_seed(data->afl, getpid());
return data;
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index b82bcd72..7a639cf6 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -1611,6 +1611,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (in_dir || in_filelist) {
afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
+ if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
afl->afl_env.afl_custom_mutator_library =
getenv("AFL_CUSTOM_MUTATOR_LIBRARY");
afl->afl_env.afl_python_module = getenv("AFL_PYTHON_MODULE");
diff --git a/test/unittests/unit_rand.c b/test/unittests/unit_rand.c
index 1ad02a80..f89b2ab5 100644
--- a/test/unittests/unit_rand.c
+++ b/test/unittests/unit_rand.c
@@ -67,6 +67,7 @@ static void test_rand_below(void **state) {
rand_set_seed(&afl, 1337);
afl.fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
+ if (afl.fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
assert(!(rand_below(&afl, 9000) > 9000));
assert_int_equal(rand_below(&afl, 1), 0);
--
cgit 1.4.1
From f87ba7ed6324e9d33c2b93da5103344d53218f2c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 28 Jul 2023 15:18:12 +0200
Subject: doc fix
---
docs/env_variables.md | 3 ++-
src/afl-fuzz.c | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 0f0869d2..1f73bbdf 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -585,7 +585,8 @@ checks or alter some of the more exotic semantics of the tool:
Note that this is not a compile time option but a runtime option :-)
- Set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to -1
- to disable although it is 1st of April.
+ to disable although it is 1st of April. 0 is the default and means enable
+ on the 1st of April automatically.
- If you need a specific interval to update fuzzer_stats file, you can
set `AFL_FUZZER_STATS_UPDATE_INTERVAL` to the interval in seconds you'd
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 21a8915c..bacbafc4 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -278,7 +278,8 @@ static void usage(u8 *argv0, int more_help) {
"AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
"AFL_INPUT_LEN_MIN/AFL_INPUT_LEN_MAX: like -g/-G set min/max fuzz length produced\n"
- "AFL_PIZZA_MODE: 1 - enforce pizza mode, 0 - disable for April 1st\n"
+ "AFL_PIZZA_MODE: 1 - enforce pizza mode, -1 - disable for April 1st,\n"
+ " 0 (default) - activate on April 1st\n"
"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc.\n"
" (default: SIGKILL)\n"
"AFL_FORK_SERVER_KILL_SIGNAL: Kill signal for the fork server on termination\n"
--
cgit 1.4.1
From 168ade3b70077ec6a24df9fc594e3b8c1db89bd6 Mon Sep 17 00:00:00 2001
From: mark0 <59284400+mark0-cn@users.noreply.github.com>
Date: Mon, 31 Jul 2023 05:51:24 +0800
Subject: Fix format specifiers (#1818)
* Update afl-mutations.h
Fix bug: compilation cannot pass when DEBUG macro is enabled
* Update afl-fuzz-one.c
Fix bug: compilation cannot pass when DEBUG macro is enabled
---
include/afl-mutations.h | 2 +-
src/afl-fuzz-one.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 0a9bbbf4..5dde4473 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -2456,7 +2456,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
}
char buf[20];
- snprintf(buf, sizeof(buf), "%ld", val);
+ snprintf(buf, sizeof(buf), "%lld", val);
u32 old_len = off2 - off;
u32 new_len = strlen(buf);
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 8ee50bbf..f4ae7bfd 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2995,7 +2995,7 @@ havoc_stage:
// fprintf(stderr, "val: %u-%u = %ld\n", off, off2, val);
char buf[20];
- snprintf(buf, sizeof(buf), "%ld", val);
+ snprintf(buf, sizeof(buf), "%lld", val);
// fprintf(stderr, "BEFORE: %s\n", out_buf);
--
cgit 1.4.1
From d0782a7f03a23f8323772d189e5b66a4eb086afd Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Sun, 30 Jul 2023 21:59:57 +0000
Subject: Various fixes for warnings, extends #1818
---
include/afl-mutations.h | 13 +++++++------
src/afl-fuzz-one.c | 2 +-
src/afl-fuzz-redqueen.c | 2 +-
unicorn_mode/unicornafl | 2 +-
4 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 5dde4473..1806790e 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -25,13 +25,14 @@
u32 max_len - the maximum size the mutated buffer may grow to
*/
-#ifndef _ANDROID_ASHMEM_H
- #define AFL_MUTATIONS_H
+#ifndef AFL_MUTATIONS_H
+#define AFL_MUTATIONS_H
- #include
- #include "afl-fuzz.h"
+#include
+#include
+#include "afl-fuzz.h"
- #define MUT_STRATEGY_ARRAY_SIZE 256
+#define MUT_STRATEGY_ARRAY_SIZE 256
enum {
@@ -2456,7 +2457,7 @@ inline u32 afl_mutate(afl_state_t *afl, u8 *buf, u32 len, u32 steps,
}
char buf[20];
- snprintf(buf, sizeof(buf), "%lld", val);
+ snprintf(buf, sizeof(buf), "%" PRId64, val);
u32 old_len = off2 - off;
u32 new_len = strlen(buf);
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index f4ae7bfd..2ad4697e 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2995,7 +2995,7 @@ havoc_stage:
// fprintf(stderr, "val: %u-%u = %ld\n", off, off2, val);
char buf[20];
- snprintf(buf, sizeof(buf), "%lld", val);
+ snprintf(buf, sizeof(buf), "%" PRId64, val);
// fprintf(stderr, "BEFORE: %s\n", out_buf);
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 8a652a9f..54bf4e32 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -2665,7 +2665,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
- rtn_fuzz_next_iter:
+ // rtn_fuzz_next_iter:
afl->stage_cur++;
}
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index f2cede37..2df75f3e 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit f2cede37a75bbd4a9b9438f0277727b5d4620572
+Subproject commit 2df75f3e1045367cab95fe3471191b38c1a9f79e
--
cgit 1.4.1
From f75c4303654602442987b9a653e5ad3af4974b43 Mon Sep 17 00:00:00 2001
From: Dominik Maier
Date: Sun, 30 Jul 2023 22:02:18 +0000
Subject: Go back to correct unicornafl version
---
unicorn_mode/unicornafl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl
index 2df75f3e..f2cede37 160000
--- a/unicorn_mode/unicornafl
+++ b/unicorn_mode/unicornafl
@@ -1 +1 @@
-Subproject commit 2df75f3e1045367cab95fe3471191b38c1a9f79e
+Subproject commit f2cede37a75bbd4a9b9438f0277727b5d4620572
--
cgit 1.4.1
From 82635dc6569d84899147b2487f19ebe3eaee92b2 Mon Sep 17 00:00:00 2001
From: Jesse Schwartzentruber
Date: Fri, 28 Jul 2023 12:02:05 -0400
Subject: Use CPPFLAGS for C++ too.
---
GNUmakefile.gcc_plugin | 2 +-
GNUmakefile.llvm | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin
index 29d0ed9d..a90b02ea 100644
--- a/GNUmakefile.gcc_plugin
+++ b/GNUmakefile.gcc_plugin
@@ -38,7 +38,7 @@ override CFLAGS += $(CFLAGS_SAFE)
CXXFLAGS ?= -O3 -g -funroll-loops
# -D_FORTIFY_SOURCE=1
-CXXEFLAGS := $(CXXFLAGS) -Wall -std=c++11
+CXXEFLAGS := $(CXXFLAGS) $(CPPFLAGS) -Wall -std=c++11
CC ?= gcc
CXX ?= g++
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index 75fb664b..d8c47ccc 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -300,7 +300,7 @@ endif
ifneq "$(LLVM_CONFIG)" ""
CLANG_CFL += -I$(shell dirname $(LLVM_CONFIG))/../include
endif
-CLANG_CPPFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC $(CXXFLAGS) -Wno-deprecated-declarations
+CLANG_CPPFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC $(CXXFLAGS) $(CPPFLAGS) -Wno-deprecated-declarations
CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
# wasm fuzzing: disable thread-local storage and unset LLVM debug flag
--
cgit 1.4.1
From 1429c9724efb62e5ac90ec27d93a64c28632ba5d Mon Sep 17 00:00:00 2001
From: Junwha
Date: Wed, 2 Aug 2023 02:59:07 +0900
Subject: Add option for treating crashing input as new crash
Signed-off-by: Junwha Hong
---
include/afl-fuzz.h | 3 +-
include/envs.h | 1 +
src/afl-fuzz-init.c | 99 +++++++++++++++++++++++++++++++++++++++++++----------
src/afl-fuzz.c | 3 +-
4 files changed, 86 insertions(+), 20 deletions(-)
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index e114b0fc..7bedc98f 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -539,7 +539,8 @@ typedef struct afl_state {
expand_havoc, /* perform expensive havoc after no find */
cycle_schedules, /* cycle power schedules? */
old_seed_selection, /* use vanilla afl seed selection */
- reinit_table; /* reinit the queue weight table */
+ reinit_table, /* reinit the queue weight table */
+ crashing_seeds_as_new_crash; /* treat crashing seeds as normal corpus */
u8 *virgin_bits, /* Regions yet untouched by fuzzing */
*virgin_tmout, /* Bits we haven't seen in tmouts */
diff --git a/include/envs.h b/include/envs.h
index edfd06e4..e396acd2 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -35,6 +35,7 @@ static char *afl_environment_variables[] = {
"AFL_COMPCOV_BINNAME",
"AFL_COMPCOV_LEVEL",
"AFL_CRASH_EXITCODE",
+ "AFL_CRASHING_SEEDS_AS_NEW_CRASH",
"AFL_CUSTOM_MUTATOR_LIBRARY",
"AFL_CUSTOM_MUTATOR_ONLY",
"AFL_CUSTOM_INFO_PROGRAM",
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 24fd7077..6b7f3036 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1056,6 +1056,13 @@ void perform_dry_run(afl_state_t *afl) {
"skipping",
fn, (int)(s8)afl->fsrv.crash_exitcode);
+ } else if (afl->crashing_seeds_as_new_crash) {
+
+ WARNF(
+ "Test case '%s' results in a crash,"
+ "as AFL_CRASHING_SEEDS_AS_NEW_CRASH is set, "
+ "saving as a crash", fn);
+
} else {
WARNF("Test case '%s' results in a crash, skipping", fn);
@@ -1078,38 +1085,94 @@ void perform_dry_run(afl_state_t *afl) {
}
- q->disabled = 1;
- q->perf_score = 0;
+ /* Crashing corpus will regrad as normal, and categorized as new crash at fuzzing */
+ if (afl->crashing_seeds_as_new_crash) {
+
+ ++afl->total_crashes;
- u32 i = 0;
- while (unlikely(i < afl->queued_items && afl->queue_buf[i] &&
- afl->queue_buf[i]->disabled)) {
+ if (likely(!afl->non_instrumented_mode)) {
- ++i;
+ classify_counts(&afl->fsrv);
+
+ simplify_trace(afl, afl->fsrv.trace_bits);
- }
+ if (!has_new_bits(afl, afl->virgin_crash)) { break; }
+
+ }
+
+
+ if (unlikely(!afl->saved_crashes) &&
+ (afl->afl_env.afl_no_crash_readme != 1)) {
+
+ write_crash_readme(afl);
+
+ }
+
+ u8 crash_fn[PATH_MAX];
+ u8 *use_name = strstr(q->fname, ",orig:");
+
+ afl->stage_name = "dry_run";
+ afl->stage_short = "dry_run";
+
+ #ifndef SIMPLE_FILES
+
+ snprintf(crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s", afl->out_dir,
+ afl->saved_crashes, afl->fsrv.last_kill_signal,
+ describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,") - strlen(use_name)), use_name);
+
+ #else
+
+ snprintf(crash_fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir,
+ afl->saved_crashes, afl->fsrv.last_kill_signal);
+
+ #endif
- if (i < afl->queued_items && afl->queue_buf[i]) {
+ ++afl->saved_crashes;
- afl->queue = afl->queue_buf[i];
+ fd = open(crash_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
+ if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", crash_fn); }
+ ck_write(fd, use_mem, read_len, crash_fn);
+ close(fd);
+
+ afl->last_crash_time = get_cur_time();
+ afl->last_crash_execs = afl->fsrv.total_execs;
} else {
- afl->queue = afl->queue_buf[0];
+ q->disabled = 1;
+ q->perf_score = 0;
- }
+ u32 i = 0;
+ while (unlikely(i < afl->queued_items && afl->queue_buf[i] &&
+ afl->queue_buf[i]->disabled)) {
- afl->max_depth = 0;
- for (i = 0; i < afl->queued_items && likely(afl->queue_buf[i]); i++) {
+ ++i;
- if (!afl->queue_buf[i]->disabled &&
- afl->queue_buf[i]->depth > afl->max_depth)
- afl->max_depth = afl->queue_buf[i]->depth;
+ }
- }
+ if (i < afl->queued_items && afl->queue_buf[i]) {
- break;
+ afl->queue = afl->queue_buf[i];
+
+ } else {
+ afl->queue = afl->queue_buf[0];
+
+ }
+
+ afl->max_depth = 0;
+ for (i = 0; i < afl->queued_items && likely(afl->queue_buf[i]); i++) {
+
+ if (!afl->queue_buf[i]->disabled &&
+ afl->queue_buf[i]->depth > afl->max_depth)
+ afl->max_depth = afl->queue_buf[i]->depth;
+
+ }
+
+ }
+
+ break;
+
case FSRV_RUN_ERROR:
FATAL("Unable to execute target application ('%s')", afl->argv[0]);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index bacbafc4..5cbebb0e 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1573,7 +1573,8 @@ int main(int argc, char **argv_orig, char **envp) {
if (get_afl_env("AFL_NO_ARITH")) { afl->no_arith = 1; }
if (get_afl_env("AFL_SHUFFLE_QUEUE")) { afl->shuffle_queue = 1; }
if (get_afl_env("AFL_EXPAND_HAVOC_NOW")) { afl->expand_havoc = 1; }
-
+ if (get_afl_env("AFL_CRASHING_SEEDS_AS_NEW_CRASH")) { afl->crashing_seeds_as_new_crash = 1; }
+
if (afl->afl_env.afl_autoresume) {
afl->autoresume = 1;
--
cgit 1.4.1
From a61e1ffe4dceb5b4dec3409faf037bea4c05bef9 Mon Sep 17 00:00:00 2001
From: Junwha
Date: Wed, 2 Aug 2023 19:21:41 +0900
Subject: Add AFL_CRASHING_SEEDS_AS_NEW_CRASH to doc
Signed-off-by: Junwha
---
docs/env_variables.md | 3 +++
1 file changed, 3 insertions(+)
diff --git a/docs/env_variables.md b/docs/env_variables.md
index 1f73bbdf..affc9e3c 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -365,6 +365,9 @@ checks or alter some of the more exotic semantics of the tool:
- `AFL_EXIT_ON_SEED_ISSUES` will restore the vanilla afl-fuzz behavior which
does not allow crashes or timeout seeds in the initial -i corpus.
+ - `AFL_CRASHING_SEEDS_AS_NEW_CRASH` will treat crashing seeds as new crash. these
+ crashes will be written to crashes folder as op:dry_run, and orig:.
+
- `AFL_EXIT_ON_TIME` causes afl-fuzz to terminate if no new paths were found
within a specified period of time (in seconds). May be convenient for some
types of automated jobs.
--
cgit 1.4.1
From 641c551ba05bcd602bd351cb705b14cd652e0dda Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Thu, 3 Aug 2023 13:46:54 +0200
Subject: update Nyx submodules
---
nyx_mode/LIBNYX_VERSION | 2 +-
nyx_mode/PACKER_VERSION | 2 +-
nyx_mode/QEMU-Nyx | 2 +-
nyx_mode/QEMU_NYX_VERSION | 2 +-
nyx_mode/libnyx | 2 +-
nyx_mode/packer | 2 +-
6 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/nyx_mode/LIBNYX_VERSION b/nyx_mode/LIBNYX_VERSION
index ed88ec10..a4ffd230 100644
--- a/nyx_mode/LIBNYX_VERSION
+++ b/nyx_mode/LIBNYX_VERSION
@@ -1 +1 @@
-c8a72dc
+8291ef4
diff --git a/nyx_mode/PACKER_VERSION b/nyx_mode/PACKER_VERSION
index 7db88233..cc20a3b6 100644
--- a/nyx_mode/PACKER_VERSION
+++ b/nyx_mode/PACKER_VERSION
@@ -1 +1 @@
-202bace
+bcf3e24
diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx
index 60c216bc..a09d3ae2 160000
--- a/nyx_mode/QEMU-Nyx
+++ b/nyx_mode/QEMU-Nyx
@@ -1 +1 @@
-Subproject commit 60c216bc9e4c79834716d4099993d8397a3a8fd9
+Subproject commit a09d3ae2e66cfe82884a227ea872e48dd2c2ad25
diff --git a/nyx_mode/QEMU_NYX_VERSION b/nyx_mode/QEMU_NYX_VERSION
index 98cb134f..75dcbe83 100644
--- a/nyx_mode/QEMU_NYX_VERSION
+++ b/nyx_mode/QEMU_NYX_VERSION
@@ -1 +1 @@
-60c216bc9e
+a09d3ae2e6
diff --git a/nyx_mode/libnyx b/nyx_mode/libnyx
index 2da7f08b..8291ef4c 160000
--- a/nyx_mode/libnyx
+++ b/nyx_mode/libnyx
@@ -1 +1 @@
-Subproject commit 2da7f08b6e0267ccfe64e1320b24cdb29223459c
+Subproject commit 8291ef4cb4f1d4bfe3026fe198167fd5c98e3a15
diff --git a/nyx_mode/packer b/nyx_mode/packer
index 202bace8..bcf3e248 160000
--- a/nyx_mode/packer
+++ b/nyx_mode/packer
@@ -1 +1 @@
-Subproject commit 202bace888d237e4e8f4507d0eba6791a811554d
+Subproject commit bcf3e248b660764f48af54232a3388389a2dfc22
--
cgit 1.4.1
From 8f31086a7fa1d7ef9d4dc416f238a10dd140e2d3 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Thu, 3 Aug 2023 14:40:10 +0200
Subject: make nyx aux buffer size configurable
---
include/envs.h | 1 +
include/forkserver.h | 1 +
src/afl-forkserver.c | 10 ++++++++++
src/afl-fuzz.c | 3 +++
4 files changed, 15 insertions(+)
diff --git a/include/envs.h b/include/envs.h
index edfd06e4..0ef331ae 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -189,6 +189,7 @@ static char *afl_environment_variables[] = {
"AFL_MAX_DET_EXTRAS",
"AFL_NO_X86", // not really an env but we dont want to warn on it
"AFL_NOOPT",
+ "AFL_NYX_AUX_SIZE",
"AFL_PASSTHROUGH",
"AFL_PATH",
"AFL_PERFORMANCE_FILE",
diff --git a/include/forkserver.h b/include/forkserver.h
index f5069ce2..c93c6f61 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -86,6 +86,7 @@ typedef struct {
uint32_t size);
bool (*nyx_remove_work_dir)(const char *workdir);
+ bool (*nyx_config_set_aux_buffer_size)(void *config, uint32_t aux_buffer_size);
} nyx_plugin_handler_t;
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index ba7cdd66..957cb2b7 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -129,6 +129,9 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) {
plugin->nyx_remove_work_dir = dlsym(handle, "nyx_remove_work_dir");
if (plugin->nyx_remove_work_dir == NULL) { goto fail; }
+ plugin->nyx_config_set_aux_buffer_size = dlsym(handle, "nyx_config_set_aux_buffer_size");
+ if (plugin->nyx_config_set_aux_buffer_size == NULL) { goto fail; }
+
OKF("libnyx plugin is ready!");
return plugin;
@@ -589,6 +592,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
+ if (getenv("AFL_NYX_AUX_SIZE") != NULL) {
+ if(fsrv->nyx_handlers->nyx_config_set_aux_buffer_size(
+ nyx_config, atoi(getenv("AFL_NYX_AUX_SIZE"))) != 1) {
+ NYX_PRE_FATAL(fsrv, "Invalid AFL_NYX_AUX_SIZE value set (must be a multiple of 4096) ...");
+ }
+ }
+
if (getenv("NYX_REUSE_SNAPSHOT") != NULL) {
if (access(getenv("NYX_REUSE_SNAPSHOT"), F_OK) == -1) {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index bacbafc4..9504d908 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -299,6 +299,9 @@ static void usage(u8 *argv0, int more_help) {
"AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n"
"AFL_NO_STARTUP_CALIBRATION: no initial seed calibration, start fuzzing at once\n"
"AFL_NO_UI: switch status screen off\n"
+ "AFL_NYX_AUX_SIZE: size of the Nyx auxiliary buffer. Must be a multiple of 4096.\n"
+ " Increase this value in case the crash reports are truncated.\n"
+ " Default value is 4096.\n"
DYN_COLOR
--
cgit 1.4.1
From 5d78a6f592fff853ff722f2722a6576b0f565abd Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Thu, 3 Aug 2023 14:43:16 +0200
Subject: update nyx mode readme (NYX_AUX_BUFFER_SIZE)
---
nyx_mode/README.md | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/nyx_mode/README.md b/nyx_mode/README.md
index eee7d363..605bc103 100644
--- a/nyx_mode/README.md
+++ b/nyx_mode/README.md
@@ -313,6 +313,27 @@ command:
If you want to disable fast snapshots (except for crashes), you can simply set
the `NYX_DISABLE_SNAPSHOT_MODE` environment variable.
+### Nyx crash reports
+
+If the Nyx agent detects a crash in the target application, it can pass
+additional information on that crash to AFL++ (assuming that the agent
+implements this feature). For each saved crashing input AFL++ will also create
+an additional file in the `crashes` directory with a `.log` file extension.
+Crash reports generated by the default agent shipped with the Nyx packer will
+contain information such as the faulting address and signal number.
+Additionally, if the target is compiled with AddressSanitizer, the crash report
+will also contain the entire ASan report.
+
+From a technical perspective, the crash report is passed from QEMU-Nyx to AFL++
+via a shared memory region called Nyx Auxiliary Buffer which is by default 4096
+bytes in size. In this shared memory region a specific amount is reserved for
+the header (1408 bytes) and the remaining bytes can be used to transfer crash
+reports (also the `hprintf` feature utilizes the very same shared memory for
+transferring data). By default a crash report will be truncated to 2688 bytes.
+However, if you want to increase the size of the shared memory region, you can
+set the `NYX_AUX_BUFFER_SIZE` environment variable to a higher value (keep in
+mind that this value must be a multiple of 4096).
+
### Run AFL++Nyx with a custom agent
Most of the common use-cases for linux userland targets are already handled by
--
cgit 1.4.1
From 79640acbf1ffff9677ec9094b61ac4a158b1551c Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 4 Aug 2023 09:25:19 +0200
Subject: nits
---
include/afl-mutations.h | 8 ++++----
include/forkserver.h | 3 ++-
src/afl-forkserver.c | 17 ++++++++++++-----
src/afl-fuzz-redqueen.c | 2 +-
src/afl-fuzz.c | 15 +++++++--------
5 files changed, 26 insertions(+), 19 deletions(-)
diff --git a/include/afl-mutations.h b/include/afl-mutations.h
index 1806790e..98ba6fcf 100644
--- a/include/afl-mutations.h
+++ b/include/afl-mutations.h
@@ -78,7 +78,7 @@ enum {
};
- #define MUT_TXT_ARRAY_SIZE 200
+#define MUT_TXT_ARRAY_SIZE 200
u32 text_array[MUT_TXT_ARRAY_SIZE] = {MUT_FLIPBIT,
MUT_FLIPBIT,
MUT_FLIPBIT,
@@ -280,7 +280,7 @@ u32 text_array[MUT_TXT_ARRAY_SIZE] = {MUT_FLIPBIT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT};
- #define MUT_BIN_ARRAY_SIZE 256
+#define MUT_BIN_ARRAY_SIZE 256
u32 binary_array[MUT_BIN_ARRAY_SIZE] = {MUT_FLIPBIT,
MUT_FLIPBIT,
MUT_FLIPBIT,
@@ -538,7 +538,7 @@ u32 binary_array[MUT_BIN_ARRAY_SIZE] = {MUT_FLIPBIT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT};
- #define MUT_NORMAL_ARRAY_SIZE 77
+#define MUT_NORMAL_ARRAY_SIZE 77
u32 normal_splice_array[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT,
MUT_FLIPBIT,
MUT_FLIPBIT,
@@ -617,7 +617,7 @@ u32 normal_splice_array[MUT_NORMAL_ARRAY_SIZE] = {MUT_FLIPBIT,
MUT_SPLICE_INSERT,
MUT_SPLICE_INSERT};
- #define MUT_SPLICE_ARRAY_SIZE 81
+#define MUT_SPLICE_ARRAY_SIZE 81
u32 full_splice_array[MUT_SPLICE_ARRAY_SIZE] = {MUT_FLIPBIT,
MUT_FLIPBIT,
MUT_FLIPBIT,
diff --git a/include/forkserver.h b/include/forkserver.h
index c93c6f61..1d41d83d 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -86,7 +86,8 @@ typedef struct {
uint32_t size);
bool (*nyx_remove_work_dir)(const char *workdir);
- bool (*nyx_config_set_aux_buffer_size)(void *config, uint32_t aux_buffer_size);
+ bool (*nyx_config_set_aux_buffer_size)(void *config,
+ uint32_t aux_buffer_size);
} nyx_plugin_handler_t;
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 957cb2b7..e90ea460 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -129,7 +129,8 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) {
plugin->nyx_remove_work_dir = dlsym(handle, "nyx_remove_work_dir");
if (plugin->nyx_remove_work_dir == NULL) { goto fail; }
- plugin->nyx_config_set_aux_buffer_size = dlsym(handle, "nyx_config_set_aux_buffer_size");
+ plugin->nyx_config_set_aux_buffer_size =
+ dlsym(handle, "nyx_config_set_aux_buffer_size");
if (plugin->nyx_config_set_aux_buffer_size == NULL) { goto fail; }
OKF("libnyx plugin is ready!");
@@ -593,10 +594,16 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
if (getenv("AFL_NYX_AUX_SIZE") != NULL) {
- if(fsrv->nyx_handlers->nyx_config_set_aux_buffer_size(
- nyx_config, atoi(getenv("AFL_NYX_AUX_SIZE"))) != 1) {
- NYX_PRE_FATAL(fsrv, "Invalid AFL_NYX_AUX_SIZE value set (must be a multiple of 4096) ...");
- }
+
+ if (fsrv->nyx_handlers->nyx_config_set_aux_buffer_size(
+ nyx_config, atoi(getenv("AFL_NYX_AUX_SIZE"))) != 1) {
+
+ NYX_PRE_FATAL(fsrv,
+ "Invalid AFL_NYX_AUX_SIZE value set (must be a multiple "
+ "of 4096) ...");
+
+ }
+
}
if (getenv("NYX_REUSE_SNAPSHOT") != NULL) {
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 54bf4e32..ca5104c0 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -2665,7 +2665,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
- // rtn_fuzz_next_iter:
+ // rtn_fuzz_next_iter:
afl->stage_cur++;
}
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 9504d908..29659013 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -311,8 +311,8 @@ static void usage(u8 *argv0, int more_help) {
PERSISTENT_MSG
- "AFL_POST_PROCESS_KEEP_ORIGINAL: save the file as it was prior post-processing to the queue,\n"
- " but execute the post-processed one\n"
+ "AFL_POST_PROCESS_KEEP_ORIGINAL: save the file as it was prior post-processing to\n"
+ " the queue, but execute the post-processed one\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
"AFL_TARGET_ENV: pass extra environment variables to target\n"
"AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
@@ -323,18 +323,17 @@ static void usage(u8 *argv0, int more_help) {
"AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)\n"
"AFL_STATSD_PORT: change default statsd port (default: 8125)\n"
"AFL_STATSD_TAGS_FLAVOR: set statsd tags format (default: disable tags)\n"
- " Supported formats are: 'dogstatsd', 'librato',\n"
- " 'signalfx' and 'influxdb'\n"
+ " suported formats: dogstatsd, librato, signalfx, influxdb\n"
"AFL_SYNC_TIME: sync time between fuzzing instances (in minutes)\n"
"AFL_NO_CRASH_README: do not create a README in the crashes directory\n"
"AFL_TESTCACHE_SIZE: use a cache for testcases, improves performance (in MB)\n"
"AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n"
"AFL_EARLY_FORKSERVER: force an early forkserver in an afl-clang-fast/\n"
" afl-clang-lto/afl-gcc-fast target\n"
- "AFL_PERSISTENT: enforce persistent mode (if __AFL_LOOP is in a shared lib\n"
- "AFL_DEFER_FORKSRV: enforced deferred forkserver (__AFL_INIT is in a .so)\n"
- "AFL_FUZZER_STATS_UPDATE_INTERVAL: interval to update fuzzer_stats file in seconds, "
- "(default: 60, minimum: 1)\n"
+ "AFL_PERSISTENT: enforce persistent mode (if __AFL_LOOP is in a shared lib)\n"
+ "AFL_DEFER_FORKSRV: enforced deferred forkserver (__AFL_INIT is in a shared lib)\n"
+ "AFL_FUZZER_STATS_UPDATE_INTERVAL: interval to update fuzzer_stats file in\n"
+ " seconds (default: 60, minimum: 1)\n"
"\n"
);
--
cgit 1.4.1
From 0a28bce0167416aa5dbe9d23c242f4ec43e79b75 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Fri, 4 Aug 2023 09:45:11 +0200
Subject: update docs
---
docs/afl-fuzz_approach.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/docs/afl-fuzz_approach.md b/docs/afl-fuzz_approach.md
index cb173f10..7d18b178 100644
--- a/docs/afl-fuzz_approach.md
+++ b/docs/afl-fuzz_approach.md
@@ -419,8 +419,8 @@ the process. Be sure to consult this file especially if any UI elements are
highlighted in red.
The fuzzing process will continue until you press Ctrl-C. At a minimum, you want
-to allow the fuzzer to complete one queue cycle, which may take anywhere from a
-couple of hours to a week or so.
+to allow the fuzzer to at least one queue cycle without any new finds, which may
+take anywhere from a couple of hours to a week or so.
There are three subdirectories created within the output directory and updated
in real-time:
--
cgit 1.4.1
From fcdfe9e990d84ab477cd3c571cbf540e8bc8e15a Mon Sep 17 00:00:00 2001
From: Junwha
Date: Fri, 4 Aug 2023 18:36:58 +0900
Subject: Define AFL_CRASHING_SEEDS_AS_NEW_CRASH as env variable
- and fix typo
Signed-off-by: Junwha
---
include/afl-fuzz.h | 6 +++---
src/afl-fuzz-init.c | 30 ++++++++++++++++--------------
src/afl-fuzz-state.c | 7 +++++++
src/afl-fuzz.c | 1 -
4 files changed, 26 insertions(+), 18 deletions(-)
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 7bedc98f..18352acb 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -1,3 +1,4 @@
+
/*
american fuzzy lop++ - fuzzer header
------------------------------------
@@ -408,7 +409,7 @@ typedef struct afl_env_vars {
*afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
*afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
*afl_testcache_entries, *afl_child_kill_signal, *afl_fsrv_kill_signal,
- *afl_target_env, *afl_persistent_record, *afl_exit_on_time;
+ *afl_target_env, *afl_persistent_record, *afl_exit_on_time, *afl_crashing_seeds_as_new_crash;
s32 afl_pizza_mode;
@@ -539,8 +540,7 @@ typedef struct afl_state {
expand_havoc, /* perform expensive havoc after no find */
cycle_schedules, /* cycle power schedules? */
old_seed_selection, /* use vanilla afl seed selection */
- reinit_table, /* reinit the queue weight table */
- crashing_seeds_as_new_crash; /* treat crashing seeds as normal corpus */
+ reinit_table; /* reinit the queue weight table */
u8 *virgin_bits, /* Regions yet untouched by fuzzing */
*virgin_tmout, /* Bits we haven't seen in tmouts */
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 6b7f3036..d994d749 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1056,17 +1056,19 @@ void perform_dry_run(afl_state_t *afl) {
"skipping",
fn, (int)(s8)afl->fsrv.crash_exitcode);
- } else if (afl->crashing_seeds_as_new_crash) {
-
- WARNF(
- "Test case '%s' results in a crash,"
- "as AFL_CRASHING_SEEDS_AS_NEW_CRASH is set, "
- "saving as a crash", fn);
-
} else {
+ if (afl->afl_env.afl_crashing_seeds_as_new_crash) {
+
+ WARNF(
+ "Test case '%s' results in a crash, "
+ "as AFL_CRASHING_SEEDS_AS_NEW_CRASH is set, "
+ "saving as a new crash", fn);
+
+ } else {
- WARNF("Test case '%s' results in a crash, skipping", fn);
-
+ WARNF("Test case '%s' results in a crash, skipping", fn);
+
+ }
}
if (afl->afl_env.afl_exit_on_seed_issues) {
@@ -1085,8 +1087,8 @@ void perform_dry_run(afl_state_t *afl) {
}
- /* Crashing corpus will regrad as normal, and categorized as new crash at fuzzing */
- if (afl->crashing_seeds_as_new_crash) {
+ /* Crashing seeds will be regarded as new crashes on startup */
+ if (afl->afl_env.afl_crashing_seeds_as_new_crash) {
++afl->total_crashes;
@@ -1139,9 +1141,6 @@ void perform_dry_run(afl_state_t *afl) {
} else {
- q->disabled = 1;
- q->perf_score = 0;
-
u32 i = 0;
while (unlikely(i < afl->queued_items && afl->queue_buf[i] &&
afl->queue_buf[i]->disabled)) {
@@ -1171,6 +1170,9 @@ void perform_dry_run(afl_state_t *afl) {
}
+ q->disabled = 1;
+ q->perf_score = 0;
+
break;
case FSRV_RUN_ERROR:
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 99f69314..5a6b95cf 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -200,6 +200,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
afl->afl_env.afl_exit_on_time =
(u8 *)get_afl_env(afl_environment_variables[i]);
+ } else if (!strncmp(env, "AFL_CRASHING_SEEDS_AS_NEW_CRASH",
+
+ afl_environment_variable_len)) {
+
+ afl->afl_env.afl_crashing_seeds_as_new_crash =
+ atoi((u8 *)get_afl_env(afl_environment_variables[i]));
+
} else if (!strncmp(env, "AFL_NO_AFFINITY",
afl_environment_variable_len)) {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 5cbebb0e..51ca4ee6 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1573,7 +1573,6 @@ int main(int argc, char **argv_orig, char **envp) {
if (get_afl_env("AFL_NO_ARITH")) { afl->no_arith = 1; }
if (get_afl_env("AFL_SHUFFLE_QUEUE")) { afl->shuffle_queue = 1; }
if (get_afl_env("AFL_EXPAND_HAVOC_NOW")) { afl->expand_havoc = 1; }
- if (get_afl_env("AFL_CRASHING_SEEDS_AS_NEW_CRASH")) { afl->crashing_seeds_as_new_crash = 1; }
if (afl->afl_env.afl_autoresume) {
--
cgit 1.4.1
From 4f3aa90a5f2b8bb53f2e1de964d54ec7f9be0578 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 4 Aug 2023 11:52:39 +0200
Subject: update QEMU-Nyx submodule
---
nyx_mode/QEMU-Nyx | 2 +-
nyx_mode/QEMU_NYX_VERSION | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx
index a09d3ae2..874fa033 160000
--- a/nyx_mode/QEMU-Nyx
+++ b/nyx_mode/QEMU-Nyx
@@ -1 +1 @@
-Subproject commit a09d3ae2e66cfe82884a227ea872e48dd2c2ad25
+Subproject commit 874fa033d117a3e9931245cb9e82836a4abc0425
diff --git a/nyx_mode/QEMU_NYX_VERSION b/nyx_mode/QEMU_NYX_VERSION
index 75dcbe83..d0a435a4 100644
--- a/nyx_mode/QEMU_NYX_VERSION
+++ b/nyx_mode/QEMU_NYX_VERSION
@@ -1 +1 @@
-a09d3ae2e6
+874fa033d1
--
cgit 1.4.1
From 1fd1f0d8ce0db7e5ccee4462c85c264dcfca328d Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 4 Aug 2023 11:54:58 +0200
Subject: fix typo in nyx_mode/README.md
---
nyx_mode/README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/nyx_mode/README.md b/nyx_mode/README.md
index 605bc103..0565331b 100644
--- a/nyx_mode/README.md
+++ b/nyx_mode/README.md
@@ -331,7 +331,7 @@ the header (1408 bytes) and the remaining bytes can be used to transfer crash
reports (also the `hprintf` feature utilizes the very same shared memory for
transferring data). By default a crash report will be truncated to 2688 bytes.
However, if you want to increase the size of the shared memory region, you can
-set the `NYX_AUX_BUFFER_SIZE` environment variable to a higher value (keep in
+set the `AFL_NYX_AUX_SIZE` environment variable to a higher value (keep in
mind that this value must be a multiple of 4096).
### Run AFL++Nyx with a custom agent
--
cgit 1.4.1
From 08a6fd7c29489f5477f50b94d7a0e425f64fef34 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 4 Aug 2023 12:13:06 +0200
Subject: update the old nyx env var naming scheme (to have a more consistent
naming overall)
---
include/envs.h | 2 ++
nyx_mode/README.md | 6 +++---
src/afl-forkserver.c | 27 ++++++++++++++-------------
src/afl-fuzz.c | 3 ++-
4 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/include/envs.h b/include/envs.h
index 0ef331ae..ff303387 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -190,6 +190,8 @@ static char *afl_environment_variables[] = {
"AFL_NO_X86", // not really an env but we dont want to warn on it
"AFL_NOOPT",
"AFL_NYX_AUX_SIZE",
+ "AFL_NYX_DISABLE_SNAPSHOT_MODE",
+ "AFL_NYX_REUSE_SNAPSHOT",
"AFL_PASSTHROUGH",
"AFL_PATH",
"AFL_PERFORMANCE_FILE",
diff --git a/nyx_mode/README.md b/nyx_mode/README.md
index 0565331b..aee9879e 100644
--- a/nyx_mode/README.md
+++ b/nyx_mode/README.md
@@ -150,12 +150,12 @@ afl-cmin -i in_dir -o out_dir -X -- ./PACKAGE-DIRECTORY
On each program startup of one the AFL++ tools in Nyx mode, a Nyx VM is spawned, and a bootstrapping procedure is performed inside the VM to prepare the target environment. As a consequence, due to the bootstrapping procedure, the launch performance is much slower compared to other modes. However, this can be optimized by reusing an existing fuzzing snapshot to avoid the slow re-execution of the bootstrap procedure.
-A fuzzing snapshot is automatically created and stored in the output directory at `out_dir/workdir/snapshot/` by the first parent process of `afl-fuzz` if parallel mode is used. To enable this feature, set the path to an existing snapshot directory in the `NYX_REUSE_SNAPSHOT` environment variable and use the tools as usual:
+A fuzzing snapshot is automatically created and stored in the output directory at `out_dir/workdir/snapshot/` by the first parent process of `afl-fuzz` if parallel mode is used. To enable this feature, set the path to an existing snapshot directory in the `AFL_NYX_REUSE_SNAPSHOT` environment variable and use the tools as usual:
```shell
afl-fuzz -i ./in_dir -o ./out_dir -Y -M 0 ./PACKAGE-DIRECTORY
-NYX_REUSE_SNAPSHOT=./out_dir/workdir/snapshot/ afl-analyze -i in_file -X -- ./PACKAGE-DIRECTORY
+AFL_NYX_REUSE_SNAPSHOT=./out_dir/workdir/snapshot/ afl-analyze -i in_file -X -- ./PACKAGE-DIRECTORY
```
@@ -311,7 +311,7 @@ command:
```
If you want to disable fast snapshots (except for crashes), you can simply set
-the `NYX_DISABLE_SNAPSHOT_MODE` environment variable.
+the `AFL_NYX_DISABLE_SNAPSHOT_MODE` environment variable.
### Nyx crash reports
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index e90ea460..717898d1 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -606,23 +606,23 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
- if (getenv("NYX_REUSE_SNAPSHOT") != NULL) {
+ if (getenv("AFL_NYX_REUSE_SNAPSHOT") != NULL) {
- if (access(getenv("NYX_REUSE_SNAPSHOT"), F_OK) == -1) {
+ if (access(getenv("AFL_NYX_REUSE_SNAPSHOT"), F_OK) == -1) {
- NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path does not exist");
+ NYX_PRE_FATAL(fsrv, "AFL_NYX_REUSE_SNAPSHOT path does not exist");
}
/* stupid sanity check to avoid passing an empty or invalid snapshot
* directory */
char *snapshot_file_path =
- alloc_printf("%s/global.state", getenv("NYX_REUSE_SNAPSHOT"));
+ alloc_printf("%s/global.state", getenv("AFL_NYX_REUSE_SNAPSHOT"));
if (access(snapshot_file_path, R_OK) == -1) {
- NYX_PRE_FATAL(
- fsrv,
- "NYX_REUSE_SNAPSHOT path does not contain a valid Nyx snapshot");
+ NYX_PRE_FATAL(fsrv,
+ "AFL_NYX_REUSE_SNAPSHOT path does not contain a valid "
+ "Nyx snapshot");
}
@@ -634,13 +634,14 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
char *workdir_snapshot_path =
alloc_printf("%s/workdir/snapshot", outdir_path_absolute);
char *reuse_snapshot_path_real =
- realpath(getenv("NYX_REUSE_SNAPSHOT"), NULL);
+ realpath(getenv("AFL_NYX_REUSE_SNAPSHOT"), NULL);
if (strcmp(workdir_snapshot_path, reuse_snapshot_path_real) == 0) {
- NYX_PRE_FATAL(fsrv,
- "NYX_REUSE_SNAPSHOT path is located in current workdir "
- "(use another output directory)");
+ NYX_PRE_FATAL(
+ fsrv,
+ "AFL_NYX_REUSE_SNAPSHOT path is located in current workdir "
+ "(use another output directory)");
}
@@ -648,7 +649,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
ck_free(workdir_snapshot_path);
fsrv->nyx_handlers->nyx_config_set_reuse_snapshot_path(
- nyx_config, getenv("NYX_REUSE_SNAPSHOT"));
+ nyx_config, getenv("AFL_NYX_REUSE_SNAPSHOT"));
}
@@ -670,7 +671,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
fsrv->nyx_handlers->nyx_get_bitmap_buffer(fsrv->nyx_runner);
fsrv->nyx_handlers->nyx_option_set_reload_mode(
- fsrv->nyx_runner, getenv("NYX_DISABLE_SNAPSHOT_MODE") == NULL);
+ fsrv->nyx_runner, getenv("AFL_NYX_DISABLE_SNAPSHOT_MODE") == NULL);
fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, 2, 0);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 29659013..3d7adf41 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -302,7 +302,8 @@ static void usage(u8 *argv0, int more_help) {
"AFL_NYX_AUX_SIZE: size of the Nyx auxiliary buffer. Must be a multiple of 4096.\n"
" Increase this value in case the crash reports are truncated.\n"
" Default value is 4096.\n"
-
+ "AFL_NYX_DISABLE_SNAPSHOT_MODE: disable snapshot mode (must be supported by the agent)\n"
+ "AFL_NYX_REUSE_SNAPSHOT: reuse an existing Nyx root snapshot\n"
DYN_COLOR
"AFL_PATH: path to AFL support binaries\n"
--
cgit 1.4.1
From c2a0a245940f71c466a776d1217adac3f8b25373 Mon Sep 17 00:00:00 2001
From: Sergej Schumilo
Date: Fri, 4 Aug 2023 12:20:44 +0200
Subject: add someone else to the "list of contributors" :-)
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 42fcaa0d..b73cf2c1 100644
--- a/README.md
+++ b/README.md
@@ -229,7 +229,7 @@ Thank you! (For people sending pull requests - please add yourself to this list
Thomas Rooijakkers David Carlier
Ruben ten Hove Joey Jiao
fuzzah @intrigus-lgtm
- Yaakov Saxon
+ Yaakov Saxon Sergej Schumilo
```
--
cgit 1.4.1
From 247d8539feb0dee3eab80586ee4e32292dc7ca78 Mon Sep 17 00:00:00 2001
From: Jesse Schwartzentruber
Date: Fri, 4 Aug 2023 15:29:10 -0400
Subject: Add AFL_NYX_LOG to redirect NYX hprintf messages to a file.
---
include/envs.h | 1 +
include/forkserver.h | 1 +
src/afl-forkserver.c | 19 +++++++++++++++++++
src/afl-fuzz.c | 1 +
4 files changed, 22 insertions(+)
diff --git a/include/envs.h b/include/envs.h
index ff303387..963e1367 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -191,6 +191,7 @@ static char *afl_environment_variables[] = {
"AFL_NOOPT",
"AFL_NYX_AUX_SIZE",
"AFL_NYX_DISABLE_SNAPSHOT_MODE",
+ "AFL_NYX_LOG",
"AFL_NYX_REUSE_SNAPSHOT",
"AFL_PASSTHROUGH",
"AFL_PATH",
diff --git a/include/forkserver.h b/include/forkserver.h
index 1d41d83d..5e498c56 100644
--- a/include/forkserver.h
+++ b/include/forkserver.h
@@ -199,6 +199,7 @@ typedef struct afl_forkserver {
char *nyx_aux_string;
bool nyx_use_tmp_workdir;
char *nyx_tmp_workdir_path;
+ s32 nyx_log_fd;
#endif
} afl_forkserver_t;
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index 717898d1..9da096f7 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -164,6 +164,8 @@ void afl_nyx_runner_kill(afl_forkserver_t *fsrv) {
}
+ if (fsrv->nyx_log_fd >= 0) { close(fsrv->nyx_log_fd); }
+
}
}
@@ -218,6 +220,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
fsrv->nyx_bind_cpu_id = 0xFFFFFFFF;
fsrv->nyx_use_tmp_workdir = false;
fsrv->nyx_tmp_workdir_path = NULL;
+ fsrv->nyx_log_fd = -1;
#endif
// this structure needs default so we initialize it if this was not done
@@ -575,6 +578,22 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config,
true);
+ char *nyx_log_path = getenv("AFL_NYX_LOG");
+ if (nyx_log_path) {
+
+ fsrv->nyx_log_fd =
+ open(nyx_log_path, O_CREAT | O_TRUNC | O_WRONLY, DEFAULT_PERMISSION);
+ if (fsrv->nyx_log_fd < 0) {
+
+ NYX_PRE_FATAL(fsrv, "AFL_NYX_LOG path could not be written");
+
+ }
+
+ fsrv->nyx_handlers->nyx_config_set_hprintf_fd(nyx_config,
+ fsrv->nyx_log_fd);
+
+ }
+
if (fsrv->nyx_standalone) {
fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, StandAlone);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 3d7adf41..e1f93f0d 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -303,6 +303,7 @@ static void usage(u8 *argv0, int more_help) {
" Increase this value in case the crash reports are truncated.\n"
" Default value is 4096.\n"
"AFL_NYX_DISABLE_SNAPSHOT_MODE: disable snapshot mode (must be supported by the agent)\n"
+ "AFL_NYX_LOG: output NYX hprintf messages to another file\n"
"AFL_NYX_REUSE_SNAPSHOT: reuse an existing Nyx root snapshot\n"
DYN_COLOR
--
cgit 1.4.1
From 5b55cf84c14cab3c37d659874c02332cbffb7242 Mon Sep 17 00:00:00 2001
From: David Carlier
Date: Sat, 5 Aug 2023 14:21:56 +0100
Subject: disable exceptions on LLVM/GCC plugins, decreasing further the
libraries's binaries size in the process.
---
GNUmakefile.gcc_plugin | 2 +-
GNUmakefile.llvm | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin
index a90b02ea..16c98399 100644
--- a/GNUmakefile.gcc_plugin
+++ b/GNUmakefile.gcc_plugin
@@ -61,7 +61,7 @@ ifeq "$(findstring Foundation,$(shell $(CC) --version))" ""
endif
PLUGIN_BASE = "$(shell $(CC) -print-file-name=plugin)"
-PLUGIN_FLAGS = -fPIC -fno-rtti -I$(PLUGIN_BASE)/include -I$(PLUGIN_BASE)
+PLUGIN_FLAGS = -fPIC -fno-rtti -fno-exceptions -I$(PLUGIN_BASE)/include -I$(PLUGIN_BASE)
HASH=\#
GCCVER = $(shell $(CC) --version 2>/dev/null | awk 'NR == 1 {print $$NF}')
diff --git a/GNUmakefile.llvm b/GNUmakefile.llvm
index d8c47ccc..65786d8b 100644
--- a/GNUmakefile.llvm
+++ b/GNUmakefile.llvm
@@ -300,7 +300,7 @@ endif
ifneq "$(LLVM_CONFIG)" ""
CLANG_CFL += -I$(shell dirname $(LLVM_CONFIG))/../include
endif
-CLANG_CPPFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fPIC $(CXXFLAGS) $(CPPFLAGS) -Wno-deprecated-declarations
+CLANG_CPPFL = `$(LLVM_CONFIG) --cxxflags` -fno-rtti -fno-exceptions -fPIC $(CXXFLAGS) $(CPPFLAGS) -Wno-deprecated-declarations
CLANG_LFL = `$(LLVM_CONFIG) --ldflags` $(LDFLAGS)
# wasm fuzzing: disable thread-local storage and unset LLVM debug flag
--
cgit 1.4.1
From 2c376f899456f3c9ecd010832e5be87c59e8c947 Mon Sep 17 00:00:00 2001
From: David CARLIER
Date: Tue, 8 Aug 2023 21:24:05 +0100
Subject: afl-fuzz-redqueen.c fix build, also forgotten math lib for ilog*
calls
---
GNUmakefile | 6 +++---
src/afl-fuzz-redqueen.c | 1 +
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/GNUmakefile b/GNUmakefile
index f6b76a6c..88816e85 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -255,17 +255,17 @@ endif
ifneq "$(findstring FreeBSD, $(SYS))" ""
override CFLAGS += -pthread
- override LDFLAGS += -lpthread
+ override LDFLAGS += -lpthread -lm
endif
ifneq "$(findstring NetBSD, $(SYS))" ""
override CFLAGS += -pthread
- override LDFLAGS += -lpthread
+ override LDFLAGS += -lpthread -lm
endif
ifneq "$(findstring OpenBSD, $(SYS))" ""
override CFLAGS += -pthread
- override LDFLAGS += -lpthread
+ override LDFLAGS += -lpthread -lm
endif
COMM_HDR = include/alloc-inl.h include/config.h include/debug.h include/types.h
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index ca5104c0..509f66a3 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -2525,6 +2525,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
*/
#ifdef _DEBUG
+ u32 j;
struct cmp_header *hh = &afl->orig_cmp_map->headers[key];
fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits, h->id,
hshape, h->attribute);
--
cgit 1.4.1
From 5618062cb55f1ac094e33ad662a03df45e048f45 Mon Sep 17 00:00:00 2001
From: marc
Date: Wed, 9 Aug 2023 16:28:04 +0200
Subject: -c - support
---
docs/Changelog.md | 2 ++
src/afl-fuzz.c | 25 ++++++++++++++++++++-----
2 files changed, 22 insertions(+), 5 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index d61ce8ec..d45b49fe 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -15,6 +15,8 @@
command line tool! See custom_mutators/aflpp/standalone/
- display the state of the fuzzing run in the UI :-)
- fix timeout setting if '+' is used or a session is restarted
+ - allow to disable CMPLOG with '-c -' (e.g. afl.rs enforces '-c 0' on
+ every instance which is counterproductive.
- afl-cmin/afl-cmin.bash:
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 9afece66..e0e54b49 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -180,7 +180,8 @@ static void usage(u8 *argv0, int more_help) {
"it.\n"
" if using QEMU/FRIDA or the fuzzing target is "
"compiled\n"
- " for CmpLog then just use -c 0.\n"
+ " for CmpLog then use '-c 0'. To disable Cmplog use '-c "
+ "-'.\n"
" -l cmplog_opts - CmpLog configuration values (e.g. \"2ATR\"):\n"
" 1=small files, 2=larger files (default), 3=all "
"files,\n"
@@ -594,8 +595,23 @@ int main(int argc, char **argv_orig, char **envp) {
case 'c': {
- afl->shm.cmplog_mode = 1;
- afl->cmplog_binary = ck_strdup(optarg);
+ if (strcmp(optarg, "-") == 0) {
+
+ if (afl->shm.cmplog_mode) {
+
+ ACTF("Disabling cmplog again because of '-c -'.");
+ afl->shm.cmplog_mode = 0;
+ afl->cmplog_binary = NULL;
+
+ }
+
+ } else {
+
+ afl->shm.cmplog_mode = 1;
+ afl->cmplog_binary = ck_strdup(optarg);
+
+ }
+
break;
}
@@ -1500,8 +1516,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (!afl->use_banner) { afl->use_banner = argv[optind]; }
- if (afl->shm.cmplog_mode &&
- (!strcmp("-", afl->cmplog_binary) || !strcmp("0", afl->cmplog_binary))) {
+ if (afl->shm.cmplog_mode && strcmp("0", afl->cmplog_binary) == 0) {
afl->cmplog_binary = strdup(argv[optind]);
--
cgit 1.4.1
From 18d9234dfe4b6db32a2da335834908e49300e5cd Mon Sep 17 00:00:00 2001
From: marc
Date: Wed, 9 Aug 2023 16:29:56 +0200
Subject: Revert "-c - support"
This reverts commit 5618062cb55f1ac094e33ad662a03df45e048f45.
---
docs/Changelog.md | 2 --
src/afl-fuzz.c | 25 +++++--------------------
2 files changed, 5 insertions(+), 22 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index d45b49fe..d61ce8ec 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -15,8 +15,6 @@
command line tool! See custom_mutators/aflpp/standalone/
- display the state of the fuzzing run in the UI :-)
- fix timeout setting if '+' is used or a session is restarted
- - allow to disable CMPLOG with '-c -' (e.g. afl.rs enforces '-c 0' on
- every instance which is counterproductive.
- afl-cmin/afl-cmin.bash:
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index e0e54b49..9afece66 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -180,8 +180,7 @@ static void usage(u8 *argv0, int more_help) {
"it.\n"
" if using QEMU/FRIDA or the fuzzing target is "
"compiled\n"
- " for CmpLog then use '-c 0'. To disable Cmplog use '-c "
- "-'.\n"
+ " for CmpLog then just use -c 0.\n"
" -l cmplog_opts - CmpLog configuration values (e.g. \"2ATR\"):\n"
" 1=small files, 2=larger files (default), 3=all "
"files,\n"
@@ -595,23 +594,8 @@ int main(int argc, char **argv_orig, char **envp) {
case 'c': {
- if (strcmp(optarg, "-") == 0) {
-
- if (afl->shm.cmplog_mode) {
-
- ACTF("Disabling cmplog again because of '-c -'.");
- afl->shm.cmplog_mode = 0;
- afl->cmplog_binary = NULL;
-
- }
-
- } else {
-
- afl->shm.cmplog_mode = 1;
- afl->cmplog_binary = ck_strdup(optarg);
-
- }
-
+ afl->shm.cmplog_mode = 1;
+ afl->cmplog_binary = ck_strdup(optarg);
break;
}
@@ -1516,7 +1500,8 @@ int main(int argc, char **argv_orig, char **envp) {
if (!afl->use_banner) { afl->use_banner = argv[optind]; }
- if (afl->shm.cmplog_mode && strcmp("0", afl->cmplog_binary) == 0) {
+ if (afl->shm.cmplog_mode &&
+ (!strcmp("-", afl->cmplog_binary) || !strcmp("0", afl->cmplog_binary))) {
afl->cmplog_binary = strdup(argv[optind]);
--
cgit 1.4.1
From d9cadb2e7db1d1c208cd40299f0e5c4f6364aa2c Mon Sep 17 00:00:00 2001
From: marc
Date: Wed, 9 Aug 2023 16:31:30 +0200
Subject: -c - support
---
docs/Changelog.md | 5 ++++-
src/afl-fuzz.c | 25 ++++++++++++++++++++-----
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 75167172..76f98547 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -15,7 +15,10 @@
command line tool! See custom_mutators/aflpp/standalone/
- display the state of the fuzzing run in the UI :-)
- fix timeout setting if '+' is used or a session is restarted
- - -c X option to enable base64 transformation solving
+ - -l X option to enable base64 transformation solving
+ - allow to disable CMPLOG with '-c -' (e.g. afl.rs enforces '-c 0' on
+ every instance which is counterproductive).
+
- afl-cmin/afl-cmin.bash:
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index e1f93f0d..cdb3f996 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -180,7 +180,8 @@ static void usage(u8 *argv0, int more_help) {
"it.\n"
" if using QEMU/FRIDA or the fuzzing target is "
"compiled\n"
- " for CmpLog then just use -c 0.\n"
+ " for CmpLog then use '-c 0'. To disable Cmplog use '-c "
+ "-'.\n"
" -l cmplog_opts - CmpLog configuration values (e.g. \"2ATR\"):\n"
" 1=small files, 2=larger files (default), 3=all "
"files,\n"
@@ -600,8 +601,23 @@ int main(int argc, char **argv_orig, char **envp) {
case 'c': {
- afl->shm.cmplog_mode = 1;
- afl->cmplog_binary = ck_strdup(optarg);
+ if (strcmp(optarg, "-") == 0) {
+
+ if (afl->shm.cmplog_mode) {
+
+ ACTF("Disabling cmplog again because of '-c -'.");
+ afl->shm.cmplog_mode = 0;
+ afl->cmplog_binary = NULL;
+
+ }
+
+ } else {
+
+ afl->shm.cmplog_mode = 1;
+ afl->cmplog_binary = ck_strdup(optarg);
+
+ }
+
break;
}
@@ -1510,8 +1526,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (!afl->use_banner) { afl->use_banner = argv[optind]; }
- if (afl->shm.cmplog_mode &&
- (!strcmp("-", afl->cmplog_binary) || !strcmp("0", afl->cmplog_binary))) {
+ if (afl->shm.cmplog_mode && strcmp("0", afl->cmplog_binary) == 0) {
afl->cmplog_binary = strdup(argv[optind]);
--
cgit 1.4.1
From 55d696fbae435e0e69adf75cb2df1361186fb999 Mon Sep 17 00:00:00 2001
From: marc
Date: Wed, 9 Aug 2023 17:14:13 +0200
Subject: code format
---
include/afl-fuzz.h | 4 ++--
src/afl-fuzz-init.c | 42 ++++++++++++++++++++++++------------------
src/afl-fuzz-redqueen.c | 2 +-
src/afl-fuzz.c | 2 +-
4 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index 18352acb..ef84a18c 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -402,14 +402,14 @@ typedef struct afl_env_vars {
afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems,
afl_keep_timeouts, afl_no_crash_readme, afl_ignore_timeouts,
afl_no_startup_calibration, afl_no_warn_instability,
- afl_post_process_keep_original;
+ afl_post_process_keep_original, afl_crashing_seeds_as_new_crash;
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
*afl_max_det_extras, *afl_statsd_host, *afl_statsd_port,
*afl_crash_exitcode, *afl_statsd_tags_flavor, *afl_testcache_size,
*afl_testcache_entries, *afl_child_kill_signal, *afl_fsrv_kill_signal,
- *afl_target_env, *afl_persistent_record, *afl_exit_on_time, *afl_crashing_seeds_as_new_crash;
+ *afl_target_env, *afl_persistent_record, *afl_exit_on_time;
s32 afl_pizza_mode;
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index d994d749..5a530821 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1057,18 +1057,21 @@ void perform_dry_run(afl_state_t *afl) {
fn, (int)(s8)afl->fsrv.crash_exitcode);
} else {
+
if (afl->afl_env.afl_crashing_seeds_as_new_crash) {
-
+
WARNF(
"Test case '%s' results in a crash, "
"as AFL_CRASHING_SEEDS_AS_NEW_CRASH is set, "
- "saving as a new crash", fn);
-
+ "saving as a new crash",
+ fn);
+
} else {
WARNF("Test case '%s' results in a crash, skipping", fn);
-
+
}
+
}
if (afl->afl_env.afl_exit_on_seed_issues) {
@@ -1089,20 +1092,19 @@ void perform_dry_run(afl_state_t *afl) {
/* Crashing seeds will be regarded as new crashes on startup */
if (afl->afl_env.afl_crashing_seeds_as_new_crash) {
-
+
++afl->total_crashes;
if (likely(!afl->non_instrumented_mode)) {
classify_counts(&afl->fsrv);
-
+
simplify_trace(afl, afl->fsrv.trace_bits);
if (!has_new_bits(afl, afl->virgin_crash)) { break; }
}
-
if (unlikely(!afl->saved_crashes) &&
(afl->afl_env.afl_no_crash_readme != 1)) {
@@ -1116,18 +1118,22 @@ void perform_dry_run(afl_state_t *afl) {
afl->stage_name = "dry_run";
afl->stage_short = "dry_run";
- #ifndef SIMPLE_FILES
+#ifndef SIMPLE_FILES
- snprintf(crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s", afl->out_dir,
- afl->saved_crashes, afl->fsrv.last_kill_signal,
- describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,") - strlen(use_name)), use_name);
+ snprintf(crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s",
+ afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal,
+ describe_op(afl, 0,
+ NAME_MAX - strlen("id:000000,sig:00,") -
+ strlen(use_name)),
+ use_name);
- #else
+#else
- snprintf(crash_fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", afl->out_dir,
- afl->saved_crashes, afl->fsrv.last_kill_signal);
+ snprintf(crash_fn, PATH_MAX, "%s/crashes/id_%06llu_%02u",
+ afl->out_dir, afl->saved_crashes,
+ afl->fsrv.last_kill_signal);
- #endif
+#endif
++afl->saved_crashes;
@@ -1169,12 +1175,12 @@ void perform_dry_run(afl_state_t *afl) {
}
}
-
+
q->disabled = 1;
q->perf_score = 0;
- break;
-
+ break;
+
case FSRV_RUN_ERROR:
FATAL("Unable to execute target application ('%s')", afl->argv[0]);
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 509f66a3..db4991db 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -2525,7 +2525,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
*/
#ifdef _DEBUG
- u32 j;
+ u32 j;
struct cmp_header *hh = &afl->orig_cmp_map->headers[key];
fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits, h->id,
hshape, h->attribute);
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 733c7429..cdb3f996 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1592,7 +1592,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (get_afl_env("AFL_NO_ARITH")) { afl->no_arith = 1; }
if (get_afl_env("AFL_SHUFFLE_QUEUE")) { afl->shuffle_queue = 1; }
if (get_afl_env("AFL_EXPAND_HAVOC_NOW")) { afl->expand_havoc = 1; }
-
+
if (afl->afl_env.afl_autoresume) {
afl->autoresume = 1;
--
cgit 1.4.1
From 3721c65a0b7fdf2b24713f8009030c6c241e200b Mon Sep 17 00:00:00 2001
From: marc
Date: Thu, 10 Aug 2023 10:41:55 +0200
Subject: v4.08c release
---
README.md | 10 +++++-----
docs/Changelog.md | 2 +-
include/config.h | 6 +++---
3 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/README.md b/README.md
index b73cf2c1..951efe59 100644
--- a/README.md
+++ b/README.md
@@ -2,9 +2,9 @@
-Release version: [4.07c](https://github.com/AFLplusplus/AFLplusplus/releases)
+Release version: [4.08c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.08a
+GitHub version: 4.08c
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
@@ -12,13 +12,13 @@ Repository:
AFL++ is maintained by:
* Marc "van Hauser" Heuse
-* Andrea Fioraldi
* Dominik Maier
-* Heiko "hexcoder-" Eiรfeldt
+* Andrea Fioraldi
+* Heiko "hexcoder-" Eissfeldt
* frida_mode is maintained by @Worksbutnottested
* Documentation: Jana Aydinbas
-Originally developed by Michaล "lcamtuf" Zalewski.
+Originally developed by Michal "lcamtuf" Zalewski.
AFL++ is a superior fork to Google's AFL - more speed, more and better
mutations, more and better instrumentation, custom module support, etc.
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 76f98547..2c747e42 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,7 +3,7 @@
This is the list of all noteworthy changes made in every public
release of the tool. See README.md for the general instruction manual.
-### Version ++4.08a (dev)
+### Version ++4.08c (release)
- afl-fuzz:
- new mutation engine: mutations that favor discovery more paths are
prefered until no new finds for 10 minutes then switching to mutations
diff --git a/include/config.h b/include/config.h
index df545583..5a81c4e2 100644
--- a/include/config.h
+++ b/include/config.h
@@ -5,9 +5,9 @@
Originally written by Michal Zalewski
Now maintained by Marc Heuse ,
- Heiko Eiรfeldt ,
- Andrea Fioraldi ,
Dominik Maier
+ Andrea Fioraldi ,
+ Heiko Eissfeldt ,
Copyright 2016, 2017 Google Inc. All rights reserved.
Copyright 2019-2023 AFLplusplus Project. All rights reserved.
@@ -26,7 +26,7 @@
/* Version string: */
// c = release, a = volatile github dev, e = experimental branch
-#define VERSION "++4.08a"
+#define VERSION "++4.08c"
/******************************************************
* *
--
cgit 1.4.1
From 9607d1db06ebfc2fe1ba565a0ef0123ab3f3e76c Mon Sep 17 00:00:00 2001
From: marc
Date: Thu, 10 Aug 2023 10:56:20 +0200
Subject: v4.09a init
---
README.md | 2 +-
docs/Changelog.md | 4 ++++
include/config.h | 2 +-
3 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/README.md b/README.md
index 951efe59..322ebcf2 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@
Release version: [4.08c](https://github.com/AFLplusplus/AFLplusplus/releases)
-GitHub version: 4.08c
+GitHub version: 4.09a
Repository:
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 2c747e42..94b4c502 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -3,6 +3,10 @@
This is the list of all noteworthy changes made in every public
release of the tool. See README.md for the general instruction manual.
+### Version ++4.09a (dev)
+ - something cool :-)
+
+
### Version ++4.08c (release)
- afl-fuzz:
- new mutation engine: mutations that favor discovery more paths are
diff --git a/include/config.h b/include/config.h
index 5a81c4e2..6a75737f 100644
--- a/include/config.h
+++ b/include/config.h
@@ -26,7 +26,7 @@
/* Version string: */
// c = release, a = volatile github dev, e = experimental branch
-#define VERSION "++4.08c"
+#define VERSION "++4.09a"
/******************************************************
* *
--
cgit 1.4.1
From 1cd9258768253e082baa1cc453c578b373839dbc Mon Sep 17 00:00:00 2001
From: marc
Date: Thu, 10 Aug 2023 14:46:37 +0200
Subject: update tritondse script
---
custom_mutators/aflpp_tritondse/aflpp_tritondse.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
index 58b506b6..58739696 100644
--- a/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
+++ b/custom_mutators/aflpp_tritondse/aflpp_tritondse.py
@@ -164,7 +164,7 @@ def init(seed):
format = SeedFormat.COMPOSITE
# Now set up TritonDSE
config = Config(coverage_strategy = CoverageStrategy.PATH,
- debug = is_debug,
+ # debug = is_debug,
pipe_stdout = is_debug,
pipe_stderr = is_debug,
execution_timeout = 1,
--
cgit 1.4.1
From 8823f22a9c87123c1bfcc5bff10044de4c7a4a1f Mon Sep 17 00:00:00 2001
From: marc
Date: Fri, 11 Aug 2023 11:22:18 +0200
Subject: add AFL_FINAL_SYNC
---
docs/Changelog.md | 7 +++----
docs/env_variables.md | 13 +++++++++----
include/afl-fuzz.h | 3 ++-
include/envs.h | 1 +
src/afl-fuzz-state.c | 7 +++++++
src/afl-fuzz.c | 9 +++++++++
6 files changed, 31 insertions(+), 9 deletions(-)
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 94b4c502..8f2b2545 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -4,7 +4,9 @@
release of the tool. See README.md for the general instruction manual.
### Version ++4.09a (dev)
- - something cool :-)
+ - afl-fuzz:
+ - added `AFL_FINAL_SYNC` which forces a final fuzzer sync (also for `-F`)
+ before terminating.
### Version ++4.08c (release)
@@ -22,7 +24,6 @@
- -l X option to enable base64 transformation solving
- allow to disable CMPLOG with '-c -' (e.g. afl.rs enforces '-c 0' on
every instance which is counterproductive).
-
- afl-cmin/afl-cmin.bash:
- fixed a bug inherited from vanilla AFL where a coverage of
map[123] = 11 would be the same as map[1123] = 1
@@ -40,7 +41,6 @@
- qemu_mode:
- added qemu_mode/utils/qemu_get_symbol_addr.sh
-
### Version ++4.07c (release)
- afl-fuzz:
- reverse reading the seeds only on restarts (increases performance)
@@ -69,7 +69,6 @@
- TritonDSE in custom_mutators/aflpp_tritondse
- SymQEMU in custom_mutators/symqemu
-
### Version ++4.06c (release)
- afl-fuzz:
- ensure temporary file descriptor is closed when not used
diff --git a/docs/env_variables.md b/docs/env_variables.md
index affc9e3c..2ce274d3 100644
--- a/docs/env_variables.md
+++ b/docs/env_variables.md
@@ -412,10 +412,15 @@ checks or alter some of the more exotic semantics of the tool:
set `AFL_IGNORE_PROBLEMS`. If you additionally want to also ignore coverage
from late loaded libraries, you can set `AFL_IGNORE_PROBLEMS_COVERAGE`.
- - When running in the `-M` or `-S` mode, setting `AFL_IMPORT_FIRST` causes the
- fuzzer to import test cases from other instances before doing anything else.
- This makes the "own finds" counter in the UI more accurate. Beyond counter
- aesthetics, not much else should change.
+ - When running with multiple afl-fuzz or with `-F`, setting `AFL_IMPORT_FIRST`
+ causes the fuzzer to import test cases from other instances before doing
+ anything else. This makes the "own finds" counter in the UI more accurate.
+
+ - When running with multiple afl-fuzz or with `-F`, setting `AFL_FINAL_SYNC`
+ will cause the fuzzer to perform a final import of test cases when
+ terminating. This is beneficial for `-M` main fuzzers to ensure it has all
+ unique test cases and hence you only need to `afl-cmin` this single
+ queue.
- Setting `AFL_INPUT_LEN_MIN` and `AFL_INPUT_LEN_MAX` are an alternative to
the afl-fuzz -g/-G command line option to control the minimum/maximum
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h
index ef84a18c..1f89bbd8 100644
--- a/include/afl-fuzz.h
+++ b/include/afl-fuzz.h
@@ -402,7 +402,8 @@ typedef struct afl_env_vars {
afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems,
afl_keep_timeouts, afl_no_crash_readme, afl_ignore_timeouts,
afl_no_startup_calibration, afl_no_warn_instability,
- afl_post_process_keep_original, afl_crashing_seeds_as_new_crash;
+ afl_post_process_keep_original, afl_crashing_seeds_as_new_crash,
+ afl_final_sync;
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
diff --git a/include/envs.h b/include/envs.h
index 0007d5a8..3f5a9e1c 100644
--- a/include/envs.h
+++ b/include/envs.h
@@ -59,6 +59,7 @@ static char *afl_environment_variables[] = {
"AFL_EXIT_ON_TIME",
"AFL_EXIT_ON_SEED_ISSUES",
"AFL_FAST_CAL",
+ "AFL_FINAL_SYNC",
"AFL_FORCE_UI",
"AFL_FRIDA_DEBUG_MAPS",
"AFL_FRIDA_DRIVER_NO_HOOK",
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 5a6b95cf..97e00415 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -269,6 +269,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
afl->afl_env.afl_import_first =
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
+ } else if (!strncmp(env, "AFL_FINAL_SYNC",
+
+ afl_environment_variable_len)) {
+
+ afl->afl_env.afl_final_sync =
+ get_afl_env(afl_environment_variables[i]) ? 1 : 0;
+
} else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_ONLY",
afl_environment_variable_len)) {
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index cdb3f996..c2ec4a1d 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -2899,6 +2899,15 @@ stop_fuzzing:
time_spent_working / afl->fsrv.total_execs);
#endif
+ if (afl->afl_env.afl_final_sync) {
+
+ SAYF(cYEL "[!] " cRST "\nPerforming final sync, this make take some time ...\n");
+ sync_fuzzers(afl);
+ write_bitmap(afl);
+ SAYF(cYEL "[!] " cRST "Done!\n\n");
+
+ }
+
if (afl->is_main_node) {
u8 path[PATH_MAX];
--
cgit 1.4.1
From 030799638ddb7bd42d97fea81951c7cb246e263b Mon Sep 17 00:00:00 2001
From: chinggg <24590067+chinggg@users.noreply.github.com>
Date: Sun, 13 Aug 2023 00:24:44 +0800
Subject: Remove redundant comparison of `fav_factor` in `update_bitmap_score`
`top_rated_fav_factor` was actually calculated twice,
but only one calculation and comparison is needed.
Since `fav_factor` > `top_rated_fav_factor` will always cause skip of current
iteration, `else if (fuzz_p2 == top_rated_fuzz_p2)` is also redundant.
---
src/afl-fuzz-queue.c | 25 ++-----------------------
1 file changed, 2 insertions(+), 23 deletions(-)
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 48fd33ec..20973f51 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -746,30 +746,9 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
}
- if (fuzz_p2 > top_rated_fuzz_p2) {
+ if (fuzz_p2 > top_rated_fuzz_p2) continue;
- continue;
-
- } else if (fuzz_p2 == top_rated_fuzz_p2) {
-
- if (fav_factor > top_rated_fav_factor) { continue; }
-
- }
-
- if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
-
- if (fav_factor > afl->top_rated[i]->len << 2) { continue; }
-
- } else {
-
- if (fav_factor >
- afl->top_rated[i]->exec_us * afl->top_rated[i]->len) {
-
- continue;
-
- }
-
- }
+ if (fav_factor > top_rated_fav_factor) continue;
/* Looks like we're going to win. Decrease ref count for the
previous winner, discard its afl->fsrv.trace_bits[] if necessary. */
--
cgit 1.4.1
From 26f29fd485efaa08824c27501f82caeea525b5e3 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 13 Aug 2023 10:18:33 +0200
Subject: nits
---
src/afl-fuzz-bitmap.c | 2 +-
src/afl-fuzz-queue.c | 27 ++++++++++++++++++++-------
src/afl-fuzz.c | 3 ++-
3 files changed, 23 insertions(+), 9 deletions(-)
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index 87157cad..0429db34 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -474,7 +474,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
/* Generating a hash on every input is super expensive. Bad idea and should
only be used for special schedules */
- if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
+ if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) {
classify_counts(&afl->fsrv);
classified = 1;
diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c
index 20973f51..14ba1ace 100644
--- a/src/afl-fuzz-queue.c
+++ b/src/afl-fuzz-queue.c
@@ -701,13 +701,20 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
u64 fav_factor;
u64 fuzz_p2;
- if (unlikely(afl->schedule >= FAST && afl->schedule < RARE))
+ if (likely(afl->schedule >= FAST && afl->schedule < RARE)) {
+
fuzz_p2 = 0; // Skip the fuzz_p2 comparison
- else if (unlikely(afl->schedule == RARE))
+
+ } else if (unlikely(afl->schedule == RARE)) {
+
fuzz_p2 = next_pow2(afl->n_fuzz[q->n_fuzz_entry]);
- else
+
+ } else {
+
fuzz_p2 = q->fuzz_level;
+ }
+
if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
fav_factor = q->len << 2;
@@ -729,12 +736,18 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
/* Faster-executing or smaller test cases are favored. */
u64 top_rated_fav_factor;
u64 top_rated_fuzz_p2;
- if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
+
+ if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) {
+
top_rated_fuzz_p2 =
next_pow2(afl->n_fuzz[afl->top_rated[i]->n_fuzz_entry]);
- else
+
+ } else {
+
top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level;
+ }
+
if (unlikely(afl->schedule >= RARE) || unlikely(afl->fixed_seed)) {
top_rated_fav_factor = afl->top_rated[i]->len << 2;
@@ -746,9 +759,9 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
}
- if (fuzz_p2 > top_rated_fuzz_p2) continue;
+ if (likely(fuzz_p2 > top_rated_fuzz_p2)) { continue; }
- if (fav_factor > top_rated_fav_factor) continue;
+ if (likely(fav_factor > top_rated_fav_factor)) { continue; }
/* Looks like we're going to win. Decrease ref count for the
previous winner, discard its afl->fsrv.trace_bits[] if necessary. */
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index c2ec4a1d..93bcdccf 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -2901,7 +2901,8 @@ stop_fuzzing:
if (afl->afl_env.afl_final_sync) {
- SAYF(cYEL "[!] " cRST "\nPerforming final sync, this make take some time ...\n");
+ SAYF(cYEL "[!] " cRST
+ "\nPerforming final sync, this make take some time ...\n");
sync_fuzzers(afl);
write_bitmap(afl);
SAYF(cYEL "[!] " cRST "Done!\n\n");
--
cgit 1.4.1
From 4d8d8633ff39cda2f1d48b66c45e5ae6cd2af477 Mon Sep 17 00:00:00 2001
From: vanhauser-thc
Date: Sun, 13 Aug 2023 11:44:37 +0200
Subject: update faq
---
docs/FAQ.md | 40 ++++++++++++++++++++++++++++++++++++++--
include/afl-fuzz.h | 9 ++++-----
2 files changed, 42 insertions(+), 7 deletions(-)
diff --git a/docs/FAQ.md b/docs/FAQ.md
index 9275eb94..242a379b 100644
--- a/docs/FAQ.md
+++ b/docs/FAQ.md
@@ -29,8 +29,8 @@ If you find an interesting or important question missing, submit it via
which then implemented their own research and features, making it now by far
the most flexible and feature rich guided fuzzer available as open source. And
in independent fuzzing benchmarks it is one of the best fuzzers available,
- e.g., [Fuzzbench
- Report](https://www.fuzzbench.com/reports/2020-08-03/index.html).
+ e.g.,
+ [Fuzzbench Report](https://www.fuzzbench.com/reports/2020-08-03/index.html).
@@ -103,6 +103,42 @@ If you find an interesting or important question missing, submit it via
to itself, this too would be an edge.
+
+ Should you ever stop afl-fuzz, minimize the corpus and restart?
+
+ To stop afl-fuzz, minimize it's corpus and restart you would usually do:
+
+ ```
+ Control-C # to terminate afl-fuzz
+ $ afl-cmin -T nproc -i out/default/queue -o minimized_queue -- ./target
+ $ AFL_FAST_CAL=1 AFL_CMPLOG_ONLY_NEW=1 afl-fuzz -i minimized_queue -o out2 [other options] -- ./target
+ ```
+
+ If this improves fuzzing or not is debated and no consensus has been reached
+ or in-depth analysis been performed.
+
+ On the pro side:
+ * The queue/corpus is reduced (up to 20%) by removing intermediate paths
+ that are maybe not needed anymore.
+
+ On the con side:
+ * Fuzzing time is lost for the time the fuzzing is stopped, minimized and
+ restarted.
+
+ The the big question:
+ * Does a minimized queue/corpus improve finding new coverage or does it
+ hinder it?
+
+ The AFL++ team's own limited analysis seem to to show that keeping
+ intermediate paths help to find more coverage, at least for afl-fuzz.
+
+ For honggfuzz in comparison it is a good idea to restart it from time to
+ time if you have other fuzzers (e.g: AFL++) running in parallel to sync
+ the finds of other fuzzers to honggfuzz as it has no syncing feature like
+ AFL++ or libfuzzer.
+
+
"
+ ],
+ "text/plain": [
+ "label Multicore: Non-persistent mode + kernel config \\\n",
+ "parallel_fuzzers \n",
+ "1.0 11019.30 \n",
+ "2.0 21111.92 \n",
+ "3.0 30568.82 \n",
+ "4.0 38963.07 \n",
+ "5.0 47693.65 \n",
+ "\n",
+ "label Multicore: Persistent mode/shared memory + kernel config \\\n",
+ "parallel_fuzzers \n",
+ "1.0 133591.26 \n",
+ "2.0 255995.07 \n",
+ "3.0 380246.34 \n",
+ "4.0 490254.72 \n",
+ "5.0 598698.16 \n",
+ "\n",
+ "label Multicore: Persistent mode/shared memory without kernel config \\\n",
+ "parallel_fuzzers \n",
+ "1.0 90851.40 \n",
+ "2.0 176159.32 \n",
+ "3.0 260268.78 \n",
+ "4.0 336355.99 \n",
+ "5.0 413750.00 \n",
+ "\n",
+ "label Multicore: afl_execs: Persistent mode/shared memory + kernel config \\\n",
+ "parallel_fuzzers \n",
+ "1.0 134423.50 \n",
+ "2.0 258490.04 \n",
+ "3.0 383777.45 \n",
+ "4.0 496249.48 \n",
+ "5.0 613089.31 \n",
+ "\n",
+ "label Singlecore: Non-persistent mode + kernel config \\\n",
+ "parallel_fuzzers \n",
+ "1.0 11038.96 \n",
+ "2.0 11038.96 \n",
+ "3.0 11038.96 \n",
+ "4.0 11038.96 \n",
+ "5.0 11038.96 \n",
+ "\n",
+ "label Singlecore: Persistent mode/shared memory + kernel config \n",
+ "parallel_fuzzers \n",
+ "1.0 135613.26 \n",
+ "2.0 135613.26 \n",
+ "3.0 135613.26 \n",
+ "4.0 135613.26 \n",
+ "5.0 135613.26 "
+ ]
+ },
+ "execution_count": 508,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "pivotdf.head()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "You can totally ignore the code cell directly below (unless you're curious). It's just preparing Markdown for the block below it to render. Jupyter Notebooks aren't able to use code variables inside Markdown blocks, so I have to do this instead."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 509,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/markdown": [
+ "\n",
+ "### Line graph analysis\n",
+ "Here are a few things that jump out from the graph above. Let's start at the bottom of the graph.\n",
+ "\n",
+ "#### test-instr vs. test-instr-persist-shmem\n",
+ "\n",
+ "This graph is scaled so that the single-core, non-persistent-mode performance (11038 execs per second) is\n",
+ "represented as 1.0x. If you build and run a fuzzer without creating a persistent mode harness for it, and without running fuzzers in parallel, this is the performance\n",
+ "you get on this machine.\n",
+ "\n",
+ "#### Multicore test-instr\n",
+ "\n",
+ "By running as many parallel fuzzers are there are CPU threads, we can reach 103765 execs per second, which is 9.4x that base speed.\n",
+ "\n",
+ "#### Persistent mode + shared memory\n",
+ "\n",
+ "By modifying the harness to use persistent mode as described [here](https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.persistent_mode.md#4-persistent-mode),\n",
+ "we end up with 12.3x base speed. So -- perhaps counter-intuively -- if you have a choice between switching to using multiple cores or rewriting\n",
+ "the harness to use persistent mode, it is better (at least on this machine) to use persistent mode on a single core, than to use non-persistent mode on every core.\n",
+ "\n",
+ "#### Kernel config\n",
+ "\n",
+ "By \"kernel config\", I'm referring to booting the Linux kernel with `mitigations=off`, which is a meta-parameter for disabling *all* hardware vulnerability meltdowns (such as Spectre,\n",
+ "Meltdown, Retbleed, etc) introduced in Linux v5.2. Disabling these results in a `total_execs_per_sec` increase of 368476 execs -- the difference between\n",
+ "109.0x (mitigations off) and 75.6x (mitigations on) base speed. Turning on mitigations\n",
+ "reduced the overall performance by 31%!\n",
+ "\n",
+ "One way to think about this is that the mitigations turn this 16-thread CPU into a 7-thread CPU, since the number of execs reached with 16 threads and mitigations on is around the same\n",
+ "number of execs reached with 7 threads and mitigations off.\n",
+ "\n",
+ "Or if we want to think in terms of cores, then the average number of execs gained per core in the initial eight is 115588 execs per sec, but the loss due to\n",
+ "mitigations is 368476 execs per sec, which is the averaged performance of 3.2 cores.\n",
+ "\n",
+ "#### afl_execs_per_sec vs. total_execs_per_sec\n",
+ "\n",
+ "* The purple line at the top is measuring `afl_execs_per_sec`. This is afl's own measurement of the speed of each fuzzer process, from the `out/fuzzer/fuzzer_stats` file.\n",
+ " * It peaks at 23 fuzzers running in parallel, on this 8-core (16-thread) CPU.\n",
+ " * In contrast, `total_execs_per_sec` shows large drops in performance as we pass 8 (cores) and 16 (threads) fuzzers.\n",
+ " * I'm inclined to trust `total_execs_per_sec` `(total_execs / (end time - start time))` more, so we'll use that from now on.\n",
+ "\n",
+ "#### How many parallel fuzzers should we use on this machine?\n",
+ "\n",
+ "* The drops in performance after 8/16 fuzzers are profound.\n",
+ " * Using 9-12 fuzzers is *worse* than using 8 fuzzers on this 8C/16T system, but using 13-16 is better than 8.\n",
+ " * And using >16 is worse than using 16. Makes sense.\n",
+ " * We should use the number of CPUs in /proc/cpuinfo (threads) to get the best performance. But if we did halve the number of\n",
+ " fuzzers, we would surprisingly only lose 21%\n",
+ " of performance. This could be a good tradeoff in terms of cost.\n"
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "execution_count": 509,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# (Ignore this code cell.)\n",
+ "from IPython.display import Markdown as md\n",
+ "singlecore_base_execs = pivotdf.iloc[0][\"Singlecore: Non-persistent mode + kernel config\"]\n",
+ "singlecore_persist_execs = pivotdf.iloc[0][\"Singlecore: Persistent mode/shared memory + kernel config\"]\n",
+ "multicore_fuzzers_with_afl_max_execs = int(pivotdf[\"Multicore: afl_execs: Persistent mode/shared memory + kernel config\"].idxmax())\n",
+ "multicore_fuzzers_with_total_max_execs = int(pivotdf[\"Multicore: Persistent mode/shared memory + kernel config\"].idxmax())\n",
+ "multicore_base_max_execs = pivotdf[\"Multicore: Non-persistent mode + kernel config\"].max()\n",
+ "factor_for_execs = lambda execs: round(execs / singlecore_base_execs, 1)\n",
+ "\n",
+ "multicore_persistent_without_mitigations_label = \"Multicore: Persistent mode/shared memory + kernel config\"\n",
+ "multicore_max_execs_mitigations_off = pivotdf[multicore_persistent_without_mitigations_label].max()\n",
+ "multicore_max_execs_mitigations_off_only_cores = pivotdf.loc[multicore_fuzzers_with_total_max_execs / 2][multicore_persistent_without_mitigations_label]\n",
+ "multicore_max_execs_mitigations_on = pivotdf[\"Multicore: Persistent mode/shared memory without kernel config\"].max()\n",
+ "multicore_avg_gain_per_core = pivotdf.loc[pivotdf.index <= 8][\"Multicore: Persistent mode/shared memory + kernel config\"].diff().dropna().mean()\n",
+ "mitigations_off_increase = int(multicore_max_execs_mitigations_off - multicore_max_execs_mitigations_on)\n",
+ "\n",
+ "md(f\"\"\"\n",
+ "### Line graph analysis\n",
+ "Here are a few things that jump out from the graph above. Let's start at the bottom of the graph.\n",
+ "\n",
+ "#### test-instr vs. test-instr-persist-shmem\n",
+ "\n",
+ "This graph is scaled so that the single-core, non-persistent-mode performance ({int(singlecore_base_execs)} execs per second) is\n",
+ "represented as 1.0x. If you build and run a fuzzer without creating a persistent mode harness for it, and without running fuzzers in parallel, this is the performance\n",
+ "you get on this machine.\n",
+ "\n",
+ "#### Multicore test-instr\n",
+ "\n",
+ "By running as many parallel fuzzers are there are CPU threads, we can reach {int(multicore_base_max_execs)} execs per second, which is {factor_for_execs(multicore_base_max_execs)}x that base speed.\n",
+ "\n",
+ "#### Persistent mode + shared memory\n",
+ "\n",
+ "By modifying the harness to use persistent mode as described [here](https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.persistent_mode.md#4-persistent-mode),\n",
+ "we end up with {factor_for_execs(singlecore_persist_execs)}x base speed. So -- perhaps counter-intuively -- if you have a choice between switching to using multiple cores or rewriting\n",
+ "the harness to use persistent mode, it is better (at least on this machine) to use persistent mode on a single core, than to use non-persistent mode on every core.\n",
+ "\n",
+ "#### Kernel config\n",
+ "\n",
+ "By \"kernel config\", I'm referring to booting the Linux kernel with `mitigations=off`, which is a meta-parameter for disabling *all* hardware vulnerability meltdowns (such as Spectre,\n",
+ "Meltdown, Retbleed, etc) introduced in Linux v5.2. Disabling these results in a `total_execs_per_sec` increase of {mitigations_off_increase} execs -- the difference between\n",
+ "{factor_for_execs(multicore_max_execs_mitigations_off)}x (mitigations off) and {factor_for_execs(multicore_max_execs_mitigations_on)}x (mitigations on) base speed. Turning on mitigations\n",
+ "reduced the overall performance by {abs(round(((multicore_max_execs_mitigations_on - multicore_max_execs_mitigations_off) / multicore_max_execs_mitigations_off) * 100))}%!\n",
+ "\n",
+ "One way to think about this is that the mitigations turn this 16-thread CPU into a 7-thread CPU, since the number of execs reached with 16 threads and mitigations on is around the same\n",
+ "number of execs reached with 7 threads and mitigations off.\n",
+ "\n",
+ "Or if we want to think in terms of cores, then the average number of execs gained per core in the initial eight is {int(multicore_avg_gain_per_core)} execs per sec, but the loss due to\n",
+ "mitigations is {mitigations_off_increase} execs per sec, which is the averaged performance of {round(mitigations_off_increase / multicore_avg_gain_per_core, 1)} cores.\n",
+ "\n",
+ "#### afl_execs_per_sec vs. total_execs_per_sec\n",
+ "\n",
+ "* The purple line at the top is measuring `afl_execs_per_sec`. This is afl's own measurement of the speed of each fuzzer process, from the `out/fuzzer/fuzzer_stats` file.\n",
+ " * It peaks at {multicore_fuzzers_with_afl_max_execs} fuzzers running in parallel, on this 8-core (16-thread) CPU.\n",
+ " * In contrast, `total_execs_per_sec` shows large drops in performance as we pass 8 (cores) and 16 (threads) fuzzers.\n",
+ " * I'm inclined to trust `total_execs_per_sec` `(total_execs / (end time - start time))` more, so we'll use that from now on.\n",
+ "\n",
+ "#### How many parallel fuzzers should we use on this machine?\n",
+ "\n",
+ "* The drops in performance after 8/16 fuzzers are profound.\n",
+ " * Using 9-12 fuzzers is *worse* than using 8 fuzzers on this 8C/16T system, but using 13-16 is better than 8.\n",
+ " * And using >16 is worse than using 16. Makes sense.\n",
+ " * We should use the number of CPUs in /proc/cpuinfo (threads) to get the best performance. But if we did halve the number of\n",
+ " fuzzers, we would surprisingly only lose {abs(int(((multicore_max_execs_mitigations_off_only_cores - multicore_max_execs_mitigations_off) / multicore_max_execs_mitigations_off) * 100))}%\n",
+ " of performance. This could be a good tradeoff in terms of cost.\n",
+ "\"\"\")\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Example with more cores\n",
+ "\n",
+ "While there was some nuance here, the answer was pretty straightforward -- use the number of CPU threads you have access to. What if there were more threads? Here the experiment is repeated on an AWS EC2 \"r6a.48xlarge\" spot instance with 192 vCPUs, and the answer calls the conclusion we just made above into question:"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 521,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "r6a_pivotdf = r6a_graphdf.pivot(index=\"parallel_fuzzers\", columns=\"label\", values=\"execs_per_sec\")\n",
+ "r6a_fig = r6a_pivotdf.plot(\n",
+ " title=\"Fuzzer performance\",\n",
+ " labels={\n",
+ " \"label\": \"Configuration\",\n",
+ " \"parallel_fuzzers\": \"Number of parallel fuzzers\",\n",
+ " \"value\": \"Fuzz target executions per second\"\n",
+ " }\n",
+ ")\n",
+ "\n",
+ "# Compute tick values and their labels for the primary Y-axis\n",
+ "tickvals = np.linspace(r6a_graphdf['execs_per_sec'].min(), r6a_graphdf['execs_per_sec'].max(), 6)\n",
+ "ticktext = [f\"{val:.0f}x\" for val in tickvals / graphdf['execs_per_sec'].min()]\n",
+ "# Update the primary Y-axis with custom tick labels\n",
+ "r6a_fig.update_yaxes(tickvals=tickvals, ticktext=ticktext)\n",
+ "r6a_fig.update_xaxes(tickvals=list(range(0,200+1, 5)))\n",
+ "r6a_fig.update_layout(width=1200, height=400)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Line graph analysis\n",
+ "\n",
+ "This is a shocking result for a 192 vCPU machine -- whether you count `afl_execs` or `total_execs`, our optimal number of parallel fuzzers was 16!\n",
+ "\n",
+ "Does this mean that AFL++ is a bad fuzzer, or that AWS tricked us and gave us a 16-thread machine instead of a 192-thread one?\n",
+ "\n",
+ "No -- the most likely cause here (based on a tip from @eqv) is that we're actually saturating the Linux kernel's ability to service system calls. We could look to reduce these, but there's another option available to us, which is to try running more system-call-servicers (read: kernels) at once, on this machine. One way to do that is to use hardware virtualization with KVM,\n",
+ "and if it is true that this particular fuzzer setup bottlenecks around 16 fuzzers, then we might expect an optimal number of KVM\n",
+ "kernels running on this machine to be around 16/192 == 8, each with 16 fuzzers in parallel, and perhaps a shared (in-memory?)\n",
+ "filesystem for the fuzzing queue."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Measuring system call saturation and experimenting with extra KVM hosts\n",
+ "\n",
+ "Coming soon!"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.11.3"
+ },
+ "orig_nbformat": 4
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/benchmark/benchmark.py b/benchmark/benchmark.py
index 52de9dcd..da32167a 100644
--- a/benchmark/benchmark.py
+++ b/benchmark/benchmark.py
@@ -1,19 +1,12 @@
#!/usr/bin/env python3
# Part of the aflplusplus project, requires Python 3.9+.
# Author: Chris Ball , ported from Marc "van Hauser" Heuse's "benchmark.sh".
-import argparse
-import asyncio
-import datetime
-import json
-import multiprocessing
-import os
-import platform
-import shutil
-import sys
-from dataclasses import dataclass
+import argparse, asyncio, datetime, json, multiprocessing, os, platform, re, shutil, sys
+from dataclasses import asdict, dataclass
from decimal import Decimal
from enum import Enum, auto
from pathlib import Path
+from typing import Optional, Union
blue = lambda text: f"\033[1;94m{text}\033[0m"; gray = lambda text: f"\033[1;90m{text}\033[0m"
green = lambda text: f"\033[0;32m{text}\033[0m"; red = lambda text: f"\033[0;31m{text}\033[0m"
@@ -28,6 +21,37 @@ class Target:
source: Path
binary: Path
+@dataclass
+class Run:
+ afl_execs_per_sec: float
+ afl_execs_total: float
+ fuzzers_used: int
+ run_end: str
+ run_start: str
+ total_execs_per_sec: float
+ total_run_time: float
+
+@dataclass
+class Config:
+ afl_persistent_config: bool
+ afl_system_config: bool
+ afl_version: Optional[str]
+ comment: str
+ compiler: str
+ target_arch: str
+
+@dataclass
+class Hardware:
+ cpu_fastest_core_mhz: Optional[float]
+ cpu_model: Optional[str]
+ cpu_threads: int
+
+@dataclass
+class Results:
+ config: Optional[Config]
+ hardware: Optional[Hardware]
+ targets: dict[str, dict[str, Optional[Run]]]
+
all_modes = [Mode.singlecore, Mode.multicore]
all_targets = [
Target(source=Path("../utils/persistent_mode/test-instr.c").resolve(), binary=Path("test-instr-persist-shmem")),
@@ -43,6 +67,7 @@ parser.add_argument("-d", "--debug", help="show verbose debugging output", actio
parser.add_argument("-r", "--runs", help="how many runs to average results over", type=int, default=5)
parser.add_argument("-f", "--fuzzers", help="how many afl-fuzz workers to use", type=int, default=cpu_count)
parser.add_argument("-m", "--mode", help="pick modes", action="append", default=["multicore"], choices=mode_names)
+parser.add_argument("-c", "--comment", help="add a comment about your setup", type=str, default="")
parser.add_argument(
"-t", "--target", help="pick targets", action="append", default=["test-instr-persist-shmem"], choices=target_names
)
@@ -54,9 +79,7 @@ if len(args.mode) > 1: args.mode = args.mode[1:]
targets = [target for target in all_targets if str(target.binary) in args.target]
modes = [mode for mode in all_modes if mode.name in args.mode]
-results: dict[str, dict] = {
- "config": {}, "hardware": {}, "targets": {str(t.binary): {m.name: {} for m in modes} for t in targets}
-}
+results = Results(config=None, hardware=None, targets={str(t.binary): {m.name: None for m in modes} for t in targets})
debug = lambda text: args.debug and print(blue(text))
if Mode.multicore in modes:
print(blue(f" [*] Using {args.fuzzers} fuzzers for multicore fuzzing "), end="")
@@ -80,19 +103,6 @@ async def check_afl_system() -> bool:
return returncode == 0 and stdout.decode().rstrip().split(" = ")[1] == "0"
return False
-async def check_deps() -> None:
- if not (plat := platform.system()) == "Linux": sys.exit(red(f" [*] {plat} is not supported by this script yet."))
- if not os.access(Path("../afl-fuzz").resolve(), os.X_OK) and os.access(Path("../afl-cc").resolve(), os.X_OK) and (
- os.path.exists(Path("../SanitizerCoveragePCGUARD.so").resolve())):
- sys.exit(red(" [*] Compile AFL++: we need afl-fuzz, afl-clang-fast and SanitizerCoveragePCGUARD.so built."))
-
- # Pick some sample settings from afl-{persistent,system}-config to try to see whether they were run.
- cmd_checks = {"afl-persistent-config": check_afl_persistent, "afl-system-config": check_afl_system}
- for cmd, checker in cmd_checks.items():
- results["config"][cmd] = await checker()
- if not results["config"][cmd]:
- print(yellow(f" [*] {cmd} was not run. You can run it to improve performance (and decrease security)."))
-
async def prep_env() -> dict:
Path(f"{args.basedir}/in").mkdir(exist_ok=True, parents=True)
with open(f"{args.basedir}/in/in.txt", "wb") as seed: seed.write(b"\x00" * 10240)
@@ -103,13 +113,21 @@ async def prep_env() -> dict:
async def compile_target(source: Path, binary: Path) -> None:
print(f" [*] Compiling the {binary} fuzzing harness for the benchmark to use.")
+ (returncode, stdout, stderr) = await run_command(
+ [str(Path("../afl-clang-lto").resolve()), "-o", str(Path(binary.resolve())), str(Path(source).resolve())],
+ env={"AFL_LLVM_INSTRUMENT": "PCGUARD"},
+ )
+ if returncode != 0:
+ print(yellow(f" [*] afl-clang-lto was unable to compile; falling back to afl-cc."))
+
(returncode, stdout, stderr) = await run_command(
[str(Path("../afl-cc").resolve()), "-o", str(Path(binary.resolve())), str(Path(source).resolve())],
- env={"AFL_INSTRUMENT": "PCGUARD"},
+ env={"AFL_LLVM_INSTRUMENT": "PCGUARD"},
)
- if returncode != 0: sys.exit(red(f" [*] Error: afl-cc is unable to compile: {stderr.decode()} {stdout.decode()}"))
+ if returncode != 0:
+ sys.exit(red(f" [*] Error: afl-cc is unable to compile: {stderr.decode()} {stdout.decode()}"))
-async def run_command(cmd: list[str], env: dict | None) -> tuple[int | None, bytes, bytes]:
+async def run_command(cmd: list[str], env: Union[dict, None]) -> tuple[Union[int, None], bytes, bytes]:
debug(f"Launching command: {cmd} with env {env}")
p = await asyncio.create_subprocess_exec(
*cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE, env=env
@@ -118,16 +136,45 @@ async def run_command(cmd: list[str], env: dict | None) -> tuple[int | None, byt
debug(f"Output: {stdout.decode()} {stderr.decode()}")
return (p.returncode, stdout, stderr)
-async def colon_value_or_none(filename: str, searchKey: str) -> str | None:
+async def check_deps() -> None:
+ if not (plat := platform.system()) == "Linux": sys.exit(red(f" [*] {plat} is not supported by this script yet."))
+ if not os.access(Path("../afl-fuzz").resolve(), os.X_OK) and os.access(Path("../afl-cc").resolve(), os.X_OK) and (
+ os.path.exists(Path("../SanitizerCoveragePCGUARD.so").resolve())):
+ sys.exit(red(" [*] Compile AFL++: we need afl-fuzz, afl-clang-fast and SanitizerCoveragePCGUARD.so built."))
+
+ (returncode, stdout, stderr) = await run_command([str(Path("../afl-cc").resolve()), "-v"], env={})
+ if returncode != 0:
+ sys.exit(red(f" [*] Error: afl-cc -v returned: {stderr.decode()} {stdout.decode()}"))
+ compiler = ""
+ target_arch = ""
+ for line in stderr.decode().split("\n"):
+ if m := re.match(r"^(clang version .*)", line):
+ compiler = m.group(1)
+ elif m := re.match(r"^Target: (.*)", line):
+ target_arch = m.group(1)
+
+ # Pick some sample settings from afl-{persistent,system}-config to try to see whether they were run.
+ afl_pc = await check_afl_persistent()
+ afl_sc = await check_afl_system()
+ if not afl_pc:
+ print(yellow(f" [*] afl-persistent-config did not run; run it to improve performance (and decrease security)."))
+ if not afl_sc:
+ print(yellow(f" [*] afl-system-config did not run; run it to improve performance (and decrease security)."))
+
+ results.config = Config(afl_persistent_config=afl_pc, afl_system_config=afl_sc, afl_version="",
+ comment=args.comment, compiler=compiler, target_arch=target_arch)
+
+async def colon_values(filename: str, searchKey: str) -> list[str]:
"""Return a colon-separated value given a key in a file, e.g. 'cpu MHz : 4976.109')"""
with open(filename, "r") as fh:
kv_pairs = (line.split(": ", 1) for line in fh if ": " in line)
- return next((v.rstrip() for k, v in kv_pairs if k.rstrip() == searchKey), None)
+ v_list = [v.rstrip() for k, v in kv_pairs if k.rstrip() == searchKey]
+ return v_list
async def save_benchmark_results() -> None:
"""Append a single row to the benchmark results in JSON Lines format (which is simple to write and diff)."""
with open("benchmark-results.jsonl", "a") as jsonfile:
- json.dump(results, jsonfile, sort_keys=True)
+ json.dump(asdict(results), jsonfile, sort_keys=True)
jsonfile.write("\n")
print(blue(f" [*] Results have been written to {jsonfile.name}"))
@@ -138,25 +185,25 @@ async def main() -> None:
except FileNotFoundError:
pass
await check_deps()
- results["hardware"] = { # Only record the first core's speed for now, even though it can vary between cores.
- "cpu_mhz": float(await colon_value_or_none("/proc/cpuinfo", "cpu MHz") or ""),
- "cpu_model": await colon_value_or_none("/proc/cpuinfo", "model name") or "",
- "cpu_threads": cpu_count
- }
+ cpu_mhz_str = await colon_values("/proc/cpuinfo", "cpu MHz")
+ cpu_mhz = max([float(c) for c in cpu_mhz_str]) # use the fastest CPU MHz for now
+ cpu_model = await colon_values("/proc/cpuinfo", "model name")
+ # Only record the first core's speed for now, even though it can vary between cores.
+ results.hardware = Hardware(cpu_fastest_core_mhz=cpu_mhz, cpu_model=cpu_model[0], cpu_threads=cpu_count)
env_vars = await prep_env()
print(f" [*] Ready, starting benchmark...")
for target in targets:
await compile_target(target.source, target.binary)
binary = str(target.binary)
for mode in modes:
- execs_per_sec, execs_total, run_time_total = ([] for _ in range(3))
- for run in range(0, args.runs):
- print(gray(f" [*] {mode.name} {binary} run {run+1} of {args.runs}, execs/s: "), end="", flush=True)
+ afl_execs_per_sec, execs_total, run_time_total = ([] for _ in range(3))
+ for run_idx in range(0, args.runs):
+ print(gray(f" [*] {mode.name} {binary} run {run_idx+1} of {args.runs}, execs/s: "), end="", flush=True)
fuzzers = range(0, args.fuzzers if mode == Mode.multicore else 1)
outdir = f"{args.basedir}/out-{mode.name}-{binary}"
cmds = []
- for idx, afl in enumerate(fuzzers):
- name = ["-o", outdir, "-M" if idx == 0 else "-S", str(afl)]
+ for fuzzer_idx, afl in enumerate(fuzzers):
+ name = ["-o", outdir, "-M" if fuzzer_idx == 0 else "-S", str(afl)]
cmds.append(["afl-fuzz", "-i", f"{args.basedir}/in"] + name + ["-s", "123", "-D", f"./{binary}"])
# Prepare the afl-fuzz tasks, and then block while waiting for them to finish.
@@ -164,34 +211,38 @@ async def main() -> None:
start_time = datetime.datetime.now()
await asyncio.gather(*fuzztasks)
end_time = datetime.datetime.now()
+ afl_versions = await colon_values(f"{outdir}/0/fuzzer_stats", "afl_version")
+ if results.config:
+ results.config.afl_version = afl_versions[0]
# Our score is the sum of all execs_per_sec entries in fuzzer_stats files for the run.
- sectasks = [colon_value_or_none(f"{outdir}/{afl}/fuzzer_stats", "execs_per_sec") for afl in fuzzers]
+ sectasks = [colon_values(f"{outdir}/{afl}/fuzzer_stats", "execs_per_sec") for afl in fuzzers]
all_execs_per_sec = await asyncio.gather(*sectasks)
- execs = sum([Decimal(count) for count in all_execs_per_sec if count is not None])
+ execs = sum([Decimal(count[0]) for count in all_execs_per_sec])
print(green(execs))
- execs_per_sec.append(execs)
+ afl_execs_per_sec.append(execs)
# Also gather execs_total and total_run_time for this run.
- exectasks = [colon_value_or_none(f"{outdir}/{afl}/fuzzer_stats", "execs_done") for afl in fuzzers]
+ exectasks = [colon_values(f"{outdir}/{afl}/fuzzer_stats", "execs_done") for afl in fuzzers]
all_execs_total = await asyncio.gather(*exectasks)
- execs_total.append(sum([Decimal(count) for count in all_execs_total if count is not None]))
+ execs_total.append(sum([Decimal(count[0]) for count in all_execs_total]))
run_time_total.append((end_time - start_time).total_seconds())
- avg_score = round(Decimal(sum(execs_per_sec) / len(execs_per_sec)), 2)
+ # (Using float() because Decimal() is not JSON-serializable.)
+ avg_afl_execs_per_sec = round(Decimal(sum(afl_execs_per_sec) / len(afl_execs_per_sec)), 2)
afl_execs_total = int(sum([Decimal(execs) for execs in execs_total]))
total_run_time = float(round(Decimal(sum(run_time_total)), 2))
- results["targets"][binary][mode.name] = { # (Using float() because Decimal() is not JSON-serializable.)
- "afl_execs_per_second": float(avg_score),
- "afl_execs_total": afl_execs_total,
- "fuzzers_used": len(fuzzers),
- "start_time_of_run": str(start_time),
- "total_execs_per_sec": float(round(Decimal(afl_execs_total / total_run_time), 2)),
- "total_run_time": total_run_time,
- }
- print(f" [*] Average score for this test across all runs was: {green(avg_score)}")
- if (((max(execs_per_sec) - min(execs_per_sec)) / avg_score) * 100) > 15:
+ total_execs_per_sec = float(round(Decimal(afl_execs_total / total_run_time), 2))
+ run = Run(afl_execs_per_sec=float(avg_afl_execs_per_sec), afl_execs_total=afl_execs_total,
+ fuzzers_used=len(fuzzers), run_end=str(end_time), run_start=str(start_time),
+ total_execs_per_sec=total_execs_per_sec, total_run_time=total_run_time)
+ results.targets[binary][mode.name] = run
+
+ print(f" [*] Average AFL execs/sec for this test across all runs was: {green(avg_afl_execs_per_sec)}")
+ print(f" [*] Average total execs/sec for this test across all runs was: {green(total_execs_per_sec)}")
+ if (((max(afl_execs_per_sec) - min(afl_execs_per_sec)) / avg_afl_execs_per_sec) * 100) > 15:
print(yellow(" [*] The difference between your slowest and fastest runs was >15%, maybe try again?"))
+
await clean_up_tempfiles()
await save_benchmark_results()
--
cgit 1.4.1
From b9db6b1254c9bf3a47c171bb96468628e9bd00f2 Mon Sep 17 00:00:00 2001
From: Chris Ball
Date: Mon, 2 Oct 2023 03:23:09 -0700
Subject: benchmark: add a README, lower default runs from 5 to 3
---
benchmark/README.md | 46 +
benchmark/benchmark.ipynb | 3502 +--------------------------------------------
benchmark/benchmark.py | 2 +-
3 files changed, 110 insertions(+), 3440 deletions(-)
create mode 100644 benchmark/README.md
diff --git a/benchmark/README.md b/benchmark/README.md
new file mode 100644
index 00000000..66f7f59e
--- /dev/null
+++ b/benchmark/README.md
@@ -0,0 +1,46 @@
+# American Fuzzy Lop plus plus (AFL++)
+
+## benchmarking
+
+This directory contains benchmarking tools that allow you to compare one machine
+with another in terms of raw ability to execute a fuzzing target repeatedly.
+
+To achieve this, we use a sample program ("test-instr.c") where each path is
+equally likely, supply it a single seed, and tell AFL to exit after one run of
+deterministic mutations against that seed.
+
+Usage:
+
+```
+cd aflplusplus/benchmark
+python3 benchmark.py
+ [*] Using 16 fuzzers for multicore fuzzing (use --fuzzers to override)
+ [*] Ready, starting benchmark...
+ [*] Compiling the test-instr-persist-shmem fuzzing harness for the benchmark to use.
+ [*] multicore test-instr-persist-shmem run 1 of 3, execs/s: 846065.81
+ [*] multicore test-instr-persist-shmem run 2 of 3, execs/s: 849694.03
+ [*] multicore test-instr-persist-shmem run 3 of 3, execs/s: 850757.52
+ [*] Average AFL execs/sec for this test across all runs was: 848839.12
+ [*] Average total execs/sec for this test across all runs was: 833138.28
+ [*] Results have been written to benchmark-results.jsonl
+```
+
+By default, the script will use a number of parallel fuzzers equal to your
+available CPUs/threads (change with `--fuzzers`), and will perform each test
+three times and average the result (change with `--runs`).
+
+The script will use multicore fuzzing instead of singlecore by default (change
+with `--mode singlecore`) and use a persistent-mode shared memory harness for
+optimal speed (change with `--target test-instr`).
+
+Each run writes results to [benchmark-results.jsonl](benchmark-results.jsonl)
+in [JSON Lines](https://jsonlines.org/) format, ready to be pulled in to other
+tools such as [jq -cs](https://jqlang.github.io/jq/) or
+[pandas](https://pandas.pydata.org/) for analysis.
+
+## Data analysis
+
+There is sample data in [benchmark-results.jsonl](benchmark-results.jsonl), and
+a Jupyter notebook for exploring the results and suggesting their meaning at
+[benchmark.ipynb](benchmark.ipynb).
+
diff --git a/benchmark/benchmark.ipynb b/benchmark/benchmark.ipynb
index b1ef6b0f..7ff90fcd 100644
--- a/benchmark/benchmark.ipynb
+++ b/benchmark/benchmark.ipynb
@@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
- "execution_count": 502,
+ "execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
@@ -20,14 +20,14 @@
"cell_type": "markdown",
"metadata": {},
"source": [
- "### Translate the JSON Lines entries into a single pandas DataFrame.\n",
+ "### Translate the JSON Lines entries into a single pandas DataFrame\n",
"\n",
"We have JSON Lines in [benchmark-results.jsonl](benchmark-results.jsonl) that look like this:"
]
},
{
"cell_type": "code",
- "execution_count": 503,
+ "execution_count": 13,
"metadata": {},
"outputs": [
{
@@ -89,7 +89,7 @@
},
{
"cell_type": "code",
- "execution_count": 504,
+ "execution_count": 14,
"metadata": {},
"outputs": [
{
@@ -371,7 +371,7 @@
"[5 rows x 37 columns]"
]
},
- "execution_count": 504,
+ "execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
@@ -404,7 +404,7 @@
},
{
"cell_type": "code",
- "execution_count": 505,
+ "execution_count": 15,
"metadata": {},
"outputs": [],
"source": [
@@ -418,1647 +418,65 @@
},
{
"cell_type": "code",
- "execution_count": 506,
+ "execution_count": 16,
"metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "