Beispiel #1
0
        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);
        }
Beispiel #3
0
        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);
        }