private static void RunDataFlowAnalysis(IndexDb indexDb, CallGraph graph, string entryPoint, List <TypeDef> requiredArgumentTypes, SymbolicEngine symbolicEngine, string output) { try { if (!entryPoint.EndsWith(")")) { entryPoint += "()"; } var entryIndex = 0; foreach (var entry in /*graph.EntryNodes.Values) //*/ graph.Nodes.Values) { if (entry.MethodSignature.ToString() != entryPoint && entry.MethodSignature.ToString() != $"{typeof(Deserializers).Namespace}.{entryPoint}") { continue; } Console.WriteLine($"{entry.MethodSignature} analyzing..."); var references = indexDb.AssemblyReferences[entry.AssemblyName]; Console.WriteLine($" Assembly: {entry.AssemblyName}, References: {references.Count}"); var timer = Stopwatch.StartNew(); var result = symbolicEngine.ExecuteForward(entry.MethodDef, requiredArgumentTypes); if (result == null) { Console.WriteLine("FATAL ERROR: DFA result is empty."); break; } timer.Stop(); Console.WriteLine($"{entry.MethodSignature}: {timer.ElapsedMilliseconds} ms"); if (result.HasPattern) { } Console.WriteLine($"DFA: {entry.MethodSignature} {result.ExternalCallCount} calls of {result.PatternCount} tainted object"); result.Stat.DumpConsole(); Console.WriteLine($"All method calls/instructions: {result.Summary.MethodCallCount} / {result.Summary.InstructionCount}"); Console.WriteLine("============"); //result.Stat.DumpTxt(output, $"dfa_stat_{entryIndex++}_{entry.MethodDef.Name}.txt"); //result.Stat.DumpCsv(output, $"dfa_stat_{entryIndex}_{entry.MethodDef.Name}.csv"); var p = result.Dump(output, $"patterns_{entryIndex}_{entry.MethodDef.Name}"); result.DumpAllStat(output, $"dfa_stat_{entryIndex}_{entry.MethodDef.Name}.txt", p); Console.WriteLine(); entryIndex++; break; } Console.WriteLine("Analysis is competed!"); } catch (ThreadAbortException) { Thread.ResetAbort(); } }
protected DataFlowAnalysisResult Execute(MethodDef method, MethodUniqueSignature taintedSignature = null) { engine = new SymbolicEngine(index, taintedSignature, 20, true, InputTaintedMode); var result = engine.ExecuteForward(method); result?.Summary.Dump(@"C:\tmp\experiments\tests", method.Name); result.Stat.DumpConsole(); Console.WriteLine($"All method calls/instructions: {result.Summary.MethodCallCount:N0} / {result.Summary.InstructionCount:N0}"); return(result); }
private static int RunAnalysis(string input, string entryPoint, string output) { Console.WriteLine("Copying SerialDetector.Experiments..."); File.Copy( typeof(Deserializers).Assembly.Location, Path.Combine(input, Path.GetFileName(typeof(Deserializers).Assembly.Location)), true); Console.WriteLine($"[{DateTime.Now:T}]"); var indexDb = new IndexDb(input); var v = new Version(); var methods = indexDb.Assemblies.FindSensitiveSinkCalls().ToList(); Console.WriteLine($"[{DateTime.Now:T}] {methods.Count} methods!"); var sensitiveSinks = methods .Select(method => method.CreateMethodUniqueSignature()) .Distinct() .Select(name => new TemplateInfo(name, v)) .ToList(); CreateCleanDirectory(output); File.WriteAllLines( Path.Combine(output, "sensitive-sinks.txt"), sensitiveSinks.Select(info => info.Method.ToString())); var setUp = GetEntryPointSetUp(entryPoint); sensitiveSinks = new List <TemplateInfo> { new TemplateInfo(new MethodUniqueSignature(setUp.SensitiveSink), v) }; Console.WriteLine($"[{DateTime.Now:T}] {sensitiveSinks.Count} patterns!"); foreach (var method in sensitiveSinks) { Console.WriteLine($" {method.Method}"); } Console.WriteLine(); // TODO: remove convertedArgumentTypes var convertedArgumentTypes = indexDb.Build(); indexDb.ShowStatistic(); Console.WriteLine($"[{DateTime.Now:T}]"); var callGraphBuilder = new CallGraphBuilder(indexDb); var i = 0; foreach (var sensitiveSink in sensitiveSinks) { var g = callGraphBuilder.CreateGraph(new List <TemplateInfo> { sensitiveSink }); Console.WriteLine(); Console.WriteLine($"[{DateTime.Now:T}] #{++i} {sensitiveSink.Method}"); callGraphBuilder.ShowStatistic(); if (g.IsEmpty) { Console.WriteLine("CFA: Not found!"); continue; } StoreEntryPoints(Path.Combine(output, $"{i}_ep_all.txt"), g); Console.WriteLine($"Graph: nodes = {g.Nodes.Count}, entry nodes = {g.EntryNodes.Count}"); g.RemoveDuplicatePaths(); Console.WriteLine($"Graph: nodes = {g.Nodes.Count}, entry nodes = {g.EntryNodes.Count}"); g.RemoveNonPublicEntryNodes(); Console.WriteLine($"Graph: nodes = {g.Nodes.Count}, entry nodes = {g.EntryNodes.Count}"); g.RemoveNonPublicMiddleNodes(); Console.WriteLine($"Graph: nodes = {g.Nodes.Count}, entry nodes = {g.EntryNodes.Count}"); //ShowEntryPoints(currentPatterns, g); StoreEntryPoints(Path.Combine(output, $"{i}_ep_public.txt"), g); if (g.Nodes.Count > 1 && g.Nodes.Count < 1000) { g.Dump(Path.Combine(output, $"{i}_po.png")); } else { Console.WriteLine($"{i}_ep_public graph contains {g.Nodes.Count} nodes!"); } // DFA var symbolicEngine = new SymbolicEngine(indexDb, sensitiveSink.Method, setUp.VirtualCallsLimit, setUp.EnableStaticFields, false); var workingThread = new Thread(() => { RunDataFlowAnalysis(indexDb, g, entryPoint, convertedArgumentTypes, symbolicEngine, output); }); var timer = Stopwatch.StartNew(); workingThread.Start(); Console.WriteLine(); Console.WriteLine("Press q and <Enter> to exit..."); while (Console.ReadLine() != "q") { } if (workingThread.IsAlive) { workingThread.Abort(); workingThread.Join(); timer.Stop(); symbolicEngine.CurrentStat?.DumpConsole(); symbolicEngine.CurrentStat?.DumpTxt(output, "dfa_stat.txt"); //symbolicEngine.CurrentStat?.DumpCsv(output, "dfa_stat.csv"); Console.WriteLine($"Analysis is aborted ({timer.ElapsedMilliseconds} ms)"); } } return(0); }