Example #1
0
        void WriteStructureHeader(ILStructure s)
        {
            switch (s.Type)
            {
            case ILStructureType.Loop:
                output.Write("// loop start", TextTokenType.Comment);
                if (s.LoopEntryPoint != null)
                {
                    output.Write(" (head: ", TextTokenType.Comment);
                    DisassemblerHelpers.WriteOffsetReference(output, s.LoopEntryPoint, null, TextTokenType.Comment);
                    output.Write(')', TextTokenType.Comment);
                }
                output.WriteLine();
                break;

            case ILStructureType.Try:
                output.WriteLine(".try", TextTokenType.ILDirective);
                output.WriteLineLeftBrace();
                break;

            case ILStructureType.Handler:
                switch (s.ExceptionHandler.HandlerType)
                {
                case ExceptionHandlerType.Catch:
                case ExceptionHandlerType.Filter:
                    output.Write("catch", TextTokenType.Keyword);
                    if (s.ExceptionHandler.CatchType != null)
                    {
                        output.WriteSpace();
                        s.ExceptionHandler.CatchType.WriteTo(output, ILNameSyntax.TypeName);
                    }
                    output.WriteLine();
                    break;

                case ExceptionHandlerType.Finally:
                    output.WriteLine("finally", TextTokenType.Keyword);
                    break;

                case ExceptionHandlerType.Fault:
                    output.WriteLine("fault", TextTokenType.Keyword);
                    break;

                default:
                    output.WriteLine(s.ExceptionHandler.HandlerType.ToString(), TextTokenType.Keyword);
                    break;
                }
                output.WriteLineLeftBrace();
                break;

            case ILStructureType.Filter:
                output.WriteLine("filter", TextTokenType.Keyword);
                output.WriteLineLeftBrace();
                break;

            default:
                throw new NotSupportedException();
            }
            output.Indent();
        }
