aboutsummaryrefslogtreecommitdiff
path: root/utils/optimin
diff options
context:
space:
mode:
authorAdrian Herrera <adrian.herrera02@gmail.com>2021-07-28 06:44:25 +0000
committerAdrian Herrera <adrian.herrera02@gmail.com>2021-07-28 06:50:41 +0000
commit0bd6fda98b4d376d40a87d5efb8cc4fa761a453e (patch)
tree12cb28ba6568c6ca1a6f69cfb43507b5fe36eb0d /utils/optimin
parent0dbd37a20b90284201a117192d126cbeee998663 (diff)
downloadafl++-0bd6fda98b4d376d40a87d5efb8cc4fa761a453e.tar.gz
optimin: add target test back in
Diffstat (limited to 'utils/optimin')
-rw-r--r--utils/optimin/src/OptiMin.cpp183
1 files changed, 118 insertions, 65 deletions
diff --git a/utils/optimin/src/OptiMin.cpp b/utils/optimin/src/OptiMin.cpp
index 4f0cb4f7..ce1fb850 100644
--- a/utils/optimin/src/OptiMin.cpp
+++ b/utils/optimin/src/OptiMin.cpp
@@ -96,7 +96,7 @@ static constexpr unsigned MAX_WEIGHT_FAILURES = 5;
static sys::TimePoint<> StartTime, EndTime;
static std::chrono::seconds Duration;
-static std::string AFLShowmapPath;
+static std::string ShowmapPath;
static bool TargetArgsHasAtAt = false;
static bool KeepTraces = false;
static bool SkipBinCheck = false;
@@ -220,82 +220,133 @@ static std::error_code readCov(const StringRef Trace, AFLCoverageVector &Cov) {
}
-static Error runShowmap(AFLCoverageMap &CovMap) {
+static Error runShowmap(AFLCoverageMap &CovMap, const StringRef Input,
+ bool BinCheck = false) {
+ const bool InputIsFile = !sys::fs::is_directory(Input);
Optional<StringRef> Redirects[] = {None, None, None};
SmallString<32> TraceDir{OutputDir};
sys::path::append(TraceDir, ".traces");
+ SmallString<32> Output{TraceDir};
SmallString<32> StdinFile{TraceDir};
- sys::path::append(StdinFile, ".cur_input");
+ // ------------------------------------------------------------------------ //
// Prepare afl-showmap arguments
- SmallVector<StringRef, 12> AFLShowmapArgs{
- AFLShowmapPath, "-m", MemLimit, "-t", Timeout,
- "-q", "-i", InputDir, "-o", TraceDir};
+ //
+ // If the given input is a file, then feed this directly into stdin.
+ // Otherwise, if it is a directory, specify this on the afl-showmap command
+ // line.
+ // ------------------------------------------------------------------------ //
+
+ SmallVector<StringRef, 12> ShowmapArgs{ShowmapPath, "-q",
+ "-m", MemLimit,
+ "-t", Timeout};
+
+ if (InputIsFile) {
+
+ StdinFile = Input;
+ sys::path::append(Output,
+ BinCheck ? ".run_test" : sys::path::filename(Input));
+
+ } else {
+
+ sys::path::append(StdinFile, ".cur_input");
+ ShowmapArgs.append({"-i", Input});
+
+ }
+
if (TargetArgsHasAtAt) {
- AFLShowmapArgs.append({"-A", StdinFile});
+ ShowmapArgs.append({"-A", StdinFile});
Redirects[/* stdin */ 0] = "/dev/null";
+ } else if (InputIsFile) {
+
+ Redirects[/* stdin */ 0] = Input;
+
}
- if (FridaMode) AFLShowmapArgs.push_back("-O");
- if (QemuMode) AFLShowmapArgs.push_back("-Q");
- if (UnicornMode) AFLShowmapArgs.push_back("-U");
+ if (FridaMode) ShowmapArgs.push_back("-O");
+ if (QemuMode) ShowmapArgs.push_back("-Q");
+ if (UnicornMode) ShowmapArgs.push_back("-U");
- AFLShowmapArgs.append({"--", TargetProg});
- AFLShowmapArgs.append(TargetArgs.begin(), TargetArgs.end());
+ ShowmapArgs.append({"-o", Output, "--", TargetProg});
+ ShowmapArgs.append(TargetArgs.begin(), TargetArgs.end());
+ // ------------------------------------------------------------------------ //
// Run afl-showmap
- const int RC = sys::ExecuteAndWait(AFLShowmapPath, AFLShowmapArgs,
+ // ------------------------------------------------------------------------ //
+
+ const int RC = sys::ExecuteAndWait(ShowmapPath, ShowmapArgs,
/*env=*/None, Redirects);
if (RC && !CrashMode) {
ErrMsg() << "Exit code " << RC << " != 0 received from afl-showmap\n";
- sys::fs::remove_directories(TraceDir);
return createStringError(inconvertibleErrorCode(), "afl-showmap failed");
}
+ // ------------------------------------------------------------------------ //
// Parse afl-showmap output
+ // ------------------------------------------------------------------------ //
+
AFLCoverageVector Cov;
std::error_code EC;
sys::fs::file_status Status;
- for (sys::fs::recursive_directory_iterator Dir(TraceDir, EC), DirEnd;
- Dir != DirEnd && !EC; Dir.increment(EC)) {
+ if (InputIsFile) {
- if (EC) return errorCodeToError(EC);
+ // Read a single output coverage file
+ if ((EC = readCov(Output, Cov))) {
- const auto &Path = Dir->path();
- if ((EC = sys::fs::status(Path, Status))) return errorCodeToError(EC);
+ sys::fs::remove(Output);
+ return errorCodeToError(EC);
- switch (Status.type()) {
+ }
- case sys::fs::file_type::regular_file:
- case sys::fs::file_type::symlink_file:
- case sys::fs::file_type::type_unknown:
- Cov.clear();
- if ((EC = readCov(Path, Cov))) {
+ CovMap.try_emplace(sys::path::filename(Input), Cov);
+ if (!KeepTraces) sys::fs::remove(Output);
- sys::fs::remove(Path);
- return errorCodeToError(EC);
+ } else {
- }
+ // Read a directory of output coverage files
+ for (sys::fs::recursive_directory_iterator Dir(TraceDir, EC), DirEnd;
+ Dir != DirEnd && !EC; Dir.increment(EC)) {
- CovMap.try_emplace(sys::path::filename(Path), Cov);
- default:
- /* Ignore */
- break;
+ if (EC) return errorCodeToError(EC);
+
+ const auto &Path = Dir->path();
+ if ((EC = sys::fs::status(Path, Status))) return errorCodeToError(EC);
+
+ switch (Status.type()) {
+
+ case sys::fs::file_type::regular_file:
+ case sys::fs::file_type::symlink_file:
+ case sys::fs::file_type::type_unknown:
+ Cov.clear();
+ if ((EC = readCov(Path, Cov))) {
+
+ sys::fs::remove(Path);
+ return errorCodeToError(EC);
+
+ }
+
+ CovMap.try_emplace(sys::path::filename(Path), Cov);
+ default:
+ // Ignore
+ break;
+
+ }
}
+ if (!KeepTraces) sys::fs::remove_directories(TraceDir);
+
}
- if (!KeepTraces) sys::fs::remove_directories(TraceDir);
return Error::success();
}
@@ -352,15 +403,15 @@ int main(int argc, char *argv[]) {
SplitString(PathEnv, EnvPaths, ":");
if (AFLPath) EnvPaths.push_back(AFLPath);
- const auto AFLShowmapOrErr = sys::findProgramByName("afl-showmap", EnvPaths);
- if (AFLShowmapOrErr.getError()) {
+ const auto ShowmapOrErr = sys::findProgramByName("afl-showmap", EnvPaths);
+ if (ShowmapOrErr.getError()) {
ErrMsg() << "Failed to find afl-showmap. Check your PATH\n";
return 1;
}
- AFLShowmapPath = *AFLShowmapOrErr;
+ ShowmapPath = *ShowmapOrErr;
// ------------------------------------------------------------------------ //
// Parse weights
@@ -401,13 +452,13 @@ int main(int argc, char *argv[]) {
bool IsDirResult;
if ((EC = sys::fs::is_directory(InputDir, IsDirResult))) {
- ErrMsg() << "Invalid input directory '" << InputDir
- << "': " << EC.message() << '\n';
+ ErrMsg() << "Invalid input directory '" << InputDir << "': " << EC.message()
+ << '\n';
return 1;
}
- sys::fs::file_status Status;
+ sys::fs::file_status Status;
StringMap<std::string> SeedFiles;
for (sys::fs::recursive_directory_iterator Dir(InputDir, EC), DirEnd;
@@ -424,22 +475,21 @@ int main(int argc, char *argv[]) {
const auto &Path = Dir->path();
if ((EC = sys::fs::status(Path, Status))) {
- ErrMsg() << "Failed to access '" << Path << "': " << EC.message()
- << '\n';
+ ErrMsg() << "Failed to access '" << Path << "': " << EC.message() << '\n';
return 1;
}
switch (Status.type()) {
- case sys::fs::file_type::regular_file:
- case sys::fs::file_type::symlink_file:
- case sys::fs::file_type::type_unknown:
- SeedFiles.try_emplace(sys::path::filename(Path),
- sys::path::parent_path(Path));
- default:
- /* Ignore */
- break;
+ case sys::fs::file_type::regular_file:
+ case sys::fs::file_type::symlink_file:
+ case sys::fs::file_type::type_unknown:
+ SeedFiles.try_emplace(sys::path::filename(Path),
+ sys::path::parent_path(Path));
+ default:
+ /* Ignore */
+ break;
}
@@ -481,24 +531,27 @@ int main(int argc, char *argv[]) {
// Test the target binary
// ------------------------------------------------------------------------ //
- AFLCoverageVector Cov;
+ AFLCoverageMap CovMap;
if (!SkipBinCheck) {
- StatMsg() << "Testing the target binary...\n";
+ const auto It = SeedFiles.begin();
+ SmallString<32> TestSeed{It->second};
+ sys::path::append(TestSeed, It->first());
+
+ StatMsg() << "Testing the target binary with '" << TestSeed << "`...\n";
StartTimer();
- // if (auto Err = runShowmap(TestSeed, Cov, /*BinCheck=*/true)) {
- //
- // ErrMsg()
- // << "No instrumentation output detected (perhaps crash or
- // timeout)";
- // return 1;
- //
- // }
+ if (auto Err = runShowmap(CovMap, TestSeed, /*BinCheck=*/true)) {
+
+ ErrMsg() << "No instrumentation output detected \n";
+ return 1;
+
+ }
EndTimer();
- SuccMsg() << "OK, " << Cov.size() << " tuples recorded\n";
+ SuccMsg() << "OK, " << CovMap.begin()->second.size()
+ << " tuples recorded\n";
}
@@ -513,12 +566,12 @@ int main(int argc, char *argv[]) {
StatMsg() << "Running afl-showmap on " << SeedFiles.size() << " seeds...\n";
StartTimer();
- AFLCoverageMap CovMap;
MaxSATSeeds SeedVars;
MaxSATCoverageMap SeedCoverage;
EvalMaxSAT Solver(/*nbMinimizeThread=*/0);
- if (auto Err = runShowmap(CovMap)) {
+ CovMap.clear();
+ if (auto Err = runShowmap(CovMap, InputDir)) {
ErrMsg() << "Failed to generate coverage: " << Err << '\n';
return 1;
@@ -526,6 +579,7 @@ int main(int argc, char *argv[]) {
}
for (const auto &SeedCov : CovMap) {
+
// Create a variable to represent the seed
const SeedID Var = Solver.newVar();
SeedVars.emplace_back(Var, SeedCov.first());
@@ -550,7 +604,6 @@ int main(int argc, char *argv[]) {
}
- SuccMsg() << "afl-showmap completed in ";
EndTimer();
// ------------------------------------------------------------------------ //
@@ -616,8 +669,8 @@ int main(int argc, char *argv[]) {
}
- StatMsg() << "Copying " << Solution.size() << " seeds to '"
- << OutputDir << "'...\n";
+ StatMsg() << "Copying " << Solution.size() << " seeds to '" << OutputDir
+ << "'...\n";
StartTimer();
SeedCount = 0;