private void buttonPitFileNameLoad_Click(object sender, EventArgs e) { if (!System.IO.File.Exists(textBoxPitFileName.Text)) { MessageBox.Show("Error, Pit file does not exist."); return; } var currentCursor = this.Cursor; this.Cursor = Cursors.WaitCursor; try { var pitParser = new Peach.Core.Analyzers.PitParser(); userSelectedDom = pitParser.asParser(null, textBoxPitFileName.Text); comboBoxPitDataModel.Items.Clear(); foreach (var model in userSelectedDom.dataModels.Keys) { comboBoxPitDataModel.Items.Add(model); } if (userSelectedDom.dataModels.Count > 0) { comboBoxPitDataModel.SelectedIndex = 0; } label4.Enabled = true; comboBoxPitDataModel.Enabled = true; } catch (PeachException ex) { MessageBox.Show(ex.Message); } finally { this.Cursor = currentCursor; } }
/// <summary> /// Run the default fuzzing run in the specified dom. /// </summary> /// <param name="dom"></param> /// <param name="config"></param> public void startFuzzing(Dom.Dom dom, RunConfiguration config) { if (dom == null) { throw new ArgumentNullException("dom parameter is null"); } if (config == null) { throw new ArgumentNullException("config paremeter is null"); } Test test = null; try { test = dom.tests[config.runName]; } catch (Exception ex) { throw new PeachException("Unable to locate test named '" + config.runName + "'.", ex); } startFuzzing(dom, test, config); }
public Program(string[] args) { AppDomain.CurrentDomain.DomainUnload += new EventHandler(CurrentDomain_DomainUnload); Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress); config = new RunConfiguration(); config.debug = 0; 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.ForegroundColor = color; if (args.Length == 0) { Syntax(); } var p = new OptionSet() { { "h|?|help", v => Syntax() }, { "analyzer=", v => analyzer = v }, { "debug", v => config.debug = 1 }, { "trace", v => config.debug = 2 }, { "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) }, { "config=", v => definedValues.Add(v) }, { "parseonly", v => parseOnly = true }, { "bob", var => bob() }, //输出他的头像,醉了 { "charlie", var => Charlie() }, //醉了 { "showdevices", var => ShowDevices() }, //列出网卡设备信息 { "showenv", var => ShowEnvironment() }, //输出使用信息?基本属性的使用? { "makexsd", var => MakeSchema() }, //生成Peach.xsd文件 }; List <string> extra = p.Parse(args);//extra[0]存放文件名即 pit文件.xml if (extra.Count == 0 && agent == null && analyzer == null) { Syntax(); } Platform.LoadAssembly(); AddNewDefine("Peach.Cwd=" + Environment.CurrentDirectory); AddNewDefine("Peach.Pwd=" + Path.GetDirectoryName(Assembly.GetCallingAssembly().Location)); // 判断是否有 pit文件.xml.config 文件,如果有我们就加载改文件 // 注意:pit文件.xml.config 应该和 pit文件.xml文件放在同一目录下 if (extra.Count > 0 && File.Exists(extra[0]) && extra[0].ToLower().EndsWith(".xml") && File.Exists(extra[0] + ".config")) { definedValues.Insert(0, extra[0] + ".config"); } 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); } } } // 如果需要则启动调试 // 如果已经由.congig文件进行配置,则不会做任何更改 ConfigureLogging(config.debug); if (agent != null) { var agentType = ClassLoader.FindTypeByAttribute <AgentServerAttribute>((x, y) => y.name == agent); if (agentType == null) { Console.WriteLine("错误, unable to locate agent server for protocol '" + agent + "'.\n"); return; } var agentServer = Activator.CreateInstance(agentType) as IAgentServer; ConsoleWatcher.WriteInfoMark(); Console.WriteLine("启动代理服务..."); 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("错误,无法定位名为'" + analyzer + "'的analyzer.\n"); return; } var field = analyzerType.GetField("supportCommandLine", BindingFlags.Static | BindingFlags.Public | BindingFlags.FlattenHierarchy); if ((bool)field.GetValue(null) == false) { Console.WriteLine("错误, 从命令行启动的analyzer还没有进行配置."); return; } var analyzerInstance = Activator.CreateInstance(analyzerType) as Analyzer; ConsoleWatcher.WriteInfoMark(); Console.WriteLine("启动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]; // 用于单元测试 if (parseOnly) { return; } foreach (string arg in args) { config.commandLine += arg + " "; } if (extra.Count > 1) { config.runName = extra[1]; } e.startFuzzing(dom, config); exitCode = 0; } catch (SyntaxException) { // 由syntax()抛出,可忽略 } catch (OptionException oe) { Console.WriteLine(oe.Message + "\n"); } catch (PeachException ee) { if (config.debug > 0) { Console.WriteLine(ee); } else { Console.WriteLine(ee.Message + "\n"); } } finally { // HACK - 需使用NLog 2.0的Mono ConfigureLogging(-1); // 重置控制台输出文字的颜色 Console.ForegroundColor = DefaultForground; } }
/// <summary> /// Run a test case. Contains main fuzzing loop. /// </summary> /// <param name="dom"></param> /// <param name="test"></param> /// <param name="context"></param> protected void runTest(Dom.Dom dom, Test test, RunContext context) { try { context.test = test; context.test.strategy.Context = context; context.test.strategy.Engine = this; context.agentManager = new AgentManager(context); context.reproducingFault = false; context.reproducingIterationJumpCount = 1; if (context.config.userDefinedSeed && !test.strategy.UsesRandomSeed) { var attr = ClassLoader.GetAttributes <MutationStrategyAttribute>(test.strategy.GetType(), null).Where(a => a.IsDefault == true).FirstOrDefault(); var name = attr != null ? attr.Name : test.strategy.GetType().Name; var msg = "The '{0}' mutation strategy does not allow setting the random seed.".Fmt(name); OnTestWarning(context, msg); } // Get mutation strategy MutationStrategy mutationStrategy = test.strategy; mutationStrategy.Initialize(context, this); uint iterationStart = 1; uint iterationStop = uint.MaxValue; uint?iterationTotal = null; uint lastControlIteration = 0; uint redoCount = 0; if (!mutationStrategy.IsDeterministic) { if (context.config.parallel) { throw new PeachException("parallel is not supported when a non-deterministic mutation strategy is used"); } if (context.config.countOnly) { throw new PeachException("count is not supported when a non-deterministic mutation strategy is used"); } } if (context.config.range) { if (context.config.parallel) { throw new PeachException("range is not supported when parallel is used"); } logger.Debug("runTest: context.config.range == true, start: " + context.config.rangeStart + ", stop: " + context.config.rangeStop); iterationStart = context.config.rangeStart; iterationStop = context.config.rangeStop; } else if (context.config.skipToIteration > 1) { logger.Debug("runTest: context.config.skipToIteration == " + context.config.skipToIteration); iterationStart = context.config.skipToIteration; } iterationStart = Math.Max(1, iterationStart); uint lastReproFault = iterationStart - 1; uint iterationCount = iterationStart; bool firstRun = true; // First iteration is always a control/recording iteration context.controlIteration = true; context.controlRecordingIteration = true; test.markMutableElements(); OnTestStarting(context); // Start agents foreach (Dom.Agent agent in test.agents.Values) { // Only use agent if on correct platform if ((agent.platform & Platform.GetOS()) != Platform.OS.None) { context.agentManager.AgentConnect(agent); context.agentManager.GetAgent(agent.name).SessionStarting(); // Note: We want to perfrom SessionStarting on each agent // in turn. We do this incase the first agent starts // a virtual machine that contains the second agent. } } while ((firstRun || iterationCount <= iterationStop) && context.continueFuzzing) { context.currentIteration = iterationCount; firstRun = false; // Clear out or iteration based state store context.iterationStateStore.Clear(); // Should we perform a control iteration? if (test.controlIteration > 0 && !context.reproducingFault) { if ((test.controlIteration == 1 || iterationCount % test.controlIteration == 1) && lastControlIteration != iterationCount) { context.controlIteration = true; } } try { // Must set iteration 1st as strategy could enable control/record bools mutationStrategy.Iteration = iterationCount; if (context.controlIteration && context.controlRecordingIteration) { context.controlRecordingActionsExecuted.Clear(); context.controlRecordingStatesExecuted.Clear(); } context.controlActionsExecuted.Clear(); context.controlStatesExecuted.Clear(); if (context.config.singleIteration && !context.controlIteration && iterationCount == 1) { logger.Debug("runTest: context.config.singleIteration == true"); break; } // Make sure we are not hanging on to old faults. context.faults.Clear(); try { if (IterationStarting != null) { IterationStarting(context, iterationCount, iterationTotal.HasValue ? iterationStop : iterationTotal); } if (context.controlIteration) { if (context.controlRecordingIteration) { logger.Debug("runTest: Performing recording iteration."); } else { logger.Debug("runTest: Performing control iteration."); } } context.agentManager.IterationStarting(iterationCount, context.reproducingFault); test.stateModel.Run(context); } catch (SoftException se) { // We should just eat SoftExceptions. // They indicate we should move to the next // iteration. if (context.controlRecordingIteration) { logger.Debug("runTest: SoftException on control recording iteration"); if (se.InnerException != null && string.IsNullOrEmpty(se.Message)) { throw new PeachException(se.InnerException.Message, se); } throw new PeachException(se.Message, se); } if (context.controlIteration) { logger.Debug("runTest: SoftException on control iteration, saving as fault"); var ex = se.InnerException ?? se; OnControlFault(context, iterationCount, "SoftException Detected:\n" + ex.ToString()); } logger.Debug("runTest: SoftException, skipping to next iteration"); } catch (PathException) { // We should just eat PathException. // They indicate we should move to the next // iteration. logger.Debug("runTest: PathException, skipping to next iteration"); } catch (System.OutOfMemoryException ex) { logger.Debug(ex.Message); logger.Debug(ex.StackTrace); logger.Debug("runTest: " + "Warning: Iteration ended due to out of memory exception. Continuing to next iteration."); throw new SoftException("Out of memory"); } finally { context.agentManager.IterationFinished(); if (IterationFinished != null) { IterationFinished(context, iterationCount); } // If this was a control iteration, verify it againt our origional // recording. if (context.controlRecordingIteration == false && context.controlIteration && !test.nonDeterministicActions) { if (context.controlRecordingActionsExecuted.Count != context.controlActionsExecuted.Count) { string description = string.Format(@"The Peach control iteration performed failed to execute same as initial control. Number of actions is different. {0} != {1}", context.controlRecordingActionsExecuted.Count, context.controlActionsExecuted.Count); logger.Debug(description); OnControlFault(context, iterationCount, description); } else if (context.controlRecordingStatesExecuted.Count != context.controlStatesExecuted.Count) { string description = string.Format(@"The Peach control iteration performed failed to execute same as initial control. Number of states is different. {0} != {1}", context.controlRecordingStatesExecuted.Count, context.controlStatesExecuted.Count); logger.Debug(description); OnControlFault(context, iterationCount, description); } if (context.faults.Count == 0) { foreach (Dom.Action action in context.controlRecordingActionsExecuted) { if (!context.controlActionsExecuted.Contains(action)) { string description = @"The Peach control iteration performed failed to execute same as initial control. Action " + action.name + " was not performed."; logger.Debug(description); OnControlFault(context, iterationCount, description); } } } if (context.faults.Count == 0) { foreach (Dom.State state in context.controlRecordingStatesExecuted) { if (!context.controlStatesExecuted.Contains(state)) { string description = @"The Peach control iteration performed failed to execute same as initial control. State " + state.name + "was not performed."; logger.Debug(description); OnControlFault(context, iterationCount, description); } } } } } // User can specify a time to wait between iterations // we can use that time to better detect faults if (context.test.waitTime > 0) { Thread.Sleep((int)(context.test.waitTime * 1000)); } if (context.reproducingFault) { // User can specify a time to wait between iterations // when reproducing faults. if (context.test.faultWaitTime > 0) { Thread.Sleep((int)(context.test.faultWaitTime * 1000)); } } // Collect any faults that were found context.OnCollectFaults(); if (context.faults.Count > 0) { logger.Debug("runTest: detected fault on iteration " + iterationCount); foreach (Fault fault in context.faults) { fault.iteration = iterationCount; fault.controlIteration = context.controlIteration; fault.controlRecordingIteration = context.controlRecordingIteration; } if (context.reproducingFault || !test.replayEnabled) { OnFault(context, iterationCount, test.stateModel, context.faults.ToArray()); } else { OnReproFault(context, iterationCount, test.stateModel, context.faults.ToArray()); } if (context.controlRecordingIteration && (!test.replayEnabled || context.reproducingFault)) { logger.Debug("runTest: Fault detected on control iteration"); throw new PeachException("Fault detected on control iteration."); } if (context.reproducingFault) { lastReproFault = iterationCount; // If we have moved less than 20 iterations, start fuzzing // from here thinking we may have not really performed the // next few iterations. // Otherwise skip forward to were we left off. if (context.reproducingInitialIteration - iterationCount > 20) { iterationCount = (uint)context.reproducingInitialIteration; } context.reproducingFault = false; context.reproducingIterationJumpCount = 1; logger.Debug("runTest: Reproduced fault, continuing fuzzing at iteration " + iterationCount); } else if (test.replayEnabled) { logger.Debug("runTest: Attempting to reproduce fault."); context.reproducingFault = true; context.reproducingInitialIteration = iterationCount; context.reproducingIterationJumpCount = 1; // User can specify a time to wait between iterations // we can use that time to better detect faults if (context.test.waitTime > 0) { Thread.Sleep((int)(context.test.waitTime * 1000)); } // User can specify a time to wait between iterations // when reproducing faults. if (context.test.faultWaitTime > 0) { Thread.Sleep((int)(context.test.faultWaitTime * 1000)); } logger.Debug("runTest: replaying iteration " + iterationCount); continue; } } else if (context.reproducingFault) { uint maxJump = context.reproducingInitialIteration - lastReproFault - 1; if (context.reproducingIterationJumpCount >= (maxJump * 2) || context.reproducingIterationJumpCount > context.reproducingMaxBacksearch) { logger.Debug("runTest: Giving up reproducing fault, reached max backsearch."); context.reproducingFault = false; iterationCount = context.reproducingInitialIteration; OnReproFailed(context, iterationCount); } else { uint delta = Math.Min(maxJump, context.reproducingIterationJumpCount); iterationCount = (uint)context.reproducingInitialIteration - delta - 1; logger.Debug("runTest: " + "Moving backwards " + delta + " iterations to reproduce fault."); } // Make next jump larger context.reproducingIterationJumpCount *= context.reproducingSkipMultiple; } if (context.agentManager.MustStop()) { logger.Debug("runTest: agents say we must stop!"); throw new PeachException("Error, agent monitor stopped run!"); } // Update our totals and stop based on new count if (context.controlIteration && context.controlRecordingIteration && !iterationTotal.HasValue) { if (context.config.countOnly) { OnHaveCount(context, mutationStrategy.Count); break; } iterationTotal = mutationStrategy.Count; if (iterationTotal < iterationStop) { iterationStop = iterationTotal.Value; } if (context.config.parallel) { if (iterationTotal < context.config.parallelTotal) { throw new PeachException(string.Format("Error, {1} parallel machines is greater than the {0} total iterations.", iterationTotal, context.config.parallelTotal)); } var range = Utilities.SliceRange(1, iterationStop, context.config.parallelNum, context.config.parallelTotal); iterationStart = range.Item1; iterationStop = range.Item2; OnHaveParallel(context, iterationStart, iterationStop); if (context.config.skipToIteration > iterationStart) { iterationStart = context.config.skipToIteration; } iterationCount = iterationStart; } } // Don't increment the iteration count if we are on a // control iteration if (!context.controlIteration) { ++iterationCount; } redoCount = 0; } catch (RedoIterationException rte) { logger.Debug("runTest: redoing test iteration for the " + redoCount + " time."); // Repeat the same iteration unless // we have already retried 3 times. if (redoCount >= 3) { throw new PeachException(rte.Message, rte); } redoCount++; } finally { if (!context.reproducingFault) { if (context.controlIteration) { lastControlIteration = iterationCount; } context.controlIteration = false; context.controlRecordingIteration = false; } } } } catch (MutatorCompleted) { // Ignore, signals end of fuzzing run logger.Debug("runTest: MutatorCompleted exception, ending fuzzing"); } finally { foreach (Publisher publisher in context.test.publishers.Values) { try { publisher.stop(); } catch { } } context.agentManager.SessionFinished(); context.agentManager.StopAllMonitors(); context.agentManager.Shutdown(); OnTestFinished(context); context.test = null; test.strategy.Finalize(context, this); } }
public virtual void asTopLevel(Dom.Dom dom, Dictionary <string, string> args) { throw new NotImplementedException(); }
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; } }