Example #2
0
        void WriteStructureHeader(ILStructure s)
        {
            switch (s.Type)
            {
            case ILStructureType.Loop:
                output.Write("// loop start");
                if (s.LoopEntryPoint != null)
                {
                    output.Write(" (head: ");
                    DisassemblerHelpers.WriteOffsetReference(output, s.LoopEntryPoint);
                    output.Write(')');
                }
                output.WriteLine();
                break;

            case ILStructureType.Try:
                output.WriteLine(".try");
                output.WriteLine("{");
                break;

            case ILStructureType.Handler:
                switch (s.ExceptionHandler.HandlerType)
                {
                case Mono.Cecil.Cil.ExceptionHandlerType.Catch:
                case Mono.Cecil.Cil.ExceptionHandlerType.Filter:
                    output.Write("catch");
                    if (s.ExceptionHandler.CatchType != null)
                    {
                        output.Write(' ');
                        s.ExceptionHandler.CatchType.WriteTo(output, ILNameSyntax.TypeName);
                    }
                    output.WriteLine();
                    break;

                case Mono.Cecil.Cil.ExceptionHandlerType.Finally:
                    output.WriteLine("finally");
                    break;

                case Mono.Cecil.Cil.ExceptionHandlerType.Fault:
                    output.WriteLine("fault");
                    break;

                default:
                    throw new NotSupportedException();
                }
                output.WriteLine("{");
                break;

            case ILStructureType.Filter:
                output.WriteLine("filter");
                output.WriteLine("{");
                break;

            default:
                throw new NotSupportedException();
            }
            output.Indent();
        }
        void WriteStructureHeader(ILStructure s)
        {
            switch (s.Type)
            {
            case ILStructureType.Loop:
                output.Write("// loop start");
                if (s.LoopEntryPointOffset >= 0)
                {
                    output.Write(" (head: ");
                    DisassemblerHelpers.WriteOffsetReference(output, s.LoopEntryPointOffset);
                    output.Write(')');
                }
                output.WriteLine();
                break;

            case ILStructureType.Try:
                output.WriteLine(".try");
                output.WriteLine("{");
                break;

            case ILStructureType.Handler:
                switch (s.ExceptionHandler.Kind)
                {
                case ExceptionRegionKind.Catch:
                case ExceptionRegionKind.Filter:
                    output.Write("catch");
                    if (!s.ExceptionHandler.CatchType.IsNil)
                    {
                        output.Write(' ');
                        s.ExceptionHandler.CatchType.WriteTo(s.Module, output, s.GenericContext, ILNameSyntax.TypeName);
                    }
                    output.WriteLine();
                    break;

                case ExceptionRegionKind.Finally:
                    output.WriteLine("finally");
                    break;

                case ExceptionRegionKind.Fault:
                    output.WriteLine("fault");
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                output.WriteLine("{");
                break;

            case ILStructureType.Filter:
                output.WriteLine("filter");
                output.WriteLine("{");
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            output.Indent();
        }
Example #4
0
        private void WriteStructureHeader(IlStructure s)
        {
            switch (s.Type)
            {
            case IlStructureType.Loop:
                _o.Write("// loop start");
                if (s.LoopEntryPoint != null)
                {
                    _o.Write(" (head: ");
                    DisassemblerHelpers.WriteOffsetReference(_o, s.LoopEntryPoint);
                    _o.Write(')');
                }
                _o.WriteLine();
                break;

            case IlStructureType.Try:
                _o.WriteLine(".try");
                _o.WriteLine("{");
                break;

            case IlStructureType.Handler:
                switch (s.ExceptionHandler.HandlerType)
                {
                case ExceptionHandlerType.Catch:
                case ExceptionHandlerType.Filter:
                    _o.Write("catch");
                    if (s.ExceptionHandler.CatchType != null)
                    {
                        _o.Write(' ');
                        s.ExceptionHandler.CatchType.WriteTo(_o, IlNameSyntax.TypeName);
                    }
                    _o.WriteLine();
                    break;

                case ExceptionHandlerType.Finally:
                    _o.WriteLine("finally");
                    break;

                case ExceptionHandlerType.Fault:
                    _o.WriteLine("fault");
                    break;

                default:
                    throw new NotSupportedException();
                }
                _o.WriteLine("{");
                break;

            case IlStructureType.Filter:
                _o.WriteLine("filter");
                _o.WriteLine("{");
                break;

            default:
                throw new NotSupportedException();
            }
            _o.Indent();
        }
Example #5
0
        public void Disassemble(MethodBody body)
        {
            // start writing IL code
            var method       = body.Method;
            var codesize     = body.ComputeCodeSize();
            var maxstacksize = body.ComputeMaxStackSize();

            body.ComputeOffsets();

            _o.WriteLine("// Code size {0} (0x{0:x})", codesize);
            _o.WriteLine(".maxstack {0}", maxstacksize);
            if (method.DeclaringType.Module.Assembly != null && method.DeclaringType.Module.Assembly.EntryPoint == method)
            {
                _o.WriteLine(".entrypoint");
            }

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

            if (body.Instructions.Count > 0)
            {
                var inst          = body.Instructions[0];
                var branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(new IlStructure(body, codesize), branchTargets, ref inst);
            }
            else
            {
                // we ignore method without instructions (but it can have exception handlers)
                _o.WriteLine();
            }
        }
		void DisassembleMethodInternal(MethodDefinition method)
		{
			//    .method public hidebysig  specialname
			//               instance default class [mscorlib]System.IO.TextWriter get_BaseWriter ()  cil managed
			//
			
			//emit flags
			WriteEnum(method.Attributes & MethodAttributes.MemberAccessMask, methodVisibility);
			WriteFlags(method.Attributes & ~MethodAttributes.MemberAccessMask, methodAttributeFlags);
			
			output.WriteLine();
			output.Indent();
			
			if (method.HasThis)
				output.Write("instance ");
			
			//call convention
			WriteEnum(method.CallingConvention & (MethodCallingConvention)0x1f, callingConvention);
			
			
			//return type
			method.ReturnType.WriteTo(output);
			output.Write(' ');
			output.Write(DisassemblerHelpers.Escape(method.Name));
			
			//( params )
			output.Write(" (");
			if (method.HasParameters) {
				output.WriteLine();
				output.Indent();
				WriteParameters(method.Parameters);
				output.Unindent();
			}
			output.Write(") ");
			//cil managed
			WriteEnum(method.ImplAttributes & MethodImplAttributes.CodeTypeMask, methodCodeType);
			if ((method.ImplAttributes & MethodImplAttributes.ManagedMask) == MethodImplAttributes.Managed)
				output.Write("managed ");
			else
				output.Write("unmanaged ");
			WriteFlags(method.ImplAttributes & ~(MethodImplAttributes.CodeTypeMask | MethodImplAttributes.ManagedMask), methodImpl);
			
			output.Unindent();
			if (method.HasBody || method.HasCustomAttributes) {
				OpenBlock(defaultCollapsed: isInType);
				WriteAttributes(method.CustomAttributes);
				
				if (method.HasBody)
					methodBodyDisassembler.Disassemble(method.Body);
				
				CloseBlock("End of method " + method.DeclaringType.Name + "." + method.Name);
			} else {
				output.WriteLine();
			}
		}
Example #7
0
        void DisassembleLocalsBlock(MethodDefinitionHandle method, MethodBodyBlock body)
        {
            if (body.LocalSignature.IsNil)
            {
                return;
            }
            output.Write(".locals");
            WriteMetadataToken(body.LocalSignature, spaceBefore: true);
            if (body.LocalVariablesInitialized)
            {
                output.Write(" init");
            }
            var blob      = metadata.GetStandaloneSignature(body.LocalSignature);
            var signature = ImmutableArray <Action <ILNameSyntax> > .Empty;

            try
            {
                if (blob.GetKind() == StandaloneSignatureKind.LocalVariables)
                {
                    signature = blob.DecodeLocalSignature(signatureDecoder, genericContext);
                }
                else
                {
                    output.Write(" /* wrong signature kind */");
                }
            }
            catch (BadImageFormatException ex)
            {
                output.Write($" /* {ex.Message} */");
            }
            output.Write(' ');
            output.WriteLine("(");
            output.Indent();
            int index = 0;

            foreach (var v in signature)
            {
                output.WriteLocalReference("[" + index + "]", "loc_" + index, isDefinition: true);
                output.Write(' ');
                v(ILNameSyntax.TypeName);
                if (DebugInfo != null && DebugInfo.TryGetName(method, index, out var name))
                {
                    output.Write(" " + DisassemblerHelpers.Escape(name));
                }
                if (index + 1 < signature.Length)
                {
                    output.Write(',');
                }
                output.WriteLine();
                index++;
            }
            output.Unindent();
            output.WriteLine(")");
        }
        public void Disassemble(MethodBody body)
        {
            MethodDefinition method = body.Method;

            output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA);
            output.WriteLine("// Code size {0} (0x{0:x})", body.CodeSize);
            output.WriteLine(".maxstack {0}", body.MaxStackSize);
            if (method.DeclaringType.Module.Assembly.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.VariableType.WriteTo(output);
                    output.Write(' ');
                    output.Write(DisassemblerHelpers.Escape(v.Name));
                    output.WriteLine();
                }
                output.Unindent();
                output.WriteLine(")");
            }
            output.WriteLine();

            if (detectControlStructure && body.Instructions.Count > 0)
            {
                Instruction inst = body.Instructions[0];
                WriteStructureBody(new ILStructure(body), ref inst);
            }
            else
            {
                foreach (var inst in method.Body.Instructions)
                {
                    inst.WriteTo(output);
                    output.WriteLine();
                }
                output.WriteLine();
                foreach (var eh in method.Body.ExceptionHandlers)
                {
                    eh.WriteTo(output);
                    output.WriteLine();
                }
            }
        }
		void WriteParameters(Collection<ParameterDefinition> parameters)
		{
			for (int i = 0; i < parameters.Count; i++) {
				var p = parameters[i];
				p.ParameterType.WriteTo(output);
				output.Write(' ');
				output.WriteDefinition(DisassemblerHelpers.Escape(p.Name), p);
				if (i < parameters.Count - 1)
					output.Write(',');
				output.WriteLine();
			}
		}
