Exemplo n.º 1
0
        public void DiGraphTest()
        {
            DotGraph graph = new DotGraph("test", true);
            var      leaf1 = new DotNode("l1")
            {
                // Set all available properties
                Shape     = "doublecircle",
                Label     = "leaf1",
                FontColor = "black",
                Style     = "",
                Height    = 0.5f
            };
            var leaf2 = new DotNode("l2")
            {
                // Set all available properties
                Shape     = "doublecircle",
                Label     = "leaf2",
                FontColor = "red",
                Style     = "",
                Height    = 0.5f
            };
            var root = new DotNode("root")
            {
                // Set all available properties
                Shape     = "ellipse",
                Label     = "leaf1",
                FontColor = "blue",
                Style     = "",
                Height    = 0.5f
            };

            graph.Add(leaf1);
            graph.Add(leaf2);
            graph.Add(root);

            var edge1 = new DotArrow(root, leaf1)
            {
                ArrowHeadShape = "none"
            };

            var edge2 = new DotArrow(root, leaf2)
            {
                ArrowHeadShape = "normal"
            };

            graph.Add(edge1);
            graph.Add(edge2);

            string actual   = graph.Compile().Replace("\r", "").Replace("\n", "");
            string expected =
                @"digraph test {l1 [  label=""leaf1"" shape=doublecircle fontcolor=black height=0.50]l2 [  label=""leaf2"" shape=doublecircle fontcolor=red height=0.50]root [  label=""leaf1"" shape=ellipse fontcolor=blue height=0.50]root->l1 [  arrowshape=none];root->l2 [  arrowshape=normal];}";

            Assert.Equal(expected, actual);
        }
Exemplo n.º 2
0
        private void MapRelationshipItemTypes(bool relsAsClasses)
        {
            Console.WriteLine("Mapping Relationship ItemTypes to graph...");

            int relTypeCount = ArasExport.RelationshipTypes.getItemCount();


            for (int i = 0; i < relTypeCount; i++)
            {
                var currentItemType = ArasExport.RelationshipTypes.getItemByIndex(i);
                var propRels        = currentItemType.getRelationships("Property");

                (string sourceClassName, string targetClassName) = DetermineSourceAndTargetName(propRels);
                if (sourceClassName == "" && targetClassName == "")
                {
                    continue;
                }
                string customStyle;
                string currentTypeName = currentItemType.getProperty("name", "");
                if (targetClassName == "")
                {
                    if (currentTypeName == "")
                    {
                        continue;
                    }
                    MapSpecialTypeAsClass(currentItemType);
                    targetClassName = currentTypeName;
                    customStyle     = "dir = \"both\", arrowtail=\"odiamond\"";
                }
                else if (relsAsClasses)
                {
                    MapRelsAsClasses(currentItemType, sourceClassName, targetClassName);
                    continue;
                }
                else
                {
                    customStyle = $"label = \"{currentTypeName}\"";
                }

                var relationshipArrow = new DotArrow(sourceClassName, targetClassName, Graph)
                {
                    CustomStyle = customStyle
                };

                Graph.GraphElements.Add(relationshipArrow);
            }


            Console.WriteLine("Relationship ItemTypes successfully mapped!");
        }
Exemplo n.º 3
0
        private void MapRelsAsClasses(Item itemType, string sourceClassName, string targetClassName)
        {
            var relClass    = MapSpecialTypeAsClass(itemType);
            var sourceArrow = new DotArrow(relClass.Name, sourceClassName, Graph)
            {
                CustomStyle = "label = source_id"
            };

            Graph.GraphElements.Add(sourceArrow);
            var targetArrow = new DotArrow(relClass.Name, targetClassName, Graph)
            {
                CustomStyle = "label = related_id"
            };

            Graph.GraphElements.Add(targetArrow);
        }
