public void EntryPointPopWithSingleItemOnStackShouldAddDependencyToExternalSource()
        {
            var instructions = new[]
            {
                DummyInstruction.Pop(0, 1),
                DummyInstruction.Ret(1),
            };

            var dfgBuilder = new DummyTransitionResolver();
            var argument   = new ExternalDataSourceNode <DummyInstruction>(-1, "Argument 1");

            dfgBuilder.DataFlowGraph.Nodes.Add(argument);
            dfgBuilder.InitialState = new SymbolicProgramState <DummyInstruction>();
            dfgBuilder.InitialState.Stack.Push(new SymbolicValue <DummyInstruction>(argument));

            var cfgBuilder = new SymbolicFlowGraphBuilder <DummyInstruction>(
                DummyArchitecture.Instance,
                instructions,
                dfgBuilder);

            cfgBuilder.ConstructFlowGraph(0);
            var dfg = dfgBuilder.DataFlowGraph;

            Assert.Equal(new[] { argument }, dfg.Nodes[0].StackDependencies[0].GetNodes());
        }
Example #2
0
        /// <summary>
        /// Constructs a control flow graph and a data flow graph from a CIL method body.
        /// </summary>
        /// <param name="self">The method body.</param>
        /// <param name="dataFlowGraph">The constructed data flow graph.</param>
        /// <returns>The control flow graph.</returns>
        public static ControlFlowGraph <Instruction> ConstructSymbolicFlowGraph(
            this MethodDef self,
            out DataFlowGraph <Instruction> dataFlowGraph)
        {
            var body = self.Body;

            var architecture = new CilArchitecture(self);
            var dfgBuilder   = new CilStateTransitionResolver(architecture);
            var cfgBuilder   = new SymbolicFlowGraphBuilder <Instruction>(
                architecture,
                body.Instructions,
                dfgBuilder);

            var ehRanges = body
                           .GetExceptionHandlerRanges()
                           .ToArray();

            var cfg = cfgBuilder.ConstructFlowGraph(0, ehRanges);

            if (ehRanges.Length > 0)
            {
                cfg.DetectExceptionHandlerRegions(ehRanges);
            }

            dataFlowGraph = dfgBuilder.DataFlowGraph;
            return(cfg);
        }
        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");
            }
        }
        private (ControlFlowGraph <Instruction> Cfg, DataFlowGraph <Instruction> Dfg) ConstructSymbolicFlowGraph(
            byte[] rawCode, long entrypoint)
        {
            var instructionProvider = new X86DecoderInstructionProvider(_architecture, rawCode, 32);
            var dfgBuilder          = new X86StateTransitionResolver(_architecture);

            var cfgBuilder = new SymbolicFlowGraphBuilder <Instruction>(
                instructionProvider,
                dfgBuilder);

            return(cfgBuilder.ConstructFlowGraph(entrypoint), dfgBuilder.DataFlowGraph);
        }
        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);
        }
Example #6
0
        private ControlFlowGraph <Statement <DummyInstruction> > ConstructAst(
            IEnumerable <DummyInstruction> instructions)
        {
            var architecture = DummyArchitecture.Instance;

            var dfgBuilder = new DummyTransitionResolver();
            var cfgBuilder = new SymbolicFlowGraphBuilder <DummyInstruction>(architecture, instructions, dfgBuilder);

            var cfg        = cfgBuilder.ConstructFlowGraph(0);
            var astBuilder = new AstParser <DummyInstruction>(cfg, dfgBuilder.DataFlowGraph);

            return(astBuilder.Parse());
        }
        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);
        }
        private static (ControlFlowGraph <DummyInstruction> cfg, DataFlowGraph <DummyInstruction> dfg) BuildFlowGraphs(
            DummyInstruction[] instructions,
            long entrypoint = 0,
            IEnumerable <long> knownBlockHeaders = null)
        {
            var dfgBuilder = new DummyTransitionResolver();
            var cfgBuilder = new SymbolicFlowGraphBuilder <DummyInstruction>(
                DummyArchitecture.Instance,
                instructions,
                dfgBuilder);

            var cfg = cfgBuilder.ConstructFlowGraph(entrypoint, knownBlockHeaders ?? ImmutableArray <long> .Empty);

            return(cfg, dfgBuilder.DataFlowGraph);
        }
        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());
        }
        public void EntryPointPopWithInitialStateEmptyShouldThrow()
        {
            var instructions = new[]
            {
                DummyInstruction.Pop(0, 1),
                DummyInstruction.Ret(1),
            };

            var dfgBuilder = new DummyTransitionResolver
            {
                InitialState = new SymbolicProgramState <DummyInstruction>()
            };

            var cfgBuilder = new SymbolicFlowGraphBuilder <DummyInstruction>(
                DummyArchitecture.Instance,
                instructions,
                dfgBuilder);

            Assert.Throws <StackImbalanceException>(() => cfgBuilder.ConstructFlowGraph(0));
        }