Beispiel #1
0
		public BlockStatement CreateMethodBody()
		{
			if (methodDef.Body == null) return null;
			
			context.CancellationToken.ThrowIfCancellationRequested();
			ILBlock ilMethod = new ILBlock();
			ILAstBuilder astBuilder = new ILAstBuilder();
			ilMethod.Body = astBuilder.Build(methodDef, true);
			
			context.CancellationToken.ThrowIfCancellationRequested();
			ILAstOptimizer bodyGraph = new ILAstOptimizer();
			bodyGraph.Optimize(context, ilMethod);
			context.CancellationToken.ThrowIfCancellationRequested();
			
			var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable).Where(v => v != null && !v.IsGenerated).Distinct();
			NameVariables.AssignNamesToVariables(methodDef.Parameters.Select(p => p.Name), allVariables, ilMethod);
			
			context.CancellationToken.ThrowIfCancellationRequested();
			Ast.BlockStatement astBlock = TransformBlock(ilMethod);
			CommentStatement.ReplaceAll(astBlock); // convert CommentStatements to Comments
			foreach (ILVariable v in localVariablesToDefine) {
				DeclareVariableInSmallestScope.DeclareVariable(astBlock, AstBuilder.ConvertType(v.Type), v.Name);
			}
			
			return astBlock;
		}
Beispiel #2
0
		public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
		{
			if (!method.HasBody) {
				return;
			}
			
			ILAstBuilder astBuilder = new ILAstBuilder();
			ILBlock ilMethod = new ILBlock();
			ilMethod.Body = astBuilder.Build(method, inlineVariables);
			
			if (abortBeforeStep != null) {
				DecompilerContext context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType, CurrentMethod = method };
				new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
			}
			
			var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
				.Where(v => v != null && !v.IsParameter).Distinct();
			foreach (ILVariable v in allVariables) {
				output.WriteDefinition(v.Name, v);
				if (v.Type != null) {
					output.Write(" : ");
					if (v.IsPinned)
						output.Write("pinned ");
					v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
				}
				output.WriteLine();
			}
			output.WriteLine();
			
			foreach (ILNode node in ilMethod.Body) {
				node.WriteTo(output);
				output.WriteLine();
			}
		}
Beispiel #3
0
        public void Run(DevirtualisationContext context)
        {
            foreach (var method in context.VirtualisedMethods)
            {
                if (method.IsExport &&
                    !context.Options.SelectedExports.Contains(method.ExportId.Value))
                {
                    continue;
                }

                context.Logger.Debug(Tag, $"Building IL AST for function_{method.Function.EntrypointAddress:X4}...");

                // Create builder.
                var builder = new ILAstBuilder
                {
                    Logger = context.Logger,
                    MaxSimplificationPasses = context.Options.MaxSimplificationPasses
                };

                // Subscribe to progress events if user specified it in the options.
                if (context.Options.OutputOptions.DumpAllControlFlowGraphs)
                {
                    int step = 1;
                    builder.InitialAstBuilt += (sender, args) =>
                    {
                        context.Logger.Debug2(Tag, $"Dumping initial IL AST for function_{method.Function.EntrypointAddress:X4}...");
                        method.ILCompilationUnit = args;
                        DumpILAst(context, method, $" (0. Initial)");
                    };

                    builder.TransformEnd += (sender, args) =>
                    {
                        context.Logger.Debug2(Tag, $"Dumping tentative IL AST for function_{method.Function.EntrypointAddress:X4}...");
                        method.ILCompilationUnit = args.Unit;
                        DumpILAst(context, method, $" ({step++}. {args.Transform.Name}-{args.Iteration})");
                    };
                }

                // Build the AST.
                try
                {
                    method.ILCompilationUnit = builder.BuildAst(method.ControlFlowGraph, method.Function.FrameLayout,
                                                                context.Constants);
                }
                catch (Exception ex) when(context.Options.EnableSalvageMode)
                {
                    context.Logger.Error(Tag,
                                         $"Failed to construct IL-AST of function_{method.Function.EntrypointAddress:X4}. "
                                         + $"The function will not be recompiled. {ex.Message}");
                }

                // Dump graphs if user specified it in the options.
                if (method.ILCompilationUnit != null && context.Options.OutputOptions.DumpControlFlowGraphs)
                {
                    context.Logger.Log(Tag, $"Dumping IL AST for function_{method.Function.EntrypointAddress:X4}...");
                    DumpILAst(context, method);
                    DumpILAstTree(context, method);
                }
            }
        }
Beispiel #4
0
        InterMethod IResolver.Resolve(MethodReference methodRef, List <InterGenericArgument> genericArgs)
        {
            InterMethod founded = null;
            InterMethod tmp     = new InterMethod(methodRef, genericArgs, this, M => founded = M);

            if (founded == null)
            {
                Messages.Verbose("Adding method {0} to compile...", tmp.ToString());
                tmp.DeclaringType.Methods.Add(tmp);
                founded = tmp;

                var unionedGenericArgs = tmp.FullGenericArguments;

                if (tmp.HasBody)
                {
                    MethodDefinition methodDef = tmp.Body.Method;

                    ILAstBuilder builder = new ILAstBuilder();
                    ILBlock      ilBody  = new ILBlock();

                    DecompilerContext context = new DecompilerContext(methodDef.Module)
                    {
                        CurrentType = methodDef.DeclaringType, CurrentMethod = methodDef
                    };
                    Utils.SetDecompillerSettings(context.Settings);

                    ilBody.Body = builder.Build(methodDef, true, context);
                    new ILAstOptimizer().Optimize(context, ilBody);
                    ProcessMethodDecencies(tmp, ilBody, tmp.FullGenericArguments);
                }
            }

            return(founded);
        }