Exemplo n.º 4
0
        private void MapPropertyRelations(Item itemType)
        {
            var itemProps     = itemType.getItemsByXPath(".//Item[@type = 'Property' and data_type = 'item']");
            int itemPropCount = itemProps.getItemCount();

            for (int i = 0; i < itemPropCount; i++)
            {
                var    currentProp = itemProps.getItemByIndex(i);
                string dataSource  = currentProp.getPropertyAttribute("data_source", "name", "");
                if (dataSource == "")
                {
                    continue;
                }
                var relationshipArrow =
                    new DotArrow(itemType.getProperty("name", $"\"{itemType.getID()}\""), dataSource, Graph)
                {
                    CustomStyle = $"label = \"{currentProp.getProperty("name", "")}\""
                };
                Graph.GraphElements.Add(relationshipArrow);
            }
        }
        private DotNode Visit(SyntaxNode <IN> node)
        {
            DotNode result = null;


            var children = new List <DotNode>();

            foreach (var n in node.Children)
            {
                var v = Visit(n);

                children.Add(v);
            }

            if (node.IsByPassNode)
            {
                result = children[0];
            }
            else
            {
                result = Node(GetNodeLabel(node));
                Graph.Add(result);
                children.ForEach(c =>
                {
                    if (c != null) // Prevent arrows with null destinations
                    {
                        var edge = new DotArrow(result, c)
                        {
                            // Set all available properties
                            ArrowHeadShape = "none"
                        };
                        Graph.Add(edge);
                    }
                });
            }


            return(result);
        }
Exemplo n.º 6
0
        private void MapPolyItemTypes()
        {
            Console.WriteLine("Mapping Poly-ItemTypes to graph...");

            int polyTypeCount = ArasExport.PolyItemTypes.getItemCount();

            for (int i = 0; i < polyTypeCount; i++)
            {
                var currentPolyType = ArasExport.PolyItemTypes.getItemByIndex(i);
                var polyClass       = MapSpecialTypeAsClass(currentPolyType);

                var morphaeRels  = currentPolyType.getRelationships("Morphae");
                int morphaeCount = morphaeRels.getItemCount();
                for (int j = 0; j < morphaeCount; j++)
                {
                    var currentMorphae = morphaeRels.getItemByIndex(j);
                    var subClassItem   = currentMorphae.getPropertyItem("related_id");
                    if (subClassItem == null)
                    {
                        continue;
                    }
                    var subClass =
                        Graph.GetDotClassByName(subClassItem.getProperty("name", "ClassHasNoName"), false);

                    subClass = subClass ?? MapSpecialTypeAsClass(subClassItem);

                    var relationshipArrow = new DotArrow(subClass, polyClass)
                    {
                        CustomStyle = "arrowhead = \"empty\""
                    };

                    Graph.GraphElements.Add(relationshipArrow);
                }
            }

            Console.WriteLine("Poly-ItemTypes successfully mapped!");
        }
Exemplo n.º 7
0
        private void processFunction(Function node, Function rootNode)
        {
            string id = node.Uid;

            var currentVertex = createOutputNode(node);

            foreach (var input in node.RootFunction.Inputs)
            {
                varStack.Push(input);
                typeStack.Push(CntkType.Variable);
            }

            //add node's inputs
            var inputs = node.Inputs;

            for (int i = 0; i < inputs.Count; i++)
            {
                Variable input = inputs[i];
                if (node.IsBlock && input.IsConstant)
                {
                    continue;
                }

                DotNode vertex = null;
                if (!input.IsOutput)
                {
                    vertex = createNonOutputNode(input);
                }
                else
                {
                    vertex = createOutputNode(input.Owner);
                }

                string label = string.IsNullOrEmpty(input.Name) ? input.Uid : input.Name;
                label += "\n" + ShapeDescription(input);

                DotArrow edge = new DotArrow(vertex, currentVertex);
                edge.Label = label;
                m_graph.Add(vertex);
                m_graph.Add(currentVertex);
                m_graph.Add(edge);
            }

            foreach (var output in node.Outputs)
            {
                //only final network outputs are drawn
                if (node.Uid == rootNode.Uid)
                {
                    var finalVertex = createVertex(output);
                    finalVertex.Label     = output.Name + "\n" + ShapeDescription(output);
                    finalVertex.Shape     = DotNodeShape.Egg;
                    finalVertex.FillColor = DotColor.Purple;
                    finalVertex.FixedSize = true;
                    finalVertex.Height    = 1f;
                    finalVertex.Width     = 1.3f;
                    finalVertex.PenWidth  = 4;
                    //add nodes
                    m_graph.Add(currentVertex);
                    m_graph.Add(finalVertex);
                }
            }
            //mark current node as visited
            visitedNodes.Add(id);
        }
