private 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 ExceptionHandlerType.Catch: case ExceptionHandlerType.Filter: _output.Write("catch"); if (s.ExceptionHandler?.CatchType != null) { _output.Write(' '); s.ExceptionHandler.CatchType.WriteTo(_output, ILNameSyntax.TypeName); } _output.WriteLine(); break; case ExceptionHandlerType.Finally: _output.WriteLine("finally"); break; case 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(); }
private void WriteTypeParameters(ITextOutput output, IGenericParameterProvider p) { if (p.HasGenericParameters) { 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 DisassembleEvent(EventDefinition ev) { // set current member _output.WriteDefinition(".event ", ev); WriteFlags(ev.Attributes, _eventAttributes); ev.EventType.WriteTo(_output, ILNameSyntax.TypeName); _output.Write(' '); _output.Write(DisassemblerHelpers.Escape(ev.Name)); OpenBlock(false); 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(); }
public void DisassembleNamespace(string nameSpace, IEnumerable <TypeDefinition> types) { if (!string.IsNullOrEmpty(nameSpace)) { _output.Write(".namespace " + DisassemblerHelpers.Escape(nameSpace)); OpenBlock(false); } var oldIsInType = _isInType; _isInType = true; foreach (var td in types) { _cancellationToken.ThrowIfCancellationRequested(); DisassembleType(td); _output.WriteLine(); } if (!string.IsNullOrEmpty(nameSpace)) { CloseBlock(); _isInType = oldIsInType; } }
private 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 (var i = 0; i < secdecl.SecurityAttributes.Count; i++) { var 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 (var na in sa.Fields) { _output.Write("field "); WriteSecurityDeclarationArgument(na); _output.WriteLine(); } foreach (var 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("}"); } }
private 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) { var info = method.PInvokeInfo; _output.Write("(\"" + TextWriterTokenWriter.ConvertString(info.Module.Name) + "\""); if (!string.IsNullOrEmpty(info.EntryPoint) && info.EntryPoint != method.Name) { _output.Write(" as \"" + TextWriterTokenWriter.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 // ReSharper disable once BitwiseOperatorOnEnumWithoutFlags WriteEnum(method.CallingConvention & (MethodCallingConvention)0x1f, _callingConvention); //return type method.ReturnType.WriteTo(_output); _output.Write(' '); if (method.MethodReturnType.HasMarshalInfo) { WriteMarshalInfo(method.MethodReturnType.MarshalInfo); } _output.Write(method.IsCompilerControlled ? DisassemblerHelpers.Escape(method.Name + "$PST" + method.MetadataToken.ToInt32().ToString("X8")) : 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); _output.Write((method.ImplAttributes & MethodImplAttributes.ManagedMask) == MethodImplAttributes.Managed ? "managed " : "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(); } } WriteParameterAttributes(0, method.MethodReturnType, method.MethodReturnType); foreach (var p in method.Parameters) { WriteParameterAttributes(p.Index + 1, p, p); } WriteSecurityDeclarations(method); if (method.HasBody) { // create IL code mappings - used in debugger _methodBodyDisassembler.Disassemble(method.Body); } CloseBlock("end of method " + DisassemblerHelpers.Escape(method.DeclaringType.Name) + "::" + DisassemblerHelpers.Escape(method.Name)); }
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 (var index = 0; index < type.Interfaces.Count; index++) { if (index > 0) { _output.WriteLine(","); } _output.Write(index == 0 ? "implements " : " "); type.Interfaces[index].InterfaceType.WriteTo(_output, ILNameSyntax.TypeName); } _output.WriteLine(); _output.Unindent(); } _output.WriteLine("{"); _output.Indent(); var 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; }
public void Disassemble(MethodBody body) { // start writing IL code var 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); if (!string.IsNullOrEmpty(v.ToString())) { _output.Write(' '); _output.Write(DisassemblerHelpers.Escape(v.ToString())); } if (v.Index + 1 < method.Body.Variables.Count) { _output.Write(','); } _output.WriteLine(); } _output.Unindent(); _output.WriteLine(")"); } _output.WriteLine(); if (_detectControlStructure && body.Instructions.Count > 0) { var inst = body.Instructions[0]; var branchTargets = GetBranchTargets(body.Instructions); WriteStructureBody(new ILStructure(body), branchTargets, ref inst); } else { foreach (var inst in method.Body.Instructions) { inst.WriteTo(_output); _output.WriteLine(); } if (method.Body.HasExceptionHandlers) { _output.WriteLine(); foreach (var eh in method.Body.ExceptionHandlers) { eh.WriteTo(_output); _output.WriteLine(); } } } }