예제 #1
0
        public void ExceptionHandler()
        {
            var instructions = new[]
            {
                DummyInstruction.Op(0, 0, 0),

                // try start
                DummyInstruction.Op(1, 0, 0),
                DummyInstruction.Jmp(2, 5),

                // handler start
                DummyInstruction.Op(3, 0, 0),
                DummyInstruction.Jmp(4, 5),

                DummyInstruction.Ret(5),
            };

            var ranges = new[]
            {
                new ExceptionHandlerRange(new AddressRange(1, 3), new AddressRange(3, 5)),
            };

            var cfg          = ConstructGraphWithEHRegions(instructions, ranges);
            var blockBuilder = new BlockBuilder <DummyInstruction>();
            var rootScope    = blockBuilder.ConstructBlocks(cfg);

            var order = rootScope.GetAllBlocks().ToArray();

            Assert.Equal(3, rootScope.Blocks.Count);
            Assert.IsAssignableFrom <ExceptionHandlerBlock <DummyInstruction> >(rootScope.Blocks[1]);
            Assert.Equal(
                new long[] { 0, 1, 3, 5 },
                order.Select(b => b.Offset));
        }
예제 #2
0
        public void Loop()
        {
            var instructions = new[]
            {
                DummyInstruction.Push(0, 1),

                DummyInstruction.Op(1, 0, 0),
                DummyInstruction.Op(2, 0, 0),
                DummyInstruction.JmpCond(3, 1),

                DummyInstruction.Op(4, 0, 0),
                DummyInstruction.Ret(5),
            };

            var cfgBuilder = new StaticFlowGraphBuilder <DummyInstruction>(
                DummyArchitecture.Instance,
                instructions,
                DummyArchitecture.Instance.SuccessorResolver);

            var cfg          = cfgBuilder.ConstructFlowGraph(0);
            var blockBuilder = new BlockBuilder <DummyInstruction>();
            var rootScope    = blockBuilder.ConstructBlocks(cfg);

            var order = rootScope.GetAllBlocks().ToArray();

            Assert.Equal(
                new long[] { 0, 1, 4 },
                order.Select(b => b.Offset));
        }
예제 #3
0
        public void FlatGraphShouldProduceFlatBlock()
        {
            var instructions = new[]
            {
                DummyInstruction.Op(0, 0, 0),
                DummyInstruction.Op(1, 0, 0),
                DummyInstruction.Op(2, 0, 0),
                DummyInstruction.Op(3, 0, 0),
                DummyInstruction.Ret(4),
            };

            var cfgBuilder = new StaticFlowGraphBuilder <DummyInstruction>(
                DummyArchitecture.Instance,
                instructions,
                DummyArchitecture.Instance.SuccessorResolver);

            var cfg = cfgBuilder.ConstructFlowGraph(0);

            var blockBuilder = new BlockBuilder <DummyInstruction>();
            var rootScope    = blockBuilder.ConstructBlocks(cfg);

            Assert.Single(rootScope.Blocks);
            Assert.IsAssignableFrom <BasicBlock <DummyInstruction> >(rootScope.Blocks[0]);
            Assert.Equal(instructions, ((BasicBlock <DummyInstruction>)rootScope.Blocks[0]).Instructions);
        }
예제 #4
0
        public void WeirdOrder()
        {
            var instructions = new[]
            {
                DummyInstruction.Op(0, 0, 0),
                DummyInstruction.Op(1, 0, 0),
                DummyInstruction.Op(2, 0, 0),
                DummyInstruction.Jmp(3, 6),

                DummyInstruction.Op(4, 0, 0),
                DummyInstruction.Ret(5),

                DummyInstruction.Op(6, 0, 0),
                DummyInstruction.Op(7, 0, 0),
                DummyInstruction.Jmp(8, 15),

                DummyInstruction.Op(9, 0, 0),
                DummyInstruction.Op(10, 0, 0),
                DummyInstruction.Jmp(11, 4),

                DummyInstruction.Op(12, 0, 0),
                DummyInstruction.Op(13, 0, 0),
                DummyInstruction.Jmp(14, 9),

                DummyInstruction.Op(15, 0, 0),
                DummyInstruction.Op(16, 0, 0),
                DummyInstruction.Jmp(17, 12),
            };

            var cfgBuilder = new StaticFlowGraphBuilder <DummyInstruction>(
                DummyArchitecture.Instance,
                instructions,
                DummyArchitecture.Instance.SuccessorResolver);

            var cfg          = cfgBuilder.ConstructFlowGraph(0);
            var blockBuilder = new BlockBuilder <DummyInstruction>();
            var rootScope    = blockBuilder.ConstructBlocks(cfg);

            var order = rootScope.GetAllBlocks().ToArray();

            Assert.Equal(
                new long[] { 0, 6, 15, 12, 9, 4 },
                order.Select(b => b.Offset));
        }