Exemplo n.º 8
0
        private void processFunction(Function node, Function rootNode)
        {
            string id = node.Uid;

            var currentVertex = LazyCreateNode(node);

            foreach (var input in node.RootFunction.Inputs)
            {
                varStack.Push(input);
                typeStack.Push(CntkType.Variable);
            }

            //add node's inputs
            var inputs = node.Inputs;

            for (int i = 0; i < inputs.Count; i++)
            {
                Variable input = inputs[i];
                if (node.IsBlock && input.IsConstant)
                {
                    continue;
                }

                DotNode vertex = null;
                if (!input.IsOutput)
                {
                    var name = input.Kind.ToString();
                    if (!string.IsNullOrEmpty(input.Name))
                    {
                        if (name.Equals("Parameter"))
                        {
                            name = input.Name;
                        }
                        else
                        {
                            name += "\n" + input.Name;
                        }
                    }
                    name += "\n" + ShapeDescription(input);

                    vertex = createVertex(input);

                    if (input.IsInput || input.IsPlaceholder)
                    {
                        vertex.Label = name;
                        //
                        vertex.FixedSize = true;
                        vertex.Height    = 1f;
                        vertex.Width     = 1.3f;
                        vertex.PenWidth  = 4;
                    }
                    else if (string.IsNullOrEmpty(input.Name) && input.IsConstant && (input.Shape.Dimensions.Count == 0 || input.Shape.Dimensions[0] == 1))
                    {
                        string label1   = "";
                        var    contView = new Constant(input).Value();
                        var    value    = new Value(contView);
                        switch (input.DataType)
                        {
                        case DataType.Float:
                            label1 = value.GetDenseData <float>(input)[0][0].ToString("N4", CultureInfo.InvariantCulture);
                            break;

                        case DataType.Double:
                            label1 = value.GetDenseData <double>(input)[0][0].ToString("N4", CultureInfo.InvariantCulture);
                            break;

                        case DataType.Float16:
                            label1 = (value.GetDenseData <float16>(input)[0][0]).ToString();
                            break;

                        default:
                            break;
                        }

                        vertex.Label = label1;
                        //
                        vertex.Height = 0.6f;
                        vertex.Width  = 1f;
                    }
                    else
                    {
                        vertex.Label = name;
                        //
                        vertex.Height = 0.6f;
                        vertex.Width  = 1f;
                    }
                }
                else
                {
                    vertex = LazyCreateNode(input.Owner);
                }

                string label = string.IsNullOrEmpty(input.Name) ? input.Uid : input.Name;
                label += "\n" + ShapeDescription(input);

                DotArrow edge = new DotArrow(vertex, currentVertex);
                edge.Label = label;
                m_graph.Add(vertex);
                m_graph.Add(currentVertex);
                m_graph.Add(edge);
            }

            foreach (var output in node.Outputs)
            {
                //only final network outputs are drawn
                if (node.Uid == rootNode.Uid)
                {
                    var finalVertex = createVertex(output);
                    finalVertex.Label     = output.Name + "\n" + ShapeDescription(output);
                    finalVertex.Shape     = DotNodeShape.Egg;
                    finalVertex.FillColor = DotColor.Purple;
                    finalVertex.FixedSize = true;
                    finalVertex.Height    = 1f;
                    finalVertex.Width     = 1.3f;
                    finalVertex.PenWidth  = 4;
                    //add nodes
                    m_graph.Add(currentVertex);
                    m_graph.Add(finalVertex);
                }
            }
            //mark current node as visited
            visitedNodes.Add(id);
        }