Example #10
0
        private static void WriteTypeParameters(PlainTextOutput output, IGenericParameterProvider p)
        {
            if (!p.HasGenericParameters)
            {
                return;
            }

            output.Write('<');
            for (var i = 0; i < p.GenericParameters.Count; i++)
            {
                if (i > 0)
                {
                    output.Write(", ");
                }
                var gp = p.GenericParameters[i];
                if (gp.HasReferenceTypeConstraint)
                {
                    output.Write("class ");
                }
                else if (gp.HasNotNullableValueTypeConstraint)
                {
                    output.Write("valuetype ");
                }
                if (gp.HasDefaultConstructorConstraint)
                {
                    output.Write(".ctor ");
                }
                if (gp.HasConstraints)
                {
                    output.Write('(');
                    for (var j = 0; j < gp.Constraints.Count; j++)
                    {
                        if (j > 0)
                        {
                            output.Write(", ");
                        }
                        gp.Constraints[j].WriteTo(output, IlNameSyntax.TypeName);
                    }
                    output.Write(") ");
                }
                if (gp.IsContravariant)
                {
                    output.Write('-');
                }
                else if (gp.IsCovariant)
                {
                    output.Write('+');
                }
                output.Write(DisassemblerHelpers.Escape(gp.Name));
            }
            output.Write('>');
        }
		public void DisassembleProperty(PropertyDefinition property)
		{
			output.WriteDefinition(".property ", property);
			WriteFlags(property.Attributes, propertyAttributes);
			property.PropertyType.WriteTo(output);
			output.Write(' ');
			output.Write(DisassemblerHelpers.Escape(property.Name));
			OpenBlock(false);
			WriteAttributes(property.CustomAttributes);
			WriteNestedMethod(".get", property.GetMethod);
			WriteNestedMethod(".set", property.SetMethod);
			foreach (var method in property.OtherMethods) {
				WriteNestedMethod(".method", method);
			}
			CloseBlock();
		}
		public void DisassembleEvent(EventDefinition ev)
		{
			output.WriteDefinition(".event ", ev);
			WriteFlags(ev.Attributes, eventAttributes);
			ev.EventType.WriteTo(output);
			output.Write(' ');
			output.Write(DisassemblerHelpers.Escape(ev.Name));
			OpenBlock(false);
			WriteAttributes(ev.CustomAttributes);
			WriteNestedMethod(".add", ev.AddMethod);
			WriteNestedMethod(".remove", ev.RemoveMethod);
			WriteNestedMethod(".invoke", ev.InvokeMethod);
			foreach (var method in ev.OtherMethods) {
				WriteNestedMethod(".method", method);
			}
			CloseBlock();
		}
		public void DisassembleNamespace(string nameSpace, IEnumerable<TypeDefinition> types)
		{
			if (!string.IsNullOrEmpty(nameSpace)) {
				output.Write(".namespace " + DisassemblerHelpers.Escape(nameSpace));
				OpenBlock(false);
			}
			bool oldIsInType = isInType;
			isInType = true;
			foreach (TypeDefinition td in types) {
				cancellationToken.ThrowIfCancellationRequested();
				DisassembleType(td);
				output.WriteLine();
			}
			if (!string.IsNullOrEmpty(nameSpace)) {
				CloseBlock();
				isInType = oldIsInType;
			}
		}