Beispiel #5
0
		public override void DecompileMethod(MethodDef method, ITextOutput output, DecompilationOptions options)
		{
			WriteComment(output, "Method: ");
			output.WriteDefinition(IdentifierEscaper.Escape(method.FullName), method, TextTokenType.Comment, false);
			output.WriteLine();

			if (!method.HasBody) {
				return;
			}
			
			StartKeywordBlock(output, ".body", method);

			ILAstBuilder astBuilder = new ILAstBuilder();
			ILBlock ilMethod = new ILBlock();
			DecompilerContext context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType, CurrentMethod = method };
			ilMethod.Body = astBuilder.Build(method, inlineVariables, context);
			
			if (abortBeforeStep != null) {
				new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
			}
			
			if (context.CurrentMethodIsAsync) {
				output.Write("async", TextTokenType.Keyword);
				output.Write('/', TextTokenType.Operator);
				output.WriteLine("await", TextTokenType.Keyword);
			}
			
			var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
				.Where(v => v != null && !v.IsParameter).Distinct();
			foreach (ILVariable v in allVariables) {
				output.WriteDefinition(IdentifierEscaper.Escape(v.Name), v, v.IsParameter ? TextTokenType.Parameter : TextTokenType.Local);
				if (v.Type != null) {
					output.WriteSpace();
					output.Write(':', TextTokenType.Operator);
					output.WriteSpace();
					if (v.IsPinned) {
						output.Write("pinned", TextTokenType.Keyword);
						output.WriteSpace();
					}
					v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
				}
				if (v.IsGenerated) {
					output.WriteSpace();
					output.Write('[', TextTokenType.Operator);
					output.Write("generated", TextTokenType.Keyword);
					output.Write(']', TextTokenType.Operator);
				}
				output.WriteLine();
			}
			
			var memberMapping = new MemberMapping(method);
			foreach (ILNode node in ilMethod.Body) {
				node.WriteTo(output, memberMapping);
				if (!node.WritesNewLine)
					output.WriteLine();
			}
			output.AddDebugSymbols(memberMapping);
			EndKeywordBlock(output);
		}
        public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
        {
            if (!method.HasBody)
            {
                return;
            }

            ILAstBuilder      astBuilder = new ILAstBuilder();
            ILBlock           ilMethod   = new ILBlock();
            DecompilerContext context    = new DecompilerContext(method.Module)
            {
                CurrentType = method.DeclaringType, CurrentMethod = method
            };

            ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

            if (abortBeforeStep != null)
            {
                new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
            }

            if (context.CurrentMethodIsAsync)
            {
                output.WriteLine("async/await");
            }

            var allVariables = ilMethod.GetSelfAndChildrenRecursive <ILExpression>().Select(e => e.Operand as ILVariable)
                               .Where(v => v != null && !v.IsParameter).Distinct();

            foreach (ILVariable v in allVariables)
            {
                output.WriteDefinition(v.Name, v);
                if (v.Type != null)
                {
                    output.Write(" : ");
                    if (v.IsPinned)
                    {
                        output.Write("pinned ");
                    }
                    v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
                }
                if (v.IsGenerated)
                {
                    output.Write(" [generated]");
                }
                output.WriteLine();
            }
            output.WriteLine();

            foreach (ILNode node in ilMethod.Body)
            {
                node.WriteTo(output);
                output.WriteLine();
            }
        }
Beispiel #7
0
		public BlockStatement CreateMethodBody(IEnumerable<ParameterDeclaration> parameters,
		                                       ConcurrentDictionary<int, IEnumerable<ILVariable>> localVariables)
		{
			if (methodDef.Body == null) return null;
			
			if (localVariables == null)
				throw new ArgumentException("localVariables must be instantiated");
			
			context.CancellationToken.ThrowIfCancellationRequested();
			ILBlock ilMethod = new ILBlock();
			ILAstBuilder astBuilder = new ILAstBuilder();
			ilMethod.Body = astBuilder.Build(methodDef, true);
			
			context.CancellationToken.ThrowIfCancellationRequested();
			ILAstOptimizer bodyGraph = new ILAstOptimizer();
			bodyGraph.Optimize(context, ilMethod);
			context.CancellationToken.ThrowIfCancellationRequested();
			
			var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
				.Where(v => v != null && !v.IsParameter).Distinct();
			Debug.Assert(context.CurrentMethod == methodDef);
			NameVariables.AssignNamesToVariables(context, astBuilder.Parameters, allVariables, ilMethod);
			
			if (parameters != null) {
				foreach (var pair in (from p in parameters
				                      join v in astBuilder.Parameters on p.Annotation<ParameterDefinition>() equals v.OriginalParameter
				                      select new { p, v.Name }))
				{
					pair.p.Name = pair.Name;
				}
			}
			
			context.CancellationToken.ThrowIfCancellationRequested();
			Ast.BlockStatement astBlock = TransformBlock(ilMethod);
			CommentStatement.ReplaceAll(astBlock); // convert CommentStatements to Comments
			
			Statement insertionPoint = astBlock.Statements.FirstOrDefault();
			foreach (ILVariable v in localVariablesToDefine) {
				AstType type;
				if (v.Type.ContainsAnonymousType())
					type = new SimpleType("var");
				else
					type = AstBuilder.ConvertType(v.Type);
				var newVarDecl = new VariableDeclarationStatement(type, v.Name);
				astBlock.Statements.InsertBefore(insertionPoint, newVarDecl);
			}
			
			// store the variables - used for debugger
			int token = methodDef.MetadataToken.ToInt32();
			localVariables.AddOrUpdate(token, allVariables, (key, oldValue) => allVariables);
			
			return astBlock;
		}
Beispiel #8
0
    private static ILBlock Decompile(MethodDefinition method)
    {
        bool inlineVariables = false;

        ILAstBuilder astBuilder = new ILAstBuilder();
        ILBlock ilMethod = new ILBlock();
        DecompilerContext context = new DecompilerContext(method.Module) { CurrentType = method.DeclaringType, CurrentMethod = method };
        ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

        new ILAstOptimizer().Optimize(context, ilMethod, ILAstOptimizationStep.None);
        return ilMethod;
    }
Beispiel #9
0
        public void Run(DevirtualisationContext context)
        {
            foreach (var method in context.VirtualisedMethods)
            {
                if (method.IsExport &&
                    !context.Options.SelectedExports.Contains(method.ExportId.Value, method.ExportInfo))
                {
                    continue;
                }

                context.Logger.Debug(Tag, $"Building IL AST for function_{method.Function.EntrypointAddress:X4}...");

                // Create builder.
                var builder = new ILAstBuilder(context.TargetImage)
                {
                    Logger = context.Logger
                };

                // Subscribe to progress events if user specified it in the options.
                if (context.Options.OutputOptions.DumpAllControlFlowGraphs)
                {
                    int step = 1;
                    builder.InitialAstBuilt += (sender, args) =>
                    {
                        context.Logger.Debug(Tag, $"Dumping initial IL AST for function_{method.Function.EntrypointAddress:X4}...");
                        method.ILCompilationUnit = args;
                        DumpILAst(context, method, $" (0. Initial)");
                    };

                    builder.TransformEnd += (sender, args) =>
                    {
                        context.Logger.Debug(Tag, $"Dumping tentative IL AST for function_{method.Function.EntrypointAddress:X4}...");
                        method.ILCompilationUnit = args.Unit;
                        DumpILAst(context, method, $" ({step++}. {args.Transform.Name}-{args.Iteration})");
                    };
                }

                // Build the AST.
                method.ILCompilationUnit = builder.BuildAst(method.ControlFlowGraph, method.Function.FrameLayout, context.Constants);

                // Dump graphs if user specified it in the options.
                if (context.Options.OutputOptions.DumpControlFlowGraphs)
                {
                    context.Logger.Log(Tag, $"Dumping IL AST for function_{method.Function.EntrypointAddress:X4}...");
                    DumpILAst(context, method);

                    DumpILAstTree(context, method);
                }
            }
        }
