diff --git a/README.md b/README.md index 1102f86..dd393b7 100644 --- a/README.md +++ b/README.md @@ -127,6 +127,8 @@ The following command line arguments are supported: `-dict ` - Provides a dictionary to be used during mutation. The dictionary should be a text file with every entry on a separate line. `\xXX` escape sequences can be used. +`-process-name - Enables fuzzing for processes that are already running in the operating system such as Windows services. The fuzzer will attach to the specified running process and get coverage from there. Then, the script specified after `--` will be opened in a new thread and will send the current testcase to running process. Note: this mode only allows for one thread and file delivery through the script. + For TinyInst instrumentation command line arguments, refer to [TinyInst readme](https://github.com/googleprojectzero/TinyInst). Example (macOS): diff --git a/fuzzer.cpp b/fuzzer.cpp index 26e2ad7..1f25ba1 100644 --- a/fuzzer.cpp +++ b/fuzzer.cpp @@ -113,6 +113,13 @@ void Fuzzer::ParseOptions(int argc, char **argv) { incremental_coverage = GetBinaryOption("-incremental_coverage", argc, argv, true); add_all_inputs = GetBinaryOption("-add_all_inputs", argc, argv, false); + + process_name = GetOption("-process_name", argc, argv); + + if (process_name != NULL) { + //set threads to one as multiple threads attaching to one process does not work well + num_threads = 1; + } } void Fuzzer::SetupDirectories() { @@ -245,8 +252,8 @@ RunResult Fuzzer::RunSampleAndGetCoverage(ThreadContext *tc, Sample *sample, Cov FATAL("Repeatedly failed to deliver sample"); } } - RunResult result = tc->instrumentation->Run(tc->target_argc, tc->target_argv, init_timeout, timeout); + tc->instrumentation->GetCoverage(*coverage, true); // save crashes and hangs immediately when they are detected @@ -325,8 +332,9 @@ RunResult Fuzzer::TryReproduceCrash(ThreadContext* tc, Sample* sample, uint32_t FATAL("Repeatedly failed to deliver sample"); } } - + result = tc->instrumentation->RunWithCrashAnalysis(tc->target_argc, tc->target_argv, init_timeout, timeout); + tc->instrumentation->ClearCoverage(); if (result == CRASH) return result; diff --git a/fuzzer.h b/fuzzer.h index 675800c..a1d1013 100644 --- a/fuzzer.h +++ b/fuzzer.h @@ -196,6 +196,8 @@ class Fuzzer { uint64_t num_samples_discarded; uint64_t num_threads; uint64_t total_execs; + + char * process_name; void SaveState(ThreadContext *tc); void RestoreState(ThreadContext *tc); diff --git a/instrumentation.h b/instrumentation.h index a8e7a42..b401844 100644 --- a/instrumentation.h +++ b/instrumentation.h @@ -31,7 +31,7 @@ class Instrumentation { virtual RunResult RunWithCrashAnalysis(int argc, char** argv, uint32_t init_timeout, uint32_t timeout) { return Run(argc, argv, init_timeout, timeout); } - + virtual void CleanTarget() = 0; virtual bool HasNewCoverage() = 0; diff --git a/tinyinstinstrumentation.cpp b/tinyinstinstrumentation.cpp index ee9ea5e..18c21c4 100644 --- a/tinyinstinstrumentation.cpp +++ b/tinyinstinstrumentation.cpp @@ -22,13 +22,19 @@ limitations under the License. #include - void TinyInstInstrumentation::Init(int argc, char **argv) { instrumentation = new LiteCov(); instrumentation->Init(argc, argv); persist = GetBinaryOption("-persist", argc, argv, false); num_iterations = GetIntOption("-iterations", argc, argv, 1); + process_name = GetOption("-process_name", argc, argv); + script = ArgvToCmd(argc, argv); + + attach_mode = false; + if(process_name != NULL) { + attach_mode = true; + } } RunResult TinyInstInstrumentation::Run(int argc, char **argv, uint32_t init_timeout, uint32_t timeout) { @@ -68,7 +74,17 @@ RunResult TinyInstInstrumentation::Run(int argc, char **argv, uint32_t init_time WARN("Target function not reached, retrying with a clean process\n"); instrumentation->Kill(); cur_iteration = 0; - status = instrumentation->Run(argc, argv, init_timeout); + if (attach_mode) { + Sleep(init_timeout); + processID = FindProcessId(process_name); + if (script != NULL) { + HANDLE thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)system, script, 0, NULL); + CloseHandle(thread_handle); + } + status = instrumentation->Attach(processID, timeout1); + } else { + status = instrumentation->Run(argc, argv, init_timeout); + } } if (status != DEBUGGER_TARGET_START) { diff --git a/tinyinstinstrumentation.h b/tinyinstinstrumentation.h index f8826a1..98437cb 100644 --- a/tinyinstinstrumentation.h +++ b/tinyinstinstrumentation.h @@ -32,7 +32,7 @@ class TinyInstInstrumentation : public Instrumentation { RunResult Run(int argc, char** argv, uint32_t init_timeout, uint32_t timeout) override; RunResult RunWithCrashAnalysis(int argc, char** argv, uint32_t init_timeout, uint32_t timeout) override; - + void CleanTarget() override; bool HasNewCoverage() override; @@ -47,6 +47,10 @@ class TinyInstInstrumentation : public Instrumentation { protected: LiteCov * instrumentation; bool persist; + boolean attach_mode; + int processID; + char * process_name; + char * script; int num_iterations; int cur_iteration; };