public string FormatControlFlowGraph(ControlFlowGraph cfg)
 {
     StringWriter writer = new StringWriter();
     foreach (InstructionBlock block in cfg.Blocks)
     {
         writer.WriteLine("block {0}:", block.Index);
         writer.WriteLine("\tbody:");
         foreach (Instruction instruction in block)
         {
             writer.Write("\t\t");
             InstructionData data = cfg.GetData(instruction);
             writer.Write("[{0}:{1}] ", data.StackBefore, data.StackAfter);
             Formatter.WriteInstruction(writer, instruction);
             writer.WriteLine();
         }
         InstructionBlock[] successors = block.Successors;
         if (successors.Length > 0)
         {
             writer.WriteLine("\tsuccessors:");
             foreach (InstructionBlock block2 in successors)
             {
                 writer.WriteLine("\t\tblock {0}", block2.Index);
             }
         }
     }
     return writer.ToString();
 }
 public ReadWriteDependencyInjectorImpl(IList<XILSInstr> instrs):
     base(instrs)
 {
     _cfg = Compilation.CreateCFG(instrs);
     SetHandler(InstructionCodes.LoadVar, HandleLoadVar);
     SetHandler(InstructionCodes.StoreVar, HandleStoreVar);
     SetHandler(InstructionCodes.LdelemFixA, HandleLoadElement);
     SetHandler(InstructionCodes.LdelemFixAFixI, HandleLoadElement);
     SetHandler(InstructionCodes.StelemFixA, HandleStoreElement);
     SetHandler(InstructionCodes.StelemFixAFixI, HandleStoreElement);
 }
Exemplo n.º 3
0
		/// <summary>
		///     Computes a key sequence of the given CFG.
		/// </summary>
		/// <param name="graph">The CFG.</param>
		/// <param name="random">The random source, or <c>null</c> if key id is needed.</param>
		/// <returns>The generated key sequence of the CFG.</returns>
		public static BlockKey[] ComputeKeys(ControlFlowGraph graph, RandomGenerator random) {
			var keys = new BlockKey[graph.Count];

			foreach (ControlFlowBlock block in graph) {
				var key = new BlockKey();
				if ((block.Type & ControlFlowBlockType.Entry) != 0)
					key.Type = BlockKeyType.Explicit;
				else
					key.Type = BlockKeyType.Incremental;
				keys[block.Id] = key;
			}
			ProcessBlocks(keys, graph, random);
			return keys;
		}
        public void Walk(MethodInfo method, ControlFlowGraph graph)
        {
            this.recorder = new CallParameterTypesRecorder();

            this.recorder.Initialize(method);

            var variables = method.GetMethodBody().LocalVariables.ToDictionary(x => x.LocalIndex, x => PotentialType.FromType(x.LocalType));
            var parameters = method.GetParameters().ToDictionary(x => x.Position, x => PotentialType.FromType(x.ParameterType));
            var initialState = new TypeAnalysisState(variables, parameters);

            var walker = new ControlFlowGraphWalker<TypeAnalysisState>
            {
                InitialState = initialState,
                VisitingBlock = (state, block) => this.recorder.Visit(state, block.Instructions)
            };

            walker.WalkCore(method, graph);
        }
Exemplo n.º 5
0
		public BlockStatement Process (DecompilationContext context, BlockStatement body)
		{
			this.cfg = context.ControlFlowGraph;
			this.annotations = AnnotationStore.CreateStore (cfg, optimization);
			this.body = context.Body;
			this.variables = context.Variables;

			this.expression_decompiler = new ExpressionDecompiler (context.Method, annotations);
			this.statements = new List<Statement> [cfg.Blocks.Length];
			this.processed = new HashSet<InstructionBlock> ();
			this.assignments = new Dictionary<VariableReference, Expression> ();

			Run ();

			PopulateBodyBlock (body);

			return body;
		}
Exemplo n.º 6
0
			public void Analyze(ControlFlowGraph graph)
			{				
				DBC.Pre(graph != null, "graph is null");

				Profile.Start("Splicing");
				var visited = new List<BasicBlock>();
				foreach (BasicBlock root in graph.Roots)
					DoSpliceHandlers(m_instructions, root, visited);

				visited.Clear();
				foreach (BasicBlock root in graph.Roots)
					DoSpliceNullCheck(m_instructions, root, visited);
				var data = new DataFlow<Lattice>(m_instructions, graph.Roots);
				m_skipped = data.Skipped;
				Profile.Stop("Splicing");
				
				var functions = new Lattice.Functions();
				Dictionary<BasicBlock, Lattice> lattices = data.Analyze(functions, m_initialState);
				
				Profile.Start("Post Transform");
				m_states = new State[m_instructions.Length];
				foreach (var entry in lattices)
				{
					BasicBlock block = entry.Key;
					if (block.Length > 0)
					{
						Lattice lattice = entry.Value;
						
						for (int index = block.First.Index; index <= block.Last.Index; ++index)	// it'd be nice to assert that every index was set, but methods often have dead code so it's a little difficult
						{
							m_states[index] = lattice.State;
							lattice = lattice.Transform(index);
						}
					}
				}
				Profile.Stop("Post Transform");
				
				for (int index = 0; index < m_instructions.Length; ++index)
				{
					Log.DebugLine(this, "{0:X2}: {1}", m_instructions[index].Untyped.Offset, m_states[index]);
				}
			}
Exemplo n.º 7
0
		public static void FormatControlFlowGraph (TextWriter writer, ControlFlowGraph cfg)
		{
			int id = 1;
			foreach (InstructionBlock block in cfg.Blocks) {
				writer.WriteLine ("block {0}:", id);
				writer.WriteLine ("\tbody:");
				foreach (Instruction instruction in block) {
					writer.Write ("\t\t");
					Formatter.WriteInstruction (writer, instruction);
					writer.WriteLine ();
				}
				InstructionBlock [] successors = block.Successors;
				if (successors.Length > 0) {
					writer.WriteLine ("\tsuccessors:");
					foreach (InstructionBlock successor in successors) {
						writer.WriteLine ("\t\tblock {0}", GetBlockId (cfg, successor));
					}
				}

				++id;
			}
		}
Exemplo n.º 8
0
 public RangeAnalysis(ControlFlowGraph cfg) : base(cfg)
 {
 }
Exemplo n.º 9
0
 public BasicAnnotationBuilder(ControlFlowGraph cfg)
     : base(cfg)
 {
 }
        public string Format(FormatOptions options)
        {
            var nl = Environment.NewLine;
            var sb = new StringBuilder();
            
            var body = _methodDef.Body;
            var cfg = new ControlFlowGraph(body);
            SourceCodePosition lastSource = null;

            _dissassembly.Format = options;

            var embedSource = options.HasFlag(FormatOptions.EmbedSourceCode) || options.HasFlag(FormatOptions.EmbedSourcePositions);
            if (embedSource && _dissassembly.MethodEntry != null)
            {
                var pos = _mapFile.GetSourceCodePositions(_dissassembly.MethodEntry).FirstOrDefault();
                if (pos != null)
                {
                    sb.Append(" // ----- Source Code: ");
                    sb.Append(pos.Document.Path);
                    sb.Append(nl);
                }
            }

            foreach (var block in cfg)
            {
                if (options.HasFlag(FormatOptions.ShowControlFlow))
                {
                    sb.AppendFormat(" // ----- Entry [{0}] Exit [{1}]{2}",
                        string.Join(", ", block.EntryBlocks.Select(x => _dissassembly.FormatAddress(x.Entry).Trim())),
                        string.Join(", ", block.ExitBlocks.Select(x => _dissassembly.FormatAddress(x.Entry).Trim())),
                        nl);
                }


                foreach (var i in block.Instructions)
                {
                    if (embedSource)
                    {
                        var source = _dissassembly.FindSourceCode(i.Offset, false);

                        if (source != null && lastSource != null && source.Document.Path != lastSource.Document.Path)
                        {
                            // print document name.
                            sb.Append(" // ----- ");
                            sb.Append(source.Document.Path);
                            sb.Append(nl);
                            lastSource = null;
                        }

                        if (source == null && lastSource != null)
                        {
                            sb.AppendLine(" // ----- (no source)");
                        }
                        else if (source != null && (lastSource == null || !source.Position.EqualExceptOffset(lastSource.Position)))
                        {
                            if (options.HasFlag(FormatOptions.EmbedSourcePositions))
                                sb.AppendFormat(" // ----- Position: {0} - {1}{2}", source.Position.Start, source.Position.End, nl);

                            if (options.HasFlag(FormatOptions.EmbedSourceCode))
                            {
                                string[] lines = GetSourceCodeLines(source);
                                if (lines != null)
                                    sb.AppendLine(" // " + string.Join(nl + " // ", lines));
                            }
                        }
                        lastSource = source;
                    }
                 
                    sb.AppendLine(_dissassembly.FormatInstruction(i));
                }
            }
            sb.AppendLine();

            if (body.Exceptions.Any())
            {
                sb.AppendLine("Exception handlers:");
                foreach (var handler in body.Exceptions)
                {
                    sb.AppendFormat("\t{0} - {1}{2}", _dissassembly.FormatAddress(handler.TryStart), _dissassembly.FormatAddress(handler.TryEnd), nl);
                    foreach (var c in handler.Catches)
                    {
                        sb.AppendFormat("\t\t{0} => {1}{2}", c.Type, _dissassembly.FormatAddress(c.Instruction), nl);
                    }
                    if (handler.CatchAll != null)
                    {
                        sb.AppendFormat("\t\t{0} => {1}{2}", "<any>", _dissassembly.FormatAddress(handler.CatchAll), nl);
                    }
                }
                sb.AppendLine();
            }

            if (_mapFile != null)
            {
                var typeEntry = _mapFile.GetTypeByNewName(_methodDef.Owner.Fullname);
                if (typeEntry != null)
                {
                    var methodEntry = typeEntry.FindDexMethod(_methodDef.Name, _methodDef.Prototype.ToSignature());
                    if (methodEntry != null)
                    {
                        _registersToVariableNames = new Dictionary<string, string>();

                        var validParameters = methodEntry.Parameters.Where(x => !string.IsNullOrEmpty(x.Name)).ToList();
                        if (validParameters.Any())
                        {
                            sb.AppendLine("Parameters:");
                            foreach (var p in validParameters)
                            {
                                var registerName = _dissassembly.FormatRegister(p.Register);
                                sb.AppendFormat("\t{0} (r{1}) -> {2}{3}", registerName, p.Register, p.Name, nl);
                                
                                if(!string.IsNullOrEmpty(p.Name))
                                    _registersToVariableNames.Add(registerName, p.Name);
                            }
                            sb.AppendLine();
                        }

                        var validVariables = methodEntry.Variables.Where(x => !string.IsNullOrEmpty(x.Name)).ToList();
                        if (validVariables.Any())
                        {
                            sb.AppendLine("Variables:");
                            foreach (var p in validVariables)
                            {
                                var registerName = _dissassembly.FormatRegister(p.Register);
                                sb.AppendFormat("\t{0} -> {1}{2}", registerName, p.Name, nl);
                                if (!string.IsNullOrEmpty(p.Name))
                                    _registersToVariableNames.Add(registerName, p.Name);
                            }
                            sb.AppendLine();
                        }

                        sb.AppendLine("Source code positions:");
                        Document lastDocument = null;
                        foreach (var row in _mapFile.GetSourceCodePositions(methodEntry))
                        {
                            if (row.Document != lastDocument)
                            {
                                sb.AppendFormat("\t{0}{1}", row.Document.Path, nl);
                                lastDocument = row.Document;
                            }
                            var pos = row.Position;
                            sb.AppendFormat("\t{0}\t({1},{2}) - ({3},{4}){5}", MethodDisassembly.FormatOffset(pos.MethodOffset), pos.Start.Line, pos.Start.Column, pos.End.Line, pos.End.Column, nl);
                        }
                    }
                }
            }
            return sb.ToString();
        }
