Exemple #1
0
        void WriteStructureBody(MethodDef method, CilBody body, ILStructure s, HashSet <uint> branchTargets, ref int index, MemberMapping currentMethodMapping, int codeSize)
        {
            bool isFirstInstructionInStructure = true;
            bool prevInstructionWasBranch      = false;
            int  childIndex = 0;

            while (index < body.Instructions.Count)
            {
                Instruction inst   = body.Instructions[index];
                uint        offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)
                {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(method, body, child, branchTargets, ref index, currentMethodMapping, codeSize);
                    WriteStructureFooter(child);
                }
                else
                {
                    if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset)))
                    {
                        output.WriteLine();                         // put an empty line after branches, and in front of branch targets
                    }
                    var startLocation = output.Location;
                    inst.WriteTo(method, output);

                    // add IL code mappings - used in debugger
                    if (currentMethodMapping != null)
                    {
                        var next = body.GetNext(inst);
                        currentMethodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            StartLocation       = startLocation,
                            EndLocation         = output.Location,
                            ILInstructionOffset = new ILRange {
                                From = inst.Offset, To = next == null ? (uint)codeSize : next.Offset
                            },
                            MemberMapping = currentMethodMapping
                        });
                    }

                    output.WriteLine();

                    prevInstructionWasBranch = inst.OpCode.FlowControl == FlowControl.Branch ||
                                               inst.OpCode.FlowControl == FlowControl.Cond_Branch ||
                                               inst.OpCode.FlowControl == FlowControl.Return ||
                                               inst.OpCode.FlowControl == FlowControl.Throw;

                    index++;
                }
                isFirstInstructionInStructure = false;
            }
        }
Exemple #2
0
        public void Disassemble(MethodDef method, MemberMapping methodMapping)
        {
            // start writing IL code
            CilBody body = method.Body;

            output.WriteLine("// Method begins at RVA 0x{0:x8}", (uint)method.RVA);
            output.WriteLine("// Metadata token 0x{0:x8} (RID {1})", method.MDToken.ToInt32(), method.Rid);
            output.WriteLine("// Code size {0} (0x{0:x})", body.GetCodeSize());
            output.WriteLine(".maxstack {0}", body.MaxStack);
            if (method.DeclaringType.Module.Assembly != null && method.DeclaringType.Module.EntryPoint == method)
            {
                output.WriteLine(".entrypoint");
            }

            if (method.Body.HasVariables)
            {
                output.Write(".locals ");
                if (method.Body.InitLocals)
                {
                    output.Write("init ");
                }
                output.WriteLine("(");
                output.Indent();
                foreach (var v in method.Body.Variables)
                {
                    output.WriteDefinition("[" + v.Index + "] ", v);
                    v.Type.WriteTo(output);
                    if (!string.IsNullOrEmpty(v.Name))
                    {
                        output.Write(' ');
                        output.Write(DisassemblerHelpers.Escape(v.Name));
                    }
                    if (v.Index + 1 < method.Body.Variables.Count)
                    {
                        output.Write(',');
                    }
                    output.WriteLine();
                }
                output.Unindent();
                output.WriteLine(")");
            }
            output.WriteLine();

            if (detectControlStructure && body.Instructions.Count > 0)
            {
                int            index         = 0;
                HashSet <uint> branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(method, body, new ILStructure(body), branchTargets, ref index, methodMapping, method.Body.GetCodeSize());
            }
            else
            {
                foreach (var inst in method.Body.Instructions)
                {
                    var startLocation = output.Location;
                    inst.WriteTo(method, output);

                    if (methodMapping != null)
                    {
                        // add IL code mappings - used in debugger
                        var next = body.GetNext(inst);
                        methodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            StartLocation       = output.Location,
                            EndLocation         = output.Location,
                            ILInstructionOffset = new ILRange {
                                From = inst.Offset, To = next == null ? (uint)method.Body.GetCodeSize() : next.Offset
                            },
                            MemberMapping = methodMapping
                        });
                    }

                    output.WriteLine();
                }
                if (method.Body.HasExceptionHandlers)
                {
                    output.WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        eh.WriteTo(method, output);
                        output.WriteLine();
                    }
                }
            }
        }