/// <summary>
        /// Allocates a metadata (IL) representation along with a source level representation of the body of a method or of a property/event accessor.
        /// </summary>
        /// <param name="ilMethodBody">A method body whose IL operations should be decompiled into a block of statements that will be the
        /// result of the Block property of the resulting source method body.</param>
        /// <param name="host">An object representing the application that is hosting the converter. It is used to obtain access to some global
        /// objects and services such as the shared name table and the table for interning references.</param>
        /// <param name="sourceLocationProvider">An object that can map some kinds of ILocation objects to IPrimarySourceLocation objects. May be null.</param>
        /// <param name="localScopeProvider">An object that can provide information about the local scopes of a method.</param>
        /// <param name="options">Set of options that control decompilation.</param>
        public SourceMethodBody(IMethodBody ilMethodBody, IMetadataHost host, ISourceLocationProvider /*?*/ sourceLocationProvider,
                                ILocalScopeProvider /*?*/ localScopeProvider, DecompilerOptions options = DecompilerOptions.None)
            : base(host, sourceLocationProvider, localScopeProvider)
        {
            Contract.Requires(ilMethodBody != null);
            Contract.Requires(host != null);

            this.ilMethodBody           = ilMethodBody;
            this.host                   = host;
            this.nameTable              = host.NameTable;
            this.sourceLocationProvider = sourceLocationProvider;
            this.pdbReader              = sourceLocationProvider as PdbReader;
            this.localScopeProvider     = localScopeProvider;
            this.options                = options;
            this.platformType           = ilMethodBody.MethodDefinition.ContainingTypeDefinition.PlatformType;
            if (IteratorHelper.EnumerableIsNotEmpty(ilMethodBody.LocalVariables))
            {
                this.LocalsAreZeroed = ilMethodBody.LocalsAreZeroed;
            }
            else
            {
                this.LocalsAreZeroed = true;
            }
            this.MethodDefinition             = ilMethodBody.MethodDefinition;
            this.privateHelperFieldsToRemove  = null;
            this.privateHelperMethodsToRemove = null;
            this.privateHelperTypesToRemove   = null;
            this.cdfg = ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, ilMethodBody, localScopeProvider);
        }
Beispiel #2
0
        public override void Traverse(IMethodBody methodBody)
        {
            sourceEmitterOutput.WriteLine("");
            this.sourceEmitterOutput.WriteLine(MemberHelper.GetMethodSignature(methodBody.MethodDefinition,
                                                                               NameFormattingOptions.Signature | NameFormattingOptions.ReturnType | NameFormattingOptions.ParameterModifiers | NameFormattingOptions.ParameterName));
            sourceEmitterOutput.WriteLine("");
            if (this.pdbReader != null)
            {
                PrintScopes(methodBody);
            }
            else
            {
                PrintLocals(methodBody.LocalVariables);
            }

            this.cdfg = ControlAndDataFlowGraph <AiBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, methodBody, this.pdbReader);

            this.cfgQueries = new ControlGraphQueries <AiBasicBlock <Instruction>, Instruction>(this.cdfg);
            SingleAssigner <AiBasicBlock <Instruction>, Instruction> .GetInSingleAssignmentForm(host.NameTable, this.cdfg, this.cfgQueries, this.pdbReader);

            this.valueMappings = new ValueMappings <Instruction>(this.host.PlatformType, new Z3Wrapper.Wrapper(host.PlatformType));
            AbstractInterpreter <AiBasicBlock <Instruction>, Instruction> .InterpretUsingAbstractValues(this.cdfg, this.cfgQueries, this.valueMappings);

            var numberOfBlocks = this.cdfg.BlockFor.Count;

            foreach (var block in this.cdfg.AllBlocks)
            {
                this.PrintBlock(block);
            }

            sourceEmitterOutput.WriteLine("**************************************************************");
            sourceEmitterOutput.WriteLine();
        }
