Example #1
0
        private void SaveVertex(ulong id, CallGraphNode node, TextWriter writer)
        {
            GetVertexAttributes(node, out var shape, out var style, out var color, out var fontcolor);

            writer.Write(id);
            writer.Write(" [");
            var isFirst = true;

            WriteAttribute(writer, "label", node.MethodSignature.ToString(), ref isFirst);
            WriteAttribute(writer, "shape", shape, ref isFirst);
            WriteAttribute(writer, "style", style, ref isFirst);
            WriteAttribute(writer, "fillcolor", color, ref isFirst);
            WriteAttribute(writer, "color", color, ref isFirst);
            WriteAttribute(writer, "fontcolor", fontcolor, ref isFirst);
            writer.WriteLine("];");
        }
Example #2
0
        private void GetVertexAttributes(CallGraphNode node, out string shape, out string style,
                                         out string color, out string fontcolor)
        {
            // https://www.graphviz.org/doc/info/colors.html
            // https://www.graphviz.org/doc/info/shapes.html
            //

            if (node.OutNodes.Count == 0)
            {
                shape     = "box";
                style     = "filled";
                color     = "brown1";
                fontcolor = "";
            }
            else if (node.InNodes.Count == 0)
            {
                shape = "box";
                style = "filled, rounded";
                if (node.IsPublic)
                {
                    color     = "darkgreen";
                    fontcolor = "white";
                }
                else
                {
                    color     = "darkgoldenrod1";
                    fontcolor = "";
                }
            }
            else
            {
                shape = "box";
                if (node.IsPublic)
                {
                    style = "filled";
                    color = "green2";
                }
                else
                {
                    style = "";
                    color = "";
                }

                fontcolor = "";
            }
        }
Example #3
0
        private CallGraph CreateGraphInternal(List <PatternInfo> patterns)
        {
            var graph = new CallGraph();
            var processingEntities = new Queue <ProcessingEntity>();

            foreach (var pattern in patterns)
            {
                var calls = index.GetCalls(pattern);
                if (calls.Count > 0)
                {
                    // HACK if we found call w/ version restriction
                    // then we add it and find again w/o version restrictions
                    // in practice the result should be the same (but not always)
                    var info = new CallInfo(
                        new AssemblyInfo(UTF8String.Empty, pattern.RequiredOlderVersion),
                        pattern.Method,
                        OpCodes.Call,
                        true,
                        new List <MethodUniqueSignature>(0));
                    var node = new CallGraphNode(info);
                    graph.Nodes.Add(pattern.Method, node);
                    processingEntities.Enqueue(new ProcessingEntity(node.MethodSignature, node));
                }
            }

            while (processingEntities.Count > 0)
            {
                var entity = processingEntities.Dequeue();

                var calls = index.GetCalls(entity.Signature /*, entity.Node.AssemblyInfo*/);
                if (calls.Count != 0)
                {
                    foreach (var callInfo in calls)
                    {
                        if (callInfo.Opcode.Code != Code.Call &&
                            callInfo.Opcode.Code != Code.Callvirt &&
                            callInfo.Opcode.Code != Code.Newobj &&
                            callInfo.Opcode.Code != Code.Ldtoken)          // used into Expression Tree in KB, need to implement DFA
                        //resume.Opcode.Code != Code.Ldvirtftn &&    // can use with calli
                        //resume.Opcode.Code != Code.Ldftn)          // https://docs.microsoft.com/en-us/dotnet/api/system.reflection.emit.opcodes.calli?view=netframework-4.7.2
                        {
                            // just ignore it for now, need to implement DFA
                            stat.IgnoredOpcodes.Add(callInfo.Opcode.Code);
                            continue;
                        }

                        if (graph.Nodes.TryGetValue(callInfo.Signature, out var callingNode))
                        {
                            // TODO: need to add a new kind of cycled edge to remove recursive calls in RemoveNonPublicEntryNodes
                            //callingNode.OutNodes.Add(entity.Node);
                            //entity.Node.InNodes.Add(callingNode);
                        }
                        else
                        {
                            callingNode = new CallGraphNode(callInfo);
                            callingNode.OutNodes.Add(entity.Node);
                            entity.Node.InNodes.Add(callingNode);

                            graph.Nodes.Add(callInfo.Signature, callingNode);
                            processingEntities.Enqueue(new ProcessingEntity(callInfo.Signature, callingNode));

                            foreach (var overrideSignature in callInfo.OverrideSignatures)
                            {
                                processingEntities.Enqueue(new ProcessingEntity(overrideSignature, callingNode));
                            }
                        }
                    }
                }
            }

            foreach (var node in graph.Nodes.Values)
            {
                if (node.InNodes.Count != 0)
                {
                    continue;
                }

                graph.EntryNodes.Add(node.MethodSignature, node);
            }

            return(graph);
        }
Example #4
0
 public ProcessingEntity(MethodUniqueSignature signature, CallGraphNode node)
 {
     Signature = signature;
     Node      = node;
 }