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 Mi.Assemblies.Cil.ExceptionHandlerType.Catch: case Mi.Assemblies.Cil.ExceptionHandlerType.Filter: output.Write("catch"); if (s.ExceptionHandler.CatchType != null) { output.Write(' '); s.ExceptionHandler.CatchType.WriteTo(output, ILNameSyntax.TypeName); } output.WriteLine(); break; case Mi.Assemblies.Cil.ExceptionHandlerType.Finally: output.WriteLine("finally {"); break; case Mi.Assemblies.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 WriteTypeParameters(ITextOutput output, IGenericParameterProvider p) { if (p.HasGenericParameters) { output.Write('<'); for (int i = 0; i < p.GenericParameters.Count; i++) { if (i > 0) { output.Write(", "); } GenericParameter 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 (int 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 currentMember = ev; 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); } bool oldIsInType = isInType; isInType = true; foreach (TypeDefinition td in types) { verifyProgress(); DisassembleType(td); output.WriteLine(); } if (!string.IsNullOrEmpty(nameSpace)) { CloseBlock(); isInType = oldIsInType; } }
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(); } }
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(); }
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(); } } } }
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("}"); } }
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("(\"" + CSharp.OutputVisitor.ConvertString(info.Module.Name) + "\""); if (!string.IsNullOrEmpty(info.EntryPoint) && info.EntryPoint != method.Name) { output.Write(" as \"" + CSharp.OutputVisitor.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 CreateCodeMappings(method.MetadataToken.ToInt32(), currentMember); MemberMapping methodMapping = method.CreateCodeMapping(this.CodeMappings[method.MetadataToken.ToInt32()], currentMember); methodBodyDisassembler.Disassemble(method.Body, methodMapping); } 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 (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) { verifyProgress(); DisassembleType(nestedType); output.WriteLine(); } output.WriteLine(); } if (type.HasFields) { output.WriteLine("// Fields"); foreach (var field in type.Fields) { verifyProgress(); DisassembleField(field); } output.WriteLine(); } if (type.HasMethods) { output.WriteLine("// Methods"); foreach (var m in type.Methods) { verifyProgress(); DisassembleMethod(m); output.WriteLine(); } } if (type.HasEvents) { output.WriteLine("// Events"); foreach (var ev in type.Events) { verifyProgress(); DisassembleEvent(ev); output.WriteLine(); } output.WriteLine(); } if (type.HasProperties) { output.WriteLine("// Properties"); foreach (var prop in type.Properties) { verifyProgress(); DisassembleProperty(prop); } output.WriteLine(); } CloseBlock("end of class " + (type.DeclaringType != null ? type.Name : type.FullName)); isInType = oldIsInType; }