Beispiel #10
0
            protected override ILBlock CreateNewBlock()
            {
                if (Context.Version != UndertaleVersion.V10000)
                {
                    throw new Exception("Cannot compile old code using new");
                }
                Locals = new Dictionary <string, ILVariable>();
                // Don't need any of that above since we don't do asms anymore
                var     error = new ErrorContext(name);
                ILBlock block = new ILBlock();

                block.Body = new Dissasembler.OldByteCodeAst().Build(this, error);
                block      = new ILAstBuilder().Build(block, Locals, error);
                block.FixParents();
                return(block);
            }
Beispiel #11
0
    private static ILBlock Decompile(MethodDefinition method)
    {
        bool inlineVariables = false;

        ILAstBuilder      astBuilder = new ILAstBuilder();
        ILBlock           ilMethod   = new ILBlock();
        DecompilerContext context    = new DecompilerContext(method.Module)
        {
            CurrentType = method.DeclaringType, CurrentMethod = method
        };

        ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

        new ILAstOptimizer().Optimize(context, ilMethod, ILAstOptimizationStep.None);
        return(ilMethod);
    }
        public Dictionary<int, EventRegistration[]> DecompileEventMappings(string fullTypeName)
        {
            var result = new Dictionary<int, EventRegistration[]>();
            TypeDefinition type = this.assembly.MainModule.GetType(fullTypeName);

            if (type == null)
                return result;

            MethodDefinition def = null;

            foreach (var method in type.Methods) {
                if (method.Name == "System.Windows.Markup.IComponentConnector.Connect") {
                    def = method;
                    break;
                }
            }

            if (def == null)
                return result;

            // decompile method and optimize the switch
            ILBlock ilMethod = new ILBlock();
            ILAstBuilder astBuilder = new ILAstBuilder();
            ILAstOptimizer optimizer = new ILAstOptimizer();
            var context = new DecompilerContext(type.Module) { CurrentMethod = def, CurrentType = type };
            ilMethod.Body = astBuilder.Build(def, true, context);
            optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.RemoveRedundantCode3);

            ILSwitch ilSwitch = ilMethod.Body.OfType<ILSwitch>().FirstOrDefault();
            ILCondition condition = ilMethod.Body.OfType<ILCondition>().FirstOrDefault();

            if (ilSwitch != null) {
                foreach (var caseBlock in ilSwitch.CaseBlocks) {
                    if (caseBlock.Values == null)
                        continue;
                    var events = FindEvents(caseBlock);
                    foreach (int id in caseBlock.Values)
                        result.Add(id, events);
                }
            } else if (condition != null) {
                result.Add(1, FindEvents(condition.FalseBlock));
            }

            return result;
        }
Beispiel #13
0
		public BlockStatement CreateMethodBody(IEnumerable<ParameterDeclaration> parameters)
		{
			if (methodDef.Body == null) return null;
			
			context.CancellationToken.ThrowIfCancellationRequested();
			ILBlock ilMethod = new ILBlock();
			ILAstBuilder astBuilder = new ILAstBuilder();
			ilMethod.Body = astBuilder.Build(methodDef, true);
			
			context.CancellationToken.ThrowIfCancellationRequested();
			ILAstOptimizer bodyGraph = new ILAstOptimizer();
			bodyGraph.Optimize(context, ilMethod);
			context.CancellationToken.ThrowIfCancellationRequested();
			
			var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
				.Where(v => v != null && !v.IsParameter).Distinct();
			Debug.Assert(context.CurrentMethod == methodDef);
			NameVariables.AssignNamesToVariables(context, astBuilder.Parameters, allVariables, ilMethod);
			
			if (parameters != null) {
				foreach (var pair in (from p in parameters
				                      join v in astBuilder.Parameters on p.Annotation<ParameterDefinition>() equals v.OriginalParameter
				                      select new { p, v.Name }))
				{
					pair.p.Name = pair.Name;
				}
			}
			
			context.CancellationToken.ThrowIfCancellationRequested();
			Ast.BlockStatement astBlock = TransformBlock(ilMethod);
			CommentStatement.ReplaceAll(astBlock); // convert CommentStatements to Comments
			
			Statement insertionPoint = astBlock.Statements.FirstOrDefault();
			foreach (ILVariable v in localVariablesToDefine) {
				var newVarDecl = new VariableDeclarationStatement(AstBuilder.ConvertType(v.Type), v.Name);
				astBlock.Statements.InsertBefore(insertionPoint, newVarDecl);
			}
			
			return astBlock;
		}
Beispiel #14
0
        public override void Decompile(MethodDef method, IDecompilerOutput output, DecompilationContext ctx)
        {
            WriteCommentBegin(output, true);
            output.Write("Method: ", BoxedTextColor.Comment);
            output.Write(IdentifierEscaper.Escape(method.FullName), method, DecompilerReferenceFlags.Definition, BoxedTextColor.Comment);
            WriteCommentEnd(output, true);
            output.WriteLine();

            if (!method.HasBody)
            {
                return;
            }

            var bodyInfo = StartKeywordBlock(output, ".body", method);

            ILAstBuilder      astBuilder = new ILAstBuilder();
            ILBlock           ilMethod   = new ILBlock(CodeBracesRangeFlags.MethodBraces);
            DecompilerContext context    = new DecompilerContext(method.Module, MetadataTextColorProvider)
            {
                CurrentType       = method.DeclaringType,
                CurrentMethod     = method,
                CalculateBinSpans = ctx.CalculateBinSpans,
            };

            ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

            if (abortBeforeStep != null)
            {
                new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
            }

            if (context.CurrentMethodIsYieldReturn)
            {
                output.Write("yield", BoxedTextColor.Keyword);
                output.Write(" ", BoxedTextColor.Text);
                output.WriteLine("return", BoxedTextColor.Keyword);
            }
            if (context.CurrentMethodIsAsync)
            {
                output.Write("async", BoxedTextColor.Keyword);
                output.Write("/", BoxedTextColor.Punctuation);
                output.WriteLine("await", BoxedTextColor.Keyword);
            }

            var allVariables = ilMethod.GetSelfAndChildrenRecursive <ILExpression>().Select(e => e.Operand as ILVariable)
                               .Where(v => v != null && !v.IsParameter).Distinct();

            foreach (ILVariable v in allVariables)
            {
                output.Write(IdentifierEscaper.Escape(v.Name), (object)v.OriginalVariable ?? (object)v.OriginalParameter ?? v.Id, DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, v.IsParameter ? BoxedTextColor.Parameter : BoxedTextColor.Local);
                if (v.Type != null)
                {
                    output.Write(" ", BoxedTextColor.Text);
                    output.Write(":", BoxedTextColor.Punctuation);
                    output.Write(" ", BoxedTextColor.Text);
                    if (v.IsPinned)
                    {
                        output.Write("pinned", BoxedTextColor.Keyword);
                        output.Write(" ", BoxedTextColor.Text);
                    }
                    v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
                }
                if (v.GeneratedByDecompiler)
                {
                    output.Write(" ", BoxedTextColor.Text);
                    var start = output.NextPosition;
                    output.Write("[", BoxedTextColor.Punctuation);
                    output.Write("generated", BoxedTextColor.Keyword);
                    var end = output.NextPosition;
                    output.Write("]", BoxedTextColor.Punctuation);
                    output.AddBracePair(new TextSpan(start, 1), new TextSpan(end, 1), CodeBracesRangeFlags.SquareBrackets);
                }
                output.WriteLine();
            }

            var builder = new MethodDebugInfoBuilder(method);

            foreach (ILNode node in ilMethod.Body)
            {
                node.WriteTo(output, builder);
                if (!node.WritesNewLine)
                {
                    output.WriteLine();
                }
            }
            output.AddDebugInfo(builder.Create());
            EndKeywordBlock(output, bodyInfo, CodeBracesRangeFlags.MethodBraces, addLineSeparator: true);
        }
