public static GraphProvider Create(MethodDef method)
        {
            var methodName = IdentifierEscaper.Escape(method.Name);

            switch (method.MethodBody)
            {
            case CilBody _:
            {
                var arch          = new CilArchitecture(method);
                var stateResolver = new CilStateTransitionResolver(arch);
                var cflowBuilder  = new SymbolicFlowGraphBuilder <Instruction>(arch, method.Body.Instructions, stateResolver);
                var cflow         = cflowBuilder.ConstructFlowGraph(0);
                return(new ControlFlowGraphProvider <Instruction>(methodName, cflow));
            }

            case NativeMethodBody _:
            {
                var cflow = IcedHelpers.ReadNativeMethodBody(method);
                return(new ControlFlowGraphProvider <Iced.Intel.Instruction>(methodName, cflow));
            }

            default:
                throw new Exception("Tried to create graph for method that has neither managed nor native body");
            }
        }
예제 #2
0
        public void ConditionalBranchShouldHaveTwoOutgoingEdges()
        {
            var method = Helpers.GetTestMethod(typeof(TestClass), nameof(TestClass.GetIsEvenString));

            var arch         = new CilArchitecture(method);
            var resolver     = new CilStateTransitionResolver(arch);
            var graphBuilder = new SymbolicFlowGraphBuilder <Instruction>(arch, arch.Method.Body.Instructions, resolver);

            var graph = graphBuilder.ConstructFlowGraph(0);

            Assert.Equal(2, graph.Entrypoint.OutDegree);
        }
예제 #3
0
        public void BranchlessMethodShouldHaveSingleBlock()
        {
            var method = Helpers.GetTestMethod(typeof(TestClass), nameof(TestClass.GetConstantString));

            var arch         = new CilArchitecture(method);
            var resolver     = new CilStateTransitionResolver(arch);
            var graphBuilder = new SymbolicFlowGraphBuilder <Instruction>(arch, arch.Method.Body.Instructions, resolver);

            var graph = graphBuilder.ConstructFlowGraph(0);

            Assert.Single(graph.Nodes);
            Assert.Empty(graph.GetEdges());
            Assert.Equal(0, graph.Entrypoint.OutDegree);
        }
예제 #4
0
        public void DataFlowGraphShouldBeCorrectOnConditional()
        {
            var method = Helpers.GetTestMethod(typeof(TestClass), nameof(TestClass.GetIsEvenString));

            var arch         = new CilArchitecture(method);
            var resolver     = new CilStateTransitionResolver(arch);
            var graphBuilder = new SymbolicFlowGraphBuilder <Instruction>(arch, arch.Method.Body.Instructions, resolver);

            _ = graphBuilder.ConstructFlowGraph(0);

            var graph = resolver.DataFlowGraph;

            // check that `arg0 % 2` is correctly turned into dfg
            var remNode = Assert.Single(graph.Nodes, n => n.StackDependencies.Count == 2);

            Assert.Single(remNode !.StackDependencies, n => Assert.Single(n) !.Node.Contents.IsLdarg());
            Assert.Single(remNode !.StackDependencies, n => Assert.Single(n) !.Node.Contents.IsLdcI4());
            Assert.Single(remNode.GetDependants());
        }