Exemplo n.º 11
0
 private FlowGraphAnalysisData(
     ControlFlowGraph controlFlowGraph,
     ISymbol owningSymbol,
     ImmutableArray <IParameterSymbol> parameters,
     PooledDictionary <BasicBlock, BasicBlockAnalysisData> analysisDataByBasicBlockMap,
     PooledDictionary <(ISymbol symbol, IOperation operation), bool> symbolsWriteMap,
Exemplo n.º 12
0
		public static void FormatControlFlowGraph (TextWriter writer, ControlFlowGraph cfg)
		{
			foreach (InstructionBlock block in cfg.Blocks) {
				writer.WriteLine ("block {0}:", block.Index);
				writer.WriteLine ("\tbody:");
				foreach (Instruction instruction in block) {
					writer.Write ("\t\t");
					var data = cfg.GetData (instruction);
					writer.Write ("[{0}:{1}] ", data.StackBefore, data.StackAfter);
					Formatter.WriteInstruction (writer, instruction);
					writer.WriteLine ();
				}
				InstructionBlock [] successors = block.Successors;
				if (successors.Length > 0) {
					writer.WriteLine ("\tsuccessors:");
					foreach (InstructionBlock successor in successors) {
						writer.WriteLine ("\t\tblock {0}", successor.Index);
					}
				}
			}
		}
Exemplo n.º 13
0
 public ZeroAnalysis(ControlFlowGraph cfg) : base(cfg)
 {
 }
Exemplo n.º 14
0
        public void ManyBlocks()
        {
            var TAC = GenerateTAC(
                @"
{
1: a = b + c;
d = b + c;
b = b + c;
t = b + c;
a = d * e;
if x
{
goto 1;
}
3: o = d * e;
a = d * e;
if y
{
goto 3;
}
}
");
            var blocks = new TACBaseBlocks(TAC.Instructions);

            blocks.GenBaseBlocks();
            var cfg       = new ControlFlowGraph(blocks.blocks);
            var optimizer = new AvailableExpressionsOptimizer();

            optimizer.Run(cfg, blocks.blocks);
            var actual   = blocks.blocks.Select(b => b.ToString().Trim());
            var expected = new List <string>()
            {
                "1\n" +
                "a = b + c\n" +
                "d = a\n" +
                "b = a\n" +
                "t = b + c\n" +
                "a = d * e\n" +
                "if x goto #L0",

                "goto #L1",

                "#L0\n" +
                "goto 1",

                "#L1",

                "3\n" +
                "o = a\n" +
                "a = a\n" +
                "if y goto #L2",

                "goto #L3",

                "#L2\n" +
                "goto 3",

                "#L3"
            };

            Assert.AreEqual(actual, expected);
        }
    private int InitialDepthOfBlock(CfgBlock block, ControlFlowGraph cfg) {
      int sd = block2depth[block.Index];

      if (this.visited[block.Index]) return sd;

      this.visited[block.Index] = true;
      int depth;

      ExceptionHandler eh = cfg.HandlerThatStartsAtBlock(block);
      if (eh == null) {
        // if we haven't seen this block and it is not the entry block
        // nor the Exception Exit of the method
        // it is unreachable
        if (block == cfg.Entry) {
          depth = 0;
        }
        else if (block == cfg.ExceptionExit) {
          depth = 0;
        }
        else {
          depth = -1;
        }
      }
      else {
        switch (eh.HandlerType) {
          case NodeType.Catch:
          case NodeType.FaultHandler:
          case NodeType.Filter:
            depth = 1;
            break;
          case NodeType.Finally:
            depth = 0;
            break;
          default:
            throw new ApplicationException("unknown handler type");
        }
      }
      block2depth[block.Index] = depth;
      return depth;
    }
        public void ExplodedGraph_NonDecisionMakingAssignments()
        {
            string        testInput = "var a = true; a |= false; var b = 42; b++; ++b;";
            SemanticModel semanticModel;
            var           method         = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol   = semanticModel.GetDeclaredSymbol(method);
            var           varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var           aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var           bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);

            SymbolicValue sv = null;
            var           numberOfProcessedInstructions = 0;
            var           branchesVisited = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = true")
                {
                    branchesVisited++;
                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "a |= false")
                {
                    branchesVisited++;
                    Assert.IsNotNull(args.ProgramState.GetSymbolValue(aSymbol));
                    Assert.IsFalse(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.False);
                    Assert.IsFalse(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.True);
                }
                if (args.Instruction.ToString() == "b = 42")
                {
                    branchesVisited++;
                    sv = args.ProgramState.GetSymbolValue(bSymbol);
                    Assert.IsNotNull(sv);
                }
                if (args.Instruction.ToString() == "b++")
                {
                    branchesVisited++;
                    var svNew = args.ProgramState.GetSymbolValue(bSymbol);
                    Assert.IsNotNull(svNew);
                    Assert.AreNotEqual(sv, svNew);
                }
                if (args.Instruction.ToString() == "++b")
                {
                    branchesVisited++;
                    var svNew = args.ProgramState.GetSymbolValue(bSymbol);
                    Assert.IsNotNull(svNew);
                    Assert.AreNotEqual(sv, svNew);
                }
            };

            explodedGraph.Walk();

            Assert.AreEqual(11, numberOfProcessedInstructions);
            Assert.AreEqual(5, branchesVisited);
        }
        public void ExplodedGraph_InternalStateCount_MaxReached()
        {
            var           testInput = @"
using System;

namespace TesteAnalyzer
{
    class Program
    {
        static bool GetBool() { return bool.Parse(""True""); }

        static void Main(string[] args)
        {
            bool corrupted = false;
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();
            corrupted |= !GetBool();

            if (!corrupted)
            {
                Console.Out.WriteLine();
            }
        }
    }
}
";
            SemanticModel semanticModel;
            var           tree         = ControlFlowGraphTest.Compile(testInput, out semanticModel);
            var           method       = tree.GetRoot().DescendantNodes().OfType <MethodDeclarationSyntax>().First(m => m.Identifier.ValueText == "Main");
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };
            var maxStepCountReached = false;

            explodedGraph.MaxStepCountReached += (sender, args) => { maxStepCountReached = true; };
            var maxInternalStateCountReached = false;

            explodedGraph.MaxInternalStateCountReached += (sender, args) => { maxInternalStateCountReached = true; };

            explodedGraph.Walk();

            Assert.IsFalse(explorationEnded);
            Assert.IsFalse(maxStepCountReached);
            Assert.IsTrue(maxInternalStateCountReached);
        }
        public void ExplodedGraph_BothBranchesVisited()
        {
            string        testInput = "var a = false; bool b; if (inParameter) { b = inParameter; } else { b = !inParameter; } a = b;";
            SemanticModel semanticModel;
            var           method       = ControlFlowGraphTest.CompileWithMethodBody(string.Format(TestInput, testInput), "Bar", out semanticModel);
            var           methodSymbol = semanticModel.GetDeclaredSymbol(method);

            var varDeclarators = method.DescendantNodes().OfType <VariableDeclaratorSyntax>();
            var aSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "a"));
            var bSymbol        = semanticModel.GetDeclaredSymbol(varDeclarators.First(d => d.Identifier.ToString() == "b"));

            var parameters        = method.DescendantNodes().OfType <ParameterSyntax>();
            var inParameterSymbol = semanticModel.GetDeclaredSymbol(parameters.First(d => d.Identifier.ToString() == "inParameter"));

            var cfg = ControlFlowGraph.Create(method.Body, semanticModel);
            var lva = LiveVariableAnalysis.Analyze(cfg, methodSymbol, semanticModel);

            var explodedGraph    = new ExplodedGraph(cfg, methodSymbol, semanticModel, lva);
            var explorationEnded = false;

            explodedGraph.ExplorationEnded += (sender, args) => { explorationEnded = true; };

            var numberOfExitBlockReached = 0;

            explodedGraph.ExitBlockReached += (sender, args) => { numberOfExitBlockReached++; };

            var numberOfLastInstructionVisits = 0;
            var numberOfProcessedInstructions = 0;

            var visitedBlocks   = new HashSet <Block>();
            var branchesVisited = 0;

            explodedGraph.InstructionProcessed +=
                (sender, args) =>
            {
                visitedBlocks.Add(args.ProgramPoint.Block);

                numberOfProcessedInstructions++;
                if (args.Instruction.ToString() == "a = false")
                {
                    branchesVisited++;

                    Assert.IsTrue(args.ProgramState.GetSymbolValue(aSymbol) == SymbolicValue.False);     // Roslyn is clever !true has const value.
                }
                if (args.Instruction.ToString() == "b = inParameter")
                {
                    branchesVisited++;

                    Assert.IsTrue(bSymbol.HasConstraint(BoolConstraint.True, args.ProgramState));
                    Assert.IsTrue(inParameterSymbol.HasConstraint(BoolConstraint.True, args.ProgramState));
                }
                if (args.Instruction.ToString() == "b = !inParameter")
                {
                    branchesVisited++;

                    // b has value, but not true or false
                    Assert.IsNotNull(args.ProgramState.GetSymbolValue(bSymbol));
                    Assert.IsFalse(bSymbol.HasConstraint(BoolConstraint.False, args.ProgramState));
                    Assert.IsFalse(bSymbol.HasConstraint(BoolConstraint.True, args.ProgramState));

                    Assert.IsTrue(inParameterSymbol.HasConstraint(BoolConstraint.False, args.ProgramState));
                }
                if (args.Instruction.ToString() == "a = b")
                {
                    branchesVisited++;

                    Assert.IsNull(args.ProgramState.GetSymbolValue(inParameterSymbol));     // not out/ref parameter and LVA says dead
                    numberOfLastInstructionVisits++;
                }
            };

            explodedGraph.Walk();

            Assert.IsTrue(explorationEnded);
            Assert.AreEqual(4 + 1, branchesVisited);
            Assert.AreEqual(1, numberOfExitBlockReached,
                            "All variables are dead at the ExitBlock, so whenever we get there, the ExplodedGraph nodes should be the same, " +
                            "and thus should be processed only once.");
            Assert.AreEqual(2, numberOfLastInstructionVisits);

            Assert.AreEqual(cfg.Blocks.Count() - 1 /* Exit block */, visitedBlocks.Count);
        }