Beispiel #15
0
        public void Compile()
        {
            MethodDefinition methodDef = thisMethod.Body.Method;

            Messages.Verbose("      Generating IL graph...");

            ILAstBuilder builder = new ILAstBuilder();

            ilBody = new ILBlock();

            DecompilerContext context = new DecompilerContext(methodDef.Module)
            {
                CurrentType = methodDef.DeclaringType, CurrentMethod = methodDef
            };

            Utils.SetDecompillerSettings(context.Settings);

            ilBody.Body = builder.Build(methodDef, true, context);
            new ILAstOptimizer().Optimize(context, ilBody);

            FillVars(builder.Parameters);

            Messages.Verbose("      Preprocess IL graph...");
            RunPreprocessor();

            Messages.Verbose("      Compiling IL graph to java bytecode...");
            CompileNode(ilBody, ExpectType.None);

            //Checking for deleted last ret
            if (ilBody.Body.Count > 0)
            {
                ILNode lastNode = ilBody.Body.Last();
                if ((lastNode is ILExpression) && (((ILExpression)lastNode).Code != ILCode.Ret) &&
                    (((ILExpression)lastNode).Code != ILCode.Throw))
                {
                    CompileRet(null, ExpectType.None);
                }
                else if (thisMethod.ReturnParameter.Type.PrimitiveType == PrimitiveType.Void)
                {
                    CompileRet(null, ExpectType.None);
                }
            }
            else
            {
                CompileRet(null, ExpectType.None);
            }

            oldCodeGenerator = codeGenerator;
            byte[] prolog = GenerateMethodProlog();
            codeGenerator = oldCodeGenerator;

            Messages.Verbose("      Linking java bytecode...");
            codeGenerator.StartOffset = prolog.Length;
            byte[] codeBytes = codeGenerator.Link(constsPool);
            GenerateJavaExceptionTable();

            resultCode           = new Java.Attributes.Code();
            resultCode.CodeBytes = prolog.Concat(codeBytes).ToArray();

            WriteJavaExceptionTable(prolog.Length);

            Messages.Verbose("      Simulating stack to calculate MaxStack and MaxLocals...");
            StackSimulator.SimulateStack(constsPool, resultCode);
            resultCode.MaxLocals = (ushort)nextVarIndex;

            if (Program.Debug)
            {
                GenerateDebugInfo(prolog.Length);
            }
        }
Beispiel #16
0
        public Dictionary <int, EventRegistration[]> DecompileEventMappings(string fullTypeName)
        {
            var            result = new Dictionary <int, EventRegistration[]>();
            TypeDefinition type   = this.assembly.MainModule.GetType(fullTypeName);

            if (type == null)
            {
                return(result);
            }

            MethodDefinition def = null;

            foreach (var method in type.Methods)
            {
                if (method.Name == "System.Windows.Markup.IComponentConnector.Connect")
                {
                    def = method;
                    break;
                }
            }

            if (def == null)
            {
                return(result);
            }

            // decompile method and optimize the switch
            ILBlock      ilMethod   = new ILBlock();
            ILAstBuilder astBuilder = new ILAstBuilder();

            ilMethod.Body = astBuilder.Build(def, true);
            ILAstOptimizer optimizer = new ILAstOptimizer();
            var            context   = new DecompilerContext(type.Module)
            {
                CurrentMethod = def, CurrentType = type
            };

            optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.RemoveRedundantCode3);

            ILSwitch    ilSwitch  = ilMethod.Body.OfType <ILSwitch>().FirstOrDefault();
            ILCondition condition = ilMethod.Body.OfType <ILCondition>().FirstOrDefault();

            if (ilSwitch != null)
            {
                foreach (var caseBlock in ilSwitch.CaseBlocks)
                {
                    if (caseBlock.Values == null)
                    {
                        continue;
                    }
                    var events = FindEvents(caseBlock);
                    foreach (int id in caseBlock.Values)
                    {
                        result.Add(id, events);
                    }
                }
            }
            else if (condition != null)
            {
                result.Add(1, FindEvents(condition.FalseBlock));
            }

            return(result);
        }
Beispiel #17
0
		/// <summary>
		/// Creates ILAst for the specified method, optimized up to before the 'YieldReturn' step.
		/// </summary>
		ILBlock CreateILAst(MethodDefinition method)
		{
			if (method == null || !method.HasBody)
				throw new SymbolicAnalysisFailedException();
			
			ILBlock ilMethod = new ILBlock();
			ILAstBuilder astBuilder = new ILAstBuilder();
			ilMethod.Body = astBuilder.Build(method, true, context);
			ILAstOptimizer optimizer = new ILAstOptimizer();
			optimizer.Optimize(context, ilMethod, ILAstOptimizationStep.YieldReturn);
			return ilMethod;
		}
