private void TestMain(object?_) { if (!File.Exists(_testCase.BinaryPath)) { Logging.RecordLogEvent($"Test {_testCase.CategoryName}{_testCase.TestName} started with missing binary {_testCase.BinaryPath}"); Finished = true; return; } Running = true; _testCase.RecordRunning(); Logging.WriteConsole($"Started test Session{_thisTest.Session}/ID{_thisTest.TestID}/{_testCase.TestName}"); Logging.WriteConsole($"Starting test process {_testCase.BinaryPath} test id {_thisTest.TestID}"); ProcessLaunchSettings settings = _testCase.CreateSettings(); System.Diagnostics.Process?testProcess = ProcessLaunching.StartLocalTrace(_testCase.TestBits, settings, testID: _thisTest.TestID); if (testProcess != null) { //GetTestTrace while (!rgatState.rgatIsExiting && !Finished) { Logging.WriteConsole($"\tWaiting for test {_thisTest.TestID} to start..."); if (_rgatState.GetTestTrace(_thisTest.TestID, out TraceRecord? testTrace) && testTrace is not null) { _thisTest.SetFirstTrace(testTrace); Logging.WriteConsole($"\tGot first trace of test {_thisTest.TestID}"); while (!rgatState.rgatIsExiting && !Finished) { /* * This is quite awkward - main concern is something that does CreateProces() => ExitProcess() * and we exit thinking the job is done just before another child process connects. * A 100 ms delay isn't foolproof but without actually instrumenting all the process creation * APIs it's difficult to come up with something to wait on. * Re-evaluate when multi-process tests are written */ Thread.Sleep(100); if (!testTrace.IsRunning && !testTrace.ProcessingRemaining_All) { Finished = true; _thisTest.SetFinishTime(DateTime.Now); } } } else { Thread.Sleep(100); } } } Running = false; _testCase.RecordFinished(); Logging.WriteConsole($"Finished test [Session{_thisTest.Session}/ID{_thisTest.TestID}/{_testCase.TestName}]"); _harness.NotifyComplete(_thisTest.TestID); }
/// <summary> /// Begin tracing a binary in command line mode /// </summary> /// <param name="targetPath">Binary to trace</param> /// <param name="saveDirectory">Where to save the result</param> /// <param name="recordVideo">If a video is being recorded</param> public static void TraceBinary(string targetPath, string?saveDirectory = null, bool recordVideo = false) { Logging.WriteConsole($"Command line mode tracing binary {targetPath}"); BinaryTarget target = new BinaryTarget(targetPath); if (!GlobalConfig.Settings.GetPreviousLaunchSettings(target.GetSHA1Hash(), out ProcessLaunchSettings? settings) || settings is null) { settings = new ProcessLaunchSettings(targetPath); settings.TraceChoices.InitDefaultExclusions(); } ProcessLaunching.StartLocalTrace(target.BitWidth, settings, target.PEFileObj); while (true) { Thread.Sleep(1000); var targets = rgatState.targets.GetBinaryTargets(); int traces = 0, running = 0; foreach (var previousTarget in targets) { foreach (var previousTrace in previousTarget.GetTracesList()) { traces += 1; if (previousTrace.IsRunning) { running += 1; } } } Logging.WriteConsole($"{running}/{traces} traces running accross {targets.Count} targets"); if (traces > 0 && running == 0) //also wait for keypress { Logging.WriteConsole("All traces done. Saving and exiting."); rgatState.SaveAllTargets(); rgatState.Shutdown(); break; } } }