Exemplo n.º 19
0
			public void Analyze()
			{
				var graph = new ControlFlowGraph(m_instructions);		
				Analyze(graph);
			}
Exemplo n.º 20
0
        /// <summary>
        /// Load the text to display
        /// </summary>
        protected override string LoadText(ISpyContext settings)
        {
            var nl = Environment.NewLine;
            var sb = new StringBuilder();
            sb.AppendFormat("AccessFlags: {0}{1}", methodDef.AccessFlags, nl);
            sb.AppendFormat("Prototype:   {0}{1}", methodDef.Prototype, nl);

            var body = methodDef.Body;
            if (body != null)
            {
                var cfg = new ControlFlowGraph(body);
                sb.AppendFormat("#Registers:  {0}{1}", body.Registers.Count, nl);
                sb.AppendFormat("#Incoming:   {0}{1}", body.IncomingArguments, nl);
                sb.AppendFormat("#Outgoing:   {0}{1}", body.OutgoingArguments, nl);
                sb.AppendLine("Code:");
#if DEBUG
                var firstBlock = true;
#endif
                foreach (var block in cfg)
                {
#if DEBUG
                    if (!firstBlock)
                    {
                        sb.AppendLine("\t----------------- ");
                    }
                    sb.AppendFormat("\tEntry [{0}], Exit [{1}]{2}",
                              string.Join(", ", block.EntryBlocks.Select(x => x.Entry.Offset.ToString("x4"))),
                              string.Join(", ", block.ExitBlocks.Select(x => x.Entry.Offset.ToString("x4"))),
                              nl);
                    firstBlock = false;
#endif
                    foreach (var i in block.Instructions)
                    {
                        sb.AppendFormat("\t{0:x4} {1} {2}   {3}{4}", i.Offset, Format(i.OpCode), Register(i), FormatOperand(i.Operand), nl);
                    }
                }
                sb.AppendLine();

                if (body.Exceptions.Any())
                {
                    sb.AppendLine("Exception handlers:");
                    foreach (var handler in body.Exceptions)
                    {
                        sb.AppendFormat("\t{0:x4}-{1:x4}{2}", handler.TryStart.Offset, handler.TryEnd.Offset, nl);
                        foreach (var c in handler.Catches)
                        {
                            sb.AppendFormat("\t\t{0} => {1:x4}{2}", c.Type, c.Instruction.Offset, nl);                            
                        }
                        if (handler.CatchAll != null)
                        {
                            sb.AppendFormat("\t\t{0} => {1:x4}{2}", "<any>", handler.CatchAll.Offset, nl);                                                        
                        }
                    }
                }

                var mapFile = settings.MapFile;
                if (mapFile != null)
                {
                    var typeEntry = mapFile.GetTypeByNewName(methodDef.Owner.Fullname);
                    if (typeEntry != null)
                    {
                        var methodEntry = typeEntry.FindDexMethod(methodDef.Name, methodDef.Prototype.ToSignature());
                        if (methodEntry != null)
                        {
                            var validParameters = methodEntry.Parameters.Where(x => !string.IsNullOrEmpty(x.Name)).ToList();
                            if (validParameters.Any())
                            {
                                sb.AppendLine("Parameters:");
                                foreach (var p in validParameters)
                                {
                                    sb.AppendFormat("\tr{0} -> {1}{2}", p.Register, p.Name, nl);
                                }
                                sb.AppendLine();
                            }

                            var validVariables = methodEntry.Variables.Where(x => !string.IsNullOrEmpty(x.Name)).ToList();
                            if (validVariables.Any())
                            {
                                sb.AppendLine("Variables:");
                                foreach (var p in validVariables)
                                {
                                    sb.AppendFormat("\tr{0} -> {1}{2}", p.Register, p.Name, nl);
                                }
                                sb.AppendLine();
                            }

                            sb.AppendLine("Source code:");
                            Document lastDocument = null;
                            foreach (var row in mapFile.GetLocations(typeEntry, methodEntry))
                            {
                                if (row.Item1 != lastDocument)
                                {
                                    sb.AppendFormat("\t{0}{1}", row.Item1.Path, nl);
                                    lastDocument = row.Item1;
                                }
                                var pos = row.Item2;
                                sb.AppendFormat("\t{0:x4}\t({1},{2}) - ({3},{4}){5}", pos.MethodOffset, pos.Start.Line, pos.Start.Column, pos.End.Line, pos.End.Column, nl);
                            }
                        }
                    }
                }

#if DEBUG
                var debugInfo = body.DebugInfo;
                if (debugInfo != null)
                {
                    sb.AppendLine();
                    sb.AppendLine("DEX Debug info:");
                    sb.AppendFormat("\tStart line: {0}{1}", debugInfo.LineStart, nl);
                    int lineNumber = (int) debugInfo.LineStart;
                    var address = 0;
                    var index = 0;
                    foreach (var ins in debugInfo.DebugInstructions)
                    {
                        if (!ins.IsLowLevel)
                            sb.AppendFormat("\t{0:x4}\tline {1}, address {2:x4} -> {3}{4}", index, lineNumber, address, ins, nl);                        
                        ins.UpdateLineAndAddress(ref lineNumber, ref address);
                        index++;
                    }
                }
#endif
            }

            return sb.ToString();
        }
Exemplo n.º 21
0
		public static string ToString (ControlFlowGraph cfg)
		{
			StringWriter writer = new StringWriter ();
			FormatControlFlowGraph (writer, cfg);
			return writer.ToString ();
		}
Exemplo n.º 22
0
		static void ProcessBlocks(BlockKey[] keys, ControlFlowGraph graph, RandomGenerator random) {
			uint id = 0;
			for (int i = 0; i < keys.Length; i++) {
				keys[i].EntryState = id++;
				keys[i].ExitState = id++;
			}

			var finallyIds = new Dictionary<ExceptionHandler, uint>();
			var ehMap = new Dictionary<ControlFlowBlock, List<ExceptionHandler>>();

			bool updated;
			do {
				updated = false;

				// Update the state ids with the maximum id
				foreach (ControlFlowBlock block in graph) {
					BlockKey key = keys[block.Id];
					if (block.Sources.Count > 0) {
						uint newEntry = block.Sources.Select(b => keys[b.Id].ExitState).Max();
						if (key.EntryState != newEntry) {
							key.EntryState = newEntry;
							updated = true;
						}
					}
					if (block.Targets.Count > 0) {
						uint newExit = block.Targets.Select(b => keys[b.Id].EntryState).Max();
						if (key.ExitState != newExit) {
							key.ExitState = newExit;
							updated = true;
						}
					}
					if (block.Footer.OpCode.Code == Code.Endfilter || block.Footer.OpCode.Code == Code.Endfinally) {
						// Match the exit state within finally/fault/filter
						List<ExceptionHandler> ehs;
						if (!ehMap.TryGetValue(block, out ehs)) {
							ehs = new List<ExceptionHandler>();
							int footerIndex = graph.IndexOf(block.Footer);
							foreach (var eh in graph.Body.ExceptionHandlers) {
								if (eh.FilterStart != null && block.Footer.OpCode.Code == Code.Endfilter) {
									if (footerIndex >= graph.IndexOf(eh.FilterStart) &&
									    footerIndex < graph.IndexOf(eh.HandlerStart))
										ehs.Add(eh);
								}
								else if (eh.HandlerType == ExceptionHandlerType.Finally ||
								         eh.HandlerType == ExceptionHandlerType.Fault) {
									if (footerIndex >= graph.IndexOf(eh.HandlerStart) &&
									    (eh.HandlerEnd == null || footerIndex < graph.IndexOf(eh.HandlerEnd)))
										ehs.Add(eh);
								}
							}
							ehMap[block] = ehs;
						}
						foreach (var eh in ehs) {
							uint ehVal;
							if (finallyIds.TryGetValue(eh, out ehVal)) {
								if (key.ExitState > ehVal) {
									finallyIds[eh] = key.ExitState;
									updated = true;
								}
								else if (key.ExitState < ehVal) {
									key.ExitState = ehVal;
									updated = true;
								}
							}
							else {
								finallyIds[eh] = key.ExitState;
								updated = true;
							}
						}
					}
					else if (block.Footer.OpCode.Code == Code.Leave || block.Footer.OpCode.Code == Code.Leave_S) {
						// Match the exit state with finally/fault/filter
						List<ExceptionHandler> ehs;
						if (!ehMap.TryGetValue(block, out ehs)) {
							ehs = new List<ExceptionHandler>();
							int footerIndex = graph.IndexOf(block.Footer);
							foreach (var eh in graph.Body.ExceptionHandlers) {
								if (footerIndex >= graph.IndexOf(eh.TryStart) &&
								    (eh.TryEnd == null || footerIndex < graph.IndexOf(eh.TryEnd)))
									ehs.Add(eh);
							}
							ehMap[block] = ehs;
						}

						uint? maxVal = null;
						foreach (var eh in ehs) {
							uint ehVal;
							if (finallyIds.TryGetValue(eh, out ehVal) && (maxVal == null || ehVal > maxVal)) {
								if (maxVal != null)
									updated = true;
								maxVal = ehVal;
							}
						}
						if (maxVal != null) {
							if (key.ExitState > maxVal.Value) {
								maxVal = key.ExitState;
								updated = true;
							}
							else if (key.ExitState < maxVal.Value) {
								key.ExitState = maxVal.Value;
								updated = true;
							}
							foreach (var eh in ehs)
								finallyIds[eh] = maxVal.Value;
						}
					}
					keys[block.Id] = key;
				}
			} while (updated);

			if (random != null) {
				// Replace id with actual values
				var idMap = new Dictionary<uint, uint>();
				for (int i = 0; i < keys.Length; i++) {
					BlockKey key = keys[i];

					uint entryId = key.EntryState;
					if (!idMap.TryGetValue(entryId, out key.EntryState))
						key.EntryState = idMap[entryId] = random.NextUInt32();

					uint exitId = key.ExitState;
					if (!idMap.TryGetValue(exitId, out key.ExitState))
						key.ExitState = idMap[exitId] = random.NextUInt32();

					keys[i] = key;
				}
			}
		}
