private static void Analyze(Arguments arguments, Config configuration)
{
Console.WriteLine("Parsing project at: " + arguments.Target);
Console.WriteLine();
foreach (var analysisStartingListener in _components.AnalysisStartingListeners)
{
// TODO - This should probably be a proper event - same goes for EndingEvent (this will also remove the loop(s)).
analysisStartingListener.AnalysisStarting(null, new AnalysisStartingEventArgs(configuration, arguments));
}
var stopwatch = Stopwatch.StartNew();
Console.WriteLine("Building ASTs..");
ParseResult parseResult = ParseTarget(arguments, configuration);
Console.WriteLine(" - AST build for {0} files ({1} failed)..", parseResult.ParsedFiles.Count, parseResult.FilesThatFailedToParse.Count);
Console.WriteLine("Traversing ASTs..");
var filesCollection = new List<File>();
var runningVulnReporter = new CompositeVulneribilityReporter(_components.VulnerabilityReporters);
var vulnerabilityStorage = new ReportingVulnerabilityStorage(runningVulnReporter);
var progrssIndicator = ProgressIndicatorFactory.CreateProgressIndicator(parseResult.ParsedFiles.Count());
foreach (var parsedFile in parseResult.ParsedFiles)
{
progrssIndicator.Step();
var file = BuildFileCFGAndExtractFileInformation(parsedFile);
filesCollection.Add(file);
}
var subroutineAnalyzerFactory = new FunctionAndMethodAnalyzerFactory { UseSummaries = arguments.UseFunctionSummaries };
Func<ImmutableVariableStorage, IIncludeResolver, AnalysisScope, AnalysisStacks,
ImmutableVariableStorage> fileTaintAnalyzer = null;
fileTaintAnalyzer = (varStorage, inclResolver, scope, stacks) =>
{
Preconditions.NotNull(varStorage, "varStorage");
Preconditions.NotNull(inclResolver, "inclResolver");
var blockAnalyzer = new TaintBlockAnalyzer(vulnerabilityStorage, inclResolver, scope, fileTaintAnalyzer, stacks, subroutineAnalyzerFactory);
blockAnalyzer.AnalysisExtensions.AddRange(_components.BlockAnalyzers);
var condAnalyser = new ConditionTaintAnalyser(scope, inclResolver, stacks.IncludeStack);
var cfgTaintAnalysis = new TaintAnalysis(blockAnalyzer, condAnalyser, varStorage);
var fileToAnalyze = stacks.IncludeStack.Peek();
var analyzer = new CFGTraverser(new ForwardTraversal(), cfgTaintAnalysis, new ReversePostOrderWorkList(fileToAnalyze.CFG));
//var analyzer = new CFGTraverser(new ForwardTraversal(), cfgTaintAnalysis, new QueueWorklist());
analyzer.Analyze(fileToAnalyze.CFG);
return cfgTaintAnalysis.Taints[fileToAnalyze.CFG.Vertices.Single(block => block.IsLeaf)].Out[EdgeType.Normal];
};
foreach (var file in filesCollection)
{
Console.WriteLine(Environment.NewLine + "=============================");
Console.WriteLine("Analyzing {0}..", file.FullPath);
var initialTaint = GetDefaultTaint();
var inclusionResolver = new IncludeResolver(filesCollection);
var stacks = new AnalysisStacks(file);
fileTaintAnalyzer(initialTaint, inclusionResolver, AnalysisScope.File, stacks);
}
Console.WriteLine("Scanned {0}/{1} subroutines. ", FunctionsHandler.Instance.ScannedFunctions.Count, FunctionsHandler.Instance.CustomFunctions.Count);
if (arguments.ScanAllSubroutines)
{
Console.WriteLine("Scanning remaining subroutines..");
ScanUnscannedSubroutines(filesCollection, fileTaintAnalyzer, subroutineAnalyzerFactory, vulnerabilityStorage);
}
vulnerabilityStorage.CheckForStoredVulnerabilities();
//parseResult.ParsedFiles.Values.First().Save(@"C:\Users\Kenneth\Documents\Uni\TestScript\current\parsedFile");
stopwatch.Stop();
foreach (var analysisEndedListener in _components.AnalysisEndedListeners)
{
analysisEndedListener.AnalysisEnding(null, new AnalysisEndedEventArgs(stopwatch.Elapsed));
}
Console.WriteLine("Time spent: " + stopwatch.Elapsed);
Console.WriteLine("Found {0} vulnerabilities.", runningVulnReporter.NumberOfReportedVulnerabilities);
}