From 62f1bfed99b82bc073c138a00ff9a30bb596d09d Mon Sep 17 00:00:00 2001 From: Adrian Herrera Date: Tue, 20 Jul 2021 04:23:26 +0000 Subject: utils: added optimin corpus minimizer --- utils/optimin/README.md | 74 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 utils/optimin/README.md (limited to 'utils/optimin/README.md') diff --git a/utils/optimin/README.md b/utils/optimin/README.md new file mode 100644 index 00000000..5001b59d --- /dev/null +++ b/utils/optimin/README.md @@ -0,0 +1,74 @@ +# OptiMin + +OptiMin is a corpus minimizer that uses a +[MaxSAT](https://en.wikipedia.org/wiki/Maximum_satisfiability_problem) solver +to identify a subset of functionally distinct files that exercise different code +paths in a target program. + +Unlike most corpus minimizers, such as `afl-cmin`, OptiMin does not rely on +heuristic and/or greedy algorithms to identify these functionally distinct +files. This means that minimized corpora are generally much smaller than those +produced by other tools. + +## Usage + +To build the `optimin` executable (when cloned from github): + +```bash +# Ensure EvalMaxSAT is available +git submodule init +git submodule update + +mkdir build +cd build + +# You may have to specify -DLLVM_DIR=`llvm-config --cmakedir` if you have a +# non-standard LLVM install (e.g., install via apt) +cmake .. +make -j +make install +``` + +Otherwise, run the `build_optimin.sh` script. Running `optimin` is the same as +running `afl-cmin`. + +### Weighted Minimizations + +OptiMin allows for weighted minimizations. For examples, seeds can be weighted +by file size (or execution time), thus preferencing the selection of smaller (or +faster) seeds. + +To perform a weighted minimization, supply a CSV file with the `-w` option. This +CSV file is formatted as follows: + +``` +SEED_1,WEIGHT_1 +SEED_2,WEIGHT_2 +... +SEED_N,WEIGHT_N +``` + +Where `SEED_N` is the file name (**not** path) of a seed in the input directory, +and `WEIGHT_N` is an integer weight. + +## Further Details and Citation + +For more details, please see the paper [Seed Selection for Successful +Fuzzing](https://dl.acm.org/doi/10.1145/3460319.3464795). If you use OptiMin in +your research, please cite this paper. + +Bibtex: + +```bibtex +@inproceedings{Herrera:2021:FuzzSeedSelection, + author = {Adrian Herrera and Hendra Gunadi and Shane Magrath and Michael Norrish and Mathias Payer and Antony L. Hosking}, + title = {Seed Selection for Successful Fuzzing}, + booktitle = {30th ACM SIGSOFT International Symposium on Software Testing and Analysis}, + series = {ISSTA}, + year = {2021}, + pages = {230--243}, + numpages = {14}, + location = {Virtual, Denmark}, + publisher = {Association for Computing Machinery}, +} +``` -- cgit 1.4.1 From 60cbe5b4bec445438718d27dc0cfda6a4d5de81e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 21 Jul 2021 09:55:22 +0200 Subject: optimin nits --- custom_mutators/grammar_mutator/grammar_mutator | 2 +- docs/Changelog.md | 5 +- qemu_mode/qemuafl | 2 +- unicorn_mode/unicornafl | 2 +- utils/optimin/README.md | 49 +++++++++++----- utils/optimin/build_optimin.sh | 7 ++- utils/optimin/src/OptiMin.cpp | 75 +++++++++++++++++++++++++ utils/optimin/src/ProgressBar.h | 13 +++++ 8 files changed, 133 insertions(+), 22 deletions(-) (limited to 'utils/optimin/README.md') diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator index b3c4fcfa..b79d51a8 160000 --- a/custom_mutators/grammar_mutator/grammar_mutator +++ b/custom_mutators/grammar_mutator/grammar_mutator @@ -1 +1 @@ -Subproject commit b3c4fcfa6ae28918bc410f7747135eafd4fb7263 +Subproject commit b79d51a8daccbd7a693f9b6765c81ead14f28e26 diff --git a/docs/Changelog.md b/docs/Changelog.md index cb22c272..d81fdf49 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,7 +9,10 @@ Want to stay in the loop on major new features? Join our mailing list by sending a mail to . ### Version ++3.15a (dev) - - added the very good grammar mutator "GramaTron" to the custom_mutators + - added the very good grammar mutator "GramaTron" to the + custom_mutators + - added optimin, a faster and better corpus minimizer by + Adrian Herrera. Thank you! ### Version ++3.14c (release) diff --git a/qemu_mode/qemuafl b/qemu_mode/qemuafl index 21ff3438..a6758d1c 160000 --- a/qemu_mode/qemuafl +++ b/qemu_mode/qemuafl @@ -1 +1 @@ -Subproject commit 21ff34383764a8c6f66509b3b8d5282468c721e1 +Subproject commit a6758d1cc3e4dde88fca3f0b3a903581b7c8b2e5 diff --git a/unicorn_mode/unicornafl b/unicorn_mode/unicornafl index 0d82727f..019b8715 160000 --- a/unicorn_mode/unicornafl +++ b/unicorn_mode/unicornafl @@ -1 +1 @@ -Subproject commit 0d82727f2b477de82fa355edef9bc158bd25d374 +Subproject commit 019b871539fe9ed3f41d882385a8b02c243d49ad diff --git a/utils/optimin/README.md b/utils/optimin/README.md index 5001b59d..ec9c4b0a 100644 --- a/utils/optimin/README.md +++ b/utils/optimin/README.md @@ -10,27 +10,46 @@ heuristic and/or greedy algorithms to identify these functionally distinct files. This means that minimized corpora are generally much smaller than those produced by other tools. -## Usage +## Building -To build the `optimin` executable (when cloned from github): +To build the `optimin` just execute the `build_optimin.sh` script. -```bash -# Ensure EvalMaxSAT is available -git submodule init -git submodule update +## Running -mkdir build -cd build +Running `optimin` is the same as running `afl-cmin`: -# You may have to specify -DLLVM_DIR=`llvm-config --cmakedir` if you have a -# non-standard LLVM install (e.g., install via apt) -cmake .. -make -j -make install +``` +Required parameters: + -i dir - input directory with starting corpus + -o dir - output directory for minimized files + +Execution control settings: + -f file - location read by the fuzzed program (stdin) + -m megs - memory limit for child process (none MB) + -t msec - run time limit for child process (none) + -O - use binary-only instrumentation (FRIDA mode) + -Q - use binary-only instrumentation (QEMU mode) + -U - use unicorn-based instrumentation (unicorn mode) + +Minimization settings: + -C - keep crashing inputs, reject everything else + -e - solve for edge coverage only, ignore hit counts + +For additional tips, please consult README.md + +Environment variables used: +AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp +AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash +AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up +AFL_KEEP_TRACES: leave the temporary /.traces directory +AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL) +AFL_NO_FORKSRV: run target via execve instead of using the forkserver +AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH +AFL_PRINT_FILENAMES: If set, the filename currently processed will be printed to stdout +AFL_SKIP_BIN_CHECK: skip afl instrumentation checks for target binary ``` -Otherwise, run the `build_optimin.sh` script. Running `optimin` is the same as -running `afl-cmin`. +Example: `optimin -i files -o seeds -- ./target @@` ### Weighted Minimizations diff --git a/utils/optimin/build_optimin.sh b/utils/optimin/build_optimin.sh index 7397aa45..9480f966 100755 --- a/utils/optimin/build_optimin.sh +++ b/utils/optimin/build_optimin.sh @@ -122,9 +122,10 @@ echo echo "[+] EvalMaxSAT successfully prepared!" echo "[+] Building OptiMin now." mkdir -p build -cd build -cmake .. -DLLVM_DIR=`$LLVM_CONFIG --cmakedir` -make -j$CORES +cd build || exit 1 +cmake .. -DLLVM_DIR=`$LLVM_CONFIG --cmakedir` || exit 1 +make -j$CORES || exit 1 cd .. echo +cp -fv build/src/optimin . || exit 1 echo "[+] OptiMin successfully built!" diff --git a/utils/optimin/src/OptiMin.cpp b/utils/optimin/src/OptiMin.cpp index e02fcbe5..4fbf3416 100644 --- a/utils/optimin/src/OptiMin.cpp +++ b/utils/optimin/src/OptiMin.cpp @@ -33,16 +33,20 @@ namespace { /// Ensure seed weights default to 1 class Weight { + public: Weight() : Weight(1){}; Weight(uint32_t V) : Value(V){}; operator unsigned() const { + return Value; + } private: const unsigned Value; + }; // -------------------------------------------------------------------------- // @@ -89,16 +93,27 @@ static std::string AFLShowmapPath; static bool TargetArgsHasAtAt = false; static const auto ErrMsg = [] { + return WithColor(errs(), HighlightColor::Error) << "[-] "; + }; + static const auto WarnMsg = [] { + return WithColor(errs(), HighlightColor::Warning) << "[-] "; + }; + static const auto SuccMsg = [] { + return WithColor(outs(), HighlightColor::String) << "[+] "; + }; + static const auto StatMsg = [] { + return WithColor(outs(), HighlightColor::Remark) << "[*] "; + }; static cl::opt CorpusDir("i", cl::desc("Input directory"), @@ -124,6 +139,7 @@ static cl::opt Timeout( static cl::opt CrashMode( "C", cl::desc("Keep crashing inputs, reject everything else")); static cl::opt QemuMode("Q", cl::desc("Use binary-only instrumentation")); + } // anonymous namespace // -------------------------------------------------------------------------- // @@ -131,24 +147,33 @@ static cl::opt QemuMode("Q", cl::desc("Use binary-only instrumentation")); // -------------------------------------------------------------------------- // static void GetWeights(const MemoryBuffer &MB, WeightsMap &Weights) { + SmallVector Lines; MB.getBuffer().trim().split(Lines, '\n'); unsigned Weight = 0; for (const auto &Line : Lines) { + const auto &[Seed, WeightStr] = Line.split(','); if (to_integer(WeightStr, Weight, 10)) { + Weights.try_emplace(Seed, Weight); + } else { + WarnMsg() << "Failed to read weight for `" << Seed << "`. Skipping...\n"; + } + } + } [[nodiscard]] static std::error_code getAFLCoverage(const StringRef Seed, AFLCoverageVector &Cov) { + Optional Redirects[] = {None, None, None}; std::error_code EC; @@ -159,6 +184,7 @@ static void GetWeights(const MemoryBuffer &MB, WeightsMap &Weights) { // Prepare afl-showmap arguments SmallVector AFLShowmapArgs{ + AFLShowmapPath, "-m", MemLimit, "-t", Timeout, "-q", "-o", OutputPath}; if (TargetArgsHasAtAt) @@ -180,8 +206,10 @@ static void GetWeights(const MemoryBuffer &MB, WeightsMap &Weights) { // Parse afl-showmap output const auto CovOrErr = MemoryBuffer::getFile(OutputPath); if (EC = CovOrErr.getError()) { + sys::fs::remove(OutputPath); return EC; + } SmallVector Lines; @@ -191,21 +219,27 @@ static void GetWeights(const MemoryBuffer &MB, WeightsMap &Weights) { unsigned Freq = 0; for (const auto &Line : Lines) { + const auto &[EdgeStr, FreqStr] = Line.split(':'); to_integer(EdgeStr, Edge, 10); to_integer(FreqStr, Freq, 10); Cov.push_back({Edge, Freq}); + } return sys::fs::remove(OutputPath); + } static inline void StartTimer(bool ShowProgBar) { + StartTime = std::chrono::system_clock::now(); + } static inline void EndTimer(bool ShowProgBar) { + EndTime = std::chrono::system_clock::now(); Duration = std::chrono::duration_cast(EndTime - StartTime); @@ -214,6 +248,7 @@ static inline void EndTimer(bool ShowProgBar) { outs() << '\n'; else outs() << Duration.count() << "s\n"; + } // -------------------------------------------------------------------------- // @@ -221,6 +256,7 @@ static inline void EndTimer(bool ShowProgBar) { // -------------------------------------------------------------------------- // int main(int argc, char *argv[]) { + WeightsMap Weights; ProgressBar ProgBar; std::error_code EC; @@ -234,8 +270,10 @@ int main(int argc, char *argv[]) { cl::ParseCommandLineOptions(argc, argv, "Optimal corpus minimizer"); if (!sys::fs::is_directory(OutputDir)) { + ErrMsg() << "Invalid output directory `" << OutputDir << "`\n"; return 1; + } for (const auto &Arg : TargetArgs) @@ -247,9 +285,12 @@ int main(int argc, char *argv[]) { const auto AFLShowmapOrErr = sys::findProgramByName("afl-showmap"); if (AFLShowmapOrErr.getError()) { + ErrMsg() << "Failed to find afl-showmap. Check your PATH\n"; return 1; + } + AFLShowmapPath = *AFLShowmapOrErr; // ------------------------------------------------------------------------ // @@ -260,19 +301,23 @@ int main(int argc, char *argv[]) { // ------------------------------------------------------------------------ // if (WeightsFile != "") { + StatMsg() << "Reading weights from `" << WeightsFile << "`... "; StartTimer(/*ShowProgBar=*/false); const auto WeightsOrErr = MemoryBuffer::getFile(WeightsFile); if (EC = WeightsOrErr.getError()) { + ErrMsg() << "Failed to read weights from `" << WeightsFile << "`: " << EC.message() << '\n'; return 1; + } GetWeights(*WeightsOrErr.get(), Weights); EndTimer(/*ShowProgBar=*/false); + } // ------------------------------------------------------------------------ // @@ -289,20 +334,26 @@ int main(int argc, char *argv[]) { for (sys::fs::directory_iterator Dir(CorpusDir, EC), DirEnd; Dir != DirEnd && !EC; Dir.increment(EC)) { + if (EC) { + ErrMsg() << "Failed to traverse corpus directory `" << CorpusDir << "`: " << EC.message() << '\n'; return 1; + } const auto &Path = Dir->path(); if (EC = sys::fs::status(Path, Status)) { + WarnMsg() << "Failed to access seed file `" << Path << "`: " << EC.message() << ". Skipping...\n"; continue; + } switch (Status.type()) { + case sys::fs::file_type::regular_file: case sys::fs::file_type::symlink_file: case sys::fs::file_type::type_unknown: @@ -310,7 +361,9 @@ int main(int argc, char *argv[]) { default: /* Ignore */ break; + } + } EndTimer(/*ShowProgBar=*/false); @@ -336,12 +389,15 @@ int main(int argc, char *argv[]) { AFLCoverageVector Cov; for (const auto &SeedFile : SeedFiles) { + // Execute seed Cov.clear(); if (EC = getAFLCoverage(SeedFile, Cov)) { + ErrMsg() << "Failed to get coverage for seed " << SeedFile << ": " << EC.message() << '\n'; return 1; + } // Create a variable to represent the seed @@ -350,18 +406,25 @@ int main(int argc, char *argv[]) { // Record the set of seeds that cover a particular edge for (const auto &[Edge, Freq] : Cov) { + if (EdgesOnly) { + // Ignore edge frequency SeedCoverage[Edge].insert(Var); + } else { + // Executing edge `E` `N` times means that it was executed `N - 1` times for (unsigned I = 0; I < Freq; ++I) SeedCoverage[MAX_EDGE_FREQ * Edge + I].insert(Var); + } + } if ((++SeedCount % 10 == 0) && ShowProgBar) ProgBar.update(SeedCount * 100 / NumSeeds, "Generating seed coverage"); + } EndTimer(ShowProgBar); @@ -379,6 +442,7 @@ int main(int argc, char *argv[]) { // (hard constraint) std::vector Clauses; for (const auto &[_, Seeds] : SeedCoverage) { + if (Seeds.empty()) continue; Clauses.clear(); @@ -390,6 +454,7 @@ int main(int argc, char *argv[]) { if ((++SeedCount % 10 == 0) && ShowProgBar) ProgBar.update(SeedCount * 100 / SeedCoverage.size(), "Generating clauses"); + } // Select the minimum number of seeds that cover a particular set of edges @@ -420,12 +485,16 @@ int main(int argc, char *argv[]) { SmallString<32> OutputSeed; if (Solved) { + for (const auto &[Var, Seed] : SeedVars) if (Solver.getValue(Var) > 0) Solution.push_back(Seed); + } else { + ErrMsg() << "Failed to find an optimal solution for `" << CorpusDir << "`\n"; return 1; + } SuccMsg() << "Minimized corpus size: " << Solution.size() << " seeds\n"; @@ -436,20 +505,26 @@ int main(int argc, char *argv[]) { SeedCount = 0; for (const auto &Seed : Solution) { + OutputSeed = OutputDir; sys::path::append(OutputSeed, sys::path::filename(Seed)); if (EC = sys::fs::copy_file(Seed, OutputSeed)) { + WarnMsg() << "Failed to copy `" << Seed << "` to `" << OutputDir << "`: " << EC.message() << '\n'; + } if ((++SeedCount % 10 == 0) && ShowProgBar) ProgBar.update(SeedCount * 100 / Solution.size(), "Copying seeds"); + } EndTimer(ShowProgBar); SuccMsg() << "Done!\n"; return 0; + } + diff --git a/utils/optimin/src/ProgressBar.h b/utils/optimin/src/ProgressBar.h index 2f8d7403..9b75594b 100644 --- a/utils/optimin/src/ProgressBar.h +++ b/utils/optimin/src/ProgressBar.h @@ -11,6 +11,7 @@ /// Display a progress bar in the terminal class ProgressBar { + private: const size_t BarWidth; const std::string Fill; @@ -18,14 +19,17 @@ class ProgressBar { public: ProgressBar() : ProgressBar(60, "#", " ") { + } ProgressBar(size_t Width, const llvm::StringRef F, const llvm::StringRef R) : BarWidth(Width), Fill(F), Remainder(R) { + } void update(float Progress, const llvm::StringRef Status = "", llvm::raw_ostream &OS = llvm::outs()) { + // No need to write once progress is 100% if (Progress > 100.0f) return; @@ -39,11 +43,17 @@ class ProgressBar { const auto Completed = static_cast(Progress * static_cast(BarWidth) / 100.0); for (size_t I = 0; I < BarWidth; ++I) { + if (I <= Completed) { + OS << Fill; + } else { + OS << Remainder; + } + } // End bar @@ -54,5 +64,8 @@ class ProgressBar { // Write status text OS << " " << Status; + } + }; + -- cgit 1.4.1 From a9328e40b3cf9cbda844da8bdce20093df7bbffa Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 21 Jul 2021 09:57:49 +0200 Subject: fix optimin readme --- utils/optimin/README.md | 55 ++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 28 deletions(-) (limited to 'utils/optimin/README.md') diff --git a/utils/optimin/README.md b/utils/optimin/README.md index ec9c4b0a..bea77225 100644 --- a/utils/optimin/README.md +++ b/utils/optimin/README.md @@ -19,34 +19,33 @@ To build the `optimin` just execute the `build_optimin.sh` script. Running `optimin` is the same as running `afl-cmin`: ``` -Required parameters: - -i dir - input directory with starting corpus - -o dir - output directory for minimized files - -Execution control settings: - -f file - location read by the fuzzed program (stdin) - -m megs - memory limit for child process (none MB) - -t msec - run time limit for child process (none) - -O - use binary-only instrumentation (FRIDA mode) - -Q - use binary-only instrumentation (QEMU mode) - -U - use unicorn-based instrumentation (unicorn mode) - -Minimization settings: - -C - keep crashing inputs, reject everything else - -e - solve for edge coverage only, ignore hit counts - -For additional tips, please consult README.md - -Environment variables used: -AFL_ALLOW_TMP: allow unsafe use of input/output directories under {/var}/tmp -AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash -AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up -AFL_KEEP_TRACES: leave the temporary /.traces directory -AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL) -AFL_NO_FORKSRV: run target via execve instead of using the forkserver -AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH -AFL_PRINT_FILENAMES: If set, the filename currently processed will be printed to stdout -AFL_SKIP_BIN_CHECK: skip afl instrumentation checks for target binary +./optimin -h +OVERVIEW: Optimal corpus minimizer +USAGE: optimin [options] [target args...] + +OPTIONS: + +Color Options: + + --color - Use colors in output (default=autodetect) + +General options: + + -C - Keep crashing inputs, reject everything else + -Q - Use binary-only instrumentation + -f - Include edge hit counts + -i dir - Input directory + -m megs - Memory limit for child process (default=none) + -o dir - Output directory + -p - Display progress bar + -t msec - Run time limit for child process (default=none) + -w csv - Weights file + +Generic Options: + + --help - Display available options (--help-hidden for more) + --help-list - Display list of available options (--help-list-hidden for more) + --version - Display the version of this program ``` Example: `optimin -i files -o seeds -- ./target @@` -- cgit 1.4.1 From 99d24d13f1ad972ab0645cf81155b47a7e693a42 Mon Sep 17 00:00:00 2001 From: Adrian Herrera Date: Thu, 22 Jul 2021 11:19:57 +0000 Subject: optimin: add missing cmin options and auto create output dir * Includes frida, unicorn modes * Automatically create the output directory if it does not already exist --- utils/optimin/README.md | 4 +++- utils/optimin/src/OptiMin.cpp | 32 +++++++++++++++++++++----------- 2 files changed, 24 insertions(+), 12 deletions(-) (limited to 'utils/optimin/README.md') diff --git a/utils/optimin/README.md b/utils/optimin/README.md index bea77225..3036b449 100644 --- a/utils/optimin/README.md +++ b/utils/optimin/README.md @@ -32,7 +32,9 @@ Color Options: General options: -C - Keep crashing inputs, reject everything else - -Q - Use binary-only instrumentation + -O - Use binary-only instrumentation (FRIDA mode) + -Q - Use binary-only instrumentation (QEMU mode) + -U - Use unicorn-based instrumentation (unicorn mode) -f - Include edge hit counts -i dir - Input directory -m megs - Memory limit for child process (default=none) diff --git a/utils/optimin/src/OptiMin.cpp b/utils/optimin/src/OptiMin.cpp index b82acbb6..55e391df 100644 --- a/utils/optimin/src/OptiMin.cpp +++ b/utils/optimin/src/OptiMin.cpp @@ -116,29 +116,38 @@ static const auto StatMsg = [] { }; -static cl::opt CorpusDir("i", cl::desc("Input directory"), +static cl::opt CorpusDir("i", cl::desc("Input directory"), cl::value_desc("dir"), cl::Required); -static cl::opt OutputDir("o", cl::desc("Output directory"), +static cl::opt OutputDir("o", cl::desc("Output directory"), cl::value_desc("dir"), cl::Required); -static cl::opt EdgesOnly("f", cl::desc("Include edge hit counts"), + +static cl::opt ShowProgBar("p", cl::desc("Display progress bar")); +static cl::opt EdgesOnly("f", cl::desc("Include edge hit counts"), cl::init(true)); -static cl::opt ShowProgBar("p", cl::desc("Display progress bar")); -static cl::opt WeightsFile("w", cl::desc("Weights file"), +static cl::opt WeightsFile("w", cl::desc("Weights file"), cl::value_desc("csv")); + static cl::opt TargetProg(cl::Positional, cl::desc(""), cl::Required); static cl::list TargetArgs(cl::ConsumeAfter, cl::desc("[target args...]")); -static cl::opt MemLimit( + +static cl::opt MemLimit( "m", cl::desc("Memory limit for child process (default=none)"), cl::value_desc("megs"), cl::init("none")); static cl::opt Timeout( "t", cl::desc("Run time limit for child process (default=5000)"), cl::value_desc("msec"), cl::init("4000")); + static cl::opt CrashMode( "C", cl::desc("Keep crashing inputs, reject everything else")); -static cl::opt QemuMode("Q", cl::desc("Use binary-only instrumentation")); +static cl::opt FridaMode( + "O", cl::desc("Use binary-only instrumentation (FRIDA mode)")); +static cl::opt QemuMode( + "Q", cl::desc("Use binary-only instrumentation (QEMU mode)")); +static cl::opt UnicornMode( + "U", cl::desc("Use unicorn-based instrumentation (unicorn mode)")); } // anonymous namespace @@ -184,7 +193,6 @@ static void GetWeights(const MemoryBuffer &MB, WeightsMap &Weights) { // Prepare afl-showmap arguments SmallVector AFLShowmapArgs{ - AFLShowmapPath, "-m", MemLimit, "-t", Timeout, "-q", "-o", OutputPath}; if (TargetArgsHasAtAt) @@ -192,8 +200,9 @@ static void GetWeights(const MemoryBuffer &MB, WeightsMap &Weights) { else Redirects[/* stdin */ 0] = Seed; + if (FridaMode) AFLShowmapArgs.push_back("-O"); if (QemuMode) AFLShowmapArgs.push_back("-Q"); - if (CrashMode) AFLShowmapArgs.push_back("-C"); + if (UnicornMode) AFLShowmapArgs.push_back("-U"); AFLShowmapArgs.append({"--", TargetProg}); AFLShowmapArgs.append(TargetArgs.begin(), TargetArgs.end()); @@ -269,9 +278,10 @@ int main(int argc, char *argv[]) { cl::ParseCommandLineOptions(argc, argv, "Optimal corpus minimizer"); - if (!sys::fs::is_directory(OutputDir)) { + if (EC = sys::fs::create_directory(OutputDir)) { - ErrMsg() << "Invalid output directory `" << OutputDir << "`\n"; + ErrMsg() << "Invalid output directory `" << OutputDir + << "`: " << EC.message() << '\n'; return 1; } -- cgit 1.4.1 From 33f9f911c13cfd513366b7b1c9f9c66c0aa944f7 Mon Sep 17 00:00:00 2001 From: Adrian Herrera Date: Sat, 24 Jul 2021 23:37:28 +0000 Subject: optimin: fix default timeout So that it matches the help text --- utils/optimin/README.md | 2 +- utils/optimin/src/OptiMin.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'utils/optimin/README.md') diff --git a/utils/optimin/README.md b/utils/optimin/README.md index 3036b449..c6f2af06 100644 --- a/utils/optimin/README.md +++ b/utils/optimin/README.md @@ -40,7 +40,7 @@ General options: -m megs - Memory limit for child process (default=none) -o dir - Output directory -p - Display progress bar - -t msec - Run time limit for child process (default=none) + -t msec - Run time limit for child process (default=5000) -w csv - Weights file Generic Options: diff --git a/utils/optimin/src/OptiMin.cpp b/utils/optimin/src/OptiMin.cpp index 84179022..4f88b897 100644 --- a/utils/optimin/src/OptiMin.cpp +++ b/utils/optimin/src/OptiMin.cpp @@ -142,7 +142,7 @@ static cl::opt MemLimit( cl::value_desc("megs"), cl::init("none")); static cl::opt Timeout( "t", cl::desc("Run time limit for child process (default=5000)"), - cl::value_desc("msec"), cl::init("4000")); + cl::value_desc("msec"), cl::init("5000")); static cl::opt CrashMode( "C", cl::desc("Keep crashing inputs, reject everything else")); -- cgit 1.4.1