Exemplo n.º 23
0
		static int GetBlockId (ControlFlowGraph cfg, InstructionBlock block)
		{
			return ((IList<InstructionBlock>) cfg.Blocks).IndexOf (block) + 1;
		}
Exemplo n.º 24
0
        public static string Serialize(ControlFlowGraph cfg)
        {
            using (var stringWriter = new StringWriter())
                using (var xmlWriter = new XmlTextWriter(stringWriter))
                {
                    xmlWriter.Formatting = Formatting.Indented;
                    xmlWriter.WriteStartElement("DirectedGraph");
                    xmlWriter.WriteAttributeString("xmlns", "http://schemas.microsoft.com/vs/2009/dgml");
                    xmlWriter.WriteStartElement("Nodes");

                    foreach (var node in cfg.Nodes)
                    {
                        var nodeId = Convert.ToString(node.Id);
                        var label  = DGMLSerializer.Serialize(node);

                        xmlWriter.WriteStartElement("Node");
                        xmlWriter.WriteAttributeString("Id", nodeId);
                        xmlWriter.WriteAttributeString("Label", label);

                        if (node.Kind == CFGNodeKind.Entry ||
                            node.Kind == CFGNodeKind.Exit)
                        {
                            xmlWriter.WriteAttributeString("Background", "Yellow");
                        }

                        xmlWriter.WriteEndElement();
                    }

                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteStartElement("Links");

                    foreach (var node in cfg.Nodes)
                    {
                        var sourceId = Convert.ToString(node.Id);

                        foreach (var successor in node.Successors)
                        {
                            var targetId = Convert.ToString(successor.Id);

                            xmlWriter.WriteStartElement("Link");
                            xmlWriter.WriteAttributeString("Source", sourceId);
                            xmlWriter.WriteAttributeString("Target", targetId);
                            xmlWriter.WriteEndElement();
                        }
                    }

                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteStartElement("Styles");
                    xmlWriter.WriteStartElement("Style");
                    xmlWriter.WriteAttributeString("TargetType", "Node");

                    xmlWriter.WriteStartElement("Setter");
                    xmlWriter.WriteAttributeString("Property", "FontFamily");
                    xmlWriter.WriteAttributeString("Value", "Consolas");
                    xmlWriter.WriteEndElement();

                    xmlWriter.WriteStartElement("Setter");
                    xmlWriter.WriteAttributeString("Property", "NodeRadius");
                    xmlWriter.WriteAttributeString("Value", "5");
                    xmlWriter.WriteEndElement();

                    xmlWriter.WriteStartElement("Setter");
                    xmlWriter.WriteAttributeString("Property", "MinWidth");
                    xmlWriter.WriteAttributeString("Value", "0");
                    xmlWriter.WriteEndElement();

                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteEndElement();
                    xmlWriter.WriteEndElement();
                    xmlWriter.Flush();
                    return(stringWriter.ToString());
                }
        }
Exemplo n.º 25
0
        private void Test(ControlFlowGraph graph, params string[] lines)
        {
            var sequences = graph.DeriveSequences();
            Print(sequences);

            var spec = new TestSpec();
            foreach (var line in lines) {
                spec.ReadLine(line);
            }

            spec.Test(graph, sequences);
        }
Exemplo n.º 26
0
 public TypeInferenceAnalysis(ControlFlowGraph cfg, ITypeReference returnType)
 {
     this.cfg        = cfg;
     this.returnType = returnType;
     fixptCount      = 0;
 }
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                compilationContext.RegisterOperationBlockStartAction(operationBlockStartContext =>
                {
                    if (!(operationBlockStartContext.OwningSymbol is IMethodSymbol containingMethod))
                    {
                        return;
                    }

                    foreach (var operationRoot in operationBlockStartContext.OperationBlocks)
                    {
                        IBlockOperation topmostBlock = operationRoot.GetTopmostParentBlock();
                        if (topmostBlock != null && topmostBlock.HasAnyOperationDescendant(op => (op as IBinaryOperation)?.IsComparisonOperator() == true || op.Kind == OperationKind.Coalesce || op.Kind == OperationKind.ConditionalAccess))
                        {
                            var cfg = ControlFlowGraph.Create(topmostBlock);
                            var wellKnownTypeProvider  = WellKnownTypeProvider.GetOrCreate(operationBlockStartContext.Compilation);
                            var nullAnalysisResult     = NullAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider);
                            var pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, nullAnalysisResult);
                            var copyAnalysisResult     = CopyAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, nullAnalysisResultOpt: nullAnalysisResult, pointsToAnalysisResultOpt: pointsToAnalysisResult);
                            // Do another null analysis pass to improve the results from PointsTo and Copy analysis.
                            nullAnalysisResult = NullAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, copyAnalysisResult, pointsToAnalysisResultOpt: pointsToAnalysisResult);
                            var stringContentAnalysisResult = StringContentAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, copyAnalysisResult, nullAnalysisResult, pointsToAnalysisResult);

                            operationBlockStartContext.RegisterOperationAction(operationContext =>
                            {
                                PredicateValueKind GetPredicateKind(IBinaryOperation operation)
                                {
                                    if (operation.IsComparisonOperator())
                                    {
                                        PredicateValueKind binaryPredicateKind = nullAnalysisResult.GetPredicateKind(operation);
                                        if (binaryPredicateKind != PredicateValueKind.Unknown)
                                        {
                                            return(binaryPredicateKind);
                                        }

                                        binaryPredicateKind = copyAnalysisResult.GetPredicateKind(operation);
                                        if (binaryPredicateKind != PredicateValueKind.Unknown)
                                        {
                                            return(binaryPredicateKind);
                                        }

                                        binaryPredicateKind = stringContentAnalysisResult.GetPredicateKind(operation);
                                        if (binaryPredicateKind != PredicateValueKind.Unknown)
                                        {
                                            return(binaryPredicateKind);
                                        }
                                        ;
                                    }

                                    return(PredicateValueKind.Unknown);
                                }

                                var binaryOperation = (IBinaryOperation)operationContext.Operation;
                                PredicateValueKind predicateKind = GetPredicateKind(binaryOperation);
                                if (predicateKind != PredicateValueKind.Unknown &&
                                    (!(binaryOperation.LeftOperand is IBinaryOperation leftBinary) || GetPredicateKind(leftBinary) == PredicateValueKind.Unknown) &&
                                    (!(binaryOperation.RightOperand is IBinaryOperation rightBinary) || GetPredicateKind(rightBinary) == PredicateValueKind.Unknown))
                                {
                                    // '{0}' is always '{1}'. Remove or refactor the condition(s) to avoid dead code.
                                    var arg1 = binaryOperation.Syntax.ToString();
                                    var arg2 = predicateKind == PredicateValueKind.AlwaysTrue ?
                                               (binaryOperation.Language == LanguageNames.VisualBasic ? "True" : "true") :
                                               (binaryOperation.Language == LanguageNames.VisualBasic ? "False" : "false");
                                    var diagnostic = binaryOperation.CreateDiagnostic(AlwaysTrueFalseOrNullRule, arg1, arg2);
                                    operationContext.ReportDiagnostic(diagnostic);
                                }
                            }, OperationKind.BinaryOperator);

                            operationBlockStartContext.RegisterOperationAction(operationContext =>
                            {
                                IOperation nullCheckedOperation = operationContext.Operation.Kind == OperationKind.Coalesce ?
                                                                  ((ICoalesceOperation)operationContext.Operation).Value :
                                                                  ((IConditionalAccessOperation)operationContext.Operation).Operation;

                                // '{0}' is always/never '{1}'. Remove or refactor the condition(s) to avoid dead code.
                                DiagnosticDescriptor rule;
                                switch (nullAnalysisResult[nullCheckedOperation])
                                {
                                case NullAbstractValue.Null:
                                    rule = AlwaysTrueFalseOrNullRule;
                                    break;

                                case NullAbstractValue.NotNull:
                                    rule = NeverNullRule;
                                    break;

                                default:
                                    return;
                                }

                                var arg1       = nullCheckedOperation.Syntax.ToString();
                                var arg2       = nullCheckedOperation.Language == LanguageNames.VisualBasic ? "Nothing" : "null";
                                var diagnostic = nullCheckedOperation.CreateDiagnostic(rule, arg1, arg2);
                                operationContext.ReportDiagnostic(diagnostic);
                            }, OperationKind.Coalesce, OperationKind.ConditionalAccess);
                        }
                    }
                });
            });
        }
 public Analyzer(ControlFlowGraph cfg, string loopIndex) : base(cfg)
 {
     ExtremalValues = _CreateExtremalValues(cfg, loopIndex);
 }