Beispiel #18
0
        public override void Decompile(MethodDef method, ITextOutput output, DecompilationContext ctx)
        {
            WriteCommentBegin(output, true);
            output.Write("Method: ", TextTokenKind.Comment);
            output.WriteDefinition(IdentifierEscaper.Escape(method.FullName), method, TextTokenKind.Comment, false);
            WriteCommentEnd(output, true);
            output.WriteLine();

            if (!method.HasBody)
            {
                return;
            }

            StartKeywordBlock(output, ".body", method);

            ILAstBuilder      astBuilder = new ILAstBuilder();
            ILBlock           ilMethod   = new ILBlock();
            DecompilerContext context    = new DecompilerContext(method.Module)
            {
                CurrentType = method.DeclaringType, CurrentMethod = method
            };

            ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

            if (abortBeforeStep != null)
            {
                new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
            }

            if (context.CurrentMethodIsAsync)
            {
                output.Write("async", TextTokenKind.Keyword);
                output.Write("/", TextTokenKind.Operator);
                output.WriteLine("await", TextTokenKind.Keyword);
            }

            var allVariables = ilMethod.GetSelfAndChildrenRecursive <ILExpression>().Select(e => e.Operand as ILVariable)
                               .Where(v => v != null && !v.IsParameter).Distinct();

            foreach (ILVariable v in allVariables)
            {
                output.WriteDefinition(IdentifierEscaper.Escape(v.Name), v, v.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local);
                if (v.Type != null)
                {
                    output.WriteSpace();
                    output.Write(":", TextTokenKind.Operator);
                    output.WriteSpace();
                    if (v.IsPinned)
                    {
                        output.Write("pinned", TextTokenKind.Keyword);
                        output.WriteSpace();
                    }
                    v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
                }
                if (v.GeneratedByDecompiler)
                {
                    output.WriteSpace();
                    output.Write("[", TextTokenKind.Operator);
                    output.Write("generated", TextTokenKind.Keyword);
                    output.Write("]", TextTokenKind.Operator);
                }
                output.WriteLine();
            }

            var memberMapping = new MemberMapping(method);

            foreach (ILNode node in ilMethod.Body)
            {
                node.WriteTo(output, memberMapping);
                if (!node.WritesNewLine)
                {
                    output.WriteLine();
                }
            }
            output.AddDebugSymbols(memberMapping);
            EndKeywordBlock(output);
        }
Beispiel #19
0
		public override void Decompile(MethodDef method, IDecompilerOutput output, DecompilationContext ctx) {
			WriteCommentBegin(output, true);
			output.Write("Method: ", BoxedTextColor.Comment);
			output.Write(IdentifierEscaper.Escape(method.FullName), method, DecompilerReferenceFlags.Definition, BoxedTextColor.Comment);
			WriteCommentEnd(output, true);
			output.WriteLine();

			if (!method.HasBody) {
				return;
			}

			StartKeywordBlock(output, ".body", method);

			ILAstBuilder astBuilder = new ILAstBuilder();
			ILBlock ilMethod = new ILBlock();
			DecompilerContext context = new DecompilerContext(method.Module, MetadataTextColorProvider) { CurrentType = method.DeclaringType, CurrentMethod = method };
			ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

			if (abortBeforeStep != null) {
				new ILAstOptimizer().Optimize(context, ilMethod, abortBeforeStep.Value);
			}

			if (context.CurrentMethodIsAsync) {
				output.Write("async", BoxedTextColor.Keyword);
				output.Write("/", BoxedTextColor.Punctuation);
				output.WriteLine("await", BoxedTextColor.Keyword);
			}

			var allVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
				.Where(v => v != null && !v.IsParameter).Distinct();
			foreach (ILVariable v in allVariables) {
				output.Write(IdentifierEscaper.Escape(v.Name), v, DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, v.IsParameter ? BoxedTextColor.Parameter : BoxedTextColor.Local);
				if (v.Type != null) {
					output.Write(" ", BoxedTextColor.Text);
					output.Write(":", BoxedTextColor.Punctuation);
					output.Write(" ", BoxedTextColor.Text);
					if (v.IsPinned) {
						output.Write("pinned", BoxedTextColor.Keyword);
						output.Write(" ", BoxedTextColor.Text);
					}
					v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
				}
				if (v.GeneratedByDecompiler) {
					output.Write(" ", BoxedTextColor.Text);
					output.Write("[", BoxedTextColor.Punctuation);
					output.Write("generated", BoxedTextColor.Keyword);
					output.Write("]", BoxedTextColor.Punctuation);
				}
				output.WriteLine();
			}

			var builder = new MethodDebugInfoBuilder(method);
			foreach (ILNode node in ilMethod.Body) {
				node.WriteTo(output, builder);
				if (!node.WritesNewLine)
					output.WriteLine();
			}
			output.AddDebugInfo(builder.Create());
			EndKeywordBlock(output);
		}
