예제 #1
0
        public static void WriteTo(this Instruction instruction, MethodDef method, CilBody body, ITextOutput writer)
        {
            writer.WriteDefinition(dnlibExtensions.OffsetToString(instruction.Offset), instruction, true);
            writer.Write(": ");
            writer.WriteReference(instruction.OpCode.Name, instruction.OpCode, true);
            if (instruction.Operand != null)
            {
                writer.Write(' ');
                if (instruction.OpCode == OpCodes.Ldtoken)
                {
                    if (dnlibExtensions.IsMethod(instruction.Operand))
                    {
                        writer.WriteKeyword("method ");
                    }
                    else if (dnlibExtensions.IsField(instruction.Operand))
                    {
                        writer.WriteKeyword("field ");
                    }
                }
                WriteOperand(writer, instruction.Operand);
            }
            else if (method != null && body != null)
            {
                switch (instruction.OpCode.Code)
                {
                case Code.Ldloc_0:
                case Code.Ldloc_1:
                case Code.Ldloc_2:
                case Code.Ldloc_3:
                    writer.WriteComment("  // ");
                    var local = instruction.GetLocal(body.Variables);
                    if (local != null)
                    {
                        WriteOperand(writer, local);
                    }
                    break;

                case Code.Ldarg_0:
                case Code.Ldarg_1:
                case Code.Ldarg_2:
                case Code.Ldarg_3:
                    writer.WriteComment("  // ");
                    var arg = instruction.GetParameter(method.Parameters);
                    if (arg != null)
                    {
                        WriteOperand(writer, arg);
                    }
                    break;
                }
            }
        }