Exemplo n.º 29
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> >(_architecture);
            var rootScope = _controlFlowGraph.ConstructBlocks();

            // 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 = _transformer.Transform(originalBlock);
                var newNode          = new ControlFlowNode <Statement <TInstruction> >(originalBlock.Offset, transformedBlock);
                newGraph.Nodes.Add(newNode);

                // Move node to newly created region.
                if (originalNode.ParentRegion is ScopeRegion <TInstruction> basicRegion)
                {
                    newNode.MoveToRegion(_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(s).
            newGraph.Entrypoint = newGraph.Nodes[_controlFlowGraph.Entrypoint.Offset];
            FixEntryPoint(_controlFlowGraph);

            return(newGraph);

            void FixEntryPoint(IControlFlowRegion <TInstruction> region)
            {
                foreach (var child in region.GetSubRegions())
                {
                    FixEntryPoint(child);
                }

                if (!(region is ScopeRegion <TInstruction> basicControlFlowRegion))
                {
                    return;
                }

                var entry = basicControlFlowRegion.Entrypoint;

                if (entry is null)
                {
                    return;
                }

                _regionsMapping[basicControlFlowRegion].Entrypoint = newGraph.Nodes[entry.Offset];
            }
        }
Exemplo n.º 30
0
        private List<Conditional> TestConditionals(ControlFlowGraph graph, params string[] args)
        {
            graph.SortByDepthFirstPostOrder();

            graph.StructureLoops();
            var conditionals = graph.StructureConditionals();

            const string fmt = "{0}: {1}";
            var lines = conditionals.Select((x, i) => {
                var str = string.Format(fmt, i, x);
                Console.WriteLine(str);
                return str;
            }).ToArray();

            Assert.AreEqual(conditionals.Count, args.Length);

            for (int i = 0; i < args.Length; i++) {
                var expected = args[i];
                var actual = lines[i];
                Assert.AreEqual(expected, actual);
            }

            return conditionals;
        }
 public Analyzer(ControlFlowGraph cfg) : base(cfg)
 {
 }
Exemplo n.º 32
0
 public BlockGenerator(ControlFlowGraph cfg, CilCodeGenerator generator)
 {
     _cfg       = cfg ?? throw new ArgumentNullException(nameof(cfg));
     _generator = generator;
 }
Exemplo n.º 33
0
        public ZCompilerResult Compile()
        {
            var sw = Stopwatch.StartNew();

            var dm = CreateDynamicMethod(routine);

            this.il = new ILBuilder(dm.GetILGenerator());

            this.calls = new List <ZRoutineCall>();

            Profiler_EnterRoutine();

            this.controlFlowGraph  = ControlFlowGraph.Build(this.routine);
            this.addressToLabelMap = new Dictionary <int, ILabel>(this.controlFlowGraph.CodeBlocks.Count());

            // Determine whether stack, memory, screen and outputStreams are used.
            foreach (var codeBlock in this.controlFlowGraph.CodeBlocks)
            {
                this.addressToLabelMap.Add(codeBlock.Address, il.NewLabel());

                foreach (var i in codeBlock.Instructions)
                {
                    if (!this.usesStack && i.UsesStack())
                    {
                        this.usesStack = true;
                    }

                    if (!this.usesMemory && i.UsesMemory())
                    {
                        this.usesMemory = true;
                    }
                }
            }

            var instructionStatistics = new List <InstructionStatistics>(this.routine.Instructions.Length);

            // Emit IL
            foreach (var codeBlock in this.controlFlowGraph.CodeBlocks)
            {
                var generators = codeBlock.Instructions
                                 .Select(i => OpcodeGenerator.GetGenerator(i, machine.Version))
                                 .ToList();

                Optimize(generators);

                foreach (var generator in generators)
                {
                    ILabel label;
                    if (this.addressToLabelMap.TryGetValue(generator.Instruction.Address, out label))
                    {
                        label.Mark();
                    }

                    if (machine.Debugging)
                    {
                        il.Arguments.LoadMachine();
                        il.Call(Reflection <CompiledZMachine> .GetMethod("Tick", @public: false));
                    }

                    Profiler_ExecutingInstruction(generator.Instruction);
                    il.DebugWrite(generator.Instruction.PrettyPrint(machine));

                    var offset = il.Size;

                    generator.Generate(il, this);

                    instructionStatistics.Add(new InstructionStatistics(generator.Instruction, offset, il.Size - offset));
                }
            }

            var code = (ZRoutineCode)dm.CreateDelegate(typeof(ZRoutineCode), machine);

            sw.Stop();

            var statistics = new RoutineCompilationStatistics(
                this.routine,
                il.OpcodeCount,
                il.LocalCount,
                il.Size,
                sw.Elapsed,
                calculatedLoadVariableCount,
                calculatedStoreVariableCount,
                instructionStatistics);

            return(new ZCompilerResult(this.routine, calls.ToArray(), code, statistics));
        }
Exemplo n.º 34
0
        public override void Initialize(AnalysisContext context)
        {
            context.EnableConcurrentExecution();
            context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.None);

            context.RegisterCompilationStartAction(compilationContext =>
            {
                INamedTypeSymbol localizableStateAttributeSymbol  = WellKnownTypes.LocalizableAttribute(compilationContext.Compilation);
                INamedTypeSymbol conditionalAttributeSymbol       = WellKnownTypes.ConditionalAttribute(compilationContext.Compilation);
                INamedTypeSymbol systemConsoleSymbol              = WellKnownTypes.Console(compilationContext.Compilation);
                ImmutableHashSet <INamedTypeSymbol> typesToIgnore = GetTypesToIgnore(compilationContext.Compilation);

                compilationContext.RegisterOperationBlockStartAction(operationBlockStartContext =>
                {
                    if (!(operationBlockStartContext.OwningSymbol is IMethodSymbol containingMethod))
                    {
                        return;
                    }

                    var lazyStringContentResult = new Lazy <DataFlowAnalysisResult <StringContentBlockAnalysisResult, StringContentAbstractValue> >(
                        valueFactory: ComputeStringContentAnalysisResult, isThreadSafe: false);

                    operationBlockStartContext.RegisterOperationAction(operationContext =>
                    {
                        var argument = (IArgumentOperation)operationContext.Operation;
                        switch (argument.Parent?.Kind)
                        {
                        case OperationKind.Invocation:
                        case OperationKind.ObjectCreation:
                            AnalyzeArgument(argument.Parameter, containingPropertySymbolOpt: null, operation: argument, reportDiagnostic: operationContext.ReportDiagnostic);
                            return;
                        }
                    }, OperationKind.Argument);

                    operationBlockStartContext.RegisterOperationAction(operationContext =>
                    {
                        var propertyReference = (IPropertyReferenceOperation)operationContext.Operation;
                        if (propertyReference.Parent is IAssignmentOperation assignment &&
                            assignment.Target == propertyReference &&
                            !propertyReference.Property.IsIndexer &&
                            propertyReference.Property.SetMethod?.Parameters.Length == 1)
                        {
                            IParameterSymbol valueSetterParam = propertyReference.Property.SetMethod.Parameters[0];
                            AnalyzeArgument(valueSetterParam, propertyReference.Property, assignment, operationContext.ReportDiagnostic);
                        }
                    }, OperationKind.PropertyReference);

                    void AnalyzeArgument(IParameterSymbol parameter, IPropertySymbol containingPropertySymbolOpt, IOperation operation, Action <Diagnostic> reportDiagnostic)
                    {
                        if (ShouldBeLocalized(parameter, containingPropertySymbolOpt, localizableStateAttributeSymbol, conditionalAttributeSymbol, systemConsoleSymbol, typesToIgnore))
                        {
                            StringContentAbstractValue stringContentValue = lazyStringContentResult.Value[operation];
                            if (stringContentValue.IsLiteralState)
                            {
                                Debug.Assert(stringContentValue.LiteralValues.Count > 0);

                                // FxCop compat: Do not fire if the literal value came from a default parameter value
                                if (stringContentValue.LiteralValues.Count == 1 &&
                                    parameter.IsOptional &&
                                    parameter.ExplicitDefaultValue is string defaultValue &&
                                    defaultValue == stringContentValue.LiteralValues.Single())
                                {
                                    return;
                                }

                                // FxCop compat: Do not fire if none of the string literals have any non-control character.
                                if (!LiteralValuesHaveNonControlCharacters(stringContentValue.LiteralValues))
                                {
                                    return;
                                }

                                // FxCop compat: Filter out xml string literals.
                                var filteredStrings = stringContentValue.LiteralValues.Where(literal => !LooksLikeXmlTag(literal));
                                if (filteredStrings.Any())
                                {
                                    // Method '{0}' passes a literal string as parameter '{1}' of a call to '{2}'. Retrieve the following string(s) from a resource table instead: "{3}".
                                    var arg1       = containingMethod.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
                                    var arg2       = parameter.Name;
                                    var arg3       = parameter.ContainingSymbol.ToDisplayString(SymbolDisplayFormat.MinimallyQualifiedFormat);
                                    var arg4       = FormatLiteralValues(filteredStrings);
                                    var diagnostic = operation.CreateDiagnostic(Rule, arg1, arg2, arg3, arg4);
                                    reportDiagnostic(diagnostic);
                                }
                            }
                        }
                    }

                    DataFlowAnalysisResult <StringContentBlockAnalysisResult, StringContentAbstractValue> ComputeStringContentAnalysisResult()
                    {
                        foreach (var operationRoot in operationBlockStartContext.OperationBlocks)
                        {
                            IBlockOperation topmostBlock = operationRoot.GetTopmostParentBlock();
                            if (topmostBlock != null)
                            {
                                var cfg = ControlFlowGraph.Create(topmostBlock);
                                var wellKnownTypeProvider  = WellKnownTypeProvider.GetOrCreate(operationBlockStartContext.Compilation);
                                var pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider);
                                var copyAnalysisResult     = CopyAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, pointsToAnalysisResultOpt: pointsToAnalysisResult);
                                // Do another analysis pass to improve the results from PointsTo and Copy analysis.
                                pointsToAnalysisResult = PointsToAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, pointsToAnalysisResult, copyAnalysisResult);
                                return(StringContentAnalysis.GetOrComputeResult(cfg, containingMethod, wellKnownTypeProvider, copyAnalysisResult, pointsToAnalysisResult));
                            }
                        }

                        return(null);
                    }
                });
            });
        }