Example #14
0
        public void DisassembleEvent(EventDefinition ev)
        {
            _o.WriteDefinition(".event ", ev);
            WriteFlags(ev.Attributes, _eventAttributes);
            ev.EventType.WriteTo(_o, IlNameSyntax.TypeName);
            _o.Write(' ');
            _o.Write(DisassemblerHelpers.Escape(ev.Name));
            OpenBlock();
            WriteAttributes(ev.CustomAttributes);
            WriteNestedMethod(".addon", ev.AddMethod);
            WriteNestedMethod(".removeon", ev.RemoveMethod);
            WriteNestedMethod(".fire", ev.InvokeMethod);
            foreach (var method in ev.OtherMethods)
            {
                WriteNestedMethod(".other", method);
            }

            CloseBlock();
        }
 void WriteTypeParameter(GenericParameterHandle paramRef, int index, ILNameSyntax syntax)
 {
     if (paramRef.IsNil || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
     {
         output.Write(index.ToString());
     }
     else
     {
         var param = metadata.GetGenericParameter(paramRef);
         if (param.Name.IsNil)
         {
             output.Write(param.Index.ToString());
         }
         else
         {
             output.Write(DisassemblerHelpers.Escape(metadata.GetString(param.Name)));
         }
     }
 }
		public void DisassembleField(FieldDefinition field)
		{
			output.WriteDefinition(".field ", field);
			WriteEnum(field.Attributes & FieldAttributes.FieldAccessMask, fieldVisibility);
			WriteFlags(field.Attributes & ~(FieldAttributes.FieldAccessMask | FieldAttributes.HasDefault), fieldAttributes);
			field.FieldType.WriteTo(output);
			output.Write(' ');
			output.Write(DisassemblerHelpers.Escape(field.Name));
			if (field.HasConstant) {
				output.Write(" = ");
				DisassemblerHelpers.WriteOperand(output, field.Constant);
			}
			if (field.HasCustomAttributes) {
				OpenBlock(false);
				WriteAttributes(field.CustomAttributes);
				CloseBlock();
			} else {
				output.WriteLine();
			}
		}
		public void WriteAssemblyHeader(AssemblyDefinition asm)
		{
			output.Write(".assembly " + DisassemblerHelpers.Escape(asm.Name.Name));
			OpenBlock(false);
			Version v = asm.Name.Version;
			if (v != null) {
				output.WriteLine(".ver {0}:{1}:{2}:{3}", v.Major, v.Minor, v.Build, v.Revision);
			}
			if (asm.Name.HashAlgorithm != AssemblyHashAlgorithm.None) {
				output.Write(".hash algorithm 0x{0:x8}", (int)asm.Name.HashAlgorithm);
				if (asm.Name.HashAlgorithm == AssemblyHashAlgorithm.SHA1)
					output.Write(" // SHA1");
				output.WriteLine();
			}
			if (asm.Name.PublicKey != null && asm.Name.PublicKey.Length > 0) {
				output.Write(".publickey = ");
				WriteBlob(asm.Name.PublicKey);
				output.WriteLine();
			}
			WriteAttributes(asm.CustomAttributes);
			CloseBlock();
		}
Example #18
0
        private void WriteSecurityDeclarationArgument(CustomAttributeNamedArgument na)
        {
            var type = na.Argument.Type;

            if (type.MetadataType == MetadataType.Class || type.MetadataType == MetadataType.ValueType)
            {
                _o.Write("enum ");
                if (type.Scope != type.Module)
                {
                    _o.Write("class ");
                    _o.Write(DisassemblerHelpers.Escape(GetAssemblyQualifiedName(type)));
                }
                else
                {
                    type.WriteTo(_o, IlNameSyntax.TypeName);
                }
            }
            else
            {
                type.WriteTo(_o);
            }

            _o.Write(' ');
            _o.Write(DisassemblerHelpers.Escape(na.Name));
            _o.Write(" = ");

            var s = na.Argument.Value as string;

            if (s != null)
            {
                // secdecls use special syntax for strings
                _o.Write("string('{0}')", DisassemblerHelpers.ConvertString(s).Replace("'", "\'"));
            }
            else
            {
                WriteConstant(na.Argument.Value);
            }
        }
Example #19
0
 public void WriteAssemblyReferences(ModuleDefinition module)
 {
     foreach (var mref in module.ModuleReferences)
     {
         output.WriteLine(".module extern {0}", DisassemblerHelpers.Escape(mref.Name));
     }
     foreach (var aref in module.AssemblyReferences)
     {
         output.Write(".assembly extern {0}", DisassemblerHelpers.Escape(aref.Name));
         OpenBlock(false);
         if (aref.PublicKeyToken != null)
         {
             output.Write(".publickeytoken = ");
             WriteBlob(aref.PublicKeyToken);
             output.WriteLine();
         }
         if (aref.Version != null)
         {
             output.WriteLine(".ver {0}:{1}:{2}:{3}", aref.Version.Major, aref.Version.Minor, aref.Version.Build, aref.Version.Revision);
         }
         CloseBlock();
     }
 }
Example #20
0
        public void DisassembleProperty(PropertyDefinition property)
        {
            // set current member
            currentMember = property;

            output.WriteDefinition(".property ", property);
            WriteFlags(property.Attributes, propertyAttributes);
            if (property.HasThis)
            {
                output.Write("instance ");
            }
            property.PropertyType.WriteTo(output);
            output.Write(' ');
            output.Write(DisassemblerHelpers.Escape(property.Name));

            output.Write("(");
            if (property.HasParameters)
            {
                output.WriteLine();
                output.Indent();
                WriteParameters(property.Parameters);
                output.Unindent();
            }
            output.Write(")");

            OpenBlock(false);
            WriteAttributes(property.CustomAttributes);
            WriteNestedMethod(".get", property.GetMethod);
            WriteNestedMethod(".set", property.SetMethod);

            foreach (var method in property.OtherMethods)
            {
                WriteNestedMethod(".other", method);
            }
            CloseBlock();
        }
        protected virtual void WriteInstruction(ITextOutput output, MetadataReader metadata, MethodDefinitionHandle methodDefinition, ref BlobReader blob)
        {
            int offset = blob.Offset;

            if (ShowSequencePoints && nextSequencePointIndex < sequencePoints?.Count)
            {
                var sp = sequencePoints[nextSequencePointIndex];
                if (sp.Offset <= offset)
                {
                    output.Write("// sequence point: ");
                    if (sp.Offset != offset)
                    {
                        output.Write("!! at " + DisassemblerHelpers.OffsetToString(sp.Offset) + " !!");
                    }
                    if (sp.IsHidden)
                    {
                        output.WriteLine("hidden");
                    }
                    else
                    {
                        output.WriteLine($"(line {sp.StartLine}, col {sp.StartColumn}) to (line {sp.EndLine}, col {sp.EndColumn}) in {sp.DocumentUrl}");
                    }
                    nextSequencePointIndex++;
                }
            }
            ILOpCode opCode = ILParser.DecodeOpCode(ref blob);

            output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset), offset, isDefinition: true);
            output.Write(": ");
            if (opCode.IsDefined())
            {
                output.WriteReference(new OpCodeInfo(opCode, opCode.GetDisplayName()));
                switch (opCode.GetOperandType())
                {
                case OperandType.BrTarget:
                case OperandType.ShortBrTarget:
                    output.Write(' ');
                    int targetOffset = ILParser.DecodeBranchTarget(ref blob, opCode);
                    output.WriteLocalReference($"IL_{targetOffset:x4}", targetOffset);
                    break;

                case OperandType.Field:
                case OperandType.Method:
                case OperandType.Sig:
                case OperandType.Type:
                    output.Write(' ');
                    int          metadataToken = blob.ReadInt32();
                    EntityHandle?handle        = MetadataTokenHelpers.TryAsEntityHandle(metadataToken);
                    try {
                        handle?.WriteTo(module, output, genericContext);
                    } catch (BadImageFormatException) {
                        handle = null;
                    }
                    WriteMetadataToken(handle, metadataToken, spaceBefore: true);
                    break;

                case OperandType.Tok:
                    output.Write(' ');
                    metadataToken = blob.ReadInt32();
                    handle        = MetadataTokenHelpers.TryAsEntityHandle(metadataToken);
                    switch (handle?.Kind)
                    {
                    case HandleKind.MemberReference:
                        switch (metadata.GetMemberReference((MemberReferenceHandle)handle).GetKind())
                        {
                        case MemberReferenceKind.Method:
                            output.Write("method ");
                            break;

                        case MemberReferenceKind.Field:
                            output.Write("field ");
                            break;
                        }
                        break;

                    case HandleKind.FieldDefinition:
                        output.Write("field ");
                        break;

                    case HandleKind.MethodDefinition:
                        output.Write("method ");
                        break;
                    }
                    try {
                        handle?.WriteTo(module, output, genericContext);
                    } catch (BadImageFormatException) {
                        handle = null;
                    }
                    WriteMetadataToken(handle, metadataToken, spaceBefore: true);
                    break;

                case OperandType.ShortI:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadSByte());
                    break;

                case OperandType.I:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadInt32());
                    break;

                case OperandType.I8:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadInt64());
                    break;

                case OperandType.ShortR:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadSingle());
                    break;

                case OperandType.R:
                    output.Write(' ');
                    DisassemblerHelpers.WriteOperand(output, blob.ReadDouble());
                    break;

                case OperandType.String:
                    metadataToken = blob.ReadInt32();
                    output.Write(' ');
                    UserStringHandle?userString;
                    string           text;
                    try {
                        userString = MetadataTokens.UserStringHandle(metadataToken);
                        text       = metadata.GetUserString(userString.Value);
                    } catch (BadImageFormatException) {
                        userString = null;
                        text       = null;
                    }
                    if (userString != null)
                    {
                        DisassemblerHelpers.WriteOperand(output, text);
                    }
                    WriteMetadataToken(userString, metadataToken, spaceBefore: true);
                    break;

                case OperandType.Switch:
                    int[] targets = ILParser.DecodeSwitchTargets(ref blob);
                    output.Write(" (");
                    for (int i = 0; i < targets.Length; i++)
                    {
                        if (i > 0)
                        {
                            output.Write(", ");
                        }
                        output.WriteLocalReference($"IL_{targets[i]:x4}", targets[i]);
                    }
                    output.Write(")");
                    break;

                case OperandType.Variable:
                    output.Write(' ');
                    int index = blob.ReadUInt16();
                    if (opCode == ILOpCode.Ldloc || opCode == ILOpCode.Ldloca || opCode == ILOpCode.Stloc)
                    {
                        DisassemblerHelpers.WriteVariableReference(output, metadata, methodDefinition, index);
                    }
                    else
                    {
                        DisassemblerHelpers.WriteParameterReference(output, metadata, methodDefinition, index);
                    }
                    break;

                case OperandType.ShortVariable:
                    output.Write(' ');
                    index = blob.ReadByte();
                    if (opCode == ILOpCode.Ldloc_s || opCode == ILOpCode.Ldloca_s || opCode == ILOpCode.Stloc_s)
                    {
                        DisassemblerHelpers.WriteVariableReference(output, metadata, methodDefinition, index);
                    }
                    else
                    {
                        DisassemblerHelpers.WriteParameterReference(output, metadata, methodDefinition, index);
                    }
                    break;
                }
            }
            else
            {
                ushort opCodeValue = (ushort)opCode;
                if (opCodeValue > 0xFF)
                {
                    // split 16-bit value into two emitbyte directives
                    output.WriteLine($".emitbyte 0x{(byte)(opCodeValue >> 8):x}");
                    // add label
                    output.WriteLocalReference(DisassemblerHelpers.OffsetToString(offset + 1), offset + 1, isDefinition: true);
                    output.Write(": ");
                    output.Write($".emitbyte 0x{(byte)(opCodeValue & 0xFF):x}");
                }
                else
                {
                    output.Write($".emitbyte 0x{(byte)opCodeValue:x}");
                }
            }
            output.WriteLine();
        }