예제 #2
0
        public void WriteKeyword(string keyword)
        {
            IMemberRef memberRef = GetCurrentMemberReference();
            var        node      = nodeStack.Peek();

            if (memberRef != null && (node is ConstructorInitializer || node is PrimitiveType))
            {
                output.WriteReference(keyword, memberRef);
            }
            else
            {
                output.WriteKeyword(keyword);
            }
        }
		public static void WriteTo(this Instruction instruction, MethodDef method, CilBody body, ITextOutput writer)
		{
			writer.WriteDefinition(dnlibExtensions.OffsetToString(instruction.Offset), instruction, true);
			writer.Write(": ");
			writer.WriteReference(instruction.OpCode.Name, instruction.OpCode, true);
			if (instruction.Operand != null) {
				writer.Write(' ');
				if (instruction.OpCode == OpCodes.Ldtoken) {
					if (dnlibExtensions.IsMethod(instruction.Operand))
						writer.WriteKeyword("method ");
					else if (dnlibExtensions.IsField(instruction.Operand))
						writer.WriteKeyword("field ");
				}
				WriteOperand(writer, instruction.Operand);
			}
			else if (method != null && body != null) {
				switch (instruction.OpCode.Code) {
					case Code.Ldloc_0:
					case Code.Ldloc_1:
					case Code.Ldloc_2:
					case Code.Ldloc_3:
						writer.WriteComment("  // ");
						var local = instruction.GetLocal(body.Variables);
						if (local != null)
							WriteOperand(writer, local);
						break;

					case Code.Ldarg_0:
					case Code.Ldarg_1:
					case Code.Ldarg_2:
					case Code.Ldarg_3:
						writer.WriteComment("  // ");
						var arg = instruction.GetParameter(method.Parameters);
						if (arg != null)
							WriteOperand(writer, arg);
						break;
				}
			}
		}
		public static void WriteTo(this ITypeDefOrRef type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature)
		{
			if (type is TypeSpec) {
				((TypeSpec)type).TypeSig.WriteTo(writer, syntax);
				return;
			}

			string name = PrimitiveTypeName(type.FullName);
			if (syntax == ILNameSyntax.ShortTypeName) {
				if (name != null)
					writer.WriteKeyword(name);
				else
					writer.WriteReference(Escape(type.Name), type);
			}
			else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) {
				writer.WriteKeyword(name);
			}
			else {
				if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
					writer.WriteKeyword(type.IsValueType ? "valuetype " : "class ");

				if (type.DeclaringType != null) {
					type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
					writer.Write('/');
					writer.WriteReference(Escape(type.Name), type);
				}
				else {
					if (!(type is TypeDef) && type.Scope != null) {
						IAssembly assembly;
						if (type.Scope is IAssembly)
							assembly = (IAssembly)type.Scope;
						else if (type.Scope is ModuleRef)
							assembly = ((ModuleRef)type.Scope).DefinitionAssembly;
						else if (type.Scope is ModuleDef)
							assembly = ((ModuleDef)type.Scope).Assembly;
						else
							throw new NotSupportedException();
						writer.Write("[");
						writer.WriteReference(Escape(assembly.Name), assembly);
						writer.Write("]");
					}
					writer.WriteReference(Escape(type.FullName), type);
				}
			}
		}
		public static void WriteTo(this TypeSig type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature)
		{
			ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;
			if (type is PinnedSig) {
				type.Next.WriteTo(writer, syntaxForElementTypes);
				writer.WriteKeyword(" pinned");
			} else if (type is SZArraySig) {
				type.Next.WriteTo(writer, syntaxForElementTypes);
				writer.Write("[]");
			} else if (type is ArraySig) {
				ArraySig sig = (ArraySig)type;
				type.Next.WriteTo(writer, syntaxForElementTypes);
				writer.Write('[');
				for (int i = 0; i < sig.Rank; i++) {
					if (i != 0)
						writer.Write(", ");
					int? lower = i < sig.LowerBounds.Count ? sig.LowerBounds[i] : (int?)null;
					uint? size = i < sig.Sizes.Count ? sig.Sizes[i] : (uint?)null;
					if (lower != null) {
						writer.Write(lower.ToString());
						writer.Write("..");
						if (size != null)
							writer.Write((lower.Value + (int)size.Value - 1).ToString());
						else
							writer.Write(".");
					}
				}
				writer.Write(']');
			} else if (type is GenericSig) {
				writer.Write('!');
				if (type is GenericMVar)
					writer.Write('!');
				var genericParam = ((GenericSig)type).GenericParam;
				if (genericParam == null || string.IsNullOrEmpty(genericParam.Name) ||
					syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
					writer.Write(((GenericSig)type).Number.ToString());
				else
					writer.Write(Escape(genericParam.Name));
			} else if (type is ByRefSig) {
				type.Next.WriteTo(writer, syntaxForElementTypes);
				writer.Write('&');
			} else if (type is PtrSig) {
				type.Next.WriteTo(writer, syntaxForElementTypes);
				writer.Write('*');
			} else if (type is GenericInstSig) {
				((GenericInstSig)type).GenericType.WriteTo(writer, syntaxForElementTypes);
				writer.Write('<');
				var arguments = ((GenericInstSig)type).GenericArguments;
				for (int i = 0; i < arguments.Count; i++) {
					if (i > 0)
						writer.Write(", ");
					arguments[i].WriteTo(writer, syntaxForElementTypes);
				}
				writer.Write('>');
			} else if (type is CModOptSig) {
				type.Next.WriteTo(writer, syntax);
				writer.WriteKeyword(" modopt(");
				((CModOptSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName);
				writer.WriteKeyword(") ");
			} else if (type is CModReqdSig) {
				type.Next.WriteTo(writer, syntax);
				writer.WriteKeyword(" modreq(");
				((CModReqdSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName);
				writer.WriteKeyword(") ");
			} else if (type is ValueArraySig) {
				type.Next.WriteTo(writer, syntax);
				writer.WriteKeyword(" ValueArray(");
				writer.Write(((ValueArraySig)type).Size.ToString());
				writer.WriteKeyword(") ");
			} else if (type is ModuleSig) {
				type.Next.WriteTo(writer, syntax);
				writer.WriteKeyword(" Module(");
				writer.Write(((ModuleSig)type).Index.ToString());
				writer.WriteKeyword(") ");
			} else if (type is FnPtrSig) {
				((FnPtrSig)type).MethodSig.WriteTo(null, writer);
			} else if (type is TypeDefOrRefSig) {
				((TypeDefOrRefSig)type).TypeDefOrRef.WriteTo(writer, syntax);
			}
		}
		public static void WriteTo(this MethodSig signature, IMethod method, ITextOutput writer)
		{
			if (signature.ExplicitThis) {
				writer.WriteKeyword("instance explicit ");
			}
			else if (signature.HasThis) {
				writer.WriteKeyword("instance ");
			}
			signature.RetType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
			writer.Write(' ');
			if (method != null && method.DeclaringType != null) {
				method.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
				writer.Write("::");
			}
			MethodDef md = method as MethodDef;
			if (md != null && md.IsCompilerControlled) {
				writer.WriteReference(Escape(method.Name + "$PST" + method.MDToken.Raw.ToString("X8")), method);
			} else if (method != null) {
				writer.WriteReference(Escape(method.Name), method);
			} else {
				writer.Write("(*)");
			}
			MethodSpec methodSpec = method as MethodSpec;
			if (methodSpec != null) {
				writer.Write('<');
				var genArgs = methodSpec.GenericInstMethodSig.GenericArguments;
				for (int i = 0; i < genArgs.Count; i++) {
					if (i > 0)
						writer.Write(", ");
					genArgs[i].WriteTo(writer);
				}
				writer.Write('>');
			}
			writer.Write("(");
			for (int i = 0; i < signature.Params.Count; ++i) {
				if (i > 0) writer.Write(", ");
				signature.Params[i].WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
			}
			if (signature.ParamsAfterSentinel != null && signature.ParamsAfterSentinel.Count > 0) {
				if (signature.Params.Count > 0)
					writer.Write(", ");

				writer.Write("...");
				for (int i = 0; i < signature.ParamsAfterSentinel.Count; ++i) {
					if (i > 0) writer.Write(", ");
					signature.ParamsAfterSentinel[i].WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
				}
			}
			writer.Write(")");
		}
예제 #7
0
        public static void WriteTo(this ITypeDefOrRef type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature)
        {
            if (type is TypeSpec)
            {
                ((TypeSpec)type).TypeSig.WriteTo(writer, syntax);
                return;
            }

            string name = PrimitiveTypeName(type.FullName);

            if (syntax == ILNameSyntax.ShortTypeName)
            {
                if (name != null)
                {
                    writer.WriteKeyword(name);
                }
                else
                {
                    writer.WriteReference(Escape(type.Name), type);
                }
            }
            else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null)
            {
                writer.WriteKeyword(name);
            }
            else
            {
                if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
                {
                    writer.WriteKeyword(type.IsValueType ? "valuetype " : "class ");
                }

                if (type.DeclaringType != null)
                {
                    type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
                    writer.Write('/');
                    writer.WriteReference(Escape(type.Name), type);
                }
                else
                {
                    if (!(type is TypeDef) && type.Scope != null)
                    {
                        IAssembly assembly;
                        if (type.Scope is IAssembly)
                        {
                            assembly = (IAssembly)type.Scope;
                        }
                        else if (type.Scope is ModuleRef)
                        {
                            assembly = ((ModuleRef)type.Scope).DefinitionAssembly;
                        }
                        else if (type.Scope is ModuleDef)
                        {
                            assembly = ((ModuleDef)type.Scope).Assembly;
                        }
                        else
                        {
                            throw new NotSupportedException();
                        }
                        writer.Write("[");
                        writer.WriteReference(Escape(assembly.Name), assembly);
                        writer.Write("]");
                    }
                    writer.WriteReference(Escape(type.FullName), type);
                }
            }
        }
예제 #8
0
        public static void WriteTo(this TypeSig type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature)
        {
            ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature;

            if (type is PinnedSig)
            {
                type.Next.WriteTo(writer, syntaxForElementTypes);
                writer.WriteKeyword(" pinned");
            }
            else if (type is SZArraySig)
            {
                type.Next.WriteTo(writer, syntaxForElementTypes);
                writer.Write("[]");
            }
            else if (type is ArraySig)
            {
                ArraySig sig = (ArraySig)type;
                type.Next.WriteTo(writer, syntaxForElementTypes);
                writer.Write('[');
                for (int i = 0; i < sig.Rank; i++)
                {
                    if (i != 0)
                    {
                        writer.Write(", ");
                    }
                    int? lower = i < sig.LowerBounds.Count ? sig.LowerBounds[i] : (int?)null;
                    uint?size  = i < sig.Sizes.Count ? sig.Sizes[i] : (uint?)null;
                    if (lower != null)
                    {
                        writer.Write(lower.ToString());
                        writer.Write("..");
                        if (size != null)
                        {
                            writer.Write((lower.Value + (int)size.Value - 1).ToString());
                        }
                        else
                        {
                            writer.Write(".");
                        }
                    }
                }
                writer.Write(']');
            }
            else if (type is GenericSig)
            {
                writer.Write('!');
                if (type is GenericMVar)
                {
                    writer.Write('!');
                }
                var genericParam = ((GenericSig)type).GenericParam;
                if (genericParam == null || string.IsNullOrEmpty(genericParam.Name) ||
                    syntax == ILNameSyntax.SignatureNoNamedTypeParameters)
                {
                    writer.Write(((GenericSig)type).Number.ToString());
                }
                else
                {
                    writer.Write(Escape(genericParam.Name));
                }
            }
            else if (type is ByRefSig)
            {
                type.Next.WriteTo(writer, syntaxForElementTypes);
                writer.Write('&');
            }
            else if (type is PtrSig)
            {
                type.Next.WriteTo(writer, syntaxForElementTypes);
                writer.Write('*');
            }
            else if (type is GenericInstSig)
            {
                ((GenericInstSig)type).GenericType.WriteTo(writer, syntaxForElementTypes);
                writer.Write('<');
                var arguments = ((GenericInstSig)type).GenericArguments;
                for (int i = 0; i < arguments.Count; i++)
                {
                    if (i > 0)
                    {
                        writer.Write(", ");
                    }
                    arguments[i].WriteTo(writer, syntaxForElementTypes);
                }
                writer.Write('>');
            }
            else if (type is CModOptSig)
            {
                type.Next.WriteTo(writer, syntax);
                writer.WriteKeyword(" modopt(");
                ((CModOptSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName);
                writer.WriteKeyword(") ");
            }
            else if (type is CModReqdSig)
            {
                type.Next.WriteTo(writer, syntax);
                writer.WriteKeyword(" modreq(");
                ((CModReqdSig)type).Modifier.WriteTo(writer, ILNameSyntax.TypeName);
                writer.WriteKeyword(") ");
            }
            else if (type is ValueArraySig)
            {
                type.Next.WriteTo(writer, syntax);
                writer.WriteKeyword(" ValueArray(");
                writer.Write(((ValueArraySig)type).Size.ToString());
                writer.WriteKeyword(") ");
            }
            else if (type is ModuleSig)
            {
                type.Next.WriteTo(writer, syntax);
                writer.WriteKeyword(" Module(");
                writer.Write(((ModuleSig)type).Index.ToString());
                writer.WriteKeyword(") ");
            }
            else if (type is FnPtrSig)
            {
                ((FnPtrSig)type).MethodSig.WriteTo(null, writer);
            }
            else if (type is TypeDefOrRefSig)
            {
                ((TypeDefOrRefSig)type).TypeDefOrRef.WriteTo(writer, syntax);
            }
        }
예제 #9
0
        public static void WriteTo(this MethodSig signature, IMethod method, ITextOutput writer)
        {
            if (signature.ExplicitThis)
            {
                writer.WriteKeyword("instance explicit ");
            }
            else if (signature.HasThis)
            {
                writer.WriteKeyword("instance ");
            }
            signature.RetType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
            writer.Write(' ');
            if (method != null && method.DeclaringType != null)
            {
                method.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName);
                writer.Write("::");
            }
            MethodDef md = method as MethodDef;

            if (md != null && md.IsCompilerControlled)
            {
                writer.WriteReference(Escape(method.Name + "$PST" + method.MDToken.Raw.ToString("X8")), method);
            }
            else if (method != null)
            {
                writer.WriteReference(Escape(method.Name), method);
            }
            else
            {
                writer.Write("(*)");
            }
            MethodSpec methodSpec = method as MethodSpec;

            if (methodSpec != null)
            {
                writer.Write('<');
                var genArgs = methodSpec.GenericInstMethodSig.GenericArguments;
                for (int i = 0; i < genArgs.Count; i++)
                {
                    if (i > 0)
                    {
                        writer.Write(", ");
                    }
                    genArgs[i].WriteTo(writer);
                }
                writer.Write('>');
            }
            writer.Write("(");
            for (int i = 0; i < signature.Params.Count; ++i)
            {
                if (i > 0)
                {
                    writer.Write(", ");
                }
                signature.Params[i].WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
            }
            if (signature.ParamsAfterSentinel != null && signature.ParamsAfterSentinel.Count > 0)
            {
                if (signature.Params.Count > 0)
                {
                    writer.Write(", ");
                }

                writer.Write("...");
                for (int i = 0; i < signature.ParamsAfterSentinel.Count; ++i)
                {
                    if (i > 0)
                    {
                        writer.Write(", ");
                    }
                    signature.ParamsAfterSentinel[i].WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters);
                }
            }
            writer.Write(")");
        }
        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();
                    }
                }
            }
        }
예제 #11
0
 public void WriteKeyword(string keyword)
 {
     output.WriteKeyword(keyword);
 }