Beispiel #3
0
        public override void Visit(IMethodBody methodBody)
        {
            Console.WriteLine();
            Console.WriteLine("==========================");
            Console.WriteLine("{0}", MemberHelper.GetMemberSignature(methodBody.MethodDefinition, NameFormattingOptions.DocumentationId));

            var cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody, this.pdbReader);

            var cfgQueries = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg);

            var numberOfBlocks = cdfg.BlockFor.Count;

            Console.WriteLine("# blocks: {0}", numberOfBlocks);
            Console.WriteLine("CFG");
            foreach (var block in cdfg.AllBlocks)
            {
                Console.WriteLine("{0:X}, Successors: {1}", block.Offset, Offsets(cdfg.SuccessorsFor(block)));
            }

            Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > > dominators = new Dictionary <EnhancedBasicBlock <Instruction>, List <EnhancedBasicBlock <Instruction> > >();

            foreach (var b in cdfg.AllBlocks)
            {
                var dom = new List <EnhancedBasicBlock <Instruction> >();
                foreach (var c in cdfg.AllBlocks)
                {
                    if (cfgQueries.Dominates(c, b))
                    {
                        dom.Add(c);
                    }
                }
                dominators.Add(b, dom);
            }

            var surroundingLoops = LoopFinder.GetLoopInformation(cdfg, cfgQueries, methodBody);

            Console.WriteLine("\nLoop information");
            foreach (var b in cdfg.AllBlocks)
            {
                List <EnhancedBasicBlock <Instruction> > loops;
                if (surroundingLoops.TryGetValue(b, out loops))
                {
                    Console.WriteLine("{0:X}: ({1} loop{3}) {2}",
                                      b.Offset,
                                      loops.Count(),
                                      String.Join(",", loops.Select(l => String.Format("{0:X}", l.Offset))),
                                      loops.Count() > 1 ? "s" : ""
                                      );
                }
                else
                {
                    //Console.WriteLine("{0:X} is not contained in a loop", b.Offset);
                }
            }

            return;
        }
Beispiel #4
0
        public void RunOnMethod(IMethodDefinition methodDefinition, IMetadataHost host)
        {
            ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> cfg =
                ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, methodDefinition.Body);

            // Note: we assume the first root block is the entrypoint of the function (and not, say, an exception handler
            // This may not be warranted; should perhaps check IL offset?

            BasicBlock <Instruction> entryBlock = cfg.RootBlocks.First();

            RunOnControlFlowGraph(cfg, entryBlock);
        }
Beispiel #5
0
        public override void Visit(IMethodBody methodBody)
        {
            var method = methodBody.MethodDefinition;

            this.currentMethod = method;
            if (methodBody.Operations != null)
            {
                var cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody, this.pdbReader);

                var cfgQueries = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg);
                this.FindObjectSourcesWithoutSinks(method, cdfg);
            }


            return;
        }