Example #22
0
        public void DisassembleType(TypeDefinition type)
        {
            // start writing IL
            output.WriteDefinition(".class ", type);

            if ((type.Attributes & TypeAttributes.ClassSemanticMask) == TypeAttributes.Interface)
            {
                output.Write("interface ");
            }
            WriteEnum(type.Attributes & TypeAttributes.VisibilityMask, typeVisibility);
            WriteEnum(type.Attributes & TypeAttributes.LayoutMask, typeLayout);
            WriteEnum(type.Attributes & TypeAttributes.StringFormatMask, typeStringFormat);
            const TypeAttributes masks = TypeAttributes.ClassSemanticMask | TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.StringFormatMask;

            WriteFlags(type.Attributes & ~masks, typeAttributes);

            output.Write(DisassemblerHelpers.Escape(type.DeclaringType != null ? type.Name : type.FullName));
            WriteTypeParameters(output, type);
            output.MarkFoldStart(defaultCollapsed: isInType);
            output.WriteLine();

            if (type.BaseType != null)
            {
                output.Indent();
                output.Write("extends ");
                type.BaseType.WriteTo(output, ILNameSyntax.TypeName);
                output.WriteLine();
                output.Unindent();
            }
            if (type.HasInterfaces)
            {
                output.Indent();
                for (int index = 0; index < type.Interfaces.Count; index++)
                {
                    if (index > 0)
                    {
                        output.WriteLine(",");
                    }
                    if (index == 0)
                    {
                        output.Write("implements ");
                    }
                    else
                    {
                        output.Write("           ");
                    }
                    type.Interfaces[index].WriteTo(output, ILNameSyntax.TypeName);
                }
                output.WriteLine();
                output.Unindent();
            }

            output.WriteLine("{");
            output.Indent();
            bool oldIsInType = isInType;

            isInType = true;
            WriteAttributes(type.CustomAttributes);
            WriteSecurityDeclarations(type);
            if (type.HasLayoutInfo)
            {
                output.WriteLine(".pack {0}", type.PackingSize);
                output.WriteLine(".size {0}", type.ClassSize);
                output.WriteLine();
            }
            if (type.HasNestedTypes)
            {
                output.WriteLine("// Nested Types");
                foreach (var nestedType in type.NestedTypes)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleType(nestedType);
                    output.WriteLine();
                }
                output.WriteLine();
            }
            if (type.HasFields)
            {
                output.WriteLine("// Fields");
                foreach (var field in type.Fields)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleField(field);
                }
                output.WriteLine();
            }
            if (type.HasMethods)
            {
                output.WriteLine("// Methods");
                foreach (var m in type.Methods)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleMethod(m);
                    output.WriteLine();
                }
            }
            if (type.HasEvents)
            {
                output.WriteLine("// Events");
                foreach (var ev in type.Events)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleEvent(ev);
                    output.WriteLine();
                }
                output.WriteLine();
            }
            if (type.HasProperties)
            {
                output.WriteLine("// Properties");
                foreach (var prop in type.Properties)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleProperty(prop);
                }
                output.WriteLine();
            }
            CloseBlock("end of class " + (type.DeclaringType != null ? type.Name : type.FullName));
            isInType = oldIsInType;
        }
Example #23
0
        public void Disassemble(MethodDef method, MemberMapping debugSymbols)
        {
            // start writing IL code
            CilBody body     = method.Body;
            uint    codeSize = (uint)body.GetCodeSize();
            uint    rva      = (uint)method.RVA;
            long    offset   = method.Module.ToFileOffset(rva);

            if (options.ShowTokenAndRvaComments)
            {
                output.WriteLine(string.Format("// Header Size: {0} {1}", method.Body.HeaderSize, method.Body.HeaderSize == 1 ? "byte" : "bytes"), TextTokenType.Comment);
                output.WriteLine(string.Format("// Code Size: {0} (0x{0:X}) {1}", codeSize, codeSize == 1 ? "byte" : "bytes"), TextTokenType.Comment);
                if (body.LocalVarSigTok != 0)
                {
                    output.WriteLine(string.Format("// LocalVarSig Token: 0x{0:X8} RID: {1}", body.LocalVarSigTok, body.LocalVarSigTok & 0xFFFFFF), TextTokenType.Comment);
                }
            }
            output.Write(".maxstack", TextTokenType.ILDirective);
            output.WriteSpace();
            output.WriteLine(string.Format("{0}", body.MaxStack), TextTokenType.Number);
            if (method.DeclaringType.Module.EntryPoint == method)
            {
                output.WriteLine(".entrypoint", TextTokenType.ILDirective);
            }

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

            uint baseRva  = rva == 0 ? 0 : rva + method.Body.HeaderSize;
            long baseOffs = baseRva == 0 ? 0 : method.Module.ToFileOffset(baseRva);

            using (var byteReader = !options.ShowILBytes || options.CreateInstructionBytesReader == null ? null : options.CreateInstructionBytesReader(method)) {
                if (detectControlStructure && body.Instructions.Count > 0)
                {
                    int            index         = 0;
                    HashSet <uint> branchTargets = GetBranchTargets(body.Instructions);
                    WriteStructureBody(body, new ILStructure(body), branchTargets, ref index, debugSymbols, method.Body.GetCodeSize(), baseRva, baseOffs, byteReader, method);
                }
                else
                {
                    var instructions = method.Body.Instructions;
                    for (int i = 0; i < instructions.Count; i++)
                    {
                        var inst          = instructions[i];
                        var startLocation = output.Location;
                        inst.WriteTo(output, options, baseRva, baseOffs, byteReader, method);

                        if (debugSymbols != null)
                        {
                            // add IL code mappings - used in debugger
                            var next = i + 1 < instructions.Count ? instructions[i + 1] : null;
                            debugSymbols.MemberCodeMappings.Add(
                                new SourceCodeMapping()
                            {
                                StartLocation       = output.Location,
                                EndLocation         = output.Location,
                                ILInstructionOffset = new ILRange(inst.Offset, next == null ? (uint)method.Body.GetCodeSize() : next.Offset),
                                MemberMapping       = debugSymbols
                            });
                        }

                        output.WriteLine();
                    }
                    if (method.Body.HasExceptionHandlers)
                    {
                        output.WriteLine();
                        foreach (var eh in method.Body.ExceptionHandlers)
                        {
                            eh.WriteTo(output, method);
                            output.WriteLine();
                        }
                    }
                }
            }
        }