Exemplo n.º 9
0
        static void Main(string[] args)
        {
            /*
             * This program gets 2 inputs:
             * List of all functions in cleaned format from IDA Pro as a list:
             * <function_name> <address> <length>
             *
             * And trace block information in cleaned format from DynamoRIO block tracking tool "drcov":
             * <block_adress>
             *
             * No other input is neccesary.
             *
             * Program outputs a graph in .dot format to be used with any GraphViz visualizer.
             *
             * There is sample input and output included in this repository.
             *
             * All numbers are in base 16. Detailed information about this algorithm can be found in the masters thesis:
             * MACHINE CODE INSTRUMENTATION FOR BLOCK RUNTIME STATISTICAL ANALYSIS AND PREDICTION
             */

            // Input
            const string FUNCTION_LIST_INPUT_PATH = @"C:\Users\edza\Desktop\mag\case_study_big\fun_list_all.txt";
            const string TRACED_BLOCKS_INPUT_PATH = @"C:\Users\edza\Desktop\mag\case_study_big\doc_cleaned.log";

            // Input seperator for function data columns <function_name>_SEPERATOR_<address>_SEPERATOR_<length>
            const string FUNCTION_SEPERATOR = "_SEPERATOR_";

            // Output
            const string NODE_STATS_OUTPUT_PATH = @"C:\Users\edza\Desktop\mag\case_study_big\node_stats.txt";
            const string GRAPH_OUTPUT_PATH      = @"C:\Users\edza\Desktop\mag\case_study_big\graph.dot";
            const string TABLE_OUTPUT_PATH      = @"C:\Users\edza\Desktop\mag\case_study_big\node_table.txt";
            const string NODE_LIST_OUTPUT_PATH  = @"C:\Users\edza\Desktop\mag\case_study_big\node_sequence.txt";

            // We want to create a list of all functions with their beginning and end adresses
            List <string> functionsAsText = File.ReadAllText(FUNCTION_LIST_INPUT_PATH)
                                            .Split('\n')
                                            .Select(l => l.Trim())
                                            .ToList();

            var functionTextPattern = new Regex($"([^\\s]+){FUNCTION_SEPERATOR}([^\\s]+){FUNCTION_SEPERATOR}([^\\s]+)");
            List <MachineCodeFunction> functions = new List <MachineCodeFunction>();

            foreach (string functionTextLine in functionsAsText)
            {
                var match = functionTextPattern.Match(functionTextLine);

                functions.Add(new MachineCodeFunction()
                {
                    Name  = match.Groups[1].Value,
                    Start = Convert.ToInt64(match.Groups[2].Value, 16),
                    End   = Convert.ToInt64(match.Groups[2].Value, 16) + Convert.ToInt64(match.Groups[3].Value, 16),
                });
            }

            // We know have a block trace, for each block we figure out which function that is and replace it with a function
            List <string> linesBlocks = File.ReadAllText(TRACED_BLOCKS_INPUT_PATH)
                                        .Split('\n', StringSplitOptions.RemoveEmptyEntries)
                                        .Select(l => l.Trim())
                                        .ToList();

            List <MachineCodeFunction> functionSequence = new List <MachineCodeFunction>();

            foreach (string block in linesBlocks)
            {
                long address = Convert.ToInt64(block, 16);

                foreach (MachineCodeFunction idaFun in functions)
                {
                    if (address >= idaFun.Start && address <= idaFun.End)
                    {
                        functionSequence.Add(idaFun);
                        break;
                    }
                }
            }

            // Add start and end
            functionSequence = functionSequence.Prepend(new MachineCodeFunction(customShortName: "Start")
            {
                Name = "Start",
            }).ToList();

            functionSequence = functionSequence.Append(new MachineCodeFunction(customShortName: "Exit")
            {
                Name = "Exit",
            }).ToList();

            // Now we reduce the function trace list by removing repeating blocks within the same func (eg. A A A B B C A A -> A B C A)
            List <MachineCodeFunction> functionListBlocksJoined = new List <MachineCodeFunction>();

            foreach (var function in functionSequence)
            {
                if (functionListBlocksJoined.Count == 0 || functionListBlocksJoined.Last() != function)
                {
                    functionListBlocksJoined.Add(function);
                }
            }

            string outputNodeSeq = string.Empty;

            foreach (var function in functionListBlocksJoined)
            {
                outputNodeSeq += function.ShortName + Environment.NewLine;
            }

            File.WriteAllText(NODE_LIST_OUTPUT_PATH, outputNodeSeq);

            string nodeStats = string.Empty;

            // We also calculate how often each function is called and store that as extra info
            functionListBlocksJoined.GroupBy(fun => fun)
            .ToList()
            .ForEach(functionCalls =>
            {
                var info   = functionCalls.First();
                info.Calls = functionCalls.Count();
                nodeStats += $"Node nr. {info.ShortName} ({info.Name}), called count: {info.Calls}\r\n";
            });

            // Then calculate avarage and stdev, if it's more than 1 stdev color change, 2 stdev extra color change
            var uniqueFunctions = functionListBlocksJoined.Distinct().ToList();

            (double stdev, double avarage) = GetStandardDeviation(uniqueFunctions.Select(node => (double)node.Calls).ToList());

            nodeStats = $"Avarage calls: {avarage}, standard deviation: {stdev}\r\n" + nodeStats;

            foreach (var function in uniqueFunctions)
            {
                if (function.Calls > avarage + 2 * stdev)
                {
                    function.NodeColor = DotColor.Green4;
                    nodeStats         += $"Node nr. {function.ShortName} ({function.Name}), is called 2 STDEV more than AVG.\r\n";
                }
                else if (function.Calls > avarage + 1 * stdev)
                {
                    function.NodeColor = DotColor.Olivedrab;
                    nodeStats         += $"Node nr. {function.ShortName} ({function.Name}), is called 1 STDEV more than AVG.\r\n";
                }
                else if (function.Calls < avarage - 2 * stdev)
                {
                    function.NodeColor = DotColor.Red1;
                    nodeStats         += $"Node nr. {function.ShortName} ({function.Name}), is called 2 STDEV less than AVG.\r\n";
                }
                else if (function.Calls < avarage - 1 * stdev)
                {
                    function.NodeColor = DotColor.Red4;
                    nodeStats         += $"Node nr. {function.ShortName} ({function.Name}), is called 1 STDEV less than AVG.\r\n";
                }
            }

            File.WriteAllText(NODE_STATS_OUTPUT_PATH, nodeStats);

            // For each node calculate all its successors for table visualization
            for (int i = 0; i < functionListBlocksJoined.Count; i++)
            {
                var @this = functionListBlocksJoined[i];

                if (i + 1 != functionListBlocksJoined.Count)
                {
                    @this.Next.Add(functionListBlocksJoined[i + 1]);
                }
            }

            string outputTable = string.Empty;

            var uniqueFunctionsNoRepeatingBlocks = functionListBlocksJoined.Distinct();

            List <(MachineCodeFunction, List <MachineCodeFunctionGrouping>)> graphAsTable = new List <(MachineCodeFunction, List <MachineCodeFunctionGrouping>)> ();

            foreach (var function in uniqueFunctionsNoRepeatingBlocks)
            {
                List <MachineCodeFunctionGrouping> tableEntry = function.Next.GroupBy(
                    functionNext => functionNext,
                    functionNext => functionNext,
                    (key, grouping) => new MachineCodeFunctionGrouping
                {
                    ShortName       = key.ShortName,
                    PreviousElement = function.ShortName,
                    NodeColor       = function.NodeColor,
                    Key             = key,
                    Probability     = grouping.Count() / (double)function.Next.Count
                }).ToList();

                outputTable += function.ShortName + Environment.NewLine;

                foreach (var group in tableEntry)
                {
                    outputTable += group.ShortName + $" {Math.Round(group.Probability, 2)} ";
                }

                outputTable += Environment.NewLine;

                graphAsTable.Add((function, tableEntry));
            }

            File.WriteAllText(TABLE_OUTPUT_PATH, outputTable);

            // GraphViz export

            var directedGraph = new DotGraph("BlockTraceGraph", true);

            foreach (var(node, _) in graphAsTable)
            {
                var graphNode = new DotNode(node.ShortName)
                {
                    Shape = DotNodeShape.Ellipse,
                    Label = node.ShortName + $"({node.Calls})",
                    // FillColor = node.NodeColor != null ? DotColor.Grey100 : DotColor.White,
                    FontColor = node.NodeColor ?? DotColor.Black,
                    Style     = (node.NodeColor != null ? DotNodeStyle.Bold : DotNodeStyle.Default),
                    Height    = 0.5f,
                };

                directedGraph.Add(graphNode);
            }

            foreach (var(_, edges) in graphAsTable)
            {
                // Let's do some coloring
                // If all edges have the same weights color blue
                // If there is one and ONLY one that is higher prob than everyone then GREEN
                // if there is one and ONLY one that is higher prob than everyone then RED
                // If only GREY

                bool areAllSameProbability = edges.All(e => e.Probability == edges[0].Probability);

                if (!areAllSameProbability)
                {
                    var maxProbability = edges.Max(e => e.Probability);
                    var isOnly         = edges.Count(e => e.Probability == maxProbability) == 1;
                    if (isOnly)
                    {
                        edges.First(e => e.Probability == maxProbability).Color = DotColor.Green3;
                    }

                    var minProbability = edges.Min(e => e.Probability);
                    var isOnlyMin      = edges.Count(e => e.Probability == minProbability) == 1;
                    if (isOnlyMin)
                    {
                        edges.First(e => e.Probability == minProbability).Color = DotColor.Red1;
                    }
                }

                foreach (var edge in edges)
                {
                    var arrow = new DotArrow(edge.PreviousElement, edge.ShortName)
                    {
                        ArrowLabel = Math.Round(edge.Probability, 2).ToString()
                    };

                    if (areAllSameProbability)
                    {
                        arrow.ArrowColor = DotColor.Blue;
                    }

                    if (edge.Color != null)
                    {
                        arrow.ArrowColor = edge.Color.Value;
                    }

                    if (edges.Count == 1)
                    {
                        arrow.ArrowColor = DotColor.Gray;
                    }

                    directedGraph.Add(arrow);
                }
            }

            // Indented version
            var dot = directedGraph.Compile(false);

            // Save it to a file
            File.WriteAllText(GRAPH_OUTPUT_PATH, dot);
        }