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