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)); }
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)); }
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); }
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)); }
/// <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); }
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)); }
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); }