Beispiel #20
0
        public override void Decompile(MethodDef method, IDecompilerOutput output, DecompilationContext ctx)
        {
            WriteCommentBegin(output, true);
            output.Write("Method: ", BoxedTextColor.Comment);
            output.Write(IdentifierEscaper.Escape(method.FullName), method, DecompilerReferenceFlags.Definition, BoxedTextColor.Comment);
            WriteCommentEnd(output, true);
            output.WriteLine();

            if (!method.HasBody)
            {
                return;
            }

            var bodyInfo = StartKeywordBlock(output, ".body", method);

            ILAstBuilder      astBuilder = new ILAstBuilder();
            ILBlock           ilMethod   = new ILBlock(CodeBracesRangeFlags.MethodBraces);
            DecompilerContext context    = new DecompilerContext(settingsVersion, method.Module, MetadataTextColorProvider)
            {
                CurrentType      = method.DeclaringType,
                CurrentMethod    = method,
                CalculateILSpans = ctx.CalculateILSpans,
            };

            ilMethod.Body = astBuilder.Build(method, inlineVariables, context);

            var                  stateMachineKind = StateMachineKind.None;
            MethodDef?           inlinedMethod    = null;
            AsyncMethodDebugInfo?asyncInfo        = null;
            string?              compilerName     = null;

            if (!(abortBeforeStep is null))
            {
                var optimizer = new ILAstOptimizer();
                optimizer.Optimize(context, ilMethod, out stateMachineKind, out inlinedMethod, out asyncInfo, abortBeforeStep.Value);
                compilerName = optimizer.CompilerName;
            }

            if (context.CurrentMethodIsYieldReturn)
            {
                output.Write("yield", BoxedTextColor.Keyword);
                output.Write(" ", BoxedTextColor.Text);
                output.WriteLine("return", BoxedTextColor.Keyword);
            }
            if (context.CurrentMethodIsAsync)
            {
                output.Write("async", BoxedTextColor.Keyword);
                output.Write("/", BoxedTextColor.Punctuation);
                output.WriteLine("await", BoxedTextColor.Keyword);
            }

            var allVariables = ilMethod.GetSelfAndChildrenRecursive <ILExpression>().Select(e => e.Operand as ILVariable)
                               .Where(v => !(v is null) && !v.IsParameter).Distinct();

            foreach (ILVariable v in allVariables)
            {
                output.Write(IdentifierEscaper.Escape(v.Name), v.GetTextReferenceObject(), DecompilerReferenceFlags.Local | DecompilerReferenceFlags.Definition, v.IsParameter ? BoxedTextColor.Parameter : BoxedTextColor.Local);
                if (!(v.Type is null))
                {
                    output.Write(" ", BoxedTextColor.Text);
                    output.Write(":", BoxedTextColor.Punctuation);
                    output.Write(" ", BoxedTextColor.Text);
                    if (v.IsPinned)
                    {
                        output.Write("pinned", BoxedTextColor.Keyword);
                        output.Write(" ", BoxedTextColor.Text);
                    }
                    v.Type.WriteTo(output, ILNameSyntax.ShortTypeName);
                }
                if (v.GeneratedByDecompiler)
                {
                    output.Write(" ", BoxedTextColor.Text);
                    var start = output.NextPosition;
                    output.Write("[", BoxedTextColor.Punctuation);
                    output.Write("generated", BoxedTextColor.Keyword);
                    var end = output.NextPosition;
                    output.Write("]", BoxedTextColor.Punctuation);
                    output.AddBracePair(new TextSpan(start, 1), new TextSpan(end, 1), CodeBracesRangeFlags.SquareBrackets);
                }
                output.WriteLine();
            }

            var localVariables = new HashSet <ILVariable>(GetVariables(ilMethod));
            var builder        = new MethodDebugInfoBuilder(settingsVersion, stateMachineKind, inlinedMethod ?? method, !(inlinedMethod is null) ? method : null, CreateSourceLocals(localVariables), CreateSourceParameters(localVariables), asyncInfo);

            builder.CompilerName = compilerName;
            foreach (ILNode node in ilMethod.Body)
            {
                node.WriteTo(output, builder);
                if (!node.WritesNewLine)
                {
                    output.WriteLine();
                }
            }
            output.AddDebugInfo(builder.Create());
            EndKeywordBlock(output, bodyInfo, CodeBracesRangeFlags.MethodBraces, addLineSeparator: true);
        }
Beispiel #21
0
 public void Return(ILAstBuilder builder)
 {
     ilAstBuilderPool.Free(builder);
 }
Beispiel #22
0
        public void WalkMethod(MethodReference methodReference, TypeReference targetType = null, bool virt = false)
        {
            if (!AddMethod(methodReference, targetType, virt))
            {
                return;
            }

            var method = methodReference.Resolve();

            var context = new DecompilerContext(method.Module)
            {
                Settings =
                {
                    AnonymousMethods = true,
                    AsyncAwait       = false,
                    YieldReturn      = false,
                    QueryExpressions = false,
                    LockStatement    = false,
                    FullyQualifyAmbiguousTypeNames = true,
                    ForEachStatement = false,
                    ExpressionTrees  = false,
                    ObjectOrCollectionInitializers = false,
                },
                CurrentModule = method.Module,
                CurrentMethod = method,
                CurrentType   = method.DeclaringType
            };

            List <Instruction> foundInstructions = (from instruction in method.Body.Instructions
                                                    where method.HasBody && method.Body.Instructions != null && instruction.Operand != null
                                                    select instruction).ToList();

            IEnumerable <TypeReference> typesFound = from instruction in foundInstructions
                                                     let tRef = instruction.Operand as TypeReference
                                                                where tRef != null
                                                                select tRef;

            IEnumerable <FieldReference> fieldsFound = from instruction in foundInstructions
                                                       let fRef = instruction.Operand as FieldReference
                                                                  where fRef != null && fRef.FieldType != null
                                                                  select fRef;

            foreach (TypeReference typeDefinition in typesFound)
            {
                AddType(typeDefinition);
            }

            foreach (FieldReference fieldDefinition in fieldsFound)
            {
                AddField(fieldDefinition);
            }

            ILBlock ilb = null;
            bool    useSimpleMethodWalk = Configuration.NonAggressiveVirtualMethodElimination;

            if (!useSimpleMethodWalk)
            {
                var virtCalls = from instruction in foundInstructions
                                let mRef = instruction.Operand as MethodReference
                                           where (instruction.OpCode == OpCodes.Callvirt || instruction.OpCode == OpCodes.Ldvirtftn) &&
                                           mRef.Resolve().IsVirtual
                                           select instruction;

                if (virtCalls.Any())
                {
                    try {
                        var decompiler = new ILAstBuilder();
                        var optimizer  = new ILAstOptimizer();

                        ilb = new ILBlock(decompiler.Build(method, false, context));
                        optimizer.Optimize(context, ilb);
                    }
                    catch (Exception) {
                        useSimpleMethodWalk = true;
                    }
                }
                else
                {
                    useSimpleMethodWalk = true;
                }
            }

            if (!useSimpleMethodWalk)
            {
                var expressions = ilb.GetSelfAndChildrenRecursive <ILExpression>();

                foreach (var ilExpression in expressions)
                {
                    var mRef = ilExpression.Operand as MethodReference;
                    if (mRef != null && mRef.DeclaringType != null)
                    {
                        bool          isVirtual = false;
                        TypeReference thisArg   = null;

                        switch (ilExpression.Code)
                        {
                        case ILCode.Ldftn:
                        case ILCode.Newobj:
                        case ILCode.Jmp:
                        case ILCode.Call:
                        case ILCode.CallGetter:
                        case ILCode.CallSetter:
                            break;

                        case ILCode.CallvirtGetter:
                        case ILCode.CallvirtSetter:
                        case ILCode.Callvirt:
                        case ILCode.Ldvirtftn:
                            isVirtual = true;
                            thisArg   = ilExpression.Arguments.Count > 0 ? ilExpression.Arguments[0].InferredType : null;
                            break;

                        case ILCode.Ldtoken:
                            isVirtual = true;
                            break;
                        }

                        WalkMethod(mRef, thisArg, isVirtual);
                    }
                }
            }
            else
            {
                IEnumerable <MethodReference> methodsFound = from instruction in foundInstructions
                                                             let mRef = instruction.Operand as MethodReference
                                                                        where mRef != null && mRef.DeclaringType != null
                                                                        select mRef;

                foreach (MethodReference methodDefinition in methodsFound)
                {
                    if (methodDefinition != method)
                    {
                        WalkMethod(methodDefinition, null, true);
                    }
                }
            }
        }
Beispiel #23
0
 public void Return(ILAstBuilder builder)
 {
     ilAstBuilderPool.Free(builder);
 }