Exemplo n.º 35
0
        /// <summary>
        /// Creates a new Ast parser with the given <see cref="ControlFlowGraph{TInstruction}"/>
        /// </summary>
        /// <param name="controlFlowGraph">The <see cref="ControlFlowGraph{TInstruction}"/> to parse</param>
        /// <param name="dataFlowGraph">The <see cref="DataFlowGraph{TContents}"/> to parse</param>
        public AstParser(ControlFlowGraph <TInstruction> controlFlowGraph, DataFlowGraph <TInstruction> dataFlowGraph)
        {
            var isa = new AstArchitecture <TInstruction>(controlFlowGraph.Architecture);

            _context = new AstParserContext <TInstruction>(controlFlowGraph, dataFlowGraph, isa);
        }
Exemplo n.º 36
0
        public static void Main()
        {
            var FileName = @"../../a.txt";

            try
            {
                var Text = File.ReadAllText(FileName);

                var scanner = new Scanner();
                scanner.SetSource(Text, 0);

                var parser = new Parser(scanner);

                var b = parser.Parse();
                if (!b)
                {
                    Console.WriteLine("Error");
                }
                else
                {
                    Console.WriteLine("Syntax tree built");

                    var fillParents = new FillParentsVisitor();
                    parser.root.Visit(fillParents);

                    var pp = new PrettyPrintVisitor();
                    parser.root.Visit(pp);
                    Console.WriteLine(pp.Text);

                    ASTOptimizer.Optimize(parser);
                    Console.WriteLine("\n\nAfter AST optimizations");
                    pp = new PrettyPrintVisitor();
                    parser.root.Visit(pp);
                    Console.WriteLine(pp.Text);

                    Console.WriteLine("\n\nThree address code");
                    var threeAddrCodeVisitor = new ThreeAddrGenVisitor();
                    parser.root.Visit(threeAddrCodeVisitor);
                    var threeAddressCode = threeAddrCodeVisitor.Instructions;
                    foreach (var instruction in threeAddressCode)
                    {
                        Console.WriteLine(instruction);
                    }

                    Console.WriteLine("\n\nOptimized three address code");
                    var optResult = ThreeAddressCodeOptimizer.OptimizeAll(threeAddressCode);
                    foreach (var x in optResult)
                    {
                        Console.WriteLine(x);
                    }

                    Console.WriteLine("\n\nDivided three address code");
                    var divResult = BasicBlockLeader.DivideLeaderToLeader(optResult);


                    foreach (var x in divResult)
                    {
                        foreach (var y in x.GetInstructions())
                        {
                            Console.WriteLine(y);
                        }
                        Console.WriteLine("--------------");
                    }

                    var cfg = new ControlFlowGraph(divResult);

                    Console.WriteLine("\n\n Edge Classification");
                    Console.WriteLine("----------");

                    foreach (var pair in cfg.ClassifiedEdges)
                    {
                        Console.WriteLine(pair);
                    }

                    Console.WriteLine("----------");


                    foreach (var block in cfg.GetCurrentBasicBlocks())
                    {
                        Console.WriteLine($"{cfg.VertexOf(block)}  {block.GetInstructions().First()}");
                        var children    = cfg.GetChildrenBasicBlocks(cfg.VertexOf(block));
                        var childrenStr = string.Join(" | ", children.Select(v => v.block.GetInstructions().First().ToString()));
                        Console.WriteLine($" children: {childrenStr}");

                        var parents    = cfg.GetParentsBasicBlocks(cfg.VertexOf(block));
                        var parentsStr = string.Join(" | ", parents.Select(v => v.block.GetInstructions().First().ToString()));
                        Console.WriteLine($" parents: {parentsStr}");
                    }

                    ///
                    /// LiveVariableAnalysisAlgorithm
                    ///
                    Console.WriteLine("------------");
                    Console.WriteLine();
                    var activeVariable    = new LiveVariables();
                    var resActiveVariable = activeVariable.Execute(cfg);

                    foreach (var x in resActiveVariable)
                    {
                        foreach (var y in x.Value.In)
                        {
                            Console.WriteLine("In " + y);
                        }
                        Console.WriteLine();
                        foreach (var y in x.Value.Out)
                        {
                            Console.WriteLine("Out " + y);
                        }
                    }


                    Console.WriteLine();
                    Console.WriteLine();
                    Console.WriteLine("NatLoop");
                    var natLoops = NaturalLoop.GetAllNaturalLoops(cfg);
                    foreach (var x in natLoops)
                    {
                        if (x.Count == 0)
                        {
                            continue;
                        }
                        //Console.WriteLine("Loop");
                        for (var i = 0; i < x.Count; i++)
                        {
                            Console.WriteLine("NumberBlock:" + i);
                            foreach (var xfrom in x[i].GetInstructions())
                            {
                                Console.WriteLine(xfrom.ToString());
                            }
                        }
                        Console.WriteLine();
                        Console.WriteLine("-------------");
                    }

                    Console.WriteLine(" \nDone");
                }
            }
            catch (FileNotFoundException)
            {
                Console.WriteLine("File {0} not found", FileName);
            }
            catch (LexException e)
            {
                Console.WriteLine("Lex Error. " + e.Message);
            }
            catch (SyntaxException e)
            {
                Console.WriteLine("Syntax Error. " + e.Message);
            }
            Console.ReadLine();
        }
 public Analyzer(ControlFlowGraph cfg, string loopIndex, CallGraph callGraph, IEnumerable <ControlFlowGraph> procedures) : base(cfg, callGraph, procedures)
 {
     ExtremalValues = _CreateExtremalValues(cfg, loopIndex);
 }
 private void InitializeReachabilityInfo(ControlFlowGraph x)
 {
     _visitedColor = x.NewColor();
 }
Exemplo n.º 39
0
        private static TaintedDataAnalysisResult?TryGetOrComputeResult(
            ControlFlowGraph cfg,
            Compilation compilation,
            ISymbol containingMethod,
            AnalyzerOptions analyzerOptions,
            TaintedDataSymbolMap <SourceInfo> taintedSourceInfos,
            TaintedDataSymbolMap <SanitizerInfo> taintedSanitizerInfos,
            TaintedDataSymbolMap <SinkInfo> taintedSinkInfos,
            InterproceduralAnalysisConfiguration interproceduralAnalysisConfig)
        {
            if (cfg == null)
            {
                Debug.Fail("Expected non-null CFG");
                return(null);
            }

            WellKnownTypeProvider      wellKnownTypeProvider      = WellKnownTypeProvider.GetOrCreate(compilation);
            ValueContentAnalysisResult?valueContentAnalysisResult = null;
            CopyAnalysisResult?        copyAnalysisResult         = null;
            PointsToAnalysisResult?    pointsToAnalysisResult     = null;

            if (taintedSourceInfos.RequiresValueContentAnalysis || taintedSanitizerInfos.RequiresValueContentAnalysis || taintedSinkInfos.RequiresValueContentAnalysis)
            {
                valueContentAnalysisResult = ValueContentAnalysis.TryGetOrComputeResult(
                    cfg,
                    containingMethod,
                    analyzerOptions,
                    wellKnownTypeProvider,
                    PointsToAnalysisKind.Complete,
                    interproceduralAnalysisConfig,
                    out copyAnalysisResult,
                    out pointsToAnalysisResult,
                    pessimisticAnalysis: true,
                    performCopyAnalysis: false);
                if (valueContentAnalysisResult == null)
                {
                    return(null);
                }
            }
            else
            {
                pointsToAnalysisResult = PointsToAnalysis.TryGetOrComputeResult(
                    cfg,
                    containingMethod,
                    analyzerOptions,
                    wellKnownTypeProvider,
                    PointsToAnalysisKind.Complete,
                    interproceduralAnalysisConfig,
                    interproceduralAnalysisPredicate: null,
                    pessimisticAnalysis: true,
                    performCopyAnalysis: false);
                if (pointsToAnalysisResult == null)
                {
                    return(null);
                }
            }

            TaintedDataAnalysisContext analysisContext = TaintedDataAnalysisContext.Create(
                TaintedDataAbstractValueDomain.Default,
                wellKnownTypeProvider,
                cfg,
                containingMethod,
                analyzerOptions,
                interproceduralAnalysisConfig,
                pessimisticAnalysis: false,
                copyAnalysisResult: copyAnalysisResult,
                pointsToAnalysisResult: pointsToAnalysisResult,
                valueContentAnalysisResult: valueContentAnalysisResult,
                tryGetOrComputeAnalysisResult: TryGetOrComputeResultForAnalysisContext,
                taintedSourceInfos: taintedSourceInfos,
                taintedSanitizerInfos: taintedSanitizerInfos,
                taintedSinkInfos: taintedSinkInfos);

            return(TryGetOrComputeResultForAnalysisContext(analysisContext));
        }
Exemplo n.º 40
0
    public static (ControlFlowGraph, string) Decompile(ControlFlowGraph graph)
    {
        if (graph == null)
        {
            throw new ArgumentNullException(nameof(graph));
        }
        foreach (var head in graph.GetDfsPostOrder())
        {
            var(trueChild, falseChild) = graph.GetBinaryChildren(head);
            if (!trueChild.HasValue || !falseChild.HasValue)
            {
                continue;
            }

            var left  = trueChild.Value;
            var right = falseChild.Value;
            // Func<string> vis = () => graph.ToVis().AddPointer("head", head).AddPointer("after", after).AddPointer("left", left).AddPointer("right", right).ToString(); // For VS Code debug visualisation

            var leftParents   = graph.Parents(left);
            var rightParents  = graph.Parents(right);
            var leftChildren  = graph.Children(left);
            var rightChildren = graph.Children(right);

            if (leftParents.Length != 1 || rightParents.Length != 1) // Branches of an if can't be jump destinations from elsewhere
            {
                continue;
            }

            bool isRegularIfThenElse =
                leftChildren.Length == 1 && rightChildren.Length == 1 &&
                leftChildren[0] == rightChildren[0];

            bool isTerminalIfThenElse = leftChildren.Length == 0 && rightChildren.Length == 0;

            if (!isRegularIfThenElse && !isTerminalIfThenElse)
            {
                continue;
            }

            var after = isRegularIfThenElse ? leftChildren[0] : -1;

            if (after == head)
            {
                continue;
            }

            var newNode = Emit.IfElse(
                graph.Nodes[head],
                graph.Nodes[left],
                graph.Nodes[right]);

            var updated = graph;
            if (isRegularIfThenElse)
            {
                updated = updated.AddEdge(head, after, CfgEdge.True);
            }

            return(updated
                   .RemoveNode(left)
                   .RemoveNode(right)
                   .ReplaceNode(head, newNode), Description);
        }

        return(graph, null);
    }
