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());
        }
Beispiel #2
0
        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);
        }
Beispiel #4
0
        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();
                }
        }
Beispiel #5
0
        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);
                }
            }
        }
Beispiel #6
0
        /// <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;
            }
        }