Beispiel #24
0
        public void WalkMethod(MethodReference methodReference, TypeReference targetType = null, bool virt = false)
        {
            if (!AddMethod(methodReference, targetType, virt)) {
                return;
            }

            var method = methodReference.Resolve();

            var context = new DecompilerContext(method.Module)
            {
                Settings =
                {
                    AnonymousMethods = true,
                    AsyncAwait = false,
                    YieldReturn = false,
                    QueryExpressions = false,
                    LockStatement = false,
                    FullyQualifyAmbiguousTypeNames = true,
                    ForEachStatement = false,
                    ExpressionTrees = false,
                    ObjectOrCollectionInitializers = false,
                },
                CurrentModule = method.Module,
                CurrentMethod = method,
                CurrentType = method.DeclaringType
            };

            List<Instruction> foundInstructions = (from instruction in method.Body.Instructions
                where method.HasBody && method.Body.Instructions != null && instruction.Operand != null
                select instruction).ToList();

            IEnumerable<TypeReference> typesFound = from instruction in foundInstructions
                let tRef = instruction.Operand as TypeReference
                where tRef != null
                select tRef;

            IEnumerable<FieldReference> fieldsFound = from instruction in foundInstructions
                let fRef = instruction.Operand as FieldReference
                where fRef != null && fRef.FieldType != null
                select fRef;

            foreach (TypeReference typeDefinition in typesFound) {
                AddType(typeDefinition);
            }

            foreach (FieldReference fieldDefinition in fieldsFound)
            {
                AddField(fieldDefinition);
            }

            ILBlock ilb = null;
            bool useSimpleMethodWalk = Configuration.NonAggressiveVirtualMethodElimination;
            if (!useSimpleMethodWalk) {
                var virtCalls = from instruction in foundInstructions
                    let mRef = instruction.Operand as MethodReference
                    where (instruction.OpCode == OpCodes.Callvirt || instruction.OpCode == OpCodes.Ldvirtftn) &&
                          mRef.Resolve().IsVirtual
                    select instruction;

                if (virtCalls.Any()) {
                    try {
                        var decompiler = new ILAstBuilder();
                        var optimizer = new ILAstOptimizer();

                        ilb = new ILBlock(decompiler.Build(method, false, context));
                        optimizer.Optimize(context, ilb);
                    }
                    catch (Exception) {
                        useSimpleMethodWalk = true;

                    }
                }
                else {
                    useSimpleMethodWalk = true;
                }
            }

            if (!useSimpleMethodWalk) {
                var expressions = ilb.GetSelfAndChildrenRecursive<ILExpression>();

                foreach (var ilExpression in expressions) {
                    var mRef = ilExpression.Operand as MethodReference;
                    if (mRef != null && mRef.DeclaringType != null) {
                        bool isVirtual = false;
                        TypeReference thisArg = null;

                        switch (ilExpression.Code)
                        {
                            case ILCode.Ldftn:
                            case ILCode.Newobj:
                            case ILCode.Jmp:
                            case ILCode.Call:
                            case ILCode.CallGetter:
                            case ILCode.CallSetter:
                                break;

                            case ILCode.CallvirtGetter:
                            case ILCode.CallvirtSetter:
                            case ILCode.Callvirt:
                            case ILCode.Ldvirtftn:
                                isVirtual = true;
                                thisArg = ilExpression.Arguments.Count >0 ? ilExpression.Arguments[0].InferredType : null;
                                break;

                            case ILCode.Ldtoken:
                                isVirtual = true;
                                break;
                        }

                        WalkMethod(mRef, thisArg, isVirtual);
                    }
                }                
            }
            else {
                IEnumerable<MethodReference> methodsFound = from instruction in foundInstructions
                                                            let mRef = instruction.Operand as MethodReference
                                                            where mRef != null && mRef.DeclaringType != null
                                                            select mRef;

                foreach (MethodReference methodDefinition in methodsFound) {
                    if (methodDefinition != method) {
                        WalkMethod(methodDefinition, null, true);
                    }
                }
            }
        }
Beispiel #25
0
        internal JSFunctionExpression TranslateMethodExpression(DecompilerContext context, MethodReference method, MethodDefinition methodDef)
        {
            var oldMethod = context.CurrentMethod;
            try {
                if (method == null)
                    throw new ArgumentNullException("method");
                if (methodDef == null)
                    throw new ArgumentNullException("methodDef");

                var methodInfo = TypeInfoProvider.GetMemberInformation<JSIL.Internal.MethodInfo>(methodDef);

                var identifier = new QualifiedMemberIdentifier(
                    methodInfo.DeclaringType.Identifier, methodInfo.Identifier
                );
                JSFunctionExpression function = null;

                if (FunctionCache.TryGetExpression(identifier, out function))
                    return function;

                if (methodInfo.IsExternal) {
                    FunctionCache.CreateNull(methodInfo, method, identifier);
                    return null;
                }

                var bodyDef = methodDef;
                if (methodInfo.IsFromProxy && methodInfo.Member.HasBody)
                    bodyDef = methodInfo.Member;

                var pr = new ProgressReporter();

                context.CurrentMethod = methodDef;
                if ((methodDef.Body.Instructions.Count > LargeMethodThreshold) && (this.DecompilingMethod != null))
                    this.DecompilingMethod(method.FullName, pr);

                ILBlock ilb;
                var decompiler = new ILAstBuilder();
                var optimizer = new ILAstOptimizer();

                try {
                    ilb = new ILBlock(decompiler.Build(bodyDef, true));
                    optimizer.Optimize(context, ilb);
                } catch (Exception exception) {
                    if (CouldNotDecompileMethod != null)
                        CouldNotDecompileMethod(bodyDef.FullName, exception);

                    FunctionCache.CreateNull(methodInfo, method, identifier);
                    pr.OnFinished();
                    return null;
                }

                var allVariables = ilb.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
                    .Where(v => v != null && !v.IsParameter).Distinct();

                foreach (var v in allVariables) {
                    if (ILBlockTranslator.IsIgnoredType(v.Type)) {
                        FunctionCache.CreateNull(methodInfo, method, identifier);
                        pr.OnFinished();
                        return null;
                    }
                }

                NameVariables.AssignNamesToVariables(context, decompiler.Parameters, allVariables, ilb);

                var translator = new ILBlockTranslator(
                    this, context, method, methodDef,
                    ilb, decompiler.Parameters, allVariables
                );
                var body = translator.Translate();

                if (body == null) {
                    FunctionCache.CreateNull(methodInfo, method, identifier);
                    pr.OnFinished();
                    return null;
                }

                var parameters = from p in translator.ParameterNames select translator.Variables[p];

                if (method.HasGenericParameters) {
                    var type = new TypeReference("System", "Type", context.CurrentModule.TypeSystem.Object.Module, context.CurrentModule.TypeSystem.Object.Scope);
                    parameters = (from gp in method.GenericParameters select new JSVariable(gp.Name, type, method)).Concat(parameters);
                }

                function = FunctionCache.Create(
                    methodInfo, methodDef, method, identifier,
                    translator, parameters, body
                );

                pr.OnFinished();
                return function;
            } finally {
                context.CurrentMethod = oldMethod;
            }
        }