Exemplo n.º 41
0
 protected AnnotationStoreBuilder(ControlFlowGraph cfg)
 {
     this.cfg   = cfg;
     this.store = new AnnotationStore();
 }
        /// <summary>
        /// Analyzers should use BatchGetOrComputeHazardousUsages instead. Gets hazardous usages of an object based on a set of its properties.
        /// </summary>
        /// <param name="cfg">Control flow graph of the code.</param>
        /// <param name="compilation">Compilation containing the code.</param>
        /// <param name="owningSymbol">Symbol of the code to examine.</param>
        /// <param name="typeToTrackMetadataNames">Names of the types to track.</param>
        /// <param name="constructorMapper">How constructor invocations map to <see cref="PropertySetAbstractValueKind"/>s.</param>
        /// <param name="propertyMappers">How property assignments map to <see cref="PropertySetAbstractValueKind"/>.</param>
        /// <param name="hazardousUsageEvaluators">When and how to evaluate <see cref="PropertySetAbstractValueKind"/>s to for hazardous usages.</param>
        /// <param name="interproceduralAnalysisConfig">Interprocedural dataflow analysis configuration.</param>
        /// <param name="pessimisticAnalysis">Whether to be pessimistic.</param>
        /// <returns>Property set analysis result.</returns>
        internal static PropertySetAnalysisResult?GetOrComputeResult(
            ControlFlowGraph cfg,
            Compilation compilation,
            ISymbol owningSymbol,
            AnalyzerOptions analyzerOptions,
            ImmutableHashSet <string> typeToTrackMetadataNames,
            ConstructorMapper constructorMapper,
            PropertyMapperCollection propertyMappers,
            HazardousUsageEvaluatorCollection hazardousUsageEvaluators,
            InterproceduralAnalysisConfiguration interproceduralAnalysisConfig,
            bool pessimisticAnalysis = false)
        {
            if (constructorMapper == null)
            {
                throw new ArgumentNullException(nameof(constructorMapper));
            }

            if (propertyMappers == null)
            {
                throw new ArgumentNullException(nameof(propertyMappers));
            }

            if (hazardousUsageEvaluators == null)
            {
                throw new ArgumentNullException(nameof(hazardousUsageEvaluators));
            }

            constructorMapper.Validate(propertyMappers.PropertyValuesCount);

            var wellKnownTypeProvider = WellKnownTypeProvider.GetOrCreate(compilation);

            PointsToAnalysisResult?    pointsToAnalysisResult;
            ValueContentAnalysisResult?valueContentAnalysisResultOpt;

            if (!constructorMapper.RequiresValueContentAnalysis && !propertyMappers.RequiresValueContentAnalysis)
            {
                pointsToAnalysisResult = PointsToAnalysis.TryGetOrComputeResult(
                    cfg,
                    owningSymbol,
                    analyzerOptions,
                    wellKnownTypeProvider,
                    PointsToAnalysisKind.Complete,
                    interproceduralAnalysisConfig,
                    interproceduralAnalysisPredicateOpt: null,
                    pessimisticAnalysis,
                    performCopyAnalysis: false);
                if (pointsToAnalysisResult == null)
                {
                    return(null);
                }

                valueContentAnalysisResultOpt = null;
            }
            else
            {
                valueContentAnalysisResultOpt = ValueContentAnalysis.TryGetOrComputeResult(
                    cfg,
                    owningSymbol,
                    analyzerOptions,
                    wellKnownTypeProvider,
                    PointsToAnalysisKind.Complete,
                    interproceduralAnalysisConfig,
                    out var copyAnalysisResult,
                    out pointsToAnalysisResult,
                    pessimisticAnalysis,
                    performCopyAnalysis: false);
                if (valueContentAnalysisResultOpt == null)
                {
                    return(null);
                }
            }

            var analysisContext = PropertySetAnalysisContext.Create(
                PropertySetAbstractValueDomain.Default,
                wellKnownTypeProvider,
                cfg,
                owningSymbol,
                analyzerOptions,
                interproceduralAnalysisConfig,
                pessimisticAnalysis,
                pointsToAnalysisResult,
                valueContentAnalysisResultOpt,
                TryGetOrComputeResultForAnalysisContext,
                typeToTrackMetadataNames,
                constructorMapper,
                propertyMappers,
                hazardousUsageEvaluators);
            var result = TryGetOrComputeResultForAnalysisContext(analysisContext);

            return(result);
        }
        /// <summary>
        /// Transform the given body.
        /// </summary>
        public bool Transform(Dex target, MethodBody body)
        {
            // Build the control flow graph
            var cfg = new ControlFlowGraph(body);

            // Go over each block to find registers that are initialized and may need initialization
            foreach (var iterator in cfg)
            {
                var block = iterator;
                var data = new BasicBlockData(block);
                block.Tag = data;

                // Go over all instructions in the block, finding source/destination registers
                foreach (var ins in block.Instructions)
                {
                    var info = OpCodeInfo.Get(ins.Code.ToDex());
                    var count = ins.Registers.Count;
                    for (var i = 0; i < count; i++)
                    {
                        var reg = ins.Registers[i];
                        if (reg.Category != RCategory.Argument)
                        {
                            var flags = info.GetUsage(i);
                            if (flags.HasFlag(RegisterFlags.Source))
                            {
                                // Must be initialize
                                if (!data.Initialized.Contains(reg))
                                {
                                    data.MayNeedInitialization.Add(reg);
                                }
                            }
                            if (flags.HasFlag(RegisterFlags.Destination))
                            {
                                // Destination
                                data.Initialized.Add(reg);
                            }
                        }
                    }
                }

            }

            // Go over all blocks to collect the register that really need initialization
            var needInitialization = new HashSet<Register>();
            foreach (var iterator in cfg)
            {
                var block = iterator;
                var data = (BasicBlockData)block.Tag;

                foreach (var regIterator in data.MayNeedInitialization)
                {
                    // Short cut
                    var reg = regIterator;
                    if (needInitialization.Contains(reg))
                        continue;

                    // If the register is initialized in all entry blocks, we do not need to initialize it
                    if (block.EntryBlocks.Select(x => (BasicBlockData) x.Tag).Any(x => !x.IsInitialized(reg)))
                    {
                        // There is an entry block that does not initialize the register, so we have to initialize it
                        needInitialization.Add(reg);
                    }
                }
            }

            var index = 0;
            Register valueReg = null;
            Register objectReg = null;
            Register wideReg = null;
            var firstSourceLocation = body.Instructions[0].SequencePoint;
            foreach (var reg in needInitialization.OrderBy(x => x.Index))
            {
                switch (reg.Type)
                {
                    case RType.Value:
                        if (valueReg == null)
                        {
                            body.Instructions.Insert(index++, new Instruction(RCode.Const, 0, new[] {reg}) { SequencePoint = firstSourceLocation });
                            valueReg = reg;
                        }
                        else if (valueReg != reg)
                        {
                            body.Instructions.Insert(index++, new Instruction(RCode.Move, reg, valueReg) { SequencePoint = firstSourceLocation });                            
                        }
                        break;
                    case RType.Object:
                        if (objectReg == null)
                        {
                            body.Instructions.Insert(index++, new Instruction(RCode.Const, 0, new[] { reg }) { SequencePoint = firstSourceLocation });
                            objectReg = reg;
                        }
                        else if (objectReg != reg)
                        {
                            body.Instructions.Insert(index++, new Instruction(RCode.Move_object, reg, objectReg) { SequencePoint = firstSourceLocation });
                        }
                        break;
                    case RType.Wide:
                        if (wideReg == null)
                        {
                            body.Instructions.Insert(index++, new Instruction(RCode.Const_wide, 0, new[] { reg }) { SequencePoint = firstSourceLocation });
                            wideReg = reg;
                        }
                        else if (wideReg != reg)
                        {
                            body.Instructions.Insert(index++, new Instruction(RCode.Move_wide, reg, wideReg) { SequencePoint = firstSourceLocation });
                        }
                        break;
                }
            }

            return false;
        }
