public void Equals() { var cfg = new PatchConfig(); var stat = new FuzzerStat <PatchConfig>(cfg); var copy = new FuzzerStat <PatchConfig>(stat.Source); Assert.IsTrue(stat.Equals(copy)); Assert.IsTrue(stat.Equals((object)copy)); Assert.IsFalse(stat.Equals(new object())); Assert.AreEqual(stat.GetHashCode(), copy.GetHashCode()); stat.Crashes++; Assert.AreNotEqual(stat.GetHashCode(), copy.GetHashCode()); }
void gridConfig_CellDoubleClick(object sender, DataGridViewCellEventArgs e) { DataGridViewRow r = gridConfig.CurrentRow; if (r == null) { return; } FuzzerStat <IFuzzingConfig> cfg = (FuzzerStat <IFuzzingConfig>)r.DataBoundItem; if (cfg == null) { return; } FGenerator f = new FGenerator(); f.LoadConfig(cfg.Source); f.Show(); }
public void IncrementTest() { var cfg = new PatchConfig(); var stat = new FuzzerStat <PatchConfig>(cfg); Assert.AreEqual(cfg, stat.Source); Assert.AreEqual(cfg.Description, stat.Description); Assert.AreEqual(cfg.Id, stat.Id); Assert.AreEqual(0, stat.Crashes); Assert.AreEqual(0, stat.Tests); Assert.AreEqual(0, stat.Errors); stat.Increment(); Assert.AreEqual(0, stat.Crashes); Assert.AreEqual(1, stat.Tests); Assert.AreEqual(0, stat.Errors); stat.Increment(FuzzerError.EFuzzingErrorType.Crash); Assert.AreEqual(1, stat.Crashes); Assert.AreEqual(2, stat.Tests); Assert.AreEqual(0, stat.Errors); stat.Increment(FuzzerError.EFuzzingErrorType.Fail); Assert.AreEqual(1, stat.Crashes); Assert.AreEqual(3, stat.Tests); Assert.AreEqual(1, stat.Errors); stat.Reset(); Assert.AreEqual(0, stat.Crashes); Assert.AreEqual(0, stat.Tests); Assert.AreEqual(0, stat.Errors); }
private void Test(FuzzerConnectionBase serverConnection, FuzzerConnectionBase clientConnection) { Fuzzer.Client.ExecutionTimeOut = TimeSpan.FromMilliseconds(5_000); using (var server = new FuzzerServer()) using (var client = new FuzzerClient()) { // Change name client.PublicName = "TestClient_" + Guid.NewGuid().ToString(); // Ensure no error client.SendLog(null); // Dummy input var entryIBuffer = new byte[100]; RandomHelper.FillWithRandomBytes(entryIBuffer); var entryI = new FuzzerStat <FuzzingInputBase>(new ManualFuzzingInput(entryIBuffer) { Description = "1" }); server.Inputs.Add(entryI.Source.Id, entryI); entryI = new FuzzerStat <FuzzingInputBase>(new RandomFuzzingInput(new FromToValue <long>(100, 200)) { Description = "2" }); server.Inputs.Add(entryI.Source.Id, entryI); // Dummy configurations var entryC = new FuzzerStat <FuzzingConfigBase>(new PatchConfig("1", new PatchChange("1", 1, 1, new byte[0]))); server.Configurations.Add(entryC.Source.Id, entryC); entryC = new FuzzerStat <FuzzingConfigBase>(new PatchConfig("2", new PatchChange("2", 2, 2, new byte[0]))); server.Configurations.Add(entryC.Source.Id, entryC); // Check server CheckConfig(() => ((IRandomValue <FuzzingConfigBase>)server).Get(), server.Configurations.Select(u => u.Value.Source).ToArray()); CheckConfig(() => ((IRandomValue <FuzzingInputBase>)server).Get(), server.Inputs.Select(u => u.Value.Source).ToArray()); CheckConfig(() => server.GetConfig(), server.Configurations.Select(u => u.Value.Source).ToArray()); CheckConfig(() => server.GetInput(), server.Inputs.Select(u => u.Value.Source).ToArray()); // Start Assert.IsFalse(server.IsStarted); Assert.IsFalse(client.IsStarted); if (serverConnection == null && clientConnection == null) { Assert.Catch <NullReferenceException>(() => server.Start(serverConnection)); Assert.Catch <NullReferenceException>(() => client.Start(clientConnection)); return; } else { if (serverConnection is TestDummyConnection && clientConnection is TestDummyConnection) { Assert.Catch <ArgumentException>(() => server.Start(serverConnection)); Assert.Catch <ArgumentException>(() => client.Start(clientConnection)); return; } } var waitInput = new ManualResetEvent(false); var waitConfigs = new ManualResetEvent(false); var waitLog = new ManualResetEvent(false); var waitLogError = new ManualResetEvent(false); client.OnReceiveInputs += (s, e) => waitInput.Set(); client.OnReceiveConfigurations += (s, e) => waitConfigs.Set(); server.OnReceiveLog += (s, e) => (e.Any(u => u.Error != null) ? waitLogError : waitLog).Set(); server.Start(serverConnection); Thread.Sleep(250); // Wait for server client.Start(clientConnection); Assert.IsTrue(server.IsStarted); Assert.IsTrue(client.IsStarted); // Already started Assert.Catch <Exception>(() => server.Start(serverConnection)); Assert.Catch <Exception>(() => client.Start(clientConnection)); // Check client Assert.IsTrue(waitConfigs.WaitOne(TimeSpan.FromSeconds(10)), "Waiting for configs"); Assert.IsTrue(waitInput.WaitOne(TimeSpan.FromSeconds(10)), "Waiting for inputs"); Assert.AreEqual(1, server.Connections.Count); Assert.IsTrue(server.Connections.Values.FirstOrDefault()?.Source.Description.Contains(client.PublicName)); Assert.AreNotEqual(Guid.Empty, server.Connections.Values.FirstOrDefault()?.Source.Id); Assert.AreNotEqual(Guid.Empty, server.Connections.Values.FirstOrDefault()?.Id); var speedInit = server.Connections.Values.FirstOrDefault().Source.Speed; CheckConfig(() => ((IRandomValue <FuzzingConfigBase>)client).Get(), server.Configurations.Select(u => u.Value.Source).ToArray()); CheckConfig(() => ((IRandomValue <FuzzingInputBase>)client).Get(), server.Inputs.Select(u => u.Value.Source).ToArray()); CheckConfig(() => client.GetConfig(), server.Configurations.Select(u => u.Value.Source).ToArray()); CheckConfig(() => client.GetInput(), server.Inputs.Select(u => u.Value.Source).ToArray()); // Send log var cfg = client.GetConfig(); var input = client.GetInput(); var log = new FuzzerLog() { ConfigId = cfg.Id, InputId = input.Id, Coverage = 10, }; var sIn = server.Inputs.Select(u => u.Value).Where(u => u.Source.Id == log.InputId).FirstOrDefault(); var sCfg = server.Configurations.Select(u => u.Value).Where(u => u.Source.Id == log.ConfigId).FirstOrDefault(); Assert.AreEqual(0, server.Logs.Count); Assert.AreEqual(0, server.UniqueErrors); Assert.AreEqual(0, server.TotalErrors); client.SendLog(log); Assert.IsTrue(waitLog.WaitOne(TimeSpan.FromSeconds(10)), "Waiting for log"); Assert.AreEqual(0, server.Logs.Count); Assert.AreEqual(0, server.UniqueErrors); Assert.AreEqual(0, server.TotalErrors); Thread.Sleep(250); Assert.IsTrue(server.Connections.Values.FirstOrDefault().Source.Speed > speedInit); Assert.AreEqual(log.Coverage, server.Connections.Values.FirstOrDefault().Source.Coverage); // Check stats Assert.AreEqual(1, sIn.Tests); Assert.AreEqual(1, sCfg.Tests); Assert.AreEqual(0, sIn.Crashes); Assert.AreEqual(0, sCfg.Crashes); Assert.AreEqual(0, sIn.Errors); Assert.AreEqual(0, sCfg.Errors); // Send error log = new FuzzerLog() { ConfigId = cfg.Id, InputId = input.Id, Error = new FuzzerError() { ErrorId = Guid.NewGuid(), Error = FuzzerError.EFuzzingErrorType.Crash, ExplotationResult = FuzzerError.EExplotationResult.Exploitable, ReplicationData = new byte[0], } }; Assert.AreEqual(0, server.UniqueErrors); Assert.AreEqual(0, server.TotalErrors); client.SendLog(log); waitLogError.Reset(); Assert.IsTrue(waitLogError.WaitOne(TimeSpan.FromSeconds(10)), "Waiting for error"); Assert.AreEqual(1, server.Logs.Count); Assert.IsTrue(server.Logs.TryGetValue(log.Error.ErrorId, out var peekLog)); Assert.IsTrue(log.Equals(peekLog)); Assert.AreEqual(1, server.UniqueErrors); Assert.AreEqual(1, server.TotalErrors); // Check stats Assert.AreEqual(2, sIn.Tests); Assert.AreEqual(2, sCfg.Tests); Assert.AreEqual(1, sIn.Crashes); Assert.AreEqual(1, sCfg.Crashes); Assert.AreEqual(0, sIn.Errors); Assert.AreEqual(0, sCfg.Errors); // Generic MultiClient FuzzerLog gerr = null; Fuzzer.Client.Stop(); if (serverConnection != clientConnection) { // Test default Fuzzer.Client.Start(clientConnection); } waitLogError.Reset(); Fuzzer.Run(FuzWERSample, new FuzzerRunArgs() { OnLog = (l, c) => { if (l.Error != null) { c.Cancel = true; gerr = l; } } }); // Could spend more time because are more tests Assert.IsTrue(waitLogError.WaitOne(TimeSpan.FromSeconds(30)), "Waiting for error"); Assert.AreEqual(2, server.Logs.Count); Assert.IsTrue(server.Logs.TryGetValue(gerr.Error.ErrorId, out peekLog)); Assert.IsTrue(gerr.Equals(peekLog)); Assert.IsTrue(gerr.Error.ReplicationData.Length > 0); Assert.AreEqual(FuzzerError.EExplotationResult.Exploitable, gerr.Error.ExplotationResult); Assert.AreEqual(FuzzerError.EFuzzingErrorType.Crash, gerr.Error.Error); Assert.AreEqual(2, server.UniqueErrors); Assert.AreEqual(2, server.TotalErrors); // Generic MultiThread Client gerr = null; Fuzzer.Client.Stop(); Thread.Sleep(250); // Wait some time for pipes if (serverConnection != clientConnection) { // Test default Fuzzer.Client.Start(clientConnection); } waitLogError.Reset(); Fuzzer.Run(1, FuzMultiThreadSample, new FuzzerRunArgs() { OnLog = (l, c) => { if (l.Error != null) { c.Cancel = true; gerr = l; } } }); // Could spend more time because are more tests Assert.IsTrue(waitLogError.WaitOne(TimeSpan.FromSeconds(30)), "Waiting for error"); Assert.AreEqual(3, server.Logs.Count); Assert.IsTrue(server.Logs.TryGetValue(gerr.Error.ErrorId, out peekLog)); Assert.IsTrue(gerr.Equals(peekLog)); Assert.IsTrue(gerr.Error.ReplicationData.Length > 0); Assert.AreEqual(3, server.UniqueErrors); Assert.AreEqual(3, server.TotalErrors); // Test timeout gerr = null; waitLogError.Reset(); Fuzzer.Client.ExecutionTimeOut = TimeSpan.FromMilliseconds(250); Fuzzer.Run(FuzTimeoutSample, new FuzzerRunArgs() { OnLog = (l, c) => { c.Cancel = true; if (l.Error != null) { gerr = l; } } }); Assert.IsTrue(waitLogError.WaitOne(TimeSpan.FromSeconds(5)), "Waiting for error"); Assert.AreEqual(4, server.Logs.Count); Assert.IsTrue(server.Logs.TryGetValue(gerr.Error.ErrorId, out peekLog)); Assert.IsTrue(gerr.Equals(peekLog)); Assert.IsTrue(gerr.Error.ReplicationData.Length > 0); Assert.AreEqual(4, server.UniqueErrors); Assert.AreEqual(4, server.TotalErrors); // Current stream var logReaded = new byte[255]; var current = new byte[logReaded.Length]; FuzzingStream fuzStream = null; Fuzzer.Run((stream) => { Array.Resize(ref current, stream.Read(current, 0, current.Length)); fuzStream = (FuzzingStream)stream; Assert.IsNotNull(fuzStream.CurrentStream); }, new FuzzerRunArgs() { StoreCurrent = true, OnLog = (l, c) => { // Read current file var fCurrent = ((FileStream)fuzStream.CurrentStream); fCurrent.Seek(0, SeekOrigin.Begin); Array.Resize(ref logReaded, fCurrent.Read(logReaded, 0, logReaded.Length)); c.Cancel = true; }, }); Assert.IsNotNull(fuzStream); Assert.IsNotNull(fuzStream.CurrentStream); CollectionAssert.AreEqual(current, logReaded); // Clean Fuzzer.Client.Stop(); waitInput.Dispose(); waitConfigs.Dispose(); waitLog.Dispose(); waitLogError.Dispose(); } }
void SaveSelectedInputWith(bool toClipbard, IGetPatch config) { if (gridInput.SelectedRows.Count != 1) { return; } FuzzerStat <IFuzzingInput> inp = (FuzzerStat <IFuzzingInput>)gridInput.SelectedRows[0].DataBoundItem; if (inp == null) { return; } byte[] stream = inp.Source.GetStream(); if (stream == null) { return; } if (toClipbard) { // Clipboard StringBuilder sb = new StringBuilder(); sb.AppendLine("byte[] payload = new byte[]"); sb.Append("{"); PatchChange[] logs = null; if (config != null) { using (MemoryStream ms = new MemoryStream()) using (FuzzingStream fzs = new FuzzingStream(stream, config)) { fzs.CopyTo(ms); stream = ms.ToArray(); logs = fzs.Log; } } for (int x = 0, off = 0, v = 0, m = stream.Length; x < m; x++, v++, off++) { byte b = stream[x]; if (x != 0) { sb.Append(", "); } if (logs != null) { foreach (PatchChange ch in logs) { if (off == ch.Offset) { off -= ch.Remove; if (ch.Append != null) { off += ch.Append.Length; } sb.AppendLine(); sb.AppendLine("\t/* " + (string.IsNullOrEmpty(ch.Description) ? "" : ch.Description + " ") + (ch.Append == null ? "0" : ch.Append.Length.ToString()) + " bytes */"); sb.Append("\t" + "".PadLeft(6 * v, ' ')); } } } if (v == 0 || v % 20 == 0) { sb.AppendLine(); sb.Append("\t"); v = 0; } sb.Append("0x" + b.ToString("x2")); } sb.AppendLine(); sb.Append("};"); Clipboard.SetText(sb.ToString()); return; } // File using (SaveFileDialog s = new SaveFileDialog() { Filter = "Dat file|*.dat", DefaultExt = "*.dat", }) { if (s.ShowDialog() != DialogResult.OK) { return; } try { if (File.Exists(s.FileName)) { File.Delete(s.FileName); } using (FileStream fs = File.OpenWrite(s.FileName)) { if (config != null) { using (Stream fzs = new FuzzingStream(stream, config)) fzs.CopyTo(fs); } else { fs.Write(stream, 0, stream.Length); } } } catch (Exception e) { MessageBox.Show(e.ToString(), "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error); } } }
/// <summary> /// Update from stream /// </summary> /// <param name="server">Stream</param> /// <param name="cancel">Cancel</param> private void UpdateFromStream(FuzzerStat <FuzzerClientInfo> stat, Stream stream, CancellationToken cancel) { var clientId = Guid.NewGuid(); Connections.TryAdd(clientId, stat); OnNewConnection?.Invoke(this, stat.Source); var buffer = new byte[40]; var uuidBuffer = new byte[16]; var sleep = new ConditionalSleep(); try { while (!cancel.IsCancellationRequested) { cancel.ThrowIfCancellationRequested(); var read = stream.ReadByte(); if (read < 0) { stream.Dispose(); continue; } switch ((EFuzzerMessageType)read) { case EFuzzerMessageType.GoodByte: { try { stream.Dispose(); } catch { } return; } case EFuzzerMessageType.PushPublicName: { var json = StreamHelper.ReadString(stream); if (string.IsNullOrWhiteSpace(json)) { stat.Source.Description = stat.Source.InternalName; } else { stat.Source.Description = stat.Source.InternalName + " [" + SerializationHelper.DeserializeFromJson <string>(json) + "]"; } break; } case EFuzzerMessageType.GetAvailableConfigs: { var data = Configurations.Select(u => u.Value.Source).ToArray(); var msg = FuzzerClient.GetMessage(EFuzzerMessageType.AvailableConfigs, data); lock (stream) { stream.Write(msg, 0, msg.Length); stream.Flush(); } break; } case EFuzzerMessageType.GetAvailableInputs: { var data = Inputs.Select(u => u.Value.Source).ToArray(); var msg = FuzzerClient.GetMessage(EFuzzerMessageType.AvailableInputs, data); lock (stream) { stream.Write(msg, 0, msg.Length); stream.Flush(); } break; } case EFuzzerMessageType.PushLog: { // Faster way to push a regular log if (StreamHelper.ReadFull(stream, uuidBuffer, 0, 16) != 16) { throw new IOException(); } var i = new Guid(uuidBuffer); if (StreamHelper.ReadFull(stream, uuidBuffer, 0, 16) != 16 || StreamHelper.ReadFull(stream, buffer, 0, 2) != 2) { throw new IOException(); } _processLogBag.Add(new LogEntry() { Stat = stat, Log = new FuzzerLog() { InputId = i, ConfigId = new Guid(uuidBuffer), Coverage = BitHelper.ToUInt16(buffer, 0) / 100D } }); break; } case EFuzzerMessageType.PushLogWithError: { var json = StreamHelper.ReadString(stream); var log = SerializationHelper.DeserializeFromJson <FuzzerLog>(json); if (log != null) { _processLogBag.Add(new LogEntry() { Stat = stat, Log = log }); } break; } } sleep.Sleep(); } Stop(); } catch (Exception ex) { // Remove the client Connections.TryRemove(clientId, out var _); throw ex; } }