From aa60a95e538c48b4c548e91690411c81dd108fd5 Mon Sep 17 00:00:00 2001 From: Tai Duy Nguyen Date: Sun, 18 Aug 2019 15:05:44 +0800 Subject: [PATCH] ignore jumpi in constant function --- fuzzer/Utils.h | 21 ++++++++++++-- libfuzzer/BytecodeBranch.cpp | 54 ++++++++++++++++++++++------------ libfuzzer/Fuzzer.cpp | 56 ++++++++++++++++++------------------ libfuzzer/Fuzzer.h | 1 + 4 files changed, 84 insertions(+), 48 deletions(-) diff --git a/fuzzer/Utils.h b/fuzzer/Utils.h index 1ec7487aa..3aa848702 100644 --- a/fuzzer/Utils.h +++ b/fuzzer/Utils.h @@ -46,7 +46,24 @@ ContractInfo parseJson(string jsonFile, string contractName, bool isMain) { contractInfo.srcmap = root.get(srcmapPath); contractInfo.srcmapRuntime = root.get(srcmapRuntimePath); contractInfo.contractName = fullContractName; - contractInfo.source = ""; + for (auto it : root.get_child("sources")) { + auto ast = it.second.get_child("AST"); + vector stack = {ast}; + while (stack.size() > 0) { + auto item = stack[stack.size() - 1]; + stack.pop_back(); + if (item.get("name") == "FunctionDefinition") { + if (item.get("attributes.constant")) { + contractInfo.constantFunctionSrcmap.push_back(item.get("src")); + } + } + if (item.get_child_optional("children")) { + for (auto it : item.get_child("children")) { + stack.push_back(it.second); + } + } + } + } return contractInfo; } @@ -90,7 +107,7 @@ string compileSolFiles(string folder) { forEachFile(folder, ".sol", [&](directory_entry file) { string filePath = file.path().string(); ret << "solc"; - ret << " --combined-json abi,bin,bin-runtime,srcmap,srcmap-runtime " + filePath; + ret << " --combined-json abi,bin,bin-runtime,srcmap,srcmap-runtime,ast " + filePath; ret << " > " + filePath + ".json"; ret << endl; }); diff --git a/libfuzzer/BytecodeBranch.cpp b/libfuzzer/BytecodeBranch.cpp index b628b2f54..9b674b185 100644 --- a/libfuzzer/BytecodeBranch.cpp +++ b/libfuzzer/BytecodeBranch.cpp @@ -10,6 +10,12 @@ namespace fuzzer { make_tuple(fromHex(deploymentBin), contractInfo.srcmap, false), make_tuple(fromHex(contractInfo.binRuntime), contractInfo.srcmapRuntime, true), }; + // JUMPI inside constant function + vector> constantJumpis; + for (auto it : contractInfo.constantFunctionSrcmap) { + auto elements = splitString(it, ':'); + constantJumpis.push_back(make_pair(stoi(elements[0]), stoi(elements[1]))); + } for (auto progIt : progInfo) { auto opcodes = decodeBytecode(get<0>(progIt)); auto isRuntime = get<2>(progIt); @@ -31,27 +37,39 @@ namespace fuzzer { for (auto candidate : candidates) { if (get<0>(candidate) > offset && get<0>(candidate) + get<1>(candidate) < offset + len) { auto candidateSnippet = contractInfo.source.substr(get<0>(candidate), get<1>(candidate)); - Logger::info(candidateSnippet); - if (isRuntime) { - runtimeJumpis.insert(get<2>(candidate)); - Logger::info("pc: " + to_string(get<2>(candidate))); - snippets.insert(make_pair(get<2>(candidate), candidateSnippet)); - } else { - deploymentJumpis.insert(get<2>(candidate)); - Logger::info("pc: " + to_string(get<2>(candidate))); - snippets.insert(make_pair(get<2>(candidate), candidateSnippet)); + auto numConstant = count_if(constantJumpis.begin(), constantJumpis.end(), [&](const pair &j) { + return get<0>(candidate) >= get<0>(j) + && get<0>(candidate) + get<1>(candidate) <= get<0>(j) + get<1>(j); + }); + if (!numConstant) { + Logger::info(candidateSnippet); + if (isRuntime) { + runtimeJumpis.insert(get<2>(candidate)); + Logger::info("pc: " + to_string(get<2>(candidate))); + snippets.insert(make_pair(get<2>(candidate), candidateSnippet)); + } else { + deploymentJumpis.insert(get<2>(candidate)); + Logger::info("pc: " + to_string(get<2>(candidate))); + snippets.insert(make_pair(get<2>(candidate), candidateSnippet)); + } } } } - Logger::info(contractInfo.source.substr(offset, len)); - if (isRuntime) { - runtimeJumpis.insert(get<0>(opcodes[i])); - Logger::info("pc: " + to_string(get<0>(opcodes[i]))); - snippets.insert(make_pair(get<0>(opcodes[i]), snippet)); - } else { - deploymentJumpis.insert(get<0>(opcodes[i])); - Logger::info("pc: " + to_string(get<0>(opcodes[i]))); - snippets.insert(make_pair(get<0>(opcodes[i]), snippet)); + auto numConstant = count_if(constantJumpis.begin(), constantJumpis.end(), [&](const pair &j) { + return offset >= get<0>(j) + && offset + len <= get<0>(j) + get<1>(j); + }); + if (!numConstant) { + Logger::info(contractInfo.source.substr(offset, len)); + if (isRuntime) { + runtimeJumpis.insert(get<0>(opcodes[i])); + Logger::info("pc: " + to_string(get<0>(opcodes[i]))); + snippets.insert(make_pair(get<0>(opcodes[i]), snippet)); + } else { + deploymentJumpis.insert(get<0>(opcodes[i])); + Logger::info("pc: " + to_string(get<0>(opcodes[i]))); + snippets.insert(make_pair(get<0>(opcodes[i]), snippet)); + } } candidates.clear(); } else { diff --git a/libfuzzer/Fuzzer.cpp b/libfuzzer/Fuzzer.cpp index 7ee863ecf..cfd2e420a 100644 --- a/libfuzzer/Fuzzer.cpp +++ b/libfuzzer/Fuzzer.cpp @@ -399,40 +399,40 @@ void Fuzzer::start() { fuzzStat.stageFinds[STAGE_FLIP32] += leaders.size() - originHitCount; originHitCount = leaders.size(); - Logger::debug("SingleArith"); - mutation.singleArith(save); - fuzzStat.stageFinds[STAGE_ARITH8] += leaders.size() - originHitCount; - originHitCount = leaders.size(); + //Logger::debug("SingleArith"); + //mutation.singleArith(save); + //fuzzStat.stageFinds[STAGE_ARITH8] += leaders.size() - originHitCount; + //originHitCount = leaders.size(); - Logger::debug("TwoArith"); - mutation.twoArith(save); - fuzzStat.stageFinds[STAGE_ARITH16] += leaders.size() - originHitCount; - originHitCount = leaders.size(); + //Logger::debug("TwoArith"); + //mutation.twoArith(save); + //fuzzStat.stageFinds[STAGE_ARITH16] += leaders.size() - originHitCount; + //originHitCount = leaders.size(); - Logger::debug("FourArith"); - mutation.fourArith(save); - fuzzStat.stageFinds[STAGE_ARITH32] += leaders.size() - originHitCount; - originHitCount = leaders.size(); + //Logger::debug("FourArith"); + //mutation.fourArith(save); + //fuzzStat.stageFinds[STAGE_ARITH32] += leaders.size() - originHitCount; + //originHitCount = leaders.size(); - Logger::debug("SingleInterest"); - mutation.singleInterest(save); - fuzzStat.stageFinds[STAGE_INTEREST8] += leaders.size() - originHitCount; - originHitCount = leaders.size(); + //Logger::debug("SingleInterest"); + //mutation.singleInterest(save); + //fuzzStat.stageFinds[STAGE_INTEREST8] += leaders.size() - originHitCount; + //originHitCount = leaders.size(); - Logger::debug("TwoInterest"); - mutation.twoInterest(save); - fuzzStat.stageFinds[STAGE_INTEREST16] += leaders.size() - originHitCount; - originHitCount = leaders.size(); + //Logger::debug("TwoInterest"); + //mutation.twoInterest(save); + //fuzzStat.stageFinds[STAGE_INTEREST16] += leaders.size() - originHitCount; + //originHitCount = leaders.size(); - Logger::debug("FourInterest"); - mutation.fourInterest(save); - fuzzStat.stageFinds[STAGE_INTEREST32] += leaders.size() - originHitCount; - originHitCount = leaders.size(); + //Logger::debug("FourInterest"); + //mutation.fourInterest(save); + //fuzzStat.stageFinds[STAGE_INTEREST32] += leaders.size() - originHitCount; + //originHitCount = leaders.size(); - Logger::debug("overwriteDict"); - mutation.overwriteWithDictionary(save); - fuzzStat.stageFinds[STAGE_EXTRAS_UO] += leaders.size() - originHitCount; - originHitCount = leaders.size(); + //Logger::debug("overwriteDict"); + //mutation.overwriteWithDictionary(save); + //fuzzStat.stageFinds[STAGE_EXTRAS_UO] += leaders.size() - originHitCount; + //originHitCount = leaders.size(); Logger::debug("overwriteAddress"); mutation.overwriteWithAddressDictionary(save); diff --git a/libfuzzer/Fuzzer.h b/libfuzzer/Fuzzer.h index 810ce6935..667d67466 100644 --- a/libfuzzer/Fuzzer.h +++ b/libfuzzer/Fuzzer.h @@ -22,6 +22,7 @@ namespace fuzzer { string srcmap; string srcmapRuntime; string source; + vector constantFunctionSrcmap; bool isMain; }; struct FuzzParam {