Exemplo n.º 44
0
        public static void RestorePopRanges(ControlFlowGraph graph)
        {
            List <ExceptionDeobfuscator.Range> lstRanges = new List <ExceptionDeobfuscator.Range
                                                                     >();

            // aggregate ranges
            foreach (ExceptionRangeCFG range in graph.GetExceptions())
            {
                bool found = false;
                foreach (ExceptionDeobfuscator.Range arr in lstRanges)
                {
                    if (arr.handler == range.GetHandler() && InterpreterUtil.EqualObjects(range.GetUniqueExceptionsString
                                                                                              (), arr.uniqueStr))
                    {
                        Sharpen.Collections.AddAll(arr.protectedRange, range.GetProtectedRange());
                        found = true;
                        break;
                    }
                }
                if (!found)
                {
                    // doesn't matter, which range chosen
                    lstRanges.Add(new ExceptionDeobfuscator.Range(range.GetHandler(), range.GetUniqueExceptionsString
                                                                      (), new HashSet <BasicBlock>(range.GetProtectedRange()), range));
                }
            }
            // process aggregated ranges
            foreach (ExceptionDeobfuscator.Range range in lstRanges)
            {
                if (range.uniqueStr != null)
                {
                    BasicBlock          handler = range.handler;
                    InstructionSequence seq     = handler.GetSeq();
                    Instruction         firstinstr;
                    if (seq.Length() > 0)
                    {
                        firstinstr = seq.GetInstr(0);
                        if (firstinstr.opcode == ICodeConstants.opc_pop || firstinstr.opcode == ICodeConstants
                            .opc_astore)
                        {
                            HashSet <BasicBlock> setrange = new HashSet <BasicBlock>(range.protectedRange);
                            foreach (ExceptionDeobfuscator.Range range_super in lstRanges)
                            {
                                // finally or strict superset
                                if (range != range_super)
                                {
                                    HashSet <BasicBlock> setrange_super = new HashSet <BasicBlock>(range_super.protectedRange
                                                                                                   );
                                    if (!setrange.Contains(range_super.handler) && !setrange_super.Contains(handler) &&
                                        (range_super.uniqueStr == null || setrange.All(setrange_super.Contains)))
                                    {
                                        if (range_super.uniqueStr == null)
                                        {
                                            setrange_super.IntersectWith(setrange);
                                        }
                                        else
                                        {
                                            setrange_super.ExceptWith(setrange);
                                        }
                                        if (!(setrange_super.Count == 0))
                                        {
                                            BasicBlock newblock = handler;
                                            // split the handler
                                            if (seq.Length() > 1)
                                            {
                                                newblock = new BasicBlock(++graph.last_id);
                                                InstructionSequence newseq = new SimpleInstructionSequence();
                                                newseq.AddInstruction(firstinstr.Clone(), -1);
                                                newblock.SetSeq(newseq);
                                                graph.GetBlocks().AddWithKey(newblock, newblock.id);
                                                List <BasicBlock> lstTemp = new List <BasicBlock>();
                                                Sharpen.Collections.AddAll(lstTemp, handler.GetPreds());
                                                Sharpen.Collections.AddAll(lstTemp, handler.GetPredExceptions());
                                                // replace predecessors
                                                foreach (BasicBlock pred in lstTemp)
                                                {
                                                    pred.ReplaceSuccessor(handler, newblock);
                                                }
                                                // replace handler
                                                foreach (ExceptionRangeCFG range_ext in graph.GetExceptions())
                                                {
                                                    if (range_ext.GetHandler() == handler)
                                                    {
                                                        range_ext.SetHandler(newblock);
                                                    }
                                                    else if (range_ext.GetProtectedRange().Contains(handler))
                                                    {
                                                        newblock.AddSuccessorException(range_ext.GetHandler());
                                                        range_ext.GetProtectedRange().Add(newblock);
                                                    }
                                                }
                                                newblock.AddSuccessor(handler);
                                                if (graph.GetFirst() == handler)
                                                {
                                                    graph.SetFirst(newblock);
                                                }
                                                // remove the first pop in the handler
                                                seq.RemoveInstruction(0);
                                            }
                                            newblock.AddSuccessorException(range_super.handler);
                                            range_super.rangeCFG.GetProtectedRange().Add(newblock);
                                            handler = range.rangeCFG.GetHandler();
                                            seq     = handler.GetSeq();
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 45
0
 public _IIGraph_314(ControlFlowGraph graph)
 {
     this.graph = graph;
 }
Exemplo n.º 46
0
 private static bool SplitExceptionRange(ExceptionRangeCFG range, HashSet <BasicBlock
                                                                           > setEntries, ControlFlowGraph graph, GenericDominatorEngine engine)
 {
     foreach (BasicBlock entry in setEntries)
     {
         List <BasicBlock> lstSubrangeBlocks = GetReachableBlocksRestricted(entry, range,
                                                                            engine);
         if (!(lstSubrangeBlocks.Count == 0) && lstSubrangeBlocks.Count < range.GetProtectedRange
                 ().Count)
         {
             // add new range
             ExceptionRangeCFG subRange = new ExceptionRangeCFG(lstSubrangeBlocks, range.GetHandler
                                                                    (), range.GetExceptionTypes());
             graph.GetExceptions().Add(subRange);
             // shrink the original range
             lstSubrangeBlocks.ForEach(block => range.GetProtectedRange().Remove(block));
             return(true);
         }
         else
         {
             // should not happen
             DecompilerContext.GetLogger().WriteMessage("Inconsistency found while splitting protected range"
                                                        , IFernflowerLogger.Severity.Warn);
         }
     }
     return(false);
 }
    private StackRemovalTransformation(ControlFlowGraph cfg) {
      this.block2depth = new int[cfg.BlockCount];
      this.visited = new bool[cfg.BlockCount];
  
      // initialize everything to unreachable
      for (int j=0; j<block2depth.Length; j++) { block2depth[j] = -1; }

    }
Exemplo n.º 48
0
        /// <summary>
        /// Reduce Nesting in switch statements by replacing break; in cases with the block exit, and extracting the default case
        /// Does not affect IL order
        /// </summary>
        private bool ReduceSwitchNesting(Block parentBlock, BlockContainer switchContainer, ILInstruction exitInst)
        {
            // break; from outer container cannot be brought inside the switch as the meaning would change
            if (exitInst is Leave leave && !leave.IsLeavingFunction)
            {
                return(false);
            }

            // find the default section, and ensure it has only one incoming edge
            var switchInst     = (SwitchInstruction)switchContainer.EntryPoint.Instructions.Single();
            var defaultSection = switchInst.Sections.MaxBy(s => s.Labels.Count());

            if (!defaultSection.Body.MatchBranch(out var defaultBlock) || defaultBlock.IncomingEdgeCount != 1)
            {
                return(false);
            }

            // tally stats for heuristic from each case block
            int maxStatements = 0, maxDepth = 0;

            foreach (var section in switchInst.Sections)
            {
                if (section != defaultSection && section.Body.MatchBranch(out var caseBlock) && caseBlock.Parent == switchContainer)
                {
                    UpdateStats(caseBlock, ref maxStatements, ref maxDepth);
                }
            }

            if (!ShouldReduceNesting(defaultBlock, maxStatements, maxDepth))
            {
                return(false);
            }

            Debug.Assert(defaultBlock.HasFlag(InstructionFlags.EndPointUnreachable));

            // ensure the default case dominator tree has no exits (branches to other cases)
            var cfg         = new ControlFlowGraph(switchContainer, context.CancellationToken);
            var defaultNode = cfg.GetNode(defaultBlock);
            var defaultTree = TreeTraversal.PreOrder(defaultNode, n => n.DominatorTreeChildren).ToList();

            if (defaultTree.SelectMany(n => n.Successors).Any(n => !defaultNode.Dominates(n)))
            {
                return(false);
            }

            if (defaultTree.Count > 1 && !(parentBlock.Parent is BlockContainer))
            {
                return(false);
            }

            context.Step("Extract default case of switch", switchContainer);

            // replace all break; statements with the exitInst
            var leaveInstructions = switchContainer.Descendants.Where(inst => inst.MatchLeave(switchContainer));

            foreach (var leaveInst in leaveInstructions.ToArray())
            {
                leaveInst.ReplaceWith(exitInst.Clone());
            }

            // replace the default section branch with a break;
            defaultSection.Body.ReplaceWith(new Leave(switchContainer));

            // remove all default blocks from the switch container
            var defaultBlocks = defaultTree.Select(c => (Block)c.UserData).ToList();

            foreach (var block in defaultBlocks)
            {
                switchContainer.Blocks.Remove(block);
            }

            // replace the parent block exit with the default case instructions
            if (parentBlock.Instructions.Last() == exitInst)
            {
                parentBlock.Instructions.RemoveLast();
            }
            // Note: even though we don't check that the switchContainer is near the end of the block,
            // we know this must be the case because we know "exitInst" is a leave/branch and directly
            // follows the switchContainer.
            Debug.Assert(parentBlock.Instructions.Last() == switchContainer);
            parentBlock.Instructions.AddRange(defaultBlock.Instructions);

            // add any additional blocks from the default case to the parent container
            Debug.Assert(defaultBlocks[0] == defaultBlock);
            if (defaultBlocks.Count > 1)
            {
                var parentContainer = (BlockContainer)parentBlock.Parent;
                int insertAt        = parentContainer.Blocks.IndexOf(parentBlock) + 1;
                foreach (var block in defaultBlocks.Skip(1))
                {
                    parentContainer.Blocks.Insert(insertAt++, block);
                }
            }

            return(true);
        }
    /// <summary>
    /// Examines a CFG and removes the stack manipulating instructions by introducing
    /// some explicit variables for stack locations.  After this transformation, no more
    /// Pop, Dup etc.
    /// </summary>
    /// <param name="cfg">Control Flow Graph that is modified by the transformation.
    /// This argument WILL be mutated.</param>
    /// <returns>A map that assigns to each block from <c>cfg</c> the stack depth at its
    /// beginning.  Useful as a pseudo-liveness information.</returns>
    public static int[] Process(ControlFlowGraph cfg) 
    {
      StackRemovalTransformation sd = new StackRemovalTransformation(cfg);

			StackRemovalVisitor srv = new StackRemovalVisitor();

      // should be in order.
      foreach (CfgBlock block in cfg.PreOrder) {
        int depth = sd.InitialDepthOfBlock(block, cfg);

        if (depth < 0) { 
          continue;
        }

        // set block starting depth
        srv.depth = depth;

        StatementList stats = block.Statements;
        for(int i = 0, n = stats.Count; i < n; i++) {
          stats[i] = (Statement) srv.Visit(stats[i]);
          if (cfg.GenericsUse == null) { cfg.GenericsUse = srv.GenericsUse; }
          if (cfg.PointerUse == null) { cfg.PointerUse = srv.PointerUse; }
          if (srv.SawMissingInfo) { cfg.HasMissingInfo = true; }
        }

        // push final depth onto successors.
        foreach (CfgBlock succ in cfg.NormalSucc(block)) {
          sd.PushDepth(succ, srv.depth);
        }
      }

      // finalize stack depth info on each block
      foreach (CfgBlock block in cfg.Blocks()) 
      {
        int depth = sd.block2depth[block.Index];
        // cache depth on block
        block.stackDepth = depth;

        if (depth < 0) {
          // unreachable
          // set statementlist to null in case some backward analysis or other code gets to it
          if (block.Statements.Count > 0) {
            block.Statements = new StatementList(0);
          }
        }
      }
      return sd.block2depth;
    }
 private DataFlowAnalyzer(ControlFlowGraph cfg, ISymbol owningSymbol)
 {
     _analysisData = FlowGraphAnalysisData.Create(cfg, owningSymbol, AnalyzeLocalFunctionOrLambdaInvocation);
 }
 protected override void Run(ControlFlowGraph cfg, IDataFlowState startState) {
   base.Run(cfg, startState);
 }
Exemplo n.º 52
0
 protected override void PreProcess()
 {
     _cfg = Compilation.CreateCFG(InInstructions);
 }