private void toolStripButtonRefreshSample_Click(object sender, EventArgs e) { var cursor = Cursor.Current; Cursor.Current = Cursors.WaitCursor; try { if (string.IsNullOrEmpty(dataModel) || string.IsNullOrEmpty(sampleFileName) || string.IsNullOrEmpty(pitFileName)) { return; } byte[] buff; using (Stream sin = new FileStream(sampleFileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { buff = new byte[sin.Length]; sin.Read(buff, 0, buff.Length); } PitParser parser; Dom dom; parser = new PitParser(); dom = parser.asParser(parserArgs, pitFileName); treeViewAdv1.BeginUpdate(); treeViewAdv1.Model = null; crackModel = new CrackModel(); try { BitStream data = new BitStream(buff); DataCracker cracker = new DataCracker(); cracker.EnterHandleNodeEvent += new EnterHandleNodeEventHandler(cracker_EnterHandleNodeEvent); cracker.ExitHandleNodeEvent += new ExitHandleNodeEventHandler(cracker_ExitHandleNodeEvent); cracker.AnalyzerEvent += new AnalyzerEventHandler(cracker_AnalyzerEvent); cracker.ExceptionHandleNodeEvent += new ExceptionHandleNodeEventHandler(cracker_ExceptionHandleNodeEvent); cracker.CrackData(dom.dataModels[dataModel], data); } catch (CrackingFailure ex) { MessageBox.Show("Error cracking \"" + ex.element.fullName + "\".\n" + ex.Message, "Error Cracking"); long endPos = -1; foreach (var element in exceptions) { CrackNode currentModel; if (crackMap.TryGetValue(element, out currentModel)) { currentModel.Error = true; if (endPos == -1) { endPos = currentModel.StartBits; } currentModel.StopBits = endPos; if (element.parent != null && crackMap.ContainsKey(element.parent)) { crackMap[element.parent].Children.Add(currentModel); } } } } foreach (var node in crackMap.Values) { if (node.DataElement.parent != null) { node.Parent = crackMap[node.DataElement.parent]; } } crackModel.Root = crackMap.Values.First().Root; treeViewAdv1.Model = crackModel; treeViewAdv1.EndUpdate(); treeViewAdv1.Root.Children[0].Expand(); // No longer needed crackMap.Clear(); } catch (Exception ex) { MessageBox.Show("Error cracking file: " + ex.ToString()); } finally { Cursor.Current = cursor; } }
public Program(string[] args) { AppDomain.CurrentDomain.DomainUnload += new EventHandler(CurrentDomain_DomainUnload); Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress); RunConfiguration config = new RunConfiguration(); config.debug = false; try { string analyzer = null; bool test = false; string agent = null; var definedValues = new List <string>(); bool parseOnly = false; var color = Console.ForegroundColor; Console.Write("\n"); Console.ForegroundColor = ConsoleColor.DarkRed; Console.Write("[[ "); Console.ForegroundColor = ConsoleColor.DarkCyan; Console.WriteLine(ProductName); Console.ForegroundColor = ConsoleColor.DarkRed; Console.Write("[[ "); Console.ForegroundColor = ConsoleColor.DarkCyan; Console.WriteLine(Copyright); Console.WriteLine(); Console.ForegroundColor = color; if (args.Length == 0) { Syntax(); } var p = new OptionSet() { { "h|?|help", v => Syntax() }, { "analyzer=", v => analyzer = v }, { "debug", v => config.debug = true }, { "1", v => config.singleIteration = true }, { "range=", v => ParseRange(config, v) }, { "t|test", v => test = true }, { "c|count", v => config.countOnly = true }, { "skipto=", v => config.skipToIteration = Convert.ToUInt32(v) }, { "seed=", v => config.randomSeed = Convert.ToUInt32(v) }, { "p|parallel=", v => ParseParallel(config, v) }, { "a|agent=", v => agent = v }, { "D|define=", v => AddNewDefine(v) }, { "definedvalues=", v => definedValues.Add(v) }, { "parseonly", v => parseOnly = true }, { "bob", var => bob() }, { "charlie", var => Charlie() }, { "showdevices", var => ShowDevices() }, { "showenv", var => ShowEnvironment() }, { "inputFilePath=", v => config.inputFilePath = v }, { "outputFilePath=", v => config.outputFilePath = v }, }; List <string> extra = p.Parse(args); if (extra.Count == 0 && agent == null && analyzer == null) { Syntax(); } Platform.LoadAssembly(); AddNewDefine("Peach.Cwd=" + Environment.CurrentDirectory); foreach (var definedValuesFile in definedValues) { var defs = PitParser.parseDefines(definedValuesFile); foreach (var kv in defs) { // Allow command line to override values in XML file. if (!DefinedValues.ContainsKey(kv.Key)) { DefinedValues.Add(kv.Key, kv.Value); } } } // Enable debugging if asked for if (config.debug) { var nconfig = new LoggingConfiguration(); var consoleTarget = new ColoredConsoleTarget(); nconfig.AddTarget("console", consoleTarget); consoleTarget.Layout = "${logger} ${message}"; var rule = new LoggingRule("*", LogLevel.Debug, consoleTarget); nconfig.LoggingRules.Add(rule); LogManager.Configuration = nconfig; } if (agent != null) { var agentType = ClassLoader.FindTypeByAttribute <AgentServerAttribute>((x, y) => y.name == agent); if (agentType == null) { Console.WriteLine("Error, unable to locate agent server for protocol '" + agent + "'.\n"); return; } var agentServer = Activator.CreateInstance(agentType) as IAgentServer; ConsoleWatcher.WriteInfoMark(); Console.WriteLine("Starting agent server"); agentServer.Run(new Dictionary <string, string>()); return; } if (analyzer != null) { var analyzerType = ClassLoader.FindTypeByAttribute <AnalyzerAttribute>((x, y) => y.Name == analyzer); if (analyzerType == null) { Console.WriteLine("Error, unable to locate analyzer called '" + analyzer + "'.\n"); return; } var field = analyzerType.GetField("supportCommandLine", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); if ((bool)field.GetValue(null) == false) { Console.WriteLine("Error, analyzer not configured to run from command line."); return; } var analyzerInstance = Activator.CreateInstance(analyzerType) as Analyzer; ConsoleWatcher.WriteInfoMark(); Console.WriteLine("Starting Analyzer"); analyzerInstance.asCommandLine(new Dictionary <string, string>()); return; } Dictionary <string, object> parserArgs = new Dictionary <string, object>(); parserArgs[PitParser.DEFINED_VALUES] = this.DefinedValues; if (test) { ConsoleWatcher.WriteInfoMark(); Console.Write("Validating file [" + extra[0] + "]... "); Analyzer.defaultParser.asParserValidation(parserArgs, extra[0]); if (Type.GetType("Mono.Runtime") != null) { Console.WriteLine("File parsed successfully, but XSD validation is not supported on the Mono runtime."); } else { Console.WriteLine("No Errors Found."); } return; } Engine e = new Engine(GetUIWatcher()); dom = GetParser(e).asParser(parserArgs, extra[0]); config.pitFile = extra[0]; // Used for unittests if (parseOnly) { return; } foreach (string arg in args) { config.commandLine += arg + " "; } if (extra.Count > 1) { if (!dom.tests.ContainsKey(extra[1])) { throw new PeachException("Error, unable to locate test named \"" + extra[1] + "\"."); } e.startFuzzing(dom, dom.tests[extra[1]], config); } else { e.startFuzzing(dom, config); } exitCode = 0; } catch (SyntaxException) { // Ignore, thrown by syntax() } catch (OptionException oe) { Console.WriteLine(oe.Message + "\n"); } catch (PeachException ee) { if (config.debug) { Console.WriteLine(ee); } else { Console.WriteLine(ee.Message + "\n"); } } finally { // HACK - Required on Mono with NLog 2.0 LogManager.Configuration = null; // Reset console colors Console.ForegroundColor = DefaultForground; } }
public void HttpClient(bool send_recv, string method, bool isHttps) { ushort port = TestBase.MakePort(56000, 57000); string url = null; SimpleHttpListener listener = null; Thread lThread = null; if (isHttps) { url = "https://changethisurltotest.peach"; } else { url = "http://localhost:" + port.ToString() + "/"; listener = new SimpleHttpListener(); string[] prefixes = new string[1] { url }; lThread = new Thread(() => listener.Listen(prefixes)); lThread.Start(); } try { string xml = string.Format(send_recv ? send_recv_template : recv_template, method, url); PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); RunConfiguration config = new RunConfiguration(); config.singleIteration = true; Engine e = new Engine(null); e.startFuzzing(dom, config); if (send_recv && !isHttps) { Assert.AreEqual(2, actions.Count); var de1 = actions[0].dataModel.find("TheDataModel.str"); Assert.NotNull(de1); var de2 = actions[1].dataModel.find("TheDataModel2.str"); Assert.NotNull(de2); string send = (string)de1.DefaultValue; string recv = (string)de2.DefaultValue; Assert.AreEqual("Hello World", send); Assert.AreEqual(method + " Hello World Too = 11", recv); } else if (!isHttps) { Assert.AreEqual(1, actions.Count); var de1 = actions[0].dataModel.find("TheDataModel.str"); Assert.NotNull(de1); string recv = (string)de1.DefaultValue; Assert.AreEqual(method + " Hello World Too = 0", recv); } } finally { if (!isHttps) { listener.Stop(); lThread.Join(); } } }
public void Test6() { // Test that the random strategy properly cycles through data models on the specified switch count string temp1 = Path.GetTempFileName(); string temp2 = Path.GetTempFileName(); File.WriteAllBytes(temp1, Encoding.ASCII.GetBytes("Hello\x00World\x00")); File.WriteAllBytes(temp2, Encoding.ASCII.GetBytes("Foo\x00")); // Test loading a dataset from a file string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" + "<Peach>" + " <DataModel name=\"TheDataModel\">" + " <String name=\"str1\" value=\"Initial\" maxOccurs=\"100\" nullTerminated=\"true\"/>" + " </DataModel>" + " <StateModel name=\"TheState\" initialState=\"Initial\">" + " <State name=\"Initial\">" + " <Action type=\"output\">" + " <DataModel ref=\"TheDataModel\"/>" + " <Data fileName=\"" + temp1 + "\"/>" + " <Data fileName=\"" + temp2 + "\"/>" + " </Action>" + " </State>" + " </StateModel>" + " <Test name=\"Default\">" + " <StateModel ref=\"TheState\"/>" + " <Publisher class=\"Null\"/>" + " <Strategy class=\"RandomStrategy\">" + " <Param name=\"SwitchCount\" value=\"10\"/>" + " </Strategy>" + " </Test>" + "</Peach>"; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); dom.tests[0].includedMutators = new List <string>(); dom.tests[0].includedMutators.Add("StringCaseMutator"); RunConfiguration config = new RunConfiguration(); config.rangeStart = 1; config.rangeStop = 50; config.range = true; config.randomSeed = 12345; Engine e = new Engine(null); e.startFuzzing(dom, config); Assert.AreEqual(50, mutations.Count); // 50 mutations, control on 1, 11, 21, 31, 41 Assert.AreEqual(50 + 5, dataModels.Count); int lastSize = 0; // Skip data model 0, its the magical 1st pass w/o mutations for (int i = 0; i < 55; ++i) { Assert.AreEqual(1, dataModels[i].Count); Dom.Array item = dataModels[i][0] as Dom.Array; // Its either an array of 1 or an array of 2 Assert.GreaterOrEqual(item.Count, 1); Assert.LessOrEqual(item.Count, 2); if (lastSize != item.Count) { // Change of data model should only occur at iteration 1, 11, 21, 31, 41 // which is the 0, 11, 22, 33, 44 indices Assert.AreEqual(i / 10, i % 10); lastSize = item.Count; } } }
public void SlurpArray() { string xml = @" <Peach> <DataModel name='TheDataModel'> <String name='str' value='Hello'/> <Block name='blk' minOccurs='1'> <String name='val'/> </Block> </DataModel> <StateModel name='TheState' initialState='State1'> <State name='State1'> <Action type='output'> <DataModel ref='TheDataModel'/> </Action> </State> </StateModel> <Test name='Default'> <StateModel ref='TheState'/> <Publisher class='Console'/> </Test> </Peach> "; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); Dom.Array array = dom.tests[0].stateModel.states["State1"].actions[0].dataModel[1] as Dom.Array; array.ExpandTo(50); PeachXPathNavigator navi = new PeachXPathNavigator(dom); var iter = navi.Select("//str"); if (!iter.MoveNext()) { Assert.Fail(); } DataElement valueElement = ((PeachXPathNavigator)iter.Current).currentNode as DataElement; if (valueElement == null) { Assert.Fail(); } if (iter.MoveNext()) { Assert.Fail(); } iter = navi.Select("//val"); if (!iter.MoveNext()) { Assert.Fail(); } int count = 0; do { var setElement = ((PeachXPathNavigator)iter.Current).currentNode as DataElement; if (setElement == null) { Assert.Fail(); } setElement.DefaultValue = valueElement.DefaultValue; ++count; }while (iter.MoveNext()); // When Array.ExpandTo() is used, it duplicates the element and adds that // same element over and over, so there are really only 2 unique elements in the array... Assert.AreEqual(2, count); Assert.AreEqual(50, array.Count); int hash = 0; for (int i = 0; i < array.Count; ++i) { if (i <= 1) { hash = array[i].GetHashCode(); } Assert.AreEqual(hash, array[i].GetHashCode()); var b = array[i] as Block; Assert.NotNull(b); Assert.AreEqual("Hello", (string)b[0].DefaultValue); } }
public void MultipleOfRelations() { string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<Peach>\n" + " <DataModel name=\"TheDataModel\">"+ " <Number name=\"num1\" size=\"16\">"+ " <Relation type=\"size\" of=\"Data\" />"+ " </Number>"+ " <Blob name=\"Data\" value=\"00 01 02 03 04 05 06 07\" valueType=\"hex\" >"+ " <Hint name=\"BlobMutator-How\" value=\"ExpandAllRandom\" />"+ " </Blob>"+ " <Number name=\"num2\" size=\"16\">"+ " <Relation type=\"size\" of=\"Data\" />"+ " </Number>"+ " </DataModel>"+ " <StateModel name=\"TheState\" initialState=\"Initial\">"+ " <State name=\"Initial\">"+ " <Action type=\"output\">"+ " <DataModel ref=\"TheDataModel\"/>"+ " </Action>"+ " </State>"+ " </StateModel>"+ " <Test name=\"Default\">"+ " <StateModel ref=\"TheState\"/>"+ " <Publisher class=\"Null\"/>"+ " <Strategy class=\"Random\"/>"+ " </Test>"+ "</Peach>"; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); dom.tests[0].includedMutators = new List <string>(); dom.tests[0].includedMutators.Add("BlobMutator"); RunConfiguration config = new RunConfiguration(); config.range = true; config.rangeStart = 0; config.rangeStop = 9; Engine e = new Engine(null); e.startFuzzing(dom, config); Assert.AreEqual(10, dataModels.Count); for (int i = 0; i < 10; ++i) { var model = dataModels[i]; Assert.AreEqual(3, model.Count); Number num1 = model[0] as Number; Variant val1 = num1.InternalValue; Assert.GreaterOrEqual((long)val1, 8); Blob blob = model[1] as Blob; Variant val2 = blob.InternalValue; int len = ((byte[])val2).Length; Assert.GreaterOrEqual(len, 8); Number num2 = model[2] as Number; Variant val3 = num2.InternalValue; Assert.GreaterOrEqual((long)val3, 8); Assert.AreEqual(len, (long)val1); Assert.AreEqual(len, (long)val3); } }
Dictionary <string, object> SpeedTest(uint repeat) { // When the data element duplicator clones blockData multiple times, // it becomes painfully slow to evaulate the final value of DM3 string outter_xml = @" <Peach> <DataModel name=""DM3""> <Number name=""tag"" size=""32"" signed=""false"" endian=""big""> <Fixup class=""Crc32Fixup""> <Param name=""ref"" value=""blockData""/> </Fixup> </Number> {0} </DataModel> </Peach> "; string inner_xml = @" <Block name=""blockData{0}""> <Number name=""CommandSize"" size=""32"" signed=""false"" endian=""big""> <Relation type=""size"" of=""DM3"" /> </Number> <Number name=""CommandCode"" size=""32"" signed=""false"" endian=""big""> <Transformer class=""Md5""/> </Number> </Block> "; StringBuilder sb = new StringBuilder(); sb.Append(string.Format(inner_xml, "")); for (int i = 0; i < repeat; ++i) { sb.Append(string.Format(inner_xml, "_" + i)); } string xml = string.Format(outter_xml, sb.ToString()); PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); Assert.AreEqual(1, dom.dataModels.Count); int start = Environment.TickCount; var value = dom.dataModels[0].Value; int end = Environment.TickCount; Assert.NotNull(value); TimeSpan delta = TimeSpan.FromMilliseconds(end - start); Dictionary <string, object> ret = new Dictionary <string, object>(); ret["delta"] = delta; ret["count"] = dom.dataModels[0].GenerateCount; return(ret); }
public void RelationInArray() { string xml = @" <Peach> <DataModel name=""ElemModel""> <Number name=""length"" size=""16"" endian=""big""> <Relation type=""size"" of=""data""/> </Number> <Blob name=""data""/> </DataModel> <DataModel name=""DM""> <Number name=""tag"" size=""16"" endian=""big"" /> <Number name=""length"" size=""16"" endian=""big""> <Relation type=""size"" of=""Elements""/> </Number> <Block name=""Elements""> <Block name=""Elem"" minOccurs=""0"" maxOccurs=""999""> <Block name=""Elem0"" ref=""ElemModel""/> </Block> </Block> </DataModel> </Peach> "; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); Assert.AreEqual(2, dom.dataModels.Count); var data = Bits.Fmt("{0}", new byte[] { 0x00, 0x10, 0x00, 0x06, 0x00, 0x04, 0xde, 0xad, 0xbe, 0xef }); DataCracker cracker = new DataCracker(); cracker.CrackData(dom.dataModels[1], data); Assert.AreEqual(3, dom.dataModels[1].Count); var tag = dom.dataModels[1][0] as Number; var len = dom.dataModels[1][1] as Number; var blk = dom.dataModels[1][2] as Block; Assert.NotNull(tag); Assert.NotNull(len); Assert.NotNull(blk); Assert.AreEqual(1, blk.Count); var arr = blk[0] as Dom.Array; Assert.NotNull(arr); Assert.AreEqual(1, arr.Count); var elm = arr[0] as Block; Assert.NotNull(elm); Assert.AreEqual(1, elm.Count); var el0 = elm[0] as DataModel; Assert.NotNull(el0); Assert.AreEqual(2, el0.Count); var length = el0[0] as Number; var blob = el0[1] as Blob; Assert.NotNull(length); Assert.NotNull(blob); Assert.AreEqual(16, (int)tag.DefaultValue); Assert.AreEqual(6, (int)len.DefaultValue); Assert.AreEqual(4, (int)length.DefaultValue); var final = (BitStream)blob.DefaultValue; Assert.NotNull(final); var actual = final.ToArray(); var expected = new byte[] { 0xde, 0xad, 0xbe, 0xef }; Assert.AreEqual(actual, expected); }
public void Test3() { // Test that random mutations stay within the correct bounds of 1x - 50x string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" + "<Peach>" + " <DataModel name=\"TheDataModel\">" + " <Number name=\"num0\" size=\"16\" signed=\"false\"/>" + " </DataModel>" + " <StateModel name=\"TheState\" initialState=\"Initial\">" + " <State name=\"Initial\">" + " <Action type=\"output\">" + " <DataModel ref=\"TheDataModel\"/>" + " </Action>" + " </State>" + " </StateModel>" + " <Test name=\"Default\">" + " <StateModel ref=\"TheState\"/>" + " <Publisher class=\"Null\"/>" + " <Strategy class=\"Random\"/>" + " </Test>" + "</Peach>"; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); dom.tests[0].includedMutators = new List <string>(); dom.tests[0].includedMutators.Add("DataElementDuplicateMutator"); RunConfiguration config = new RunConfiguration(); config.range = true; config.rangeStart = 0; config.rangeStop = 1000; config.randomSeed = 100; Engine e = new Engine(null); e.startFuzzing(dom, config); // verify values // 1000 mutations, switch every 200 iterations Assert.AreEqual(1005, dataModels.Count); Assert.AreEqual(1000, mutatedDataModels.Count); // No mutation on the 1st control iteration Assert.AreEqual(1, dataModels[0].Count); int min = int.MaxValue; int max = int.MinValue; for (int i = 0; i < mutatedDataModels.Count; ++i) { if (dataModels[i].Count > max) { max = dataModels[i].Count; } if (dataModels[i].Count < min) { min = dataModels[i].Count; } } // Either duplicates or it doesn't. This is what Peach 2.3 does, but is it right? Assert.AreEqual(1, min); Assert.AreEqual(2, max); }
public void TestEarlyExit() { string pit = @" <Peach> <DataModel name='TheDataModel'> <String value='Hello'/> </DataModel> <StateModel name='TheState' initialState='Initial'> <State name='Initial'> <Action type='output'> <DataModel ref='TheDataModel'/> </Action> </State> </StateModel> <Agent name='LocalAgent'> <Monitor class='WindowsDebugger'> <Param name='CommandLine' value='CrashingFileConsumer.exe'/> <Param name='FaultOnEarlyExit' value='true'/> </Monitor> </Agent> <Test name='Default' replayEnabled='true'> <Agent ref='LocalAgent'/> <StateModel ref='TheState'/> <Publisher class='Null'/> </Test> </Peach>"; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(pit))); RunConfiguration config = new RunConfiguration(); config.range = true; config.rangeStart = 1; config.rangeStop = 1; Engine e = new Engine(null); e.Fault += _AppendFault; e.ReproFault += _AppendFault; try { e.startFuzzing(dom, config); Assert.Fail("Should throw!"); } catch (PeachException ex) { Assert.AreEqual("Fault detected on control iteration.", ex.Message); } Assert.NotNull(this.faults); Assert.AreEqual(2, this.faults.Length); Assert.AreEqual(FaultType.Fault, this.faults[0].type); Assert.AreEqual("SystemDebugger", this.faults[0].detectionSource); Assert.AreEqual(FaultType.Fault, this.faults[1].type); Assert.AreEqual("WindowsDebugEngine", this.faults[1].detectionSource); }
public void TestBlock() { // standard test of swapping the data elements string xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n" + "<Peach>" + " <DataModel name=\"TheDataModel\">" + " <Block name=\"blk\">" + " <Number name=\"num0\" size=\"32\" signed=\"true\" value=\"41\"/>" + " <Number name=\"num1\" size=\"32\" signed=\"true\" value=\"42\"/>" + " <Number name=\"num2\" size=\"32\" signed=\"true\" value=\"43\"/>" + " <Number name=\"num3\" size=\"32\" signed=\"true\" value=\"44\"/>" + " <Number name=\"num4\" size=\"32\" signed=\"true\" value=\"45\"/>" + " </Block>" + " </DataModel>" + " <StateModel name=\"TheState\" initialState=\"Initial\">" + " <State name=\"Initial\">" + " <Action type=\"output\">" + " <DataModel ref=\"TheDataModel\"/>" + " </Action>" + " </State>" + " </StateModel>" + " <Test name=\"Default\">" + " <StateModel ref=\"TheState\"/>" + " <Publisher class=\"Null\"/>" + " <Strategy class=\"Sequential\"/>" + " </Test>" + "</Peach>"; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); dom.tests[0].includedMutators = new List <string>(); dom.tests[0].includedMutators.Add("DataElementSwapNearNodesMutator"); RunConfiguration config = new RunConfiguration(); Engine e = new Engine(null); e.startFuzzing(dom, config); DataElementContainer blk = null; Assert.AreEqual(5, dataModels.Count); Assert.AreEqual(1, dataModels[0].Count); blk = dataModels[0][0] as DataElementContainer; Assert.NotNull(blk); Assert.AreEqual("blk", blk.name); Assert.AreEqual(5, blk.Count); Assert.AreEqual("num0", blk[0].name); Assert.AreEqual("num1", blk[1].name); Assert.AreEqual("num2", blk[2].name); Assert.AreEqual("num3", blk[3].name); Assert.AreEqual("num4", blk[4].name); Assert.AreEqual(1, dataModels[2].Count); blk = dataModels[1][0] as DataElementContainer; Assert.NotNull(blk); Assert.AreEqual("blk", blk.name); Assert.AreEqual(5, blk.Count); Assert.AreEqual("num1", blk[0].name); Assert.AreEqual("num0", blk[1].name); Assert.AreEqual("num2", blk[2].name); Assert.AreEqual("num3", blk[3].name); Assert.AreEqual("num4", blk[4].name); Assert.AreEqual(1, dataModels[2].Count); blk = dataModels[2][0] as DataElementContainer; Assert.NotNull(blk); Assert.AreEqual("blk", blk.name); Assert.AreEqual(5, blk.Count); Assert.AreEqual("num0", blk[0].name); Assert.AreEqual("num2", blk[1].name); Assert.AreEqual("num1", blk[2].name); Assert.AreEqual("num3", blk[3].name); Assert.AreEqual("num4", blk[4].name); Assert.AreEqual(1, dataModels[3].Count); blk = dataModels[3][0] as DataElementContainer; Assert.NotNull(blk); Assert.AreEqual("blk", blk.name); Assert.AreEqual(5, blk.Count); Assert.AreEqual("num0", blk[0].name); Assert.AreEqual("num1", blk[1].name); Assert.AreEqual("num3", blk[2].name); Assert.AreEqual("num2", blk[3].name); Assert.AreEqual("num4", blk[4].name); Assert.AreEqual(1, dataModels[4].Count); blk = dataModels[4][0] as DataElementContainer; Assert.NotNull(blk); Assert.AreEqual("blk", blk.name); Assert.AreEqual(5, blk.Count); Assert.AreEqual("num0", blk[0].name); Assert.AreEqual("num1", blk[1].name); Assert.AreEqual("num2", blk[2].name); Assert.AreEqual("num4", blk[3].name); Assert.AreEqual("num3", blk[4].name); }
public void RecursiveStates() { // When using recursive states, ensure the data model is reset // so that mutations from the previous actions don't carry // over to subsequent runs. When slrup is used to set a value // in a different state, that value will be cleared when the state // is re-entered. string xml = @" <Peach> <DataModel name='Foo'> <String name='str1' value='Foo Data Model' mutable='false'/> </DataModel> <DataModel name='DM'> <Number name='num' size='8' mutable='false'> <Fixup class='SequenceIncrementFixup'> <Param name='Offset' value='0'/> </Fixup> </Number> <String name='str1' value='Hello'/> <String name='str2' value='World'/> </DataModel> <StateModel name='SM' initialState='Initial'> <State name='Initial'> <Action type='output'> <DataModel ref='Foo'/> </Action> <Action type='slurp' valueXpath='//Foo/str1' setXpath='//DM/str2'/> <Action type='changeState' ref='Send'/> </State> <State name='Send'> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='changeState' ref='Send' when='int(state.actions[0].dataModel["num"].InternalValue) < 5'/> </State> </StateModel> <Test name='Default'> <StateModel ref='SM'/> <Publisher class='Null'/> <Strategy class='Random'> <Param name='MaxFieldsToMutate' value='1'/> </Strategy> </Test> </Peach>"; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); dom.tests[0].includedMutators = new List <string>(); dom.tests[0].includedMutators.Add("StringMutator"); RunConfiguration config = new RunConfiguration(); config.range = true; config.rangeStart = 1; config.rangeStop = 10; Engine e = new Engine(null); e.startFuzzing(dom, config); Assert.AreEqual(66, dataModels.Count); for (int i = 1; i < 6; ++i) { Assert.AreEqual(i, (int)dataModels[i][0].InternalValue); Assert.AreEqual("Hello", (string)dataModels[i][1].InternalValue); if (i == 1) { Assert.AreEqual("Foo Data Model", (string)dataModels[i][2].InternalValue); } else { Assert.AreEqual("World", (string)dataModels[i][2].InternalValue); } } for (int i = 6; i < dataModels.Count; i += 6) { int count = 0; for (int j = 1; j < 6; ++j) { Assert.AreEqual(j, (int)dataModels[i + j][0].InternalValue); string str1 = (string)dataModels[i + j][1].InternalValue; string str2 = (string)dataModels[i + j][2].InternalValue; string exp = j == 1 ? "Foo Data Model" : "World"; if (str1 != "Hello") { ++count; } if (str2 != exp) { ++count; } } Assert.AreEqual(1, count); } }
public void TestUniqueNames() { var tmp = Path.GetTempFileName(); string xml = @" <Peach> <DataModel name='DM'> <String name='str' value='Hello'/> </DataModel> <Agent name='MyAgent'> <Monitor class='FaultingMonitor'/> <Monitor class='FaultingMonitor'/> <Monitor class='FaultingMonitor'/> </Agent> <Agent name='MyAgent2'> <Monitor class='FaultingMonitor'/> <Monitor class='FaultingMonitor'/> <Monitor class='FaultingMonitor'/> </Agent> <StateModel name='SM' initialState='Initial'> <State name='Initial'> <Action type='call' method='foo' > <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> </Action> <Action type='call' method='foo' > <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> </Action> </State> <State name='Second'> <Action type='call' method='foo' > <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> </Action> <Action type='call' method='foo' > <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> <Param> <DataModel ref='DM'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data fileName='{0}'/> <Data><Field name='str' value='other'/></Data> </Param> </Action> </State> </StateModel> <Test name='Default'> <StateModel ref='SM'/> <Publisher class='Null'/> <Publisher class='Null'/> <Publisher class='Null'/> <Strategy class='RandomDeterministic'/> </Test> </Peach>".Fmt(tmp); var tmpName = Path.GetFileName(tmp); Assert.False(tmpName.Contains(Path.DirectorySeparatorChar)); var parser = new PitParser(); var dom = parser.asParser(null, new MemoryStream(Encoding.ASCII.GetBytes(xml))); Assert.AreEqual(2, dom.agents.Count); foreach (var agent in dom.agents) { Assert.AreEqual(3, agent.monitors.Count); Assert.AreEqual("Monitor", agent.monitors[0].name); Assert.AreEqual("Monitor_1", agent.monitors[1].name); Assert.AreEqual("Monitor_2", agent.monitors[2].name); } Assert.AreEqual(3, dom.tests[0].publishers.Count); Assert.True(dom.tests[0].publishers.ContainsKey("Pub")); Assert.True(dom.tests[0].publishers.ContainsKey("Pub_1")); Assert.True(dom.tests[0].publishers.ContainsKey("Pub_2")); Assert.AreEqual(2, dom.tests[0].stateModel.states.Count); foreach (var state in dom.tests[0].stateModel.states) { Assert.AreEqual(2, state.actions.Count); Assert.AreEqual("Action", state.actions[0].name); Assert.AreEqual("Action_1", state.actions[1].name); foreach (var action in state.actions) { var actionData = action.allData.ToList(); Assert.AreEqual(3, actionData.Count); Assert.AreEqual("Param", actionData[0].name); Assert.AreEqual("Param_1", actionData[1].name); Assert.AreEqual("Param_2", actionData[2].name); foreach (var item in actionData) { Assert.AreEqual(4, item.dataSets.Count); Assert.AreEqual("Data", item.dataSets[0].name); Assert.AreEqual("Data_1", item.dataSets[1].name); Assert.AreEqual("Data_2", item.dataSets[2].name); Assert.AreEqual("Data_3", item.dataSets[3].name); var data = item.allData.ToList(); Assert.AreEqual(4, item.dataSets.Count); Assert.AreEqual("Data/" + tmpName, data[0].name); Assert.AreEqual("Data_1/" + tmpName, data[1].name); Assert.AreEqual("Data_2/" + tmpName, data[2].name); Assert.AreEqual("Data_3", data[3].name); } } } }
public void ParseDefinesFileNotFound() { PitParser.parseDefines("filenotfound.xml"); }
public void PickChoice() { string temp = Path.GetTempFileName(); string xml = @" <Peach> <DataModel name='DM1'> <String name='str' value='token1' token='true'/> </DataModel> <DataModel name='DM2'> <String name='str' value='token2' token='true'/> </DataModel> <DataModel name='DM'> <Choice name='choice'> <Block name='token1' ref='DM1'/> <Block name='token2' ref='DM2'/> </Choice> </DataModel> <StateModel name='SM_In' initialState='Initial'> <State name='Initial'> <Action type='input'> <DataModel ref='DM' /> <Data DataModel='DM'> <Field name='choice.token2' value='' /> </Data> </Action> </State> </StateModel> <StateModel name='SM_Out' initialState='Initial'> <State name='Initial'> <Action type='output'> <DataModel ref='DM' /> <Data DataModel='DM'> <Field name='choice.token2' value='' /> </Data> </Action> </State> </StateModel> <Test name='Input'> <StateModel ref='SM_In' /> <Publisher class='File'> <Param name='FileName' value='{0}'/> <Param name='Overwrite' value='false'/> </Publisher> </Test> <Test name='Output'> <StateModel ref='SM_Out' /> <Publisher class='File'> <Param name='FileName' value='{0}'/> <Param name='Overwrite' value='true'/> </Publisher> </Test> </Peach>".Fmt(temp); PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); RunConfiguration config = new RunConfiguration(); config.singleIteration = true; config.runName = "Output"; Engine e = new Engine(null); e.startFuzzing(dom, config); var file = File.ReadAllText(temp); Assert.AreEqual("token2", file); config.runName = "Input"; dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); e = new Engine(null); e.startFuzzing(dom, config); }
public void SizedParent() { // Make sure increment loops when it would overflow the size of the parent string xml = @" <Peach> <DataModel name='DM'> <Number name='str' size='2' mutable='false'> <Fixup class='SequenceIncrementFixup'> <Param name='Offset' value='3'/> </Fixup> </Number> <String/> </DataModel> <StateModel name='TheState' initialState='Initial'> <State name='Initial'> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> </State> </StateModel> <Test name='Default'> <StateModel ref='TheState'/> <Publisher class='Null'/> </Test> </Peach> "; cloneActions = true; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); RunConfiguration config = new RunConfiguration(); config.range = true; config.rangeStart = 0; config.rangeStop = 10; Engine e = new Engine(null); e.startFuzzing(dom, config); Assert.AreEqual(33, this.dataModels.Count); Assert.AreEqual(0, (int)dom.dataModels[0][0].DefaultValue); Assert.AreEqual(0, (int)dom.dataModels[0][0].InternalValue); for (int i = 0; i < 33; i += 3) { Assert.AreEqual(0, (int)dataModels[i + 0][0].DefaultValue); Assert.AreEqual(1, (int)dataModels[i + 0][0].InternalValue); Assert.AreEqual(0, (int)dataModels[i + 1][0].DefaultValue); Assert.AreEqual(2, (int)dataModels[i + 1][0].InternalValue); Assert.AreEqual(0, (int)dataModels[i + 2][0].DefaultValue); Assert.AreEqual(3, (int)dataModels[i + 2][0].InternalValue); } ResetContainers(); cloneActions = true; parser = new PitParser(); dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); config = new RunConfiguration(); config.range = true; config.rangeStart = 3; config.rangeStop = 12; e = new Engine(null); e.startFuzzing(dom, config); Assert.AreEqual(33, this.dataModels.Count); Assert.AreEqual(0, (int)dom.dataModels[0][0].DefaultValue); Assert.AreEqual(0, (int)dom.dataModels[0][0].InternalValue); for (int i = 0; i < 33; i += 3) { Assert.AreEqual(0, (int)dataModels[i + 0][0].DefaultValue); Assert.AreEqual(1, (int)dataModels[i + 0][0].InternalValue); Assert.AreEqual(0, (int)dataModels[i + 1][0].DefaultValue); Assert.AreEqual(2, (int)dataModels[i + 1][0].InternalValue); Assert.AreEqual(0, (int)dataModels[i + 2][0].DefaultValue); Assert.AreEqual(3, (int)dataModels[i + 2][0].InternalValue); } }
public void TestActionParam() { string xml = @" <Peach> <DataModel name='DM1'> <String name='str1' value='Hello' mutable='false'/> <String name='str2' value='World'/> </DataModel> <DataModel name='DM2'> <String name='str'/> </DataModel> <StateModel name='SM' initialState='Initial'> <State name='Initial'> <Action name='action' type='call'> <Param name='Named Param 1' type='in'> <DataModel ref='DM1'/> <Data> <Field name='str1' value='Param1'/> </Data> </Param> <Param name='Named Param 2' type='out'> <DataModel ref='DM1'/> <Data> <Field name='str1' value='Param2'/> </Data> </Param> <Param name='Named Param 3' type='inout'> <DataModel ref='DM1'/> <Data> <Field name='str1' value='Param3'/> </Data> </Param> <Param> <DataModel ref='DM1'/> <Data> <Field name='str1' value='Param4'/> </Data> </Param> <Result name='res'> <DataModel ref='DM2'/> </Result> </Action> </State> </StateModel> <Test name='Default'> <StateModel ref='SM'/> <Publisher class='Null'/> <Mutators mode='include'> <Mutator class='StringCaseMutator'/> </Mutators> <Strategy class='RandomDeterministic'/> </Test> </Peach>"; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(Encoding.ASCII.GetBytes(xml))); dom.tests[0].publishers[0] = new ParamPublisher(new Dictionary <string, Variant>()); RunConfiguration config = new RunConfiguration(); config.singleIteration = true; Engine e = new Engine(null); e.startFuzzing(dom, config); var act = dom.tests[0].stateModel.states["Initial"].actions[0]; Assert.NotNull(act.result); Assert.AreEqual("res", act.result.name); Assert.NotNull(act.result.dataModel); string str = (string)act.result.dataModel[0].InternalValue; Assert.AreEqual("The Result!", str); }
public void TestIncrementInitialField() { string tempFile = Path.GetTempFileName(); string xml = @" <Peach> <DataModel name='DM'> <Number name='num' size='16'> <Fixup class='SequenceIncrementFixup'/> </Number> </DataModel> <StateModel name='TheState' initialState='Initial'> <State name='Initial'> <Action type='output' publisher='null'> <DataModel ref='DM'/> <Data DataModel='DM'> <Field name='num' value='100' /> </Data> </Action> <Action type='changeState' ref='Second'/> </State> <State name='Second'> <Action type='changeState' ref='Third'/> </State> <State name='Third'> <Action type='output' publisher='null'> <DataModel ref='DM'/> </Action> </State> </StateModel> <Test name='Default'> <StateModel ref='TheState'/> <Publisher name='null' class='Null'/> <Publisher name='file' class='File'> <Param name='Overwrite' value='false'/> <Param name='FileName' value='{0}'/> </Publisher> </Test> </Peach> ".Fmt(tempFile); File.WriteAllBytes(tempFile, new byte[] { 12, 0 }); PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); RunConfiguration config = new RunConfiguration(); config.singleIteration = true; Engine e = new Engine(null); e.startFuzzing(dom, config); Assert.AreEqual(2, this.actions.Count); Assert.AreEqual(0, (int)dom.dataModels[0][0].DefaultValue); Assert.AreEqual(0, (int)dom.dataModels[0][0].InternalValue); Assert.AreEqual(100, (int)this.actions[0].dataModel[0].DefaultValue); Assert.AreEqual(1, (int)this.actions[0].dataModel[0].InternalValue); Assert.AreEqual(0, (int)this.actions[1].dataModel[0].DefaultValue); Assert.AreEqual(2, (int)this.actions[1].dataModel[0].InternalValue); }
public void RelationGetSet() { string xml = @" <Peach> <DataModel name=""TheModel""> <Number size=""8"" mutable=""false""/> <Number name=""len"" size=""64"" mutable=""false""> <Relation type=""size"" of=""data"" expressionGet=""size+2"" expressionSet=""size-2""/> </Number> <Block name=""data""> <Blob length=""1""/> <Blob length=""2""/> </Block> </DataModel> <StateModel name=""TheState"" initialState=""Initial""> <State name=""Initial""> <Action type=""output""> <DataModel name=""foo"" ref=""TheModel""/> </Action> </State> </StateModel> <Test name=""Default""> <StateModel ref=""TheState""/> <Publisher class=""Null""/> <Strategy class=""Sequential""/> </Test> </Peach> "; cloneActions = true; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); dom.tests[0].includedMutators = new List <string>(); dom.tests[0].includedMutators.Add("DataElementRemoveMutator"); RunConfiguration config = new RunConfiguration(); Engine e = new Engine(null); e.startFuzzing(dom, config); Assert.AreEqual(4, actions.Count); byte[] act1 = Encoding.ASCII.GetBytes("\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"); Assert.False(actions[0].error); Assert.AreEqual(act1, actions[0].dataModel.Value.Value); byte[] act2 = Encoding.ASCII.GetBytes("\x00\x00\x00\x00\x00\x00\x00\x00\x00"); Assert.False(actions[1].error); Assert.AreEqual(act2, actions[1].dataModel.Value.Value); byte[] act3 = Encoding.ASCII.GetBytes("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"); Assert.False(actions[2].error); Assert.AreEqual(act3, actions[2].dataModel.Value.Value); Assert.True(actions[3].error); try { var x = actions[3].dataModel.Value; Assert.Fail("should throw"); Assert.NotNull(x); } catch (SoftException se) { Assert.AreEqual("Error, Number 'foo.len' value '-1' is less than the minimum 64-bit unsigned number.", se.Message); } }
public void FuzzOffsetFive() { string xml = @" <Peach> <DataModel name='DM'> <Number name='str' size='16' mutable='false'> <Fixup class='SequenceIncrementFixup'> <Param name='Offset' value='5'/> </Fixup> </Number> <String/> </DataModel> <StateModel name='TheState' initialState='Initial'> <State name='Initial'> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> </State> </StateModel> <Test name='Default'> <StateModel ref='TheState'/> <Publisher class='Null'/> </Test> </Peach> "; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); RunConfiguration config = new RunConfiguration(); config.range = true; config.rangeStart = 0; config.rangeStop = 3; Engine e = new Engine(null); e.startFuzzing(dom, config); Assert.AreEqual((1 + 3) * 3, this.dataModels.Count); Assert.AreEqual(0, (int)dom.dataModels[0][0].DefaultValue); Assert.AreEqual(0, (int)dom.dataModels[0][0].InternalValue); for (int i = 0; i < 12; i += 3) { // Should be: // 1, 2, 3 // 1, 2, 3 // 6, 7, 8 // 11, 12, 13 int exp = Math.Max(0, i - 3); int start = 5 * (exp / 3); Assert.AreEqual(0, (int)dataModels[i + 0][0].DefaultValue); Assert.AreEqual(start + 1, (int)dataModels[i + 0][0].InternalValue); Assert.AreEqual(0, (int)dataModels[i + 1][0].DefaultValue); Assert.AreEqual(start + 2, (int)dataModels[i + 1][0].InternalValue); Assert.AreEqual(0, (int)dataModels[i + 2][0].DefaultValue); Assert.AreEqual(start + 3, (int)dataModels[i + 2][0].InternalValue); } }
public void RelationInArray() { string xml = @" <Peach> <DataModel name=""ElemModel""> <Number name=""length"" size=""16"" endian=""big""> <Relation type=""size"" of=""data""/> </Number> <Blob name=""data""/> </DataModel> <DataModel name=""DM""> <Number name=""tag"" size=""16"" endian=""big"" /> <Number name=""length"" size=""16"" endian=""big""> <Relation type=""size"" of=""Elements""/> </Number> <Block name=""Elements""> <Block name=""Elem"" minOccurs=""0"" maxOccurs=""999""> <Block name=""Elem0"" ref=""ElemModel""/> </Block> </Block> </DataModel> </Peach> "; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); Assert.AreEqual(2, dom.dataModels.Count); BitStream data = new BitStream(); data.WriteBytes(new byte[] { 0x00, 0x10, 0x00, 0x06, 0x00, 0x04, 0xde, 0xad, 0xbe, 0xef }); data.SeekBits(0, SeekOrigin.Begin); DataCracker cracker = new DataCracker(); cracker.CrackData(dom.dataModels[1], data); Assert.AreEqual(3, dom.dataModels[1].Count); var tag = dom.dataModels[1][0] as Number; var len = dom.dataModels[1][1] as Number; var blk = dom.dataModels[1][2] as Block; Assert.NotNull(tag); Assert.NotNull(len); Assert.NotNull(blk); Assert.AreEqual(1, blk.Count); var arr = blk[0] as Dom.Array; Assert.NotNull(arr); Assert.AreEqual(1, arr.Count); var elm = arr[0] as Block; Assert.NotNull(elm); Assert.AreEqual(1, elm.Count); var el0 = elm[0] as DataModel; Assert.NotNull(el0); Assert.AreEqual(2, el0.Count); var length = el0[0] as Number; var blob = el0[1] as Blob; Assert.NotNull(length); Assert.NotNull(blob); Assert.AreEqual(16, (int)tag.DefaultValue); Assert.AreEqual(6, (int)len.DefaultValue); Assert.AreEqual(4, (int)length.DefaultValue); var bs = (BitStream)blob.DefaultValue; Assert.NotNull(bs); MemoryStream ms = bs.Stream as MemoryStream; Assert.NotNull(ms); Assert.AreEqual(4, ms.Length); var buf = ms.GetBuffer(); Assert.AreEqual(0xde, buf[0]); Assert.AreEqual(0xad, buf[1]); Assert.AreEqual(0xbe, buf[2]); Assert.AreEqual(0xef, buf[3]); }
public void TwoDataModels() { string xml = @" <Peach> <DataModel name='DM'> <Number name='str' size='16' mutable='false'> <Fixup class='SequenceIncrementFixup'/> </Number> </DataModel> <DataModel name='DM2'> <Number name='str' size='32' mutable='false'> <Fixup class='SequenceIncrementFixup'/> </Number> </DataModel> <StateModel name='TheState' initialState='Initial'> <State name='Initial'> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> </State> </StateModel> <Test name='Default'> <StateModel ref='TheState'/> <Publisher class='Null'/> </Test> </Peach> "; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); RunConfiguration config = new RunConfiguration(); config.singleIteration = true; Engine e = new Engine(null); e.startFuzzing(dom, config); Assert.AreEqual(3, this.dataModels.Count); Assert.AreEqual(0, (int)dom.dataModels[0][0].DefaultValue); Assert.AreEqual(0, (int)dom.dataModels[0][0].InternalValue); Assert.AreEqual(0, (int)dataModels[0][0].DefaultValue); Assert.AreEqual(1, (int)dataModels[0][0].InternalValue); Assert.AreEqual(0, (int)dataModels[1][0].DefaultValue); Assert.AreEqual(2, (int)dataModels[1][0].InternalValue); Assert.AreEqual(0, (int)dataModels[2][0].DefaultValue); Assert.AreEqual(3, (int)dataModels[2][0].InternalValue); }
public void BugUtf16Length() { string xml = @"<?xml version='1.0' encoding='UTF-8'?> <Peach> <DataModel name='bug_utf16_length'> <String name='signature' token='true' value='START_MARKER'/> <Number name='FILENAME_LENGTH' endian='little' size='16' signed='false' occurs='1'> <Relation of='FILENAME' type='size'/> </Number> <Number name='OBJECT_LENGTH' endian='little' size='32' signed='false' occurs='1'> <Relation of='OBJECT' type='size'/> </Number> <String name='FILENAME' occurs='1' type='utf16' nullTerminated='false'/> <Block name='OBJECT' occurs='1'> <String value='END_MARKER'/> </Block> </DataModel> </Peach>"; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); byte[] FILENAME = Encoding.Unicode.GetBytes("sample_mpeg4.mp4"); byte[] OBJECT = Encoding.ASCII.GetBytes("END_MARKER"); var data = Bits.Fmt("{0}{1:L16}{2:L32}{3}{4}", "START_MARKER", FILENAME.Length, OBJECT.Length, FILENAME, OBJECT); DataCracker cracker = new DataCracker(); cracker.CrackData(dom.dataModels[0], data); Assert.AreEqual(5, dom.dataModels[0].Count); Assert.AreEqual("START_MARKER", (string)dom.dataModels[0][0].DefaultValue); var array = dom.dataModels[0][1] as Dom.Array; Assert.NotNull(array); Assert.AreEqual(1, array.Count); Assert.AreEqual(FILENAME.Length, (int)array[0].DefaultValue); array = dom.dataModels[0][2] as Dom.Array; Assert.NotNull(array); Assert.AreEqual(1, array.Count); Assert.AreEqual(OBJECT.Length, (int)array[0].DefaultValue); array = dom.dataModels[0][3] as Dom.Array; Assert.NotNull(array); Assert.AreEqual(1, array.Count); Assert.AreEqual("sample_mpeg4.mp4", (string)array[0].DefaultValue); array = dom.dataModels[0][4] as Dom.Array; Assert.NotNull(array); Assert.AreEqual(1, array.Count); var block = array[0] as Block; Assert.NotNull(block); Assert.AreEqual(1, block.Count); Assert.AreEqual("END_MARKER", (string)block[0].DefaultValue); }
public void CrossIterationOnce() { string xml = @" <Peach> <DataModel name='DM'> <Number name='str' size='16' mutable='false'> <Fixup class='SequenceIncrementFixup'> <Param name='Once' value='true'/> </Fixup> </Number> <String/> </DataModel> <StateModel name='TheState' initialState='Initial'> <State name='Initial'> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> </State> </StateModel> <Test name='Default'> <StateModel ref='TheState'/> <Publisher class='Null'/> </Test> </Peach> "; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); RunConfiguration config = new RunConfiguration(); config.range = true; config.rangeStart = 1; config.rangeStop = 20; Engine e = new Engine(null); e.startFuzzing(dom, config); Assert.AreEqual(21 * 3, this.dataModels.Count); Assert.AreEqual(0, (int)dom.dataModels[0][0].DefaultValue); Assert.AreEqual(0, (int)dom.dataModels[0][0].InternalValue); for (int i = 0; i < 21; ++i) { Assert.AreEqual(0, (int)dataModels[(3 * i) + 0][0].DefaultValue); Assert.AreEqual(i + 1, (int)dataModels[(3 * i) + 0][0].InternalValue); Assert.AreEqual(0, (int)dataModels[(3 * i) + 1][0].DefaultValue); Assert.AreEqual(i + 1, (int)dataModels[(3 * i) + 1][0].InternalValue); Assert.AreEqual(0, (int)dataModels[(3 * i) + 2][0].DefaultValue); Assert.AreEqual(i + 1, (int)dataModels[(3 * i) + 2][0].InternalValue); } }
public void TestOverWrite() { string xml = @" <Peach> <DataModel name='Base'> <Choice name='c'> <Block name='b1'> <String name='s' value='Hello'/> </Block> <Block name='b2'> <String name='s' value='World'/> </Block> <Block name='b3'> <String name='s' value='!'/> </Block> </Choice> </DataModel> <DataModel name='Derived' ref='Base'> <String name='c.b1.s' value='World'/> <String name='c.b3' value='.'/> </DataModel> </Peach>"; var parser = new PitParser(); var dom = parser.asParser(null, new MemoryStream(Encoding.ASCII.GetBytes(xml))); Assert.AreEqual(2, dom.dataModels.Count); Assert.AreEqual(1, dom.dataModels[0].Count); var c1 = dom.dataModels[0][0] as Dom.Choice; Assert.NotNull(c1); Assert.AreEqual(3, c1.choiceElements.Count); var c1_b1 = c1.choiceElements[0] as Dom.Block; Assert.NotNull(c1_b1); Assert.AreEqual(1, c1_b1.Count); Assert.AreEqual("Hello", (string)c1_b1[0].DefaultValue); var c1_b2 = c1.choiceElements[1] as Dom.Block; Assert.NotNull(c1_b2); Assert.AreEqual(1, c1_b2.Count); Assert.AreEqual("World", (string)c1_b2[0].DefaultValue); var c1_b3 = c1.choiceElements[2] as Dom.Block; Assert.NotNull(c1_b3); Assert.AreEqual(1, c1_b3.Count); Assert.AreEqual("!", (string)c1_b3[0].DefaultValue); Assert.AreEqual(1, dom.dataModels[1].Count); var c2 = dom.dataModels[1][0] as Dom.Choice; Assert.NotNull(c2); Assert.AreEqual(3, c2.choiceElements.Count); var c2_b1 = c2.choiceElements[0] as Dom.Block; Assert.NotNull(c2_b1); Assert.AreEqual(1, c2_b1.Count); Assert.AreEqual("World", (string)c2_b1[0].DefaultValue); var c2_b2 = c2.choiceElements[1] as Dom.Block; Assert.NotNull(c2_b2); Assert.AreEqual(1, c2_b2.Count); Assert.AreEqual("World", (string)c2_b2[0].DefaultValue); var c3_b3 = c2.choiceElements[2] as Dom.String; Assert.NotNull(c3_b3); Assert.AreEqual(".", (string)c3_b3.DefaultValue); }
public void ReplayNoOffset() { // When the Offset parameter is not used, the fixup will continue to // increment even when the engine replays iterations string xml = @" <Peach> <DataModel name='DM'> <Number name='str' size='16' mutable='false'> <Fixup class='SequenceIncrementFixup'/> </Number> <String/> </DataModel> <StateModel name='TheState' initialState='Initial'> <State name='Initial'> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> </State> </StateModel> <Agent name='LocalAgent'> <Monitor class='FaultingMonitor'> <Param name='Iteration' value='2'/> </Monitor> </Agent> <Test name='Default' faultWaitTime='0' replayEnabled='true'> <Agent ref='LocalAgent'/> <StateModel ref='TheState'/> <Publisher class='Null'/> </Test> </Peach> "; cloneActions = true; iterationHistory = new List <uint>(); PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); RunConfiguration config = new RunConfiguration(); config.range = true; config.rangeStart = 1; config.rangeStop = 3; Engine e = new Engine(null); e.IterationStarting += IterationStarting; e.startFuzzing(dom, config); Assert.AreEqual(new uint[] { 1, 1, 2, 2, 3 }, iterationHistory.ToArray()); Assert.AreEqual(15, actions.Count); for (int i = 0; i < 15; ++i) { Assert.AreEqual(i + 1, (int)actions[i].dataModel[0].InternalValue); } }
public void NumericString() { // Test string parent string xml = @" <Peach> <DataModel name='DM'> <String name='str' value='100' mutable='false'> <Fixup class='SequenceRandomFixup'/> </String> <String/> </DataModel> <StateModel name='TheState' initialState='Initial'> <State name='Initial'> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> <Action type='output'> <DataModel ref='DM'/> </Action> </State> </StateModel> <Test name='Default'> <StateModel ref='TheState'/> <Publisher class='Null'/> <Strategy class='RandomDeterministic'/> </Test> </Peach> "; PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); RunConfiguration config = new RunConfiguration(); config.range = true; config.rangeStart = 0; config.rangeStop = 3; Engine e = new Engine(null); e.startFuzzing(dom, config); Assert.AreEqual((1 + 3) * 3, this.dataModels.Count); Assert.AreEqual("100", (string)dom.dataModels[0][0].DefaultValue); Assert.AreEqual("100", (string)dom.dataModels[0][0].InternalValue); HashSet <string> numbers = new HashSet <string>(); Assert.True(numbers.Add("100")); Assert.AreEqual("100", (string)dataModels[0][0].DefaultValue); Assert.True(numbers.Add((string)dataModels[0][0].InternalValue)); Assert.AreEqual("100", (string)dataModels[1][0].DefaultValue); Assert.True(numbers.Add((string)dataModels[1][0].InternalValue)); Assert.AreEqual("100", (string)dataModels[2][0].DefaultValue); Assert.True(numbers.Add((string)dataModels[2][0].InternalValue)); // Fuzz run 1 should be the same as the control iteration Assert.AreEqual("100", (string)dataModels[3][0].DefaultValue); Assert.AreEqual((string)dataModels[0][0].InternalValue, (string)dataModels[3][0].InternalValue); Assert.AreEqual("100", (string)dataModels[4][0].DefaultValue); Assert.AreEqual((string)dataModels[1][0].InternalValue, (string)dataModels[4][0].InternalValue); Assert.AreEqual("100", (string)dataModels[5][0].DefaultValue); Assert.AreEqual((string)dataModels[2][0].InternalValue, (string)dataModels[5][0].InternalValue); // Other fuzz runs should not produce the same numbers for (int i = 6; i < 12; i++) { Assert.AreEqual("100", (string)dataModels[i][0].DefaultValue); Assert.True(numbers.Add((string)dataModels[i][0].InternalValue)); } }
public static DataElement PitParser(PitParser context, XmlNode node, DataElementContainer parent) { if (node.Name != "String") { return(null); } var str = DataElement.Generate <String>(node); if (node.hasAttr("nullTerminated")) { str.nullTerminated = node.getAttrBool("nullTerminated"); } else { str.nullTerminated = context.getDefaultAttr(typeof(String), "nullTerminated", str.nullTerminated); } string type = "ascii"; if (node.hasAttr("type")) { type = node.getAttrString("type"); } else { type = context.getDefaultAttr(typeof(String), "type", type); } StringType stringType; if (!Enum.TryParse <StringType>(type, true, out stringType)) { throw new PeachException("Error, unknown String type '" + type + "' on element '" + str.name + "'."); } str.stringType = stringType; if (node.hasAttr("padCharacter")) { str.padCharacter = node.getAttrChar("padCharacter"); } else { str.padCharacter = context.getDefaultAttr(typeof(String), "padCharacter", str.padCharacter); } if (node.hasAttr("tokens")) // This item has a default! { throw new NotSupportedException("Tokens attribute is depricated in Peach 3. Use parameter to StringToken analyzer isntead."); } if (node.hasAttr("analyzer")) // this should be passed via a child element me things! { throw new NotSupportedException("Analyzer attribute is depricated in Peach 3. Use a child element instead."); } context.handleCommonDataElementAttributes(node, str); context.handleCommonDataElementChildren(node, str); context.handleCommonDataElementValue(node, str); if (!node.hasAttr("value")) { str.DefaultValue = new Variant(""); } return(str); }
public void Test3() { string inc1 = @"<?xml version=""1.0"" encoding=""utf-8""?> <Peach> <DataModel name=""BaseModel""> <String name=""str"" value=""Hello World!""/> </DataModel> <DataModel name=""DerivedModel""> <Block ref=""BaseModel"" /> </DataModel> </Peach> "; string inc2 = @"<?xml version=""1.0"" encoding=""utf-8""?> <Peach> <Include ns=""abc"" src=""file:{0}"" /> <DataModel name=""BaseModel2"" ref=""abc:DerivedModel""/> </Peach> "; string template = @" <Peach> <Include ns=""example"" src=""file:{0}"" /> <DataModel name=""DM""> <Block ref=""example:BaseModel2""/> </DataModel> <StateModel name=""State"" initialState=""Initial""> <State name=""Initial""> <Action type=""output""> <DataModel ref=""DM"" /> </Action> </State> </StateModel> <Test name=""Default""> <StateModel ref=""State"" /> <Publisher class=""File""> <Param name=""FileName"" value=""{1}""/> </Publisher> </Test> </Peach>"; string remote1 = Path.GetTempFileName(); string remote2 = Path.GetTempFileName(); string output = Path.GetTempFileName(); string xml = string.Format(template, remote2, output); using (TextWriter writer = File.CreateText(remote1)) { writer.Write(inc1); } using (TextWriter writer = File.CreateText(remote2)) { writer.Write(string.Format(inc2, remote1)); } PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); RunConfiguration config = new RunConfiguration(); config.singleIteration = true; Engine e = new Engine(null); e.startFuzzing(dom, config); string result = File.ReadAllText(output); Assert.AreEqual("Hello World!", result); }
public void StringTest1() { string fixup = @" class FixupReturningString: def __init__(self, parent): self._parent = parent def fixup(self, element): return 'Hello from FixupReturningString' "; string tmpPath = Path.GetTempPath(); string tmpFile = tmpPath + "/fixup.py"; string xml = @"<Peach> <PythonPath path='{0}'/> <Import import='fixup' /> <!-- Create a simple data template containing a single string --> <DataModel name='TheDataModel'> <String value='Hello World!'> <Fixup class='ScriptFixup'> <Param name='class' value='fixup.FixupReturningString'/> <Param name='ref' value='TheDataModel' /> </Fixup> </String> </DataModel> <StateModel name='State' initialState='State1' > <State name='State1' > <Action type='output' > <DataModel ref='TheDataModel'/> </Action> </State> </StateModel> <Test name='Default'> <StateModel ref='State'/> <Publisher class='Console' /> </Test> </Peach>".Fmt(tmpPath, tmpFile); try { //Writes tmp python fixup File.WriteAllText(tmpFile, fixup); PitParser parser = new PitParser(); Dom.Dom dom = parser.asParser(null, new MemoryStream(ASCIIEncoding.ASCII.GetBytes(xml))); RunConfiguration config = new RunConfiguration(); config.singleIteration = true; Engine e = new Engine(null); e.startFuzzing(dom, config); // verify values byte[] expected = Encoding.ASCII.GetBytes("Hello from FixupReturningString"); Assert.AreEqual(1, dataModels.Count); Assert.AreEqual(expected, dataModels[0].Value.ToArray()); } finally { File.Delete(tmpFile); Scripting.Imports.Clear(); } }