Example #24
0
        void DisassembleMethodInternal(MethodDefinition method)
        {
            //    .method public hidebysig  specialname
            //               instance default class [mscorlib]System.IO.TextWriter get_BaseWriter ()  cil managed
            //

            //emit flags
            WriteEnum(method.Attributes & MethodAttributes.MemberAccessMask, methodVisibility);
            WriteFlags(method.Attributes & ~MethodAttributes.MemberAccessMask, methodAttributeFlags);
            if (method.IsCompilerControlled)
            {
                output.Write("privatescope ");
            }

            if ((method.Attributes & MethodAttributes.PInvokeImpl) == MethodAttributes.PInvokeImpl)
            {
                output.Write("pinvokeimpl");
                if (method.HasPInvokeInfo && method.PInvokeInfo != null)
                {
                    PInvokeInfo info = method.PInvokeInfo;
                    output.Write("(\"" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(info.Module.Name) + "\"");

                    if (!string.IsNullOrEmpty(info.EntryPoint) && info.EntryPoint != method.Name)
                    {
                        output.Write(" as \"" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(info.EntryPoint) + "\"");
                    }

                    if (info.IsNoMangle)
                    {
                        output.Write(" nomangle");
                    }

                    if (info.IsCharSetAnsi)
                    {
                        output.Write(" ansi");
                    }
                    else if (info.IsCharSetAuto)
                    {
                        output.Write(" autochar");
                    }
                    else if (info.IsCharSetUnicode)
                    {
                        output.Write(" unicode");
                    }

                    if (info.SupportsLastError)
                    {
                        output.Write(" lasterr");
                    }

                    if (info.IsCallConvCdecl)
                    {
                        output.Write(" cdecl");
                    }
                    else if (info.IsCallConvFastcall)
                    {
                        output.Write(" fastcall");
                    }
                    else if (info.IsCallConvStdCall)
                    {
                        output.Write(" stdcall");
                    }
                    else if (info.IsCallConvThiscall)
                    {
                        output.Write(" thiscall");
                    }
                    else if (info.IsCallConvWinapi)
                    {
                        output.Write(" winapi");
                    }

                    output.Write(')');
                }
                output.Write(' ');
            }

            output.WriteLine();
            output.Indent();
            if (method.ExplicitThis)
            {
                output.Write("instance explicit ");
            }
            else if (method.HasThis)
            {
                output.Write("instance ");
            }

            //call convention
            WriteEnum(method.CallingConvention & (MethodCallingConvention)0x1f, callingConvention);

            //return type
            method.ReturnType.WriteTo(output);
            output.Write(' ');
            if (method.MethodReturnType.HasMarshalInfo)
            {
                WriteMarshalInfo(method.MethodReturnType.MarshalInfo);
            }

            if (method.IsCompilerControlled)
            {
                output.Write(DisassemblerHelpers.Escape(method.Name + "$PST" + method.MetadataToken.ToInt32().ToString("X8")));
            }
            else
            {
                output.Write(DisassemblerHelpers.Escape(method.Name));
            }

            WriteTypeParameters(output, method);

            //( params )
            output.Write(" (");
            if (method.HasParameters)
            {
                output.WriteLine();
                output.Indent();
                WriteParameters(method.Parameters);
                output.Unindent();
            }
            output.Write(") ");
            //cil managed
            WriteEnum(method.ImplAttributes & MethodImplAttributes.CodeTypeMask, methodCodeType);
            if ((method.ImplAttributes & MethodImplAttributes.ManagedMask) == MethodImplAttributes.Managed)
            {
                output.Write("managed ");
            }
            else
            {
                output.Write("unmanaged ");
            }
            WriteFlags(method.ImplAttributes & ~(MethodImplAttributes.CodeTypeMask | MethodImplAttributes.ManagedMask), methodImpl);

            output.Unindent();
            OpenBlock(defaultCollapsed: isInType);
            WriteAttributes(method.CustomAttributes);
            if (method.HasOverrides)
            {
                foreach (var methodOverride in method.Overrides)
                {
                    output.Write(".override method ");
                    methodOverride.WriteTo(output);
                    output.WriteLine();
                }
            }
            foreach (var p in method.Parameters)
            {
                WriteParameterAttributes(p);
            }
            WriteSecurityDeclarations(method);

            if (method.HasBody)
            {
                // create IL code mappings - used in debugger
                MemberMapping methodMapping = new MemberMapping(method);
                methodBodyDisassembler.Disassemble(method.Body, methodMapping);
                output.AddDebuggerMemberMapping(methodMapping);
            }

            CloseBlock("end of method " + DisassemblerHelpers.Escape(method.DeclaringType.Name) + "::" + DisassemblerHelpers.Escape(method.Name));
        }
