Skip to content

Commit

Permalink
Update score
Browse files Browse the repository at this point in the history
  • Loading branch information
duytai committed Aug 7, 2019
1 parent fc7f0c1 commit 66f17f6
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 105 deletions.
2 changes: 1 addition & 1 deletion libfuzzer/FuzzItem.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ namespace fuzzer {
struct FuzzItem {
bytes data;
TargetContainerResult res;
uint64_t fuzzedCount = 0;
bool fuzzed = false;
uint64_t depth = 0;
FuzzItem(bytes _data) {
data = _data;
Expand Down
164 changes: 70 additions & 94 deletions libfuzzer/Fuzzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,11 @@ bool Fuzzer::hasNewExceptions(unordered_map<string, unordered_set<u64>> uexps) {
}

/* Detect new bits by comparing tracebits to virginbits */
bool Fuzzer::hasNewBits(unordered_set<uint64_t> _tracebits) {
auto originSize = tracebits.size();
for (auto it : _tracebits) tracebits.insert(it);
auto newSize = tracebits.size();
return newSize - originSize;
void Fuzzer::updateTracebits(unordered_set<uint64_t> _tracebits) {
for (auto it: _tracebits) tracebits.insert(it);
}

void Fuzzer::updatePredicates(unordered_map<uint64_t, u256> _pred) {
// If predicate is in tracebits => need to remove it
vector<uint64_t> eleminated_keys = {};
for (auto it : _pred) {
predicates.insert(it.first);
};
Expand Down Expand Up @@ -113,7 +108,7 @@ void Fuzzer::showStats(Mutation mutation, vector<bool> vulnerabilities) {
auto callOrder1 = to_string(mutation.stageCycles[STAGE_ORDER]);
auto callOrder = padStr(callOrder1, 30);
auto pending = padStr(to_string(queues.size() - fuzzStat.idx - 1), 5);
auto fav = count_if(queues.begin() + fuzzStat.idx + 1, queues.end(), [](FuzzItem item) { return !item.fuzzedCount; });
auto fav = count_if(queues.begin() + fuzzStat.idx + 1, queues.end(), [](FuzzItem item) { return !item.fuzzed; });
auto pendingFav = padStr(to_string(fav), 5);
auto maxdepthStr = padStr(to_string(fuzzStat.maxdepth), 5);
for (auto exp: uniqExceptions) expCout+= exp.second.size();
Expand All @@ -131,7 +126,7 @@ void Fuzzer::showStats(Mutation mutation, vector<bool> vulnerabilities) {
printf(bH " stage execs : %s" bH " branches : %s" bH "\n", stageExec.c_str(), numBranches.c_str());
printf(bH " total execs : %s" bH " coverage : %s" bH "\n", allExecs.c_str(), coverage.c_str());
printf(bH " exec speed : %s" bH " %s" bH "\n", execSpeed.c_str(), padStr("", 15).c_str());
printf(bH " cycle prog : %s" bH " %s" bH "\n", cycleProgress.c_str(), coverage.c_str());
printf(bH " cycle prog : %s" bH " %s" bH "\n", cycleProgress.c_str(), padStr("", 15).c_str());
printf(bLTR bV5 cGRN " fuzzing yields " cRST bV5 bV5 bV5 bV2 bV bBTR bV10 bV bTTR bV cGRN " path geometry " cRST bV2 bV2 bRTR "\n");
printf(bH " bit flips : %s" bH " pending : %s" bH "\n", bitflip.c_str(), pending.c_str());
printf(bH " byte flips : %s" bH " pending fav : %s" bH "\n", byteflip.c_str(), pendingFav.c_str());
Expand Down Expand Up @@ -242,45 +237,12 @@ FuzzItem Fuzzer::saveIfInterest(TargetExecutive& te, bytes data, uint64_t depth)
FuzzItem item(revisedData);
item.res = te.exec(revisedData);
fuzzStat.totalExecs ++;
auto hasNewBranch = hasNewBits(item.res.tracebits);
for (auto it : item.res.predicates) {
auto leader_it = std::find_if(leaders.begin(), leaders.end(), [&](const Leader& leader) {
return leader.branchId == it.first;
});
if (leader_it == leaders.end()) {
// New leader
Leader leader;
leader.branchId = it.first;
leader.queue_pos = queues.size();
leader.comparisonValue = it.second;
leader.replaceable = !hasNewBranch;
leaders.push_back(leader);
if (!hasNewBranch) {
if (depth + 1 > fuzzStat.maxdepth) fuzzStat.maxdepth = depth + 1;
item.depth = depth + 1;
queues.push_back(item);
}
} else {
if((*leader_it).comparisonValue > it.second) {
// Replace previous leader
(*leader_it).comparisonValue = it.second;
if (!hasNewBranch) {
if (depth + 1 > fuzzStat.maxdepth) fuzzStat.maxdepth = depth + 1;
if ((*leader_it).replaceable) {
queues[fuzzStat.idx] = item;
} else {
(*leader_it).queue_pos = queues.size();
(*leader_it).replaceable = true;
queues.push_back(item);
}
} else {
(*leader_it).queue_pos = queues.size();
(*leader_it).replaceable = false;
}
};
for (auto it : item.res.tracebits) {
if (!tracebits.count(it)) {
auto leader = Leader(item, 0);
}
}
if (hasNewBranch) {
if (hasNewBranch(item.res.tracebits).size() > 0) {
if (depth + 1 > fuzzStat.maxdepth) fuzzStat.maxdepth = depth + 1;
item.depth = depth + 1;
fuzzStat.lastNewPath = timer.elapsed();
Expand All @@ -290,6 +252,7 @@ FuzzItem Fuzzer::saveIfInterest(TargetExecutive& te, bytes data, uint64_t depth)
if (hasNewExceptions(item.res.uniqExceptions)) {
writeException(revisedData, "__EXCEPTION__");
}
updateTracebits(item.res.tracebits);
updatePredicates(item.res.predicates);
return item;
}
Expand Down Expand Up @@ -322,7 +285,10 @@ void Fuzzer::start() {
saveIfInterest(executive, ca.randomTestcase(), 0);
int origHitCount = queues.size();
while (true) {
FuzzItem curItem = queues[fuzzStat.idx];
auto branchId = queues[fuzzStat.idx];
Leader leader = leaders[branchId];
FuzzItem curItem = leader.item;
//FuzzItem curItem = queues[fuzzStat.idx];
Mutation mutation(curItem, make_tuple(codeDict, addressDict));
auto save = [&](bytes data) {
auto item = saveIfInterest(executive, data, curItem.depth);
Expand All @@ -345,68 +311,78 @@ void Fuzzer::start() {
}
return item;
};
// Haven't fuzzed before
if (!curItem.fuzzed) {
mutation.singleWalkingBit(save);
fuzzStat.stageFinds[STAGE_FLIP1] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.singleWalkingBit(save);
fuzzStat.stageFinds[STAGE_FLIP1] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.twoWalkingBit(save);
fuzzStat.stageFinds[STAGE_FLIP2] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.twoWalkingBit(save);
fuzzStat.stageFinds[STAGE_FLIP2] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.fourWalkingBit(save);
fuzzStat.stageFinds[STAGE_FLIP4] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.fourWalkingBit(save);
fuzzStat.stageFinds[STAGE_FLIP4] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.singleWalkingByte(save);
fuzzStat.stageFinds[STAGE_FLIP8] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.singleWalkingByte(save);
fuzzStat.stageFinds[STAGE_FLIP8] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.twoWalkingByte(save);
fuzzStat.stageFinds[STAGE_FLIP16] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.twoWalkingByte(save);
fuzzStat.stageFinds[STAGE_FLIP16] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.fourWalkingByte(save);
fuzzStat.stageFinds[STAGE_FLIP32] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.fourWalkingByte(save);
fuzzStat.stageFinds[STAGE_FLIP32] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.singleArith(save);
fuzzStat.stageFinds[STAGE_ARITH8] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.singleArith(save);
fuzzStat.stageFinds[STAGE_ARITH8] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.twoArith(save);
fuzzStat.stageFinds[STAGE_ARITH16] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.twoArith(save);
fuzzStat.stageFinds[STAGE_ARITH16] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.fourArith(save);
fuzzStat.stageFinds[STAGE_ARITH32] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.fourArith(save);
fuzzStat.stageFinds[STAGE_ARITH32] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.singleInterest(save);
fuzzStat.stageFinds[STAGE_INTEREST8] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.singleInterest(save);
fuzzStat.stageFinds[STAGE_INTEREST8] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.twoInterest(save);
fuzzStat.stageFinds[STAGE_INTEREST16] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.twoInterest(save);
fuzzStat.stageFinds[STAGE_INTEREST16] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.fourInterest(save);
fuzzStat.stageFinds[STAGE_INTEREST32] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.fourInterest(save);
fuzzStat.stageFinds[STAGE_INTEREST32] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.overwriteWithDictionary(save);
fuzzStat.stageFinds[STAGE_EXTRAS_UO] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.overwriteWithDictionary(save);
fuzzStat.stageFinds[STAGE_EXTRAS_UO] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.overwriteWithAddressDictionary(save);
fuzzStat.stageFinds[STAGE_EXTRAS_AO] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.overwriteWithAddressDictionary(save);
fuzzStat.stageFinds[STAGE_EXTRAS_AO] += queues.size() - origHitCount;
origHitCount = queues.size();
mutation.havoc(save);
fuzzStat.stageFinds[STAGE_HAVOC] += queues.size() - origHitCount;
origHitCount = queues.size();

mutation.havoc(save);
fuzzStat.stageFinds[STAGE_HAVOC] += queues.size() - origHitCount;
origHitCount = queues.size();

queues[fuzzStat.idx].fuzzedCount ++;
queues[fuzzStat.idx].fuzzed = true;
} else {
// less data => more for-loop | more data => less for-loop
auto forRate = curItem.data.size() / 32;
for (auto i = 0; i < 100000 / forRate; i += 1) {
mutation.havoc(save);
fuzzStat.stageFinds[STAGE_HAVOC] += queues.size() - origHitCount;
origHitCount = queues.size();
}
}
fuzzStat.idx = (fuzzStat.idx + 1) % queues.size();
if (fuzzStat.idx == 0) fuzzStat.queueCycle ++;
}
Expand Down
20 changes: 10 additions & 10 deletions libfuzzer/Fuzzer.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,6 @@ using namespace std;
namespace fuzzer {
enum FuzzMode { RANDOM, AFL };
enum Reporter { TERMINAL, CSV_FILE };
struct Leader {
uint64_t branchId = 0;
u256 comparisonValue = 0;
uint64_t queue_pos = 0;
bool replaceable = false;
};
struct ContractInfo {
string abiJson;
string bin;
Expand Down Expand Up @@ -49,12 +43,18 @@ namespace fuzzer {
int numException = 0;
int numJumpis = 0;
};

struct Leader {
FuzzItem item;
u256 comparisonValue = 0;
Leader(FuzzItem _item, u256 _comparisionValue): item(_item) {
comparisonValue = _comparisionValue;
}
};
class Fuzzer {
unordered_set<uint64_t> tracebits;
unordered_set<uint64_t> predicates;
vector<FuzzItem> queues;
vector<Leader> leaders;
vector<uint64_t> queues;
unordered_map<uint64_t, Leader> leaders;
unordered_map<string, unordered_set<u64>> uniqExceptions;
Timer timer;
FuzzParam fuzzParam;
Expand All @@ -63,12 +63,12 @@ namespace fuzzer {
ContractInfo mainContract();
public:
Fuzzer(FuzzParam fuzzParam);
bool hasNewBits(unordered_set<uint64_t> tracebits);
bool hasNewExceptions(unordered_map<string, unordered_set<u64>> uniqExceptions);
FuzzItem saveIfInterest(TargetExecutive& te, bytes data, uint64_t depth);
void writeTestcase(bytes data, string prefix);
void writeException(bytes data, string prefix);
void showStats(Mutation mutation, vector<bool> vulerabilities);
void updateTracebits(unordered_set<uint64_t> tracebits);
void updatePredicates(unordered_map<uint64_t, u256> predicates);
void start();
};
Expand Down

0 comments on commit 66f17f6

Please sign in to comment.