Beispiel #26
0
		BlockStatement CreateMethodBody(IEnumerable<ParameterDeclaration> parameters, out MemberMapping mm)
		{
			if (methodDef.Body == null) {
				mm = null;
				return null;
			}
			
			context.CancellationToken.ThrowIfCancellationRequested();
			ILBlock ilMethod = new ILBlock();
			ILAstBuilder astBuilder = new ILAstBuilder();
			ilMethod.Body = astBuilder.Build(methodDef, true, context);
			
			context.CancellationToken.ThrowIfCancellationRequested();
			ILAstOptimizer bodyGraph = new ILAstOptimizer();
			bodyGraph.Optimize(context, ilMethod);
			context.CancellationToken.ThrowIfCancellationRequested();
			
			var localVariables = ilMethod.GetSelfAndChildrenRecursive<ILExpression>().Select(e => e.Operand as ILVariable)
				.Where(v => v != null && !v.IsParameter).Distinct();
			Debug.Assert(context.CurrentMethod == methodDef);
			NameVariables.AssignNamesToVariables(context, astBuilder.Parameters, localVariables, ilMethod);
			
			if (parameters != null) {
				foreach (var pair in (from p in parameters
				                      join v in astBuilder.Parameters on p.Annotation<Parameter>() equals v.OriginalParameter
				                      select new { p, v.Name }))
				{
					pair.p.NameToken = Identifier.Create(pair.Name).WithAnnotation(TextTokenType.Parameter);
				}
			}
			
			context.CancellationToken.ThrowIfCancellationRequested();
			Ast.BlockStatement astBlock = TransformBlock(ilMethod);
			CommentStatement.ReplaceAll(astBlock); // convert CommentStatements to Comments
			
			Statement insertionPoint = astBlock.Statements.FirstOrDefault();
			foreach (ILVariable v in localVariablesToDefine) {
				AstType type;
				if (v.Type.ContainsAnonymousType())
					type = new SimpleType("var").WithAnnotation(TextTokenType.Keyword);
				else
					type = AstBuilder.ConvertType(v.Type);
				var newVarDecl = new VariableDeclarationStatement(v.IsParameter ? TextTokenType.Parameter : TextTokenType.Local, type, v.Name);
				newVarDecl.Variables.Single().AddAnnotation(v);
				astBlock.Statements.InsertBefore(insertionPoint, newVarDecl);
			}
			
			mm = new MemberMapping(methodDef) { LocalVariables = localVariables.ToList() };
			
			return astBlock;
		}
Beispiel #27
0
        public bool RemoveDeadCode(MethodDef method, List <Instruction> dead)
        {
            ILAstBuilder astBuilder      = new ILAstBuilder();
            bool         inlineVariables = true;

            if (!method.HasBody)
            {
                return(false);
            }

            DecompilerContext context = new DecompilerContext(method.Module)
            {
                CurrentType = method.DeclaringType, CurrentMethod = method
            };

            try
            {
                ILMethod.Body = astBuilder.Build(method, inlineVariables, context);
            }
            catch (Exception ex)
            {
                if (DeFlowSettings.Settings.Logs)
                {
                    OutputLog.Instance.WriteLine("Failed to de-obfuscate method: " + method.MDToken.Raw.ToString());
                }
                return(false);
            }

            Instructions = method.Body.Instructions.Where(x => x.OpCode.Code != Code.Constrained).ToList();

            foreach (ILNode node in ILMethod.Body)
            {
                GetNodes(node);
            }

            if (ILNodes.Count != method.Body.Instructions.Count() + ILNodes.Where(x => x is ILLabel).Count() + ILNodes.Where(x => x is string && (x as string) != "pop" && (x as string) != "prefix").Count()
                + ILNodes.Where(x => x is ILExpression && IsReAssign(x as ILExpression)).Count())
            {
                if (DeFlowSettings.Settings.Logs)
                {
                    OutputLog.Instance.WriteLine("ilNodes is wrong: " + string.Format("0x{0:X8}", method.MDToken.Raw));
                }
                return(false);
            }

            var entries = CreateILEntries();
            var exprs   = entries.Where(x => x.Node is ILExpression && (x.Node as ILExpression).Operand != null && (x.Node as ILExpression).Operand is ILVariable).ToList();
            var catchs  = ILNodes.Where(y => y is string && (y as string).Contains("catch"));
            var rets    = entries.Where(x => x.Instr != null && x.Instr.OpCode.Code == Code.Ret);

            SetILEntriesRefs(entries, exprs);

            bool modified;

            do
            {
                modified = false;

                var unused = exprs.Where(x => x.Targets == null || x.Targets.All(y => y.Instr != null && y.Instr.OpCode == OpCodes.Pop)).ToList();

                foreach (var expr in unused)
                {
                    if (expr.Instr != null)
                    {
                        // If its func call without returned value, we cant delete it.
                        if (!CallInstruction(expr.Instr.OpCode.Code))
                        {
                            // If its func call with returned value we dont want to delete this returned value too even if its unused.
                            if (!(expr.Sources != null && expr.Sources.Any(x => CallInstruction(x.Instr.OpCode.Code))))
                            {
                                // Exception Variable
                                if (!(expr.Node as ILExpression).Arguments.Any(x => x.Operand is ILVariable && catchs.Any(y => (y as string).Contains((x.Operand as ILVariable).Name))))
                                {
                                    // Dups
                                    List <ILEntry> path = new List <ILEntry>();
                                    if (!(expr.Instr.OpCode.Code != Code.Dup && CheckDupSources(expr, path)))
                                    {
                                        modified = true;

                                        dead.Add(expr.Instr);

                                        foreach (var source in exprs.Where(x => x.Targets != null && x.Targets.Any(y => y == expr)).ToList())
                                        {
                                            source.Targets = source.Targets.Where(x => x != expr).ToList();
                                        }

                                        exprs.Remove(expr);

                                        if (expr.Targets != null)
                                        {
                                            foreach (var pop in expr.Targets)
                                            {
                                                dead.Add(pop.Instr);
                                                exprs.Remove(pop);
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }while (modified);

            return(true);
        }