/// <summary> /// Apply patch /// </summary> /// <param name="data">Data</param> /// <param name="logs">Logs</param> /// <returns>Data result</returns> private static byte[] Apply(byte[] data, PatchChange[] logs) { var cfg = new PatchConfig("", logs); using (var mem = new MemoryStream()) using (var stream = new FuzzingStream(cfg, data)) { stream.CopyTo(mem, 1024); return(mem.ToArray()); } }
/// <summary> /// Constructor /// </summary> /// <param name="fs">Stream</param> public FuzzingLogInfo(FuzzingStream fs) { if (fs == null) { return; } Info = ""; if (!string.IsNullOrEmpty(fs.InputName)) { Info = "Input: " + fs.InputName; } if (!string.IsNullOrEmpty(fs.ConfigName)) { Info += (Info != "" ? "\n" : "") + "Config: " + fs.ConfigName; } OriginalData = fs.OriginalData; if (fs.Log != null && fs.Log.Length > 0) { Patch = new PatchConfig(fs.SampleId.ToString(), fs.Log); } }
FuzzingStream GetRandomStream(OpenStreamMessageRequest msg, TuringSocket sender, bool fuzzer, Guid id) { FuzzerStat <IFuzzingInput> sinput = RandomHelper.GetRandom(Inputs); MemoryStream binput = null; IFuzzingInput input = sinput == null ? null : sinput.Source; if (input != null) { if (sender["INPUT"] == null) { List <FuzzerStat <IFuzzingInput> > ls = new List <FuzzerStat <IFuzzingInput> >(); ls.Add(sinput); sender["INPUT"] = ls; } else { List <FuzzerStat <IFuzzingInput> > ls = (List <FuzzerStat <IFuzzingInput> >)sender["INPUT"]; ls.Add(sinput); } } if (input != null && !(input is EmptyFuzzingInput)) { binput = new MemoryStream(input.GetStream()); } else { binput = new MemoryStream(); } FuzzingStream ret = null; if (fuzzer) { FuzzerStat <IFuzzingConfig> sconfig = RandomHelper.GetRandom(Configurations); if (sconfig != null && sconfig != null) { IFuzzingConfig config = sconfig.Source; if (sconfig == null) { throw (new Exception("Require fuzzer configuration")); } if (sender["CONFIG"] == null) { List <FuzzerStat <IFuzzingConfig> > ls = new List <FuzzerStat <IFuzzingConfig> >(); ls.Add(sconfig); sender["CONFIG"] = ls; } else { List <FuzzerStat <IFuzzingConfig> > ls = (List <FuzzerStat <IFuzzingConfig> >)sender["CONFIG"]; ls.Add(sconfig); } ret = new FuzzingStream(binput, config); if (ret != null) { ret.InputName = sinput == null ? "None" : sinput.ToString(); ret.ConfigName = sconfig.ToString(); } } } if (ret == null) { // Disable Fuzzing if (binput == null) { ret = new FuzzingStream(new MemoryStream(), null) { InputName = sinput == null ? "None" : sinput.ToString() } } ; else { ret = new FuzzingStream(binput, null) { InputName = sinput == null ? "None" : sinput.ToString() } }; } //if (!msg.RequireStream) //{ // ret.CanRead = msg.CanRead; // ret.CanSeek = msg.CanSeek; // ret.CanTimeout = msg.CanTimeout; // ret.CanWrite = msg.CanWrite; //} return(ret); } }
/// <summary> /// Message logic /// </summary> /// <param name="sender">Socket</param> /// <param name="message">Message</param> void _Socket_OnMessage(TuringSocket sender, TuringMessage message) { if (_Paused) { // Send Paused signal //sender.SendMessage(new WaitMessage(TimeSpan.FromSeconds(1))); // Wait disable pause while (_Paused) { Thread.Sleep(500); } } TuringMessage response = new ExceptionMessage("Bad request"); try { switch (message.Type) { case ETuringMessageType.EndTask: { EndTaskMessage msg = (EndTaskMessage)message; List <FuzzerStat <IFuzzingInput> > sinput = null; List <FuzzerStat <IFuzzingConfig> > sconfig = null; // Log if are data FuzzerLog log = msg.SaveResult(sender, out sinput, out sconfig); if (log != null) { RaiseOnCrashLog(log); } // Send message of the end RaiseOnTestEnd(msg.Result, sinput == null ? null : sinput.ToArray(), sconfig == null ? null : sconfig.ToArray()); response = new BoolMessageResponse(true); break; } case ETuringMessageType.OpenStreamRequest: { Guid id = Guid.NewGuid(); OpenStreamMessageRequest msg = (OpenStreamMessageRequest)message; FuzzingStream stream = GetRandomStream(msg, sender, true, id); if (stream == null) { response = new ExceptionMessage("Not found stream"); break; } sender[id.ToString()] = stream; //if (msg.UseMemoryStream) // response = new OpenStreamMessageResponse(id) // { // CanRead = msg.CanRead, // CanSeek = msg.CanSeek, // CanTimeout = msg.CanTimeout, // CanWrite = msg.CanWrite // }; //else response = new OpenStreamMessageResponse(id) { CanRead = stream.CanRead, CanSeek = stream.CanSeek, CanTimeout = stream.CanTimeout, CanWrite = stream.CanWrite }; break; } case ETuringMessageType.GetStreamLengthRequest: { GetStreamLengthMessageRequest msg = (GetStreamLengthMessageRequest)message; FuzzingStream stream = (FuzzingStream)sender[msg.Id.ToString()]; if (stream == null) { response = new ExceptionMessage("No stream openned with id: " + msg.Id.ToString()); break; } response = new LongMessageResponse(stream.Length); break; } case ETuringMessageType.GetStreamPositionRequest: { GetStreamPositionMessageRequest msg = (GetStreamPositionMessageRequest)message; FuzzingStream stream = (FuzzingStream)sender[msg.Id.ToString()]; if (stream == null) { response = new ExceptionMessage("No stream openned with id: " + msg.Id.ToString()); break; } response = new LongMessageResponse(stream.Position); break; } case ETuringMessageType.SetStreamRequest: { SetStreamMessageRequest msg = (SetStreamMessageRequest)message; FuzzingStream stream = (FuzzingStream)sender[msg.Id.ToString()]; if (stream == null) { response = new ExceptionMessage("No stream openned with id: " + msg.Id.ToString()); break; } switch (msg.ValueType) { case SetStreamMessageRequest.EMode.Position: stream.Position = msg.Value; break; case SetStreamMessageRequest.EMode.Length: stream.SetLength(msg.Value); break; } response = new BoolMessageResponse(true); break; } case ETuringMessageType.FlushStreamRequest: { FlushStreamMessageRequest msg = (FlushStreamMessageRequest)message; FuzzingStream stream = (FuzzingStream)sender[msg.Id.ToString()]; if (stream == null) { response = new ExceptionMessage("No stream openned with id: " + msg.Id.ToString()); break; } stream.Flush(); response = new BoolMessageResponse(true); break; } case ETuringMessageType.CloseStreamRequest: { CloseStreamMessageRequest msg = (CloseStreamMessageRequest)message; FuzzingStream stream = (FuzzingStream)sender[msg.Id.ToString()]; if (stream == null) { response = new ExceptionMessage("No stream openned with id: " + msg.Id.ToString()); break; } // Save patch for dump sender[msg.Id.ToString()] = null; sender["Info=" + msg.Id.ToString()] = new FuzzingLogInfo(stream); try { stream.Close(); } catch { } try { stream.Dispose(); } catch { } response = new BoolMessageResponse(true); break; } case ETuringMessageType.ReadStreamRequest: { StreamReadMessageRequest msg = (StreamReadMessageRequest)message; FuzzingStream stream = (FuzzingStream)sender[msg.Id.ToString()]; if (stream == null) { response = new ExceptionMessage("No stream openned with id: " + msg.Id.ToString()); break; } if (msg.PreAppend != null) { stream.AppendToSource(msg.PreAppend, 0, msg.PreAppend.Length, msg.PreAppendReSeek); } byte[] data = new byte[msg.Length]; int r = stream.Read(data, 0, data.Length); if (r != data.Length) { Array.Resize(ref data, r); } response = new ByteArrayMessageResponse(data); break; } case ETuringMessageType.WriteStreamRequest: { StreamWriteMessageRequest msg = (StreamWriteMessageRequest)message; FuzzingStream stream = (FuzzingStream)sender[msg.Id.ToString()]; if (stream == null) { response = new ExceptionMessage("No stream openned with id: " + msg.Id.ToString()); break; } stream.Write(msg.Data, 0, msg.Data.Length); response = new BoolMessageResponse(true); break; } } } catch (Exception e) { response = new ExceptionMessage(e.ToString()); } sender.SendMessage(response); }
/// <summary> /// Run fuzzer /// </summary> /// <param name="action">Action</param> /// <param name="args">Arguments</param> public static void Run(Action <Stream> action, FuzzerRunArgs args = null) { CoverageHelper.CreateCoverageListener(); if (action == null) { throw new NullReferenceException(nameof(action)); } // Check supervisor Mutex mutex; var supervisor = FuzzerRunArgs.SupervisorType.None; if (args != null && args.Supervisor != FuzzerRunArgs.SupervisorType.None) { // Check if is the listener or the task with mutex mutex = new Mutex(false, "TuringMachine.Supervisor." + Client.PublicName, out var isNew); if (!isNew) { Client.PublicName += $".{Process.GetCurrentProcess().Id}:{args.TaskId}"; } else { Client.PublicName += ".Supervisor"; supervisor = args.Supervisor; } } else { mutex = null; } if (!Client.IsStarted) { // If you want other connection you must call this method before Run Client.Start(CommandLineOptions.Parse().GetConnection()); } // Send current files Client.SendCurrentFiles(new OperationCanceledException(), null, true); // Fuzz var cancel = new CancelEventArgs(); var handler = new ConsoleCancelEventHandler((o, s) => { cancel.Cancel = true; s.Cancel = true; }); Console.CancelKeyPress += handler; // Ensure data while (Client.GetInput() == null || Client.GetConfig() == null) { Thread.Sleep(50); } switch (supervisor) { case FuzzerRunArgs.SupervisorType.RegularSupervisor: { var pi = new ProcessStartInfoEx() { FileName = "dotnet", Arguments = string.Join(" ", Environment.GetCommandLineArgs().Select(u => u)), WindowStyle = ProcessWindowStyle.Normal, RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = false, }; while (!cancel.Cancel) { using (var pr = new ProcessEx(pi)) { pr.WaitForExit(); Exception exception; switch (pr.ExitCode) { case StackOverflowExceptionCode: { exception = new StackOverflowException($"Unhandled exception: {pr.ExitCode}"); break; } default: { exception = new InvalidProgramException($"Unhandled exception: {pr.ExitCode}"); break; } } if (Client.SendCurrentFiles(exception, pr.Output, true) == 0) { Client.SendLog(new FuzzerLog() { Coverage = CoverageHelper.CurrentCoverage, InputId = Guid.Empty, ConfigId = Guid.Empty, }); } } } break; } case FuzzerRunArgs.SupervisorType.None: { while (!cancel.Cancel) { var input = Client.GetInput(); var config = Client.GetConfig(); string currentStreamPath = null; FileStream storeCurrentStream = null; if (args?.StoreCurrent == true) { // Free current stream currentStreamPath = $"{input.Id}.{config.Id}.{Process.GetCurrentProcess().Id}.{args.TaskId}.current"; storeCurrentStream = new FileStream(currentStreamPath, FileMode.Create, FileAccess.ReadWrite, FileShare.Read); } using (var stream = new FuzzingStream(config, input, storeCurrentStream) { ExtraLogInformation = "TaskId: " + args.TaskId }) { var log = Client.Execute(action, stream); if (log != null) { Client.SendLog(log); args?.OnLog?.Invoke(log, cancel); } } if (storeCurrentStream != null) { // Delete current stream storeCurrentStream.Close(); storeCurrentStream.Dispose(); File.Delete(currentStreamPath); } } break; } } Console.CancelKeyPress -= handler; mutex?.Dispose(); }