Example #25
0
        public void DisassembleType(TypeDefinition type)
        {
            // create IL code mappings - used for debugger
            if (this.CodeMappings == null)
            {
                this.CodeMappings = new Tuple <string, List <MemberMapping> >(type.FullName, new List <MemberMapping>());
            }

            // start writing IL
            output.WriteDefinition(".class ", type);

            if ((type.Attributes & TypeAttributes.ClassSemanticMask) == TypeAttributes.Interface)
            {
                output.Write("interface ");
            }
            WriteEnum(type.Attributes & TypeAttributes.VisibilityMask, typeVisibility);
            WriteEnum(type.Attributes & TypeAttributes.LayoutMask, typeLayout);
            WriteEnum(type.Attributes & TypeAttributes.StringFormatMask, typeStringFormat);
            const TypeAttributes masks = TypeAttributes.ClassSemanticMask | TypeAttributes.VisibilityMask | TypeAttributes.LayoutMask | TypeAttributes.StringFormatMask;

            WriteFlags(type.Attributes & ~masks, typeAttributes);

            output.Write(DisassemblerHelpers.Escape(type.Name));
            WriteTypeParameters(output, type);
            output.MarkFoldStart(defaultCollapsed: isInType);
            output.WriteLine();

            if (type.BaseType != null)
            {
                output.Indent();
                output.Write("extends ");
                type.BaseType.WriteTo(output, true);
                output.WriteLine();
                output.Unindent();
            }
            if (type.HasInterfaces)
            {
                output.Indent();
                for (int index = 0; index < type.Interfaces.Count; index++)
                {
                    if (index > 0)
                    {
                        output.WriteLine(",");
                    }
                    if (index == 0)
                    {
                        output.Write("implements ");
                    }
                    else
                    {
                        output.Write("           ");
                    }
                    if (type.Interfaces[index].Namespace != null)
                    {
                        output.Write("{0}.", type.Interfaces[index].Namespace);
                    }
                    output.Write(type.Interfaces[index].Name);
                }
                output.WriteLine();
                output.Unindent();
            }

            output.WriteLine("{");
            output.Indent();
            bool oldIsInType = isInType;

            isInType = true;
            WriteAttributes(type.CustomAttributes);
            if (type.HasLayoutInfo)
            {
                output.WriteLine(".pack {0}", type.PackingSize);
                output.WriteLine(".size {0}", type.ClassSize);
                output.WriteLine();
            }
            if (type.HasNestedTypes)
            {
                output.WriteLine("// Nested Types");
                foreach (var nestedType in type.NestedTypes)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleType(nestedType);
                    output.WriteLine();
                }
                output.WriteLine();
            }
            if (type.HasFields)
            {
                output.WriteLine("// Fields");
                foreach (var field in type.Fields)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleField(field);
                }
                output.WriteLine();
            }
            if (type.HasProperties)
            {
                output.WriteLine("// Properties");
                foreach (var prop in type.Properties)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleProperty(prop);
                }
                output.WriteLine();
            }
            if (type.HasEvents)
            {
                output.WriteLine("// Events");
                foreach (var ev in type.Events)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    DisassembleEvent(ev);
                    output.WriteLine();
                }
                output.WriteLine();
            }
            if (type.HasMethods)
            {
                output.WriteLine("// Methods");
                var accessorMethods = type.GetAccessorMethods();
                foreach (var m in type.Methods)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    if (!(detectControlStructure && accessorMethods.Contains(m)))
                    {
                        DisassembleMethod(m);
                        output.WriteLine();
                    }
                }
            }
            CloseBlock("End of class " + type.FullName);
            isInType = oldIsInType;
        }
Example #26
0
        public void Disassemble(MethodDef method, MemberMapping debugSymbols)
        {
            // start writing IL code
            CilBody body     = method.Body;
            uint    codeSize = (uint)body.GetCodeSize();

            output.WriteLine(string.Format("// RVA 0x{0:x8} - 0x{1:x8} ({2} (0x{2:x}) bytes)", (uint)method.RVA, (uint)method.RVA + codeSize, codeSize), TextTokenType.Comment);
            output.WriteLine(string.Format("// Metadata token 0x{0:x8} (RID {1})", method.MDToken.ToInt32(), method.Rid), TextTokenType.Comment);
            if (body.LocalVarSigTok != 0)
            {
                output.WriteLine(string.Format("// LocalVarSig token 0x{0:x8} (RID {1})", body.LocalVarSigTok, body.LocalVarSigTok & 0xFFFFFF), TextTokenType.Comment);
            }
            output.Write(".maxstack", TextTokenType.ILDirective);
            output.WriteSpace();
            output.WriteLine(string.Format("{0}", body.MaxStack), TextTokenType.Number);
            if (method.DeclaringType.Module.EntryPoint == method)
            {
                output.WriteLine(".entrypoint", TextTokenType.ILDirective);
            }

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

            if (detectControlStructure && body.Instructions.Count > 0)
            {
                int            index         = 0;
                HashSet <uint> branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(body, new ILStructure(body), branchTargets, ref index, debugSymbols, method.Body.GetCodeSize());
            }
            else
            {
                var instructions = method.Body.Instructions;
                for (int i = 0; i < instructions.Count; i++)
                {
                    var inst          = instructions[i];
                    var startLocation = output.Location;
                    inst.WriteTo(output, options.GetOpCodeDocumentation);

                    if (debugSymbols != null)
                    {
                        // add IL code mappings - used in debugger
                        var next = i + 1 < instructions.Count ? instructions[i + 1] : null;
                        debugSymbols.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            StartLocation       = output.Location,
                            EndLocation         = output.Location,
                            ILInstructionOffset = new ILRange(inst.Offset, next == null ? (uint)method.Body.GetCodeSize() : next.Offset),
                            MemberMapping       = debugSymbols
                        });
                    }

                    output.WriteLine();
                }
                if (method.Body.HasExceptionHandlers)
                {
                    output.WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        eh.WriteTo(output);
                        output.WriteLine();
                    }
                }
            }
        }
        public void Disassemble(MethodBody body, MethodDebugSymbols debugSymbols)
        {
            // start writing IL code
            MethodDefinition method = body.Method;

            output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA);
            output.WriteLine("// Code size {0} (0x{0:x})", body.CodeSize);
            output.WriteLine(".maxstack {0}", body.MaxStackSize);
            if (method.DeclaringType.Module.Assembly != null && method.DeclaringType.Module.Assembly.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.VariableType.WriteTo(output);
                    string name;
                    if (body.Method.DebugInformation.TryGetName(v, out name))
                    {
                        output.Write(' ');
                        output.Write(DisassemblerHelpers.Escape(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)
            {
                Instruction   inst          = body.Instructions[0];
                HashSet <int> branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(new ILStructure(body), branchTargets, ref inst, debugSymbols, method.Body.CodeSize);
            }
            else
            {
                foreach (var inst in method.Body.Instructions)
                {
                    var startLocation = output.Location;
                    inst.WriteTo(output);

                    if (debugSymbols != null)
                    {
                        // add IL code mappings - used in debugger
                        debugSymbols.SequencePoints.Add(
                            new SequencePoint()
                        {
                            StartLocation = output.Location,
                            EndLocation   = output.Location,
                            ILRanges      = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? method.Body.CodeSize : inst.Next.Offset) }
                        });
                    }

                    output.WriteLine();
                }
                if (method.Body.HasExceptionHandlers)
                {
                    output.WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        eh.WriteTo(output);
                        output.WriteLine();
                    }
                }
            }
        }
        public void Disassemble(MethodDef method, CilBody body, MemberMapping methodMapping)
        {
            // start writing IL code
            output.WriteLineComment("// Method Token is 0x{0:x8}", method.MDToken.Raw);
            output.WriteLineComment("// Method begins at RVA 0x{0:x}", method.RVA);
            output.WriteLineComment("// Code size {0} (0x{0:x})", body.GetCodeSize());
            output.WriteKeyword(".maxstack ");
            output.WriteLiteral(body.MaxStack.ToString());
            output.WriteLine();
            if (method.DeclaringType.Module.Assembly != null && method.DeclaringType.Module.EntryPoint == method)
            {
                output.WriteKeyword(".entrypoint");
                output.WriteLine();
            }

            if (method.Body.HasVariables)
            {
                output.WriteKeyword(".locals ");
                if (method.Body.InitLocals)
                {
                    output.WriteKeyword("init ");
                }
                output.WriteLine("(");
                output.Indent();
                foreach (var v in method.Body.Variables)
                {
                    output.WriteDefinition("[" + v.Index + "]", v, true);
                    output.Write(" ");
                    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)
            {
                Instruction inst          = body.Instructions[0];
                var         branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(method, body, new ILStructure(body), branchTargets, ref inst, methodMapping, method.Body.GetCodeSize());
            }
            else
            {
                foreach (var inst in method.Body.Instructions)
                {
                    var startLocation = output.Location;
                    inst.WriteTo(method, body, output);

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

                    output.WriteLine();
                }
                if (method.Body.HasExceptionHandlers)
                {
                    output.WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        eh.WriteTo(output);
                        output.WriteLine();
                    }
                }
            }
        }