Beispiel #6
0
        public override void Traverse(IMethodBody methodBody)
        {
            sourceEmitterOutput.WriteLine("");
            if (this.pdbReader != null)
            {
                PrintScopes(methodBody);
            }
            else
            {
                PrintLocals(methodBody.LocalVariables);
            }

            this.cdfg = ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(host, methodBody, this.pdbReader);

            var numberOfBlocks = this.cdfg.BlockFor.Count;

            foreach (var block in this.cdfg.AllBlocks)
            {
                this.PrintBlock(block);
            }

            sourceEmitterOutput.WriteLine("**************************************************************");
            sourceEmitterOutput.WriteLine();
        }
        public override IMethodBody Rewrite(IMethodBody methodBody)
        {
            this.cdfg = ControlAndDataFlowGraph <BasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(this.host, methodBody);

            this.ilGenerator = new ILGenerator(host, methodBody.MethodDefinition);

            var numberOfBlocks = this.cdfg.BlockFor.Count;

            this.labelFor = new Hashtable <ILGeneratorLabel>(numberOfBlocks);
            this.counterFieldsForCurrentMethod = new NestedTypeDefinition()
            {
                BaseClasses = new List <ITypeReference>(1)
                {
                    this.host.PlatformType.SystemObject
                },
                ContainingTypeDefinition = methodBody.MethodDefinition.ContainingTypeDefinition,
                Fields            = new List <IFieldDefinition>((int)numberOfBlocks * 2),
                Methods           = new List <IMethodDefinition>(1),
                InternFactory     = this.host.InternFactory,
                IsBeforeFieldInit = true,
                IsClass           = true,
                IsSealed          = true,
                IsAbstract        = true,
                Name       = this.host.NameTable.GetNameFor(methodBody.MethodDefinition.Name + "_Counters" + methodBody.MethodDefinition.InternedKey),
                Visibility = TypeMemberVisibility.Assembly,
            };
            this.fieldOffsets = new List <uint>((int)numberOfBlocks * 2);

            foreach (var exceptionInfo in methodBody.OperationExceptionInformation)
            {
                this.ilGenerator.AddExceptionHandlerInformation(exceptionInfo.HandlerKind, exceptionInfo.ExceptionType,
                                                                this.GetLabelFor(exceptionInfo.TryStartOffset), this.GetLabelFor(exceptionInfo.TryEndOffset),
                                                                this.GetLabelFor(exceptionInfo.HandlerStartOffset), this.GetLabelFor(exceptionInfo.HandlerEndOffset),
                                                                exceptionInfo.HandlerKind == HandlerKind.Filter ? this.GetLabelFor(exceptionInfo.FilterDecisionStartOffset) : null);
            }

            if (this.pdbReader == null)
            {
                foreach (var localDef in methodBody.LocalVariables)
                {
                    this.ilGenerator.AddVariableToCurrentScope(localDef);
                }
            }
            else
            {
                foreach (var ns in this.pdbReader.GetNamespaceScopes(methodBody))
                {
                    foreach (var uns in ns.UsedNamespaces)
                    {
                        this.ilGenerator.UseNamespace(uns.NamespaceName.Value);
                    }
                }
                this.scopeEnumerator        = this.pdbReader.GetLocalScopes(methodBody).GetEnumerator();
                this.scopeEnumeratorIsValid = this.scopeEnumerator.MoveNext();
            }

            foreach (var block in this.cdfg.AllBlocks)
            {
                this.InstrumentBlock(block);
            }

            while (this.scopeStack.Count > 0)
            {
                this.ilGenerator.EndScope();
                this.scopeStack.Pop();
            }

            this.ilGenerator.AdjustBranchSizesToBestFit();

            this.InjectMethodToDumpCounters();

            return(new ILGeneratorMethodBody(this.ilGenerator, methodBody.LocalsAreZeroed, (ushort)(methodBody.MaxStack + 2), methodBody.MethodDefinition,
                                             methodBody.LocalVariables, IteratorHelper.GetSingletonEnumerable((ITypeDefinition)this.counterFieldsForCurrentMethod)));
        }
Beispiel #8
0
        public bool AnalyzeMethods()
        {
            foreach (INamedTypeDefinition t in PrimaryModule.GetAllTypes())
            {
                if (t.IsClass && t.Methods.Count() > 0 && !t.Name.Value.StartsWith("<"))
                {
                    Environment.Message("Class {0} has {1} members, {2} methods.", t.Name.Value, t.Members.Count(), t.Methods.Count());
                    List <IMethodDefinition> methods = t.Methods.ToList();
                    foreach (IMethodDefinition m in methods)
                    {
                        ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> cdfg = ControlAndDataFlowGraph <EnhancedBasicBlock <Instruction>, Instruction> .GetControlAndDataFlowGraphFor(MetadataReaderHost, m.Body);

                        ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction> query = new ControlGraphQueries <EnhancedBasicBlock <Instruction>, Instruction>(cdfg);

                        Environment.Message("  Method {0} has visibility {3}, {1} parameters, {2} local variables in body, {4} total basic blocks or nodes and {5} successor edges in CFG.\n", m.Name.Value, m.ParameterCount,
                                            m.Body.LocalVariables.Count(), m.Visibility.ToString(), cdfg.AllBlocks.Count,
                                            cdfg.SuccessorEdges.Count);
                    }
                }
            }
            return(true);
        }