update honggfuzz custom mutator

This commit is contained in:
vanhauser-thc 2021-02-18 11:15:59 +01:00
parent 5dd35f5281
commit 89af2ef7a9
3 changed files with 551 additions and 677 deletions

View File

@ -0,0 +1,3 @@
#ifndef LOG_E
#define LOG_E LOG_F
#endif

View File

@ -208,6 +208,7 @@ typedef struct {
const char* crashDir;
const char* covDirNew;
bool saveUnique;
bool saveSmaller;
size_t dynfileqMaxSz;
size_t dynfileqCnt;
dynfile_t* dynfileqCurrent;
@ -279,9 +280,9 @@ typedef struct {
cmpfeedback_t* cmpFeedbackMap;
int cmpFeedbackFd;
bool cmpFeedback;
const char* blacklistFile;
uint64_t* blacklist;
size_t blacklistCnt;
const char* blocklistFile;
uint64_t* blocklist;
size_t blocklistCnt;
bool skipFeedbackOnTimeout;
uint64_t maxCov[4];
dynFileMethod_t dynFileMethod;

View File

@ -39,74 +39,58 @@
#include "libhfcommon/log.h"
#include "libhfcommon/util.h"
static inline size_t mangle_LenLeft(run_t *run, size_t off) {
static inline size_t mangle_LenLeft(run_t* run, size_t off) {
if (off >= run->dynfile->size) {
LOG_F("Offset is too large: off:%zu >= len:%zu", off, run->dynfile->size);
}
return (run->dynfile->size - off - 1);
}
/* Get a random value <1:max>, but prefer smaller ones - up to 4KiB */
/*
* Get a random value <1:max>, but prefer smaller ones
* Based on an idea by https://twitter.com/gamozolabs
*/
static inline size_t mangle_getLen(size_t max) {
if (max > _HF_INPUT_MAX_SIZE) {
LOG_F("max (%zu) > _HF_INPUT_MAX_SIZE (%zu)", max,
(size_t)_HF_INPUT_MAX_SIZE);
LOG_F("max (%zu) > _HF_INPUT_MAX_SIZE (%zu)", max, (size_t)_HF_INPUT_MAX_SIZE);
}
if (max == 0) {
LOG_F("max == 0");
}
if (max == 1) {
return 1;
}
if (max == 0) { LOG_F("max == 0"); }
if (max == 1) { return 1; }
/* Give 50% chance the the uniform distribution */
switch (util_rndGet(0, 9)) {
case 0:
return (size_t)util_rndGet(1, HF_MIN(16, max));
case 1:
return (size_t)util_rndGet(1, HF_MIN(64, max));
case 2:
return (size_t)util_rndGet(1, HF_MIN(256, max));
case 3:
return (size_t)util_rndGet(1, HF_MIN(1024, max));
case 4:
return (size_t)util_rndGet(1, HF_MIN(4096, max));
default:
break;
if (util_rnd64() & 1) {
return (size_t)util_rndGet(1, max);
}
return (size_t)util_rndGet(1, max);
/* effectively exprand() */
return (size_t)util_rndGet(1, util_rndGet(1, max));
}
/* Prefer smaller values here, so use mangle_getLen() */
static inline size_t mangle_getOffSet(run_t *run) {
static inline size_t mangle_getOffSet(run_t* run) {
return mangle_getLen(run->dynfile->size) - 1;
}
/* Offset which can be equal to the file size */
static inline size_t mangle_getOffSetPlus1(run_t *run) {
static inline size_t mangle_getOffSetPlus1(run_t* run) {
size_t reqlen = HF_MIN(run->dynfile->size + 1, _HF_INPUT_MAX_SIZE);
return mangle_getLen(reqlen) - 1;
}
static inline void mangle_Move(run_t *run, size_t off_from, size_t off_to,
size_t len) {
if (off_from >= run->dynfile->size) { return; }
if (off_to >= run->dynfile->size) { return; }
if (off_from == off_to) { return; }
static inline void mangle_Move(run_t* run, size_t off_from, size_t off_to, size_t len) {
if (off_from >= run->dynfile->size) {
return;
}
if (off_to >= run->dynfile->size) {
return;
}
if (off_from == off_to) {
return;
}
size_t len_from = run->dynfile->size - off_from;
len = HF_MIN(len, len_from);
@ -115,176 +99,148 @@ static inline void mangle_Move(run_t *run, size_t off_from, size_t off_to,
len = HF_MIN(len, len_to);
memmove(&run->dynfile->data[off_to], &run->dynfile->data[off_from], len);
}
static inline void mangle_Overwrite(run_t *run, size_t off, const uint8_t *src,
size_t len, bool printable) {
if (len == 0) { return; }
static inline void mangle_Overwrite(
run_t* run, size_t off, const uint8_t* src, size_t len, bool printable) {
if (len == 0) {
return;
}
size_t maxToCopy = run->dynfile->size - off;
if (len > maxToCopy) { len = maxToCopy; }
if (len > maxToCopy) {
len = maxToCopy;
}
memmove(&run->dynfile->data[off], src, len);
if (printable) { util_turnToPrintable(&run->dynfile->data[off], len); }
if (printable) {
util_turnToPrintable(&run->dynfile->data[off], len);
}
}
static inline size_t mangle_Inflate(run_t *run, size_t off, size_t len,
bool printable) {
if (run->dynfile->size >= run->global->mutate.maxInputSz) { return 0; }
static inline size_t mangle_Inflate(run_t* run, size_t off, size_t len, bool printable) {
if (run->dynfile->size >= run->global->mutate.maxInputSz) {
return 0;
}
if (len > (run->global->mutate.maxInputSz - run->dynfile->size)) {
len = run->global->mutate.maxInputSz - run->dynfile->size;
}
input_setSize(run, run->dynfile->size + len);
mangle_Move(run, off, off + len, run->dynfile->size);
if (printable) { memset(&run->dynfile->data[off], ' ', len); }
return len;
}
static inline void mangle_Insert(run_t *run, size_t off, const uint8_t *val,
size_t len, bool printable) {
len = mangle_Inflate(run, off, len, printable);
mangle_Overwrite(run, off, val, len, printable);
}
static inline void mangle_UseValue(run_t *run, const uint8_t *val, size_t len,
bool printable) {
if (util_rnd64() % 2) {
mangle_Insert(run, mangle_getOffSetPlus1(run), val, len, printable);
} else {
mangle_Overwrite(run, mangle_getOffSet(run), val, len, printable);
if (printable) {
memset(&run->dynfile->data[off], ' ', len);
}
return len;
}
static void mangle_MemSwap(run_t *run, bool printable HF_ATTR_UNUSED) {
static inline void mangle_Insert(
run_t* run, size_t off, const uint8_t* val, size_t len, bool printable) {
len = mangle_Inflate(run, off, len, printable);
mangle_Overwrite(run, off, val, len, printable);
}
static inline void mangle_UseValue(run_t* run, const uint8_t* val, size_t len, bool printable) {
if (util_rnd64() & 1) {
mangle_Overwrite(run, mangle_getOffSet(run), val, len, printable);
} else {
mangle_Insert(run, mangle_getOffSetPlus1(run), val, len, printable);
}
}
static inline void mangle_UseValueAt(
run_t* run, size_t off, const uint8_t* val, size_t len, bool printable) {
if (util_rnd64() & 1) {
mangle_Overwrite(run, off, val, len, printable);
} else {
mangle_Insert(run, off, val, len, printable);
}
}
static void mangle_MemSwap(run_t* run, bool printable HF_ATTR_UNUSED) {
/* No big deal if those two are overlapping */
size_t off1 = mangle_getOffSet(run);
size_t maxlen1 = run->dynfile->size - off1;
size_t off2 = mangle_getOffSet(run);
size_t maxlen2 = run->dynfile->size - off2;
size_t len = mangle_getLen(HF_MIN(maxlen1, maxlen2));
uint8_t *tmpbuf = (uint8_t *)util_Malloc(len);
defer {
free(tmpbuf);
};
memcpy(tmpbuf, &run->dynfile->data[off1], len);
memmove(&run->dynfile->data[off1], &run->dynfile->data[off2], len);
memcpy(&run->dynfile->data[off2], tmpbuf, len);
if (off1 == off2) {
return;
}
for (size_t i = 0; i < (len / 2); i++) {
/*
* First - from the head, next from the tail. Don't worry about layout of the overlapping
* part - there's no good solution to that, and it can be left somewhat scrambled,
* while still preserving the entropy
*/
const uint8_t tmp1 = run->dynfile->data[off2 + i];
run->dynfile->data[off2 + i] = run->dynfile->data[off1 + i];
run->dynfile->data[off1 + i] = tmp1;
const uint8_t tmp2 = run->dynfile->data[off2 + (len - 1) - i];
run->dynfile->data[off2 + (len - 1) - i] = run->dynfile->data[off1 + (len - 1) - i];
run->dynfile->data[off1 + (len - 1) - i] = tmp2;
}
}
static void mangle_MemCopy(run_t *run, bool printable HF_ATTR_UNUSED) {
static void mangle_MemCopy(run_t* run, bool printable HF_ATTR_UNUSED) {
size_t off = mangle_getOffSet(run);
size_t len = mangle_getLen(run->dynfile->size - off);
/* Use a temp buf, as Insert/Inflate can change source bytes */
uint8_t *tmpbuf = (uint8_t *)util_Malloc(len);
uint8_t* tmpbuf = (uint8_t*)util_Malloc(len);
defer {
free(tmpbuf);
};
memcpy(tmpbuf, &run->dynfile->data[off], len);
memmove(tmpbuf, &run->dynfile->data[off], len);
mangle_UseValue(run, tmpbuf, len, printable);
}
static void mangle_Bytes(run_t *run, bool printable) {
static void mangle_Bytes(run_t* run, bool printable) {
uint16_t buf;
if (printable) {
util_rndBufPrintable((uint8_t *)&buf, sizeof(buf));
util_rndBufPrintable((uint8_t*)&buf, sizeof(buf));
} else {
buf = util_rnd64();
}
/* Overwrite with random 1-2-byte values */
size_t toCopy = util_rndGet(1, 2);
mangle_UseValue(run, (const uint8_t *)&buf, toCopy, printable);
mangle_UseValue(run, (const uint8_t*)&buf, toCopy, printable);
}
static void mangle_ByteRepeatOverwrite(run_t *run, bool printable) {
static void mangle_ByteRepeat(run_t* run, bool printable) {
size_t off = mangle_getOffSet(run);
size_t destOff = off + 1;
size_t maxSz = run->dynfile->size - destOff;
/* No space to repeat */
if (!maxSz) {
mangle_Bytes(run, printable);
return;
}
size_t len = mangle_getLen(maxSz);
memset(&run->dynfile->data[destOff], run->dynfile->data[off], len);
}
static void mangle_ByteRepeatInsert(run_t *run, bool printable) {
size_t off = mangle_getOffSet(run);
size_t destOff = off + 1;
size_t maxSz = run->dynfile->size - destOff;
/* No space to repeat */
if (!maxSz) {
mangle_Bytes(run, printable);
return;
}
size_t len = mangle_getLen(maxSz);
if (util_rnd64() & 0x1) {
len = mangle_Inflate(run, destOff, len, printable);
}
memset(&run->dynfile->data[destOff], run->dynfile->data[off], len);
}
static void mangle_Bit(run_t *run, bool printable) {
static void mangle_Bit(run_t* run, bool printable) {
size_t off = mangle_getOffSet(run);
run->dynfile->data[off] ^= (uint8_t)(1U << util_rndGet(0, 7));
if (printable) { util_turnToPrintable(&(run->dynfile->data[off]), 1); }
if (printable) {
util_turnToPrintable(&(run->dynfile->data[off]), 1);
}
}
static const struct {
const uint8_t val[8];
const size_t size;
} mangleMagicVals[] = {
/* 1B - No endianness */
{"\x00\x00\x00\x00\x00\x00\x00\x00", 1},
{"\x01\x00\x00\x00\x00\x00\x00\x00", 1},
@ -516,208 +472,160 @@ static const struct {
{"\x00\x00\x00\x00\x00\x00\x00\x80", 8},
{"\x01\x00\x00\x00\x00\x00\x00\x80", 8},
{"\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
};
static void mangle_Magic(run_t *run, bool printable) {
static void mangle_Magic(run_t* run, bool printable) {
uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleMagicVals) - 1);
mangle_UseValue(run, mangleMagicVals[choice].val,
mangleMagicVals[choice].size, printable);
mangle_UseValue(run, mangleMagicVals[choice].val, mangleMagicVals[choice].size, printable);
}
static void mangle_StaticDict(run_t *run, bool printable) {
static void mangle_StaticDict(run_t* run, bool printable) {
if (run->global->mutate.dictionaryCnt == 0) {
mangle_Bytes(run, printable);
return;
}
uint64_t choice = util_rndGet(0, run->global->mutate.dictionaryCnt - 1);
mangle_UseValue(run, run->global->mutate.dictionary[choice].val,
run->global->mutate.dictionary[choice].len, printable);
}
static inline const uint8_t *mangle_FeedbackDict(run_t *run, size_t *len) {
if (!run->global->feedback.cmpFeedback) { return NULL; }
cmpfeedback_t *cmpf = run->global->feedback.cmpFeedbackMap;
static inline const uint8_t* mangle_FeedbackDict(run_t* run, size_t* len) {
if (!run->global->feedback.cmpFeedback) {
return NULL;
}
cmpfeedback_t* cmpf = run->global->feedback.cmpFeedbackMap;
uint32_t cnt = ATOMIC_GET(cmpf->cnt);
if (cnt == 0) { return NULL; }
if (cnt > ARRAYSIZE(cmpf->valArr)) { cnt = ARRAYSIZE(cmpf->valArr); }
if (cnt == 0) {
return NULL;
}
if (cnt > ARRAYSIZE(cmpf->valArr)) {
cnt = ARRAYSIZE(cmpf->valArr);
}
uint32_t choice = util_rndGet(0, cnt - 1);
*len = (size_t)ATOMIC_GET(cmpf->valArr[choice].len);
if (*len == 0) { return NULL; }
if (*len == 0) {
return NULL;
}
return cmpf->valArr[choice].val;
}
static void mangle_ConstFeedbackDict(run_t *run, bool printable) {
static void mangle_ConstFeedbackDict(run_t* run, bool printable) {
size_t len;
const uint8_t *val = mangle_FeedbackDict(run, &len);
const uint8_t* val = mangle_FeedbackDict(run, &len);
if (val == NULL) {
mangle_Bytes(run, printable);
return;
}
mangle_UseValue(run, val, len, printable);
}
static void mangle_MemSet(run_t *run, bool printable) {
static void mangle_MemSet(run_t* run, bool printable) {
size_t off = mangle_getOffSet(run);
size_t len = mangle_getLen(run->dynfile->size - off);
int val =
printable ? (int)util_rndPrintable() : (int)util_rndGet(0, UINT8_MAX);
int val = printable ? (int)util_rndPrintable() : (int)util_rndGet(0, UINT8_MAX);
if (util_rnd64() & 1) {
len = mangle_Inflate(run, off, len, printable);
}
memset(&run->dynfile->data[off], val, len);
}
static void mangle_RandomOverwrite(run_t *run, bool printable) {
size_t off = mangle_getOffSet(run);
size_t len = mangle_getLen(run->dynfile->size - off);
if (printable) {
util_rndBufPrintable(&run->dynfile->data[off], len);
} else {
util_rndBuf(&run->dynfile->data[off], len);
}
}
static void mangle_RandomInsert(run_t *run, bool printable) {
static void mangle_MemClr(run_t* run, bool printable) {
size_t off = mangle_getOffSet(run);
size_t len = mangle_getLen(run->dynfile->size - off);
int val = printable ? ' ' : 0;
if (util_rnd64() & 1) {
len = mangle_Inflate(run, off, len, printable);
if (printable) {
util_rndBufPrintable(&run->dynfile->data[off], len);
} else {
util_rndBuf(&run->dynfile->data[off], len);
}
memset(&run->dynfile->data[off], val, len);
}
static inline void mangle_AddSubWithRange(run_t *run, size_t off, size_t varLen,
uint64_t range, bool printable) {
static void mangle_RandomBuf(run_t* run, bool printable) {
size_t off = mangle_getOffSet(run);
size_t len = mangle_getLen(run->dynfile->size - off);
if (util_rnd64() & 1) {
len = mangle_Inflate(run, off, len, printable);
}
if (printable) {
util_rndBufPrintable(&run->dynfile->data[off], len);
} else {
util_rndBuf(&run->dynfile->data[off], len);
}
}
static inline void mangle_AddSubWithRange(
run_t* run, size_t off, size_t varLen, uint64_t range, bool printable) {
int64_t delta = (int64_t)util_rndGet(0, range * 2) - (int64_t)range;
switch (varLen) {
case 1: {
run->dynfile->data[off] += delta;
break;
}
case 2: {
int16_t val;
memcpy(&val, &run->dynfile->data[off], sizeof(val));
if (util_rnd64() & 0x1) {
val += delta;
} else {
/* Foreign endianess */
val = __builtin_bswap16(val);
val += delta;
val = __builtin_bswap16(val);
}
mangle_Overwrite(run, off, (uint8_t *)&val, varLen, printable);
mangle_Overwrite(run, off, (uint8_t*)&val, varLen, printable);
break;
}
case 4: {
int32_t val;
memcpy(&val, &run->dynfile->data[off], sizeof(val));
if (util_rnd64() & 0x1) {
val += delta;
} else {
/* Foreign endianess */
val = __builtin_bswap32(val);
val += delta;
val = __builtin_bswap32(val);
}
mangle_Overwrite(run, off, (uint8_t *)&val, varLen, printable);
mangle_Overwrite(run, off, (uint8_t*)&val, varLen, printable);
break;
}
case 8: {
int64_t val;
memcpy(&val, &run->dynfile->data[off], sizeof(val));
if (util_rnd64() & 0x1) {
val += delta;
} else {
/* Foreign endianess */
val = __builtin_bswap64(val);
val += delta;
val = __builtin_bswap64(val);
}
mangle_Overwrite(run, off, (uint8_t *)&val, varLen, printable);
mangle_Overwrite(run, off, (uint8_t*)&val, varLen, printable);
break;
}
default: {
LOG_F("Unknown variable length size: %zu", varLen);
}
}
}
static void mangle_AddSub(run_t *run, bool printable) {
static void mangle_AddSub(run_t* run, bool printable) {
size_t off = mangle_getOffSet(run);
/* 1,2,4,8 */
size_t varLen = 1U << util_rndGet(0, 3);
if ((run->dynfile->size - off) < varLen) { varLen = 1; }
if ((run->dynfile->size - off) < varLen) {
varLen = 1;
}
uint64_t range;
switch (varLen) {
case 1:
range = 16;
break;
@ -732,190 +640,170 @@ static void mangle_AddSub(run_t *run, bool printable) {
break;
default:
LOG_F("Invalid operand size: %zu", varLen);
}
mangle_AddSubWithRange(run, off, varLen, range, printable);
}
static void mangle_IncByte(run_t *run, bool printable) {
static void mangle_IncByte(run_t* run, bool printable) {
size_t off = mangle_getOffSet(run);
if (printable) {
run->dynfile->data[off] = (run->dynfile->data[off] - 32 + 1) % 95 + 32;
} else {
run->dynfile->data[off] += (uint8_t)1UL;
}
}
static void mangle_DecByte(run_t *run, bool printable) {
static void mangle_DecByte(run_t* run, bool printable) {
size_t off = mangle_getOffSet(run);
if (printable) {
run->dynfile->data[off] = (run->dynfile->data[off] - 32 + 94) % 95 + 32;
} else {
run->dynfile->data[off] -= (uint8_t)1UL;
}
}
static void mangle_NegByte(run_t *run, bool printable) {
static void mangle_NegByte(run_t* run, bool printable) {
size_t off = mangle_getOffSet(run);
if (printable) {
run->dynfile->data[off] = 94 - (run->dynfile->data[off] - 32) + 32;
} else {
run->dynfile->data[off] = ~(run->dynfile->data[off]);
}
}
static void mangle_Expand(run_t *run, bool printable) {
static void mangle_Expand(run_t* run, bool printable) {
size_t off = mangle_getOffSet(run);
size_t len;
if (util_rnd64() % 16) {
len = mangle_getLen(HF_MIN(16, run->global->mutate.maxInputSz - off));
} else {
len = mangle_getLen(run->global->mutate.maxInputSz - off);
}
mangle_Inflate(run, off, len, printable);
}
static void mangle_Shrink(run_t *run, bool printable HF_ATTR_UNUSED) {
if (run->dynfile->size <= 2U) { return; }
static void mangle_Shrink(run_t* run, bool printable HF_ATTR_UNUSED) {
if (run->dynfile->size <= 2U) {
return;
}
size_t off_start = mangle_getOffSet(run);
size_t len = mangle_LenLeft(run, off_start);
if (len == 0) { return; }
if (util_rnd64() % 16) {
len = mangle_getLen(HF_MIN(16, len));
} else {
len = mangle_getLen(len);
if (len == 0) {
return;
}
if (util_rnd64() % 16) {
len = mangle_getLen(HF_MIN(16, len));
} else {
len = mangle_getLen(len);
}
size_t off_end = off_start + len;
size_t len_to_move = run->dynfile->size - off_end;
mangle_Move(run, off_end, off_start, len_to_move);
input_setSize(run, run->dynfile->size - len);
}
static void mangle_ASCIINum(run_t *run, bool printable) {
static void mangle_ASCIINum(run_t* run, bool printable) {
size_t len = util_rndGet(2, 8);
char buf[20];
snprintf(buf, sizeof(buf), "%-19" PRId64, (int64_t)util_rnd64());
mangle_UseValue(run, (const uint8_t *)buf, len, printable);
mangle_UseValue(run, (const uint8_t*)buf, len, printable);
}
static void mangle_ASCIINumChange(run_t *run, bool printable) {
static void mangle_ASCIINumChange(run_t* run, bool printable) {
size_t off = mangle_getOffSet(run);
/* Find a digit */
for (; off < run->dynfile->size; off++) {
if (isdigit(run->dynfile->data[off])) { break; }
if (isdigit(run->dynfile->data[off])) {
break;
}
if (off == run->dynfile->size) {
mangle_Bytes(run, printable);
}
size_t left = run->dynfile->size - off;
if (left == 0) {
return;
}
size_t len = HF_MIN(20, run->dynfile->size - off);
char numbuf[21] = {};
strncpy(numbuf, (const char *)&run->dynfile->data[off], len);
uint64_t val = (uint64_t)strtoull(numbuf, NULL, 10);
switch (util_rndGet(0, 5)) {
size_t len = 0;
uint64_t val = 0;
/* 20 is maximum lenght of a string representing a 64-bit unsigned value */
for (len = 0; (len < 20) && (len < left); len++) {
char c = run->dynfile->data[off + len];
if (!isdigit(c)) {
break;
}
val *= 10;
val += (c - '0');
}
switch (util_rndGet(0, 7)) {
case 0:
val += util_rndGet(1, 256);
val++;
break;
case 1:
val -= util_rndGet(1, 256);
val--;
break;
case 2:
val *= util_rndGet(1, 256);
val *= 2;
break;
case 3:
val /= util_rndGet(1, 256);
val /= 2;
break;
case 4:
val = ~(val);
val = util_rnd64();
break;
case 5:
val = util_rnd64();
val += util_rndGet(1, 256);
break;
case 6:
val -= util_rndGet(1, 256);
break;
case 7:
val = ~(val);
break;
default:
LOG_F("Invalid choice");
};
len = HF_MIN((size_t)snprintf(numbuf, sizeof(numbuf), "%" PRIu64, val), len);
mangle_Overwrite(run, off, (const uint8_t *)numbuf, len, printable);
char buf[20];
snprintf(buf, sizeof(buf), "%-19" PRIu64, val);
mangle_UseValueAt(run, off, (const uint8_t*)buf, len, printable);
}
static void mangle_Splice(run_t *run, bool printable) {
const uint8_t *buf;
size_t sz = input_getRandomInputAsBuf(run, &buf);
if (!sz) {
static void mangle_Splice(run_t* run, bool printable) {
if (run->global->feedback.dynFileMethod == _HF_DYNFILE_NONE) {
mangle_Bytes(run, printable);
return;
}
size_t sz = 0;
const uint8_t* buf = input_getRandomInputAsBuf(run, &sz);
if (!buf) {
LOG_E("input_getRandomInputAsBuf() returned no input");
mangle_Bytes(run, printable);
return;
}
if (!sz) {
mangle_Bytes(run, printable);
return;
}
size_t remoteOff = mangle_getLen(sz) - 1;
size_t len = mangle_getLen(sz - remoteOff);
mangle_UseValue(run, &buf[remoteOff], len, printable);
}
static void mangle_Resize(run_t *run, bool printable) {
static void mangle_Resize(run_t* run, bool printable) {
ssize_t oldsz = run->dynfile->size;
ssize_t newsz = 0;
uint64_t choice = util_rndGet(0, 32);
switch (choice) {
case 0: /* Set new size arbitrarily */
newsz = (ssize_t)util_rndGet(1, run->global->mutate.maxInputSz);
break;
@ -937,33 +825,24 @@ static void mangle_Resize(run_t *run, bool printable) {
default:
LOG_F("Illegal value from util_rndGet: %" PRIu64, choice);
break;
}
if (newsz < 1) { newsz = 1; }
if (newsz < 1) {
newsz = 1;
}
if (newsz > (ssize_t)run->global->mutate.maxInputSz) {
newsz = run->global->mutate.maxInputSz;
}
input_setSize(run, (size_t)newsz);
if (newsz > oldsz) {
if (printable) { memset(&run->dynfile->data[oldsz], ' ', newsz - oldsz); }
if (printable) {
memset(&run->dynfile->data[oldsz], ' ', newsz - oldsz);
}
}
}
void mangle_mangleContent(run_t *run, int speed_factor) {
void mangle_mangleContent(run_t* run, int speed_factor) {
static void (*const mangleFuncs[])(run_t * run, bool printable) = {
/* Every *Insert or Expand expands file, so add more Shrink's */
mangle_Shrink,
mangle_Shrink,
mangle_Shrink,
mangle_Shrink,
mangle_Expand,
mangle_Bit,
@ -972,66 +851,57 @@ void mangle_mangleContent(run_t *run, int speed_factor) {
mangle_NegByte,
mangle_AddSub,
mangle_MemSet,
mangle_MemClr,
mangle_MemSwap,
mangle_MemCopy,
mangle_Bytes,
mangle_ASCIINum,
mangle_ASCIINumChange,
mangle_ByteRepeatOverwrite,
mangle_ByteRepeatInsert,
mangle_ByteRepeat,
mangle_Magic,
mangle_StaticDict,
mangle_ConstFeedbackDict,
mangle_RandomOverwrite,
mangle_RandomInsert,
mangle_RandomBuf,
mangle_Splice,
};
if (run->mutationsPerRun == 0U) { return; }
if (run->mutationsPerRun == 0U) {
return;
}
if (run->dynfile->size == 0U) {
mangle_Resize(run, /* printable= */ run->global->cfg.only_printable);
}
uint64_t changesCnt;
uint64_t changesCnt = run->global->mutate.mutationsPerRun;
if (speed_factor < 5) {
changesCnt = util_rndGet(1, run->global->mutate.mutationsPerRun);
} else if (speed_factor < 10) {
changesCnt = run->global->mutate.mutationsPerRun;
} else {
changesCnt = HF_MIN(speed_factor, 12);
changesCnt = HF_MAX(changesCnt, run->global->mutate.mutationsPerRun);
changesCnt = HF_MIN(speed_factor, 10);
changesCnt = HF_MAX(changesCnt, (run->global->mutate.mutationsPerRun * 5));
}
/* If last coverage acquisition was more than 5 secs ago, use splicing more
* frequently */
/* If last coverage acquisition was more than 5 secs ago, use splicing more frequently */
if ((time(NULL) - ATOMIC_GET(run->global->timing.lastCovUpdate)) > 5) {
if (util_rnd64() % 2) {
if (util_rnd64() & 0x1) {
mangle_Splice(run, run->global->cfg.only_printable);
}
}
for (uint64_t x = 0; x < changesCnt; x++) {
if (run->global->feedback.cmpFeedback && (util_rnd64() & 0x1)) {
/*
* mangle_ConstFeedbackDict() is quite powerful if the dynamic feedback dictionary
* exists. If so, give it 50% chance of being used among all mangling functions.
*/
mangle_ConstFeedbackDict(run, /* printable= */ run->global->cfg.only_printable);
} else {
uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleFuncs) - 1);
mangleFuncs[choice](run, /* printable= */ run->global->cfg.only_printable);
}
}
wmb();
}