Example #29
0
        public void Disassemble(MethodBody body, MemberMapping methodMapping)
        {
            // start writing IL code
            MethodDefinition method = body.Method;

            output.WriteLine("// Method begins at RVA 0x{0:x4}", method.RVA);
            output.WriteLine("// Code size {0} (0x{0:x})", body.CodeSize);
            output.WriteLine(".maxstack {0}", body.MaxStackSize);
            if (method.DeclaringType.Module.Assembly.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.VariableType.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)
            {
                Instruction   inst          = body.Instructions[0];
                HashSet <int> branchTargets = GetBranchTargets(body.Instructions);
                WriteStructureBody(new ILStructure(body), branchTargets, ref inst, methodMapping, method.Body.CodeSize);
            }
            else
            {
                foreach (var inst in method.Body.Instructions)
                {
                    inst.WriteTo(output);

                    if (methodMapping != null)
                    {
                        // add IL code mappings - used in debugger
                        methodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            SourceCodeLine      = output.CurrentLine,
                            ILInstructionOffset = new ILRange {
                                From = inst.Offset, To = inst.Next == null ? method.Body.CodeSize : inst.Next.Offset
                            },
                            MemberMapping = methodMapping
                        });
                    }

                    output.WriteLine();
                }
                if (method.Body.HasExceptionHandlers)
                {
                    output.WriteLine();
                    foreach (var eh in method.Body.ExceptionHandlers)
                    {
                        eh.WriteTo(output);
                        output.WriteLine();
                    }
                }
            }
        }
Example #30
0
        void WriteSecurityDeclarations(ISecurityDeclarationProvider secDeclProvider)
        {
            if (!secDeclProvider.HasSecurityDeclarations)
            {
                return;
            }
            foreach (var secdecl in secDeclProvider.SecurityDeclarations)
            {
                output.Write(".permissionset ");
                switch (secdecl.Action)
                {
                case SecurityAction.Request:
                    output.Write("request");
                    break;

                case SecurityAction.Demand:
                    output.Write("demand");
                    break;

                case SecurityAction.Assert:
                    output.Write("assert");
                    break;

                case SecurityAction.Deny:
                    output.Write("deny");
                    break;

                case SecurityAction.PermitOnly:
                    output.Write("permitonly");
                    break;

                case SecurityAction.LinkDemand:
                    output.Write("linkcheck");
                    break;

                case SecurityAction.InheritDemand:
                    output.Write("inheritcheck");
                    break;

                case SecurityAction.RequestMinimum:
                    output.Write("reqmin");
                    break;

                case SecurityAction.RequestOptional:
                    output.Write("reqopt");
                    break;

                case SecurityAction.RequestRefuse:
                    output.Write("reqrefuse");
                    break;

                case SecurityAction.PreJitGrant:
                    output.Write("prejitgrant");
                    break;

                case SecurityAction.PreJitDeny:
                    output.Write("prejitdeny");
                    break;

                case SecurityAction.NonCasDemand:
                    output.Write("noncasdemand");
                    break;

                case SecurityAction.NonCasLinkDemand:
                    output.Write("noncaslinkdemand");
                    break;

                case SecurityAction.NonCasInheritance:
                    output.Write("noncasinheritance");
                    break;

                default:
                    output.Write(secdecl.Action.ToString());
                    break;
                }
                output.WriteLine(" = {");
                output.Indent();
                for (int i = 0; i < secdecl.SecurityAttributes.Count; i++)
                {
                    SecurityAttribute sa = secdecl.SecurityAttributes[i];
                    if (sa.AttributeType.Scope == sa.AttributeType.Module)
                    {
                        output.Write("class ");
                        output.Write(DisassemblerHelpers.Escape(GetAssemblyQualifiedName(sa.AttributeType)));
                    }
                    else
                    {
                        sa.AttributeType.WriteTo(output, ILNameSyntax.TypeName);
                    }
                    output.Write(" = {");
                    if (sa.HasFields || sa.HasProperties)
                    {
                        output.WriteLine();
                        output.Indent();

                        foreach (CustomAttributeNamedArgument na in sa.Fields)
                        {
                            output.Write("field ");
                            WriteSecurityDeclarationArgument(na);
                            output.WriteLine();
                        }

                        foreach (CustomAttributeNamedArgument na in sa.Properties)
                        {
                            output.Write("property ");
                            WriteSecurityDeclarationArgument(na);
                            output.WriteLine();
                        }

                        output.Unindent();
                    }
                    output.Write('}');

                    if (i + 1 < secdecl.SecurityAttributes.Count)
                    {
                        output.Write(',');
                    }
                    output.WriteLine();
                }
                output.Unindent();
                output.WriteLine("}");
            }
        }