public void DisassembleField(FieldDefinition field) { _output.WriteDefinition(".field ", field); if (field.HasLayoutInfo) { _output.Write("[" + field.Offset + "] "); } WriteEnum(field.Attributes & FieldAttributes.FieldAccessMask, _fieldVisibility); const FieldAttributes hasXAttributes = FieldAttributes.HasDefault | FieldAttributes.HasFieldMarshal | FieldAttributes.HasFieldRVA; WriteFlags(field.Attributes & ~(FieldAttributes.FieldAccessMask | hasXAttributes), _fieldAttributes); if (field.HasMarshalInfo) { WriteMarshalInfo(field.MarshalInfo); } field.FieldType.WriteTo(_output); _output.Write(' '); _output.Write(DisassemblerHelpers.Escape(field.Name)); if ((field.Attributes & FieldAttributes.HasFieldRVA) == FieldAttributes.HasFieldRVA) { _output.Write(" at I_{0:x8}", field.RVA); } if (field.HasConstant) { _output.Write(" = "); WriteConstant(field.Constant); } _output.WriteLine(); if (field.HasCustomAttributes) { _output.MarkFoldStart(); WriteAttributes(field.CustomAttributes); _output.MarkFoldEnd(); } }
public void DisassembleProperty(PropertyDefinition property) { // set current member _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(); }
private void WriteParameters(Collection <ParameterDefinition> parameters) { for (var i = 0; i < parameters.Count; i++) { var p = parameters[i]; if (p.IsIn) { _output.Write("[in] "); } if (p.IsOut) { _output.Write("[out] "); } if (p.IsOptional) { _output.Write("[opt] "); } p.ParameterType.WriteTo(_output); _output.Write(' '); if (p.HasMarshalInfo) { WriteMarshalInfo(p.MarshalInfo); } _output.WriteDefinition(DisassemblerHelpers.Escape(p.Name), p); if (i < parameters.Count - 1) { _output.Write(','); } _output.WriteLine(); } }
private void WriteSecurityDeclarationArgument(CustomAttributeNamedArgument na) { var type = na.Argument.Type; if (type.MetadataType == MetadataType.Class || type.MetadataType == MetadataType.ValueType) { _output.Write("enum "); if (type.Scope != type.Module) { _output.Write("class "); _output.Write(DisassemblerHelpers.Escape(GetAssemblyQualifiedName(type))); } else { type.WriteTo(_output, ILNameSyntax.TypeName); } } else { type.WriteTo(_output); } _output.Write(' '); _output.Write(DisassemblerHelpers.Escape(na.Name)); _output.Write(" = "); if (na.Argument.Value is string value) { // secdecls use special syntax for strings _output.Write("string('{0}')", TextWriterTokenWriter.ConvertString(value).Replace("'", "\'")); } else { WriteConstant(na.Argument.Value); } }
public void WriteModuleHeader(ModuleDefinition module) { if (module.HasExportedTypes) { foreach (var exportedType in module.ExportedTypes) { _output.Write(".class extern "); if (exportedType.IsForwarder) { _output.Write("forwarder "); } _output.Write(exportedType.DeclaringType != null ? exportedType.Name : exportedType.FullName); OpenBlock(false); if (exportedType.DeclaringType != null) { _output.WriteLine(".class extern {0}", DisassemblerHelpers.Escape(exportedType.DeclaringType.FullName)); } else { _output.WriteLine(".assembly extern {0}", DisassemblerHelpers.Escape(exportedType.Scope.Name)); } CloseBlock(); } } _output.WriteLine(".module {0}", module.Name); _output.WriteLine("// MVID: {0}", module.Mvid.ToString("B").ToUpperInvariant()); // TODO: imagebase, file alignment, stackreserve, subsystem _output.WriteLine(".corflags 0x{0:x} // {1}", module.Attributes, module.Attributes.ToString()); WriteAttributes(module.CustomAttributes); }
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 "); if (aref.IsWindowsRuntime) { _output.Write("windowsruntime "); } _output.Write(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 WriteAssemblyHeader(AssemblyDefinition asm) { _output.Write(".assembly "); if (asm.Name.IsWindowsRuntime) { _output.Write("windowsruntime "); } _output.Write(DisassemblerHelpers.Escape(asm.Name.Name)); OpenBlock(false); WriteAttributes(asm.CustomAttributes); WriteSecurityDeclarations(asm); if (asm.Name.PublicKey != null && asm.Name.PublicKey.Length > 0) { _output.Write(".publickey = "); WriteBlob(asm.Name.PublicKey); _output.WriteLine(); } 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(); } var v = asm.Name.Version; if (v != null) { _output.WriteLine(".ver {0}:{1}:{2}:{3}", v.Major, v.Minor, v.Build, v.Revision); } CloseBlock(); }
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(); } } } }