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 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)); }
private static ControlFlowGraph <DummyInstruction> BuildControlFlowGraph(DummyInstruction[] instructions, long entrypoint = 0, IEnumerable <long> knownBlockHeaders = null) { var builder = new StaticFlowGraphBuilder <DummyInstruction>( DummyArchitecture.Instance, instructions, DummyArchitecture.Instance.SuccessorResolver); return(builder.ConstructFlowGraph(entrypoint, knownBlockHeaders ?? ImmutableArray <long> .Empty)); }
private static ControlFlowGraph <Instruction> ConstructStaticFlowGraph(byte[] rawCode, long entrypoint) { var architecture = new X86Architecture(); var instructionProvider = new X86DecoderInstructionProvider(architecture, rawCode, 32); var cfgBuilder = new StaticFlowGraphBuilder <Instruction>( instructionProvider, new X86StaticSuccessorResolver()); return(cfgBuilder.ConstructFlowGraph(entrypoint)); }
public void ConditionalBranchShouldHaveTwoOutgoingEdges() { var method = Helpers.GetTestMethod(typeof(TestClass), nameof(TestClass.GetIsEvenString)); var arch = new CilArchitecture(method); var resolver = new CilStaticSuccessorResolver(); var graphBuilder = new StaticFlowGraphBuilder <Instruction>(arch, arch.Method.Body.Instructions, resolver); var graph = graphBuilder.ConstructFlowGraph(0); Assert.Equal(2, graph.Entrypoint.OutDegree); }
public void BranchlessMethodShouldHaveSingleBlock() { var method = Helpers.GetTestMethod(typeof(TestClass), nameof(TestClass.GetConstantString)); var arch = new CilArchitecture(method); var resolver = new CilStaticSuccessorResolver(); var graphBuilder = new StaticFlowGraphBuilder <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> ConstructGraphWithEHRegions(IEnumerable <DummyInstruction> instructions, IEnumerable <ExceptionHandlerRange> ranges) { var architecture = DummyArchitecture.Instance; var builder = new StaticFlowGraphBuilder <DummyInstruction>( architecture, instructions, architecture.SuccessorResolver); var rangesArray = ranges as ExceptionHandlerRange[] ?? ranges.ToArray(); var cfg = builder.ConstructFlowGraph(0, rangesArray); cfg.DetectExceptionHandlerRegions(rangesArray); return(cfg); }
public static ControlFlowGraph <Instruction> ReadNativeFunction(string loc, uint fileOffset, bool is32Bit) { using var fs = File.OpenRead(loc); fs.Position = fileOffset; var architecture = new X86Architecture(); var instructionProvider = new X86DecoderInstructionProvider(architecture, fs, is32Bit ? 32 : 64); var cfgBuilder = new StaticFlowGraphBuilder <Instruction>( instructionProvider, new X86StaticSuccessorResolver()); // pass in a file offset, since we're working on a file on disk. would pass rva (and base addr in provider // ctor) for in-memory. ControlFlowGraph <Instruction> graph = cfgBuilder.ConstructFlowGraph(fileOffset); return(graph); }
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> /// Constructs a control flow graph from a CIL method body. /// </summary> /// <param name="self">The method body.</param> /// <returns>The control flow graph.</returns> public static ControlFlowGraph <CilInstruction> ConstructStaticFlowGraph(this CilMethodBody self) { var architecture = new CilArchitecture(self); var cfgBuilder = new StaticFlowGraphBuilder <CilInstruction>( architecture, self.Instructions, architecture.SuccessorResolver); var ehRanges = self.ExceptionHandlers .ToEchoRanges() .ToArray(); var cfg = cfgBuilder.ConstructFlowGraph(0, ehRanges); if (ehRanges.Length > 0) { cfg.DetectExceptionHandlerRegions(ehRanges); } return(cfg); }
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)); }
/// <summary> /// Constructs a control flow graph from a CIL method body. /// </summary> /// <param name="self">The method body.</param> /// <returns>The control flow graph.</returns> public static ControlFlowGraph <Instruction> ConstructStaticFlowGraph(this MethodDef self) { var body = self.Body; var architecture = new CilArchitecture(self); var cfgBuilder = new StaticFlowGraphBuilder <Instruction>( architecture, body.Instructions, architecture.SuccessorResolver); var ehRanges = body .GetExceptionHandlerRanges() .ToArray(); var cfg = cfgBuilder.ConstructFlowGraph(0, ehRanges); if (ehRanges.Length > 0) { cfg.DetectExceptionHandlerRegions(ehRanges); } return(cfg); }