예제 #5
0
        /// <summary>
        /// Parses the given <see cref="ControlFlowGraph{TInstruction}"/>
        /// </summary>
        /// <returns>A <see cref="ControlFlowGraph{TInstruction}"/> representing the Ast</returns>
        public ControlFlowGraph <Statement <TInstruction> > Parse()
        {
            var newGraph     = new ControlFlowGraph <Statement <TInstruction> >(AstArchitecture);
            var blockBuilder = new BlockBuilder <TInstruction>();
            var rootScope    = blockBuilder.ConstructBlocks(ControlFlowGraph);

            // Transform and add regions.
            foreach (var originalRegion in ControlFlowGraph.Regions)
            {
                var newRegion = TransformRegion(originalRegion);
                newGraph.Regions.Add(newRegion);
            }

            // Transform and add nodes.
            foreach (var originalBlock in rootScope.GetAllBlocks())
            {
                var originalNode     = ControlFlowGraph.Nodes[originalBlock.Offset];
                var transformedBlock = TransformBlock(originalBlock);
                var newNode          = new ControlFlowNode <Statement <TInstruction> >(originalBlock.Offset, transformedBlock);
                newGraph.Nodes.Add(newNode);

                // Move node to newly created region.
                if (originalNode.ParentRegion is BasicControlFlowRegion <TInstruction> basicRegion)
                {
                    newNode.MoveToRegion(_context.RegionsMapping[basicRegion]);
                }
            }

            // Clone edges.
            foreach (var originalEdge in ControlFlowGraph.GetEdges())
            {
                var newOrigin = newGraph.Nodes[originalEdge.Origin.Offset];
                var newTarget = newGraph.Nodes[originalEdge.Target.Offset];
                newOrigin.ConnectWith(newTarget, originalEdge.Type);
            }

            // Fix entry point.
            newGraph.Entrypoint = newGraph.Nodes[_context.ControlFlowGraph.Entrypoint.Offset];

            return(newGraph);
        }
예제 #6
0
        public void BasicRegionShouldTranslateToSingleScopeBlock()
        {
            var instructions = new[]
            {
                DummyInstruction.Push(0, 1),
                DummyInstruction.JmpCond(1, 4),

                DummyInstruction.Op(2, 0, 0),
                DummyInstruction.Jmp(3, 4),

                DummyInstruction.Op(4, 0, 0),
                DummyInstruction.Ret(5),
            };

            var cfgBuilder = new StaticFlowGraphBuilder <DummyInstruction>(
                DummyArchitecture.Instance,
                instructions,
                DummyArchitecture.Instance.SuccessorResolver);

            var cfg = cfgBuilder.ConstructFlowGraph(0);

            var region = new BasicControlFlowRegion <DummyInstruction>();

            cfg.Regions.Add(region);
            region.Nodes.Add(cfg.Nodes[2]);

            var blockBuilder = new BlockBuilder <DummyInstruction>();
            var rootScope    = blockBuilder.ConstructBlocks(cfg);

            Assert.Equal(3, rootScope.Blocks.Count);
            Assert.IsAssignableFrom <BasicBlock <DummyInstruction> >(rootScope.Blocks[0]);
            Assert.IsAssignableFrom <ScopeBlock <DummyInstruction> >(rootScope.Blocks[1]);
            Assert.IsAssignableFrom <BasicBlock <DummyInstruction> >(rootScope.Blocks[2]);

            var order = rootScope.GetAllBlocks().ToArray();

            Assert.Equal(
                new long[] { 0, 2, 4 },
                order.Select(b => b.Offset));
        }
예제 #7
0
        public void EHWithMultipleHandlersByRangesShouldGroupTogether()
        {
            var ranges = new[]
            {
                new ExceptionHandlerRange(new AddressRange(1, 3), new AddressRange(3, 5)),
                new ExceptionHandlerRange(new AddressRange(1, 3), new AddressRange(5, 7)),
            };

            var instructions = new[]
            {
                DummyInstruction.Op(0, 0, 0),

                // try start 1 & 2
                DummyInstruction.Op(1, 0, 0),
                DummyInstruction.Jmp(2, 7),

                // handler start 2
                DummyInstruction.Op(3, 0, 0),
                DummyInstruction.Jmp(4, 7),

                // handler start 1
                DummyInstruction.Op(5, 0, 0),
                DummyInstruction.Jmp(6, 7),

                DummyInstruction.Ret(7),
            };

            var cfg          = ConstructGraphWithEHRegions(instructions, ranges);
            var blockBuilder = new BlockBuilder <DummyInstruction>();
            var rootScope    = blockBuilder.ConstructBlocks(cfg);

            var order = rootScope.GetAllBlocks().ToArray();

            Assert.Equal(3, rootScope.Blocks.Count);
            Assert.IsAssignableFrom <ExceptionHandlerBlock <DummyInstruction> >(rootScope.Blocks[1]);
            Assert.Equal(2, ((ExceptionHandlerBlock <DummyInstruction>)rootScope.Blocks[1]).HandlerBlocks.Count);
        }