public static void WriteTo(this Instruction instruction, ITextOutput writer, Func<OpCode, string> getOpCodeDocumentation) { writer.WriteDefinition(DnlibExtensions.OffsetToString(instruction.GetOffset()), instruction, TextTokenType.Label, false); writer.Write(':', TextTokenType.Operator); writer.WriteSpace(); writer.WriteReference(instruction.OpCode.Name, instruction.OpCode, TextTokenType.OpCode); if (instruction.Operand != null) { writer.WriteSpace(); if (instruction.OpCode == OpCodes.Ldtoken) { var member = instruction.Operand as IMemberRef; if (member != null && member.IsMethod) { writer.Write("method", TextTokenType.Keyword); writer.WriteSpace(); } else if (member != null && member.IsField) { writer.Write("field", TextTokenType.Keyword); writer.WriteSpace(); } } WriteOperand(writer, instruction.Operand); } if (getOpCodeDocumentation != null) { var doc = getOpCodeDocumentation(instruction.OpCode); if (doc != null) { writer.Write("\t", TextTokenType.Text); writer.Write("// " + doc, TextTokenType.Comment); } } }
public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) { if (options.FullDecompilation && options.SaveAsProjectDirectory != null) { HashSet<string> directories = new HashSet<string>(StringComparer.OrdinalIgnoreCase); var files = WriteCodeFilesInProject(assembly.AssemblyDefinition, options, directories).ToList(); files.AddRange(WriteResourceFilesInProject(assembly, options, directories)); WriteProjectFile(new TextOutputWriter(output), files, assembly.AssemblyDefinition.MainModule); } else { base.DecompileAssembly(assembly, output, options); output.WriteLine(); ModuleDefinition mainModule = assembly.AssemblyDefinition.MainModule; if (mainModule.EntryPoint != null) { output.Write("' Entry point: "); output.WriteReference(mainModule.EntryPoint.DeclaringType.FullName + "." + mainModule.EntryPoint.Name, mainModule.EntryPoint); output.WriteLine(); } switch (mainModule.Architecture) { case TargetArchitecture.I386: if ((mainModule.Attributes & ModuleAttributes.Required32Bit) == ModuleAttributes.Required32Bit) WriteCommentLine(output, "Architecture: x86"); else WriteCommentLine(output, "Architecture: AnyCPU"); break; case TargetArchitecture.AMD64: WriteCommentLine(output, "Architecture: x64"); break; case TargetArchitecture.IA64: WriteCommentLine(output, "Architecture: Itanium-64"); break; } if ((mainModule.Attributes & ModuleAttributes.ILOnly) == 0) { WriteCommentLine(output, "This assembly contains unmanaged code."); } switch (mainModule.Runtime) { case TargetRuntime.Net_1_0: WriteCommentLine(output, "Runtime: .NET 1.0"); break; case TargetRuntime.Net_1_1: WriteCommentLine(output, "Runtime: .NET 1.1"); break; case TargetRuntime.Net_2_0: WriteCommentLine(output, "Runtime: .NET 2.0"); break; case TargetRuntime.Net_4_0: WriteCommentLine(output, "Runtime: .NET 4.0"); break; } output.WriteLine(); // don't automatically load additional assemblies when an assembly node is selected in the tree view using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) { AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.AssemblyDefinition.MainModule); codeDomBuilder.AddAssembly(assembly.AssemblyDefinition, onlyAssemblyLevel: !options.FullDecompilation); RunTransformsAndGenerateCode(codeDomBuilder, output, options); } } OnDecompilationFinished(null); }
public static void WriteTo(this Instruction instruction, ITextOutput writer) { writer.WriteDefinition(CecilExtensions.OffsetToString(instruction.Offset), instruction); writer.Write(": "); writer.WriteReference(instruction.OpCode.Name, instruction.OpCode); if(null != instruction.Operand) { writer.Write(' '); WriteOperand(writer, instruction.Operand); } }
public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) { if (options.FullDecompilation && options.SaveAsProjectDirectory != null) { var decompiler = new VBProjectDecompiler(); decompiler.Decompile(this, assembly, output, options); } else { base.DecompileAssembly(assembly, output, options); output.WriteLine(); ModuleDefinition mainModule = assembly.ModuleDefinition; if (mainModule.EntryPoint != null) { output.Write("' Entry point: "); output.WriteReference(mainModule.EntryPoint.DeclaringType.FullName + "." + mainModule.EntryPoint.Name, mainModule.EntryPoint); output.WriteLine(); } WriteCommentLine(output, "Architecture: " + CSharpLanguage.GetPlatformDisplayName(mainModule)); if ((mainModule.Attributes & ModuleAttributes.ILOnly) == 0) { WriteCommentLine(output, "This assembly contains unmanaged code."); } switch (mainModule.Runtime) { case TargetRuntime.Net_1_0: WriteCommentLine(output, "Runtime: .NET 1.0"); break; case TargetRuntime.Net_1_1: WriteCommentLine(output, "Runtime: .NET 1.1"); break; case TargetRuntime.Net_2_0: WriteCommentLine(output, "Runtime: .NET 2.0"); break; case TargetRuntime.Net_4_0: if (assembly.IsNet45()) { WriteCommentLine(output, "Runtime: .NET 4.5"); } else { WriteCommentLine(output, "Runtime: .NET 4.0"); } break; } output.WriteLine(); // don't automatically load additional assemblies when an assembly node is selected in the tree view using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) { AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.ModuleDefinition); codeDomBuilder.AddAssembly(assembly.ModuleDefinition, onlyAssemblyLevel: !options.FullDecompilation); RunTransformsAndGenerateCode(codeDomBuilder, output, options, assembly.ModuleDefinition); } } }
public override void WriteTo(ITextOutput output) { output.Write("catch "); output.WriteReference(ExceptionType.FullName, ExceptionType); if (ExceptionVariable != null) { output.Write(' '); output.Write(ExceptionVariable.Name); } output.WriteLine(" {"); output.Indent(); base.WriteTo(output); output.Unindent(); output.WriteLine("}"); }
public static void WriteTo(this Instruction instruction, ITextOutput writer) { writer.WriteDefinition(CecilExtensions.OffsetToString(instruction.Offset), instruction); writer.Write(": "); writer.WriteReference(instruction.OpCode.Name, instruction.OpCode); if (instruction.Operand != null) { writer.Write(' '); if (instruction.OpCode == OpCodes.Ldtoken) { if (instruction.Operand is MethodReference) writer.Write("method "); else if (instruction.Operand is FieldReference) writer.Write("field "); } WriteOperand(writer, instruction.Operand); } }
public static void WriteTo(this XMethodReference method, ITextOutput writer) { if (method.HasThis) { writer.Write("instance "); } method.ReturnType.WriteTo(writer, AstNameSyntax.SignatureNoNamedTypeParameters); writer.Write(' '); if (method.DeclaringType != null) { method.DeclaringType.WriteTo(writer, AstNameSyntax.TypeName); writer.Write("::"); } writer.WriteReference(Escape(method.Name), method); var gim = method as XGenericInstanceMethod; if (gim != null) { writer.Write('<'); for (int i = 0; i < gim.GenericArguments.Count; i++) { if (i > 0) { writer.Write(", "); } gim.GenericArguments[i].WriteTo(writer); } writer.Write('>'); } writer.Write("("); var parameters = method.Parameters; for (int i = 0; i < parameters.Count; ++i) { if (i > 0) { writer.Write(", "); } parameters[i].ParameterType.WriteTo(writer, AstNameSyntax.SignatureNoNamedTypeParameters); } writer.Write(")"); }
internal static void WriteKeyword(ITextOutput writer, string name, ITypeDefOrRef tdr) { var parts = name.Split(' '); for (int i = 0; i < parts.Length; i++) { if (i > 0) { writer.WriteSpace(); } if (tdr != null) { writer.WriteReference(parts[i], tdr, TextTokenType.Keyword); } else { writer.Write(parts[i], TextTokenType.Keyword); } } }
public static void WriteOffsetComment(this ITextOutput output, IResourceNode node) { if (!DecompilerSettingsPanel.CurrentDecompilerSettings.ShowTokenAndRvaComments) { return; } ulong fo = node.FileOffset; if (fo == 0) { return; } var mod = ILSpyTreeNode.GetModule((SharpTreeNode)node); var filename = mod == null ? null : mod.Location; output.WriteReference(string.Format("0x{0:X8}", fo), new AddressReference(filename, false, fo, node.Length), TextTokenType.Comment); output.Write(": ", TextTokenType.Comment); }
public static void WriteOffsetComment(this ITextOutput output, IResourceDataProvider node, bool showOffsetComment) { if (!showOffsetComment) { return; } ulong fo = node.FileOffset; if (fo == 0) { return; } var mod = (node as IFileTreeNodeData).GetModule(); var filename = mod == null ? null : mod.Location; output.WriteReference(string.Format("0x{0:X8}", fo), new AddressReference(filename, false, fo, node.Length), TextTokenKind.Comment); output.Write(": ", TextTokenKind.Comment); }
public override void Decompile(TypeDef type, ITextOutput output, DecompilationContext ctx) { this.WriteCommentLine(output, string.Format("Type: {0}", type.FullName)); if (type.BaseType != null) { WriteCommentBegin(output, true); output.Write("Base type: ", TextTokenKind.Comment); output.WriteReference(IdentifierEscaper.Escape(type.BaseType.FullName), type.BaseType, TextTokenKind.Comment); WriteCommentEnd(output, true); output.WriteLine(); } foreach (var nested in type.NestedTypes) { Decompile(nested, output, ctx); output.WriteLine(); } foreach (var field in type.Fields) { Decompile(field, output, ctx); output.WriteLine(); } foreach (var property in type.Properties) { Decompile(property, output, ctx); output.WriteLine(); } foreach (var @event in type.Events) { Decompile(@event, output, ctx); output.WriteLine(); } foreach (var method in type.Methods) { Decompile(method, output, ctx); output.WriteLine(); } }
public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) { if (options.FullDecompilation && options.SaveAsProjectDirectory != null) { HashSet <string> directories = new HashSet <string>(StringComparer.OrdinalIgnoreCase); var files = WriteCodeFilesInProject(assembly.ModuleDefinition, options, directories).ToList(); files.AddRange(WriteResourceFilesInProject(assembly, options, directories)); WriteProjectFile(new TextOutputWriter(output), files, assembly.ModuleDefinition); } else { base.DecompileAssembly(assembly, output, options); output.WriteLine(); ModuleDefinition mainModule = assembly.ModuleDefinition; if (mainModule.EntryPoint != null) { output.Write("// Entry point: "); output.WriteReference(mainModule.EntryPoint.DeclaringType.FullName + "." + mainModule.EntryPoint.Name, mainModule.EntryPoint); output.WriteLine(); } output.WriteLine("// Architecture: " + GetPlatformDisplayName(mainModule)); if ((mainModule.Attributes & ModuleAttributes.ILOnly) == 0) { output.WriteLine("// This assembly contains unmanaged code."); } string runtimeName = GetRuntimeDisplayName(mainModule); if (runtimeName != null) { output.WriteLine("// Runtime: " + runtimeName); } output.WriteLine(); // don't automatically load additional assemblies when an assembly node is selected in the tree view using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) { AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.ModuleDefinition); codeDomBuilder.AddAssembly(assembly.ModuleDefinition, onlyAssemblyLevel: !options.FullDecompilation); codeDomBuilder.RunTransformations(transformAbortCondition); codeDomBuilder.GenerateCode(output); } } }
public override void DecompileType(TypeDef type, ITextOutput output, DecompilationOptions options) { WriteCommentLine(output, string.Format("Type: {0}", type.FullName)); if (type.BaseType != null) { WriteComment(output, string.Format("Base type: ")); output.WriteReference(IdentifierEscaper.Escape(type.BaseType.FullName), type.BaseType, TextTokenType.Comment); output.WriteLine(); } foreach (var nested in type.NestedTypes) { DecompileType(nested, output, options); output.WriteLine(); } foreach (var field in type.Fields) { DecompileField(field, output, options); output.WriteLine(); } foreach (var property in type.Properties) { DecompileProperty(property, output, options); output.WriteLine(); } foreach (var @event in type.Events) { DecompileEvent(@event, output, options); output.WriteLine(); } foreach (var method in type.Methods) { DecompileMethod(method, output, options); output.WriteLine(); } }
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 Instruction instruction, ITextOutput writer) { writer.WriteDefinition(CecilExtensions.OffsetToString(instruction.Offset), instruction); writer.Write(": "); writer.WriteReference(instruction.OpCode.Name, instruction.OpCode); if (instruction.Operand != null) { writer.Write(' '); if (instruction.OpCode == OpCodes.Ldtoken) { if (instruction.Operand is MethodReference) { writer.Write("method "); } else if (instruction.Operand is FieldReference) { writer.Write("field "); } } WriteOperand(writer, instruction.Operand); } }
public static void WriteTo(this Instruction instruction, MethodDef method, ITextOutput writer) { writer.WriteDefinition(DnlibExtensions.OffsetToString(instruction.Offset), instruction); writer.Write(": "); writer.WriteReference(instruction.OpCode.Name, instruction.OpCode); if (instruction.Operand != null) { writer.Write(' '); if (instruction.OpCode == OpCodes.Ldtoken) { MemberRef member = instruction.Operand as MemberRef; if ((member != null && member.IsMethodRef) || instruction.Operand is MethodDef || instruction.Operand is MethodSpec) { writer.Write("method "); } else if ((member != null && member.IsFieldRef) || instruction.Operand is FieldDef) { writer.Write("field "); } } WriteOperand(writer, instruction.Operand.ResolveGenericParams(method)); } }
public static void WriteTo(this MethodReference method, ITextOutput writer) { if (method.ExplicitThis) { writer.Write("instance explicit "); } else if (method.HasThis) { writer.Write("instance "); } method.ReturnType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); writer.Write(' '); if (method.DeclaringType != null) { method.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write("::"); } if (method is MethodDefinition md && md.IsCompilerControlled) { writer.WriteReference(Escape(method.Name + "$PST" + method.MetadataToken.ToInt32().ToString("X8")), method); }
protected void WriteModule(ModuleDef mod, ITextOutput output, DecompilationContext ctx) { DecompileInternal(mod, output, ctx); output.WriteLine(); if (mod.Types.Count > 0) { this.WriteCommentBegin(output, true); output.Write(Languages_Resources.Decompile_GlobalType + " ", TextTokenKind.Comment); output.WriteReference(IdentifierEscaper.Escape(mod.GlobalType.FullName), mod.GlobalType, TextTokenKind.Comment); output.WriteLine(); } this.PrintEntryPoint(mod, output); this.WriteCommentLine(output, Languages_Resources.Decompile_Architecture + " " + GetPlatformDisplayName(mod)); if (!mod.IsILOnly) { this.WriteCommentLine(output, Languages_Resources.Decompile_ThisAssemblyContainsUnmanagedCode); } string runtimeName = GetRuntimeDisplayName(mod); if (runtimeName != null) { this.WriteCommentLine(output, Languages_Resources.Decompile_Runtime + " " + runtimeName); } var peImage = TryGetPEImage(mod); if (peImage != null) { this.WriteCommentBegin(output, true); uint ts = peImage.ImageNTHeaders.FileHeader.TimeDateStamp; var date = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc).AddSeconds(ts); var dateString = date.ToString(CultureInfo.CurrentUICulture.DateTimeFormat); output.Write(string.Format(Languages_Resources.Decompile_Timestamp, ts, dateString), TextTokenKind.Comment); this.WriteCommentEnd(output, true); output.WriteLine(); } output.WriteLine(); }
public static void WriteTo(this MethodReference method, ITextOutput writer) { if (method.HasThis) { writer.Write("instance "); } method.ReturnType.WriteTo(writer); writer.Write(' '); method.DeclaringType.WriteTo(writer, true); writer.Write("::"); writer.WriteReference(method.Name, method); writer.Write("("); var parameters = method.Parameters; for (int i = 0; i < parameters.Count; ++i) { if (i > 0) { writer.Write(", "); } parameters[i].ParameterType.WriteTo(writer); } writer.Write(")"); }
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 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 static void WriteTo(this ITypeDefOrRef type, ITextOutput writer, ILNameSyntax syntax, int depth) { if (depth++ > MAX_CONVERTTYPE_DEPTH || type == null) return; var ts = type as TypeSpec; if (ts != null && !(ts.TypeSig is FnPtrSig)) { WriteTo(((TypeSpec)type).TypeSig, writer, syntax, depth); return; } string typeFullName = type.FullName; string typeName = type.Name.String; if (ts != null) { var fnPtrSig = ts.TypeSig as FnPtrSig; typeFullName = DnlibExtensions.GetFnPtrFullName(fnPtrSig); typeName = DnlibExtensions.GetFnPtrName(fnPtrSig); } TypeSig typeSig = null; string name = type.DefinitionAssembly.IsCorLib() ? PrimitiveTypeName(typeFullName, type.Module, out typeSig) : null; if (syntax == ILNameSyntax.ShortTypeName) { if (name != null) WriteKeyword(writer, name, typeSig.ToTypeDefOrRef()); else writer.WriteReference(Escape(typeName), type, TextTokenHelper.GetTextTokenType(type)); } else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) { WriteKeyword(writer, name, typeSig.ToTypeDefOrRef()); } else { if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) { writer.Write(DnlibExtensions.IsValueType(type) ? "valuetype" : "class", TextTokenType.Keyword); writer.WriteSpace(); } if (type.DeclaringType != null) { type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName, depth); writer.Write('/', TextTokenType.Operator); writer.WriteReference(Escape(typeName), type, TextTokenHelper.GetTextTokenType(type)); } else { if (!(type is TypeDef) && type.Scope != null && !(type is TypeSpec)) { writer.Write('[', TextTokenType.Operator); writer.Write(Escape(type.Scope.GetScopeName()), TextTokenType.ILModule); writer.Write(']', TextTokenType.Operator); } if (ts != null || MustEscape(typeFullName)) writer.WriteReference(Escape(typeFullName), type, TextTokenHelper.GetTextTokenType(type)); else { WriteNamespace(writer, type.Namespace); if (!string.IsNullOrEmpty(type.Namespace)) writer.Write('.', TextTokenType.Operator); writer.WriteReference(IdentifierEscaper.Escape(type.Name), type, TextTokenHelper.GetTextTokenType(type)); } } } }
public static void WriteOperand(ITextOutput writer, object operand, MethodDef method = null) { Instruction targetInstruction = operand as Instruction; if (targetInstruction != null) { WriteOffsetReference(writer, targetInstruction, method); return; } IList<Instruction> targetInstructions = operand as IList<Instruction>; if (targetInstructions != null) { WriteLabelList(writer, targetInstructions, method); return; } Local variable = operand as Local; if (variable != null) { if (string.IsNullOrEmpty(variable.Name)) writer.WriteReference(variable.Index.ToString(), variable, TextTokenType.Number); else writer.WriteReference(Escape(variable.Name), variable, TextTokenType.Local); return; } Parameter paramRef = operand as Parameter; if (paramRef != null) { if (string.IsNullOrEmpty(paramRef.Name)) { if (paramRef.IsHiddenThisParameter) writer.WriteReference("<hidden-this>", paramRef, TextTokenType.Parameter); else writer.WriteReference(paramRef.MethodSigIndex.ToString(), paramRef, TextTokenType.Parameter); } else writer.WriteReference(Escape(paramRef.Name), paramRef, TextTokenType.Parameter); return; } MemberRef memberRef = operand as MemberRef; if (memberRef != null) { if (memberRef.IsMethodRef) memberRef.WriteMethodTo(writer); else memberRef.WriteFieldTo(writer); return; } MethodDef methodDef = operand as MethodDef; if (methodDef != null) { methodDef.WriteMethodTo(writer); return; } FieldDef fieldDef = operand as FieldDef; if (fieldDef != null) { fieldDef.WriteFieldTo(writer); return; } ITypeDefOrRef typeRef = operand as ITypeDefOrRef; if (typeRef != null) { typeRef.WriteTo(writer, ILNameSyntax.TypeName); return; } IMethod m = operand as IMethod; if (m != null) { m.WriteMethodTo(writer); return; } MethodSig sig = operand as MethodSig; if (sig != null) { sig.WriteTo(writer); return; } string s = operand as string; if (s != null) { writer.Write("\"" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(s) + "\"", TextTokenType.String); } else if (operand is char) { writer.Write(((int)(char)operand).ToString(), TextTokenType.Number); } else if (operand is float) { float val = (float)operand; if (val == 0) { if (1 / val == float.NegativeInfinity) { // negative zero is a special case writer.Write("-0.0", TextTokenType.Number); } else writer.Write("0.0", TextTokenType.Number); } else if (float.IsInfinity(val) || float.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); writer.Write('(', TextTokenType.Operator); for (int i = 0; i < data.Length; i++) { if (i > 0) writer.WriteSpace(); writer.Write(data[i].ToString("X2"), TextTokenType.Number); } writer.Write(')', TextTokenType.Operator); } else { writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture), TextTokenType.Number); } } else if (operand is double) { double val = (double)operand; if (val == 0) { if (1 / val == double.NegativeInfinity) { // negative zero is a special case writer.Write("-0.0", TextTokenType.Number); } else writer.Write("0.0", TextTokenType.Number); } else if (double.IsInfinity(val) || double.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); writer.Write('(', TextTokenType.Operator); for (int i = 0; i < data.Length; i++) { if (i > 0) writer.WriteSpace(); writer.Write(data[i].ToString("X2"), TextTokenType.Number); } writer.Write(')', TextTokenType.Operator); } else { writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture), TextTokenType.Number); } } else if (operand is bool) { writer.Write((bool)operand ? "true" : "false", TextTokenType.Keyword); } else { s = ToInvariantCultureString(operand); writer.Write(s, TextTokenHelper.GetTextTokenType(operand)); } }
public static void WriteFieldTo(this IField field, ITextOutput writer) { if (field == null || field.FieldSig == null) return; field.FieldSig.Type.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); writer.WriteSpace(); field.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write("::", TextTokenType.Operator); writer.WriteReference(Escape(field.Name), field, TextTokenHelper.GetTextTokenType(field)); }
public static void WriteOperand(ITextOutput writer, object operand) { if (operand == null) throw new ArgumentNullException("operand"); Instruction targetInstruction = operand as Instruction; if (targetInstruction != null) { WriteOffsetReference(writer, targetInstruction); return; } Instruction[] targetInstructions = operand as Instruction[]; if (targetInstructions != null) { WriteLabelList(writer, targetInstructions); return; } VariableReference variableRef = operand as VariableReference; if (variableRef != null) { if (string.IsNullOrEmpty(variableRef.Name)) writer.WriteReference(variableRef.Index.ToString(), variableRef); else writer.WriteReference(Escape(variableRef.Name), variableRef); return; } ParameterReference paramRef = operand as ParameterReference; if (paramRef != null) { if (string.IsNullOrEmpty(paramRef.Name)) writer.WriteReference(paramRef.Index.ToString(), paramRef); else writer.WriteReference(Escape(paramRef.Name), paramRef); return; } MethodReference methodRef = operand as MethodReference; if (methodRef != null) { methodRef.WriteTo(writer); return; } TypeReference typeRef = operand as TypeReference; if (typeRef != null) { typeRef.WriteTo(writer, ILNameSyntax.TypeName); return; } FieldReference fieldRef = operand as FieldReference; if (fieldRef != null) { fieldRef.WriteTo(writer); return; } string s = operand as string; if (s != null) { writer.Write("\"" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(s) + "\""); } else if (operand is char) { writer.Write(((int)(char)operand).ToString()); } else if (operand is float) { float val = (float)operand; if (val == 0) { writer.Write("0.0"); } else if (float.IsInfinity(val) || float.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); writer.Write('('); for (int i = 0; i < data.Length; i++) { if (i > 0) writer.Write(' '); writer.Write(data[i].ToString("X2")); } writer.Write(')'); } else { writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture)); } } else if (operand is double) { double val = (double)operand; if (val == 0) { writer.Write("0.0"); } else if (double.IsInfinity(val) || double.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); writer.Write('('); for (int i = 0; i < data.Length; i++) { if (i > 0) writer.Write(' '); writer.Write(data[i].ToString("X2")); } writer.Write(')'); } else { writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture)); } } else if (operand is bool) { writer.Write((bool)operand ? "true" : "false"); } else { s = ToInvariantCultureString(operand); writer.Write(s); } }
public static void WriteOffsetReference(ITextOutput writer, Instruction instruction) { writer.WriteReference(CecilExtensions.OffsetToString(instruction.Offset), instruction); }
public static void WriteTo(this IMember member, ITextOutput output) { if (member is IMethod method && method.IsConstructor) { output.WriteReference(member, method.DeclaringType?.Name + "." + method.Name); }
public static void WriteTo(this IType type, ITextOutput output, ILNameSyntax nameSyntax = ILNameSyntax.ShortTypeName) { output.WriteReference(type, type.ReflectionName); }
public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) { if (options.FullDecompilation && options.SaveAsProjectDirectory != null) { HashSet<string> directories = new HashSet<string>(StringComparer.OrdinalIgnoreCase); var files = WriteCodeFilesInProject(assembly.ModuleDefinition, options, directories).ToList(); files.AddRange(WriteResourceFilesInProject(assembly, options, directories)); WriteProjectFile(new TextOutputWriter(output), files, assembly.ModuleDefinition); } else { base.DecompileAssembly(assembly, output, options); output.WriteLine(); ModuleDefinition mainModule = assembly.ModuleDefinition; if (mainModule.Types.Count > 0) { output.Write("// Global type: "); output.WriteReference(mainModule.Types[0].FullName, mainModule.Types[0]); output.WriteLine(); } if (mainModule.EntryPoint != null) { output.Write("// Entry point: "); output.WriteReference(mainModule.EntryPoint.DeclaringType.FullName + "." + mainModule.EntryPoint.Name, mainModule.EntryPoint); output.WriteLine(); } output.WriteLine("// Architecture: " + GetPlatformDisplayName(mainModule)); if ((mainModule.Attributes & ModuleAttributes.ILOnly) == 0) { output.WriteLine("// This assembly contains unmanaged code."); } string runtimeName = GetRuntimeDisplayName(mainModule); if (runtimeName != null) { output.WriteLine("// Runtime: " + runtimeName); } output.WriteLine(); // don't automatically load additional assemblies when an assembly node is selected in the tree view using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) { AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.ModuleDefinition); codeDomBuilder.AddAssembly(assembly.ModuleDefinition, onlyAssemblyLevel: !options.FullDecompilation); codeDomBuilder.RunTransformations(transformAbortCondition); codeDomBuilder.GenerateCode(output); } } }
public override void WriteTo(ITextOutput output, MemberMapping memberMapping) { var startLoc = output.Location; if (Operand is ILVariable && ((ILVariable)Operand).GeneratedByDecompiler) { if (Code == ILCode.Stloc && this.InferredType == null) { output.WriteReference(((ILVariable)Operand).Name, Operand, ((ILVariable)Operand).IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local); output.WriteSpace(); output.Write("=", TextTokenKind.Operator); output.WriteSpace(); Arguments.First().WriteTo(output, null); UpdateMemberMapping(memberMapping, startLoc, output.Location, this.GetSelfAndChildrenRecursiveILRanges()); return; } else if (Code == ILCode.Ldloc) { output.WriteReference(((ILVariable)Operand).Name, Operand, ((ILVariable)Operand).IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local); if (this.InferredType != null) { output.Write(":", TextTokenKind.Operator); this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName); if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName) { output.Write("[", TextTokenKind.Operator); output.Write("exp", TextTokenKind.Keyword); output.Write(":", TextTokenKind.Operator); this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write("]", TextTokenKind.Operator); } } UpdateMemberMapping(memberMapping, startLoc, output.Location, this.GetSelfAndChildrenRecursiveILRanges()); return; } } if (this.Prefixes != null) { foreach (var prefix in this.Prefixes) { output.Write(prefix.Code.GetName() + ".", TextTokenKind.OpCode); output.WriteSpace(); } } output.Write(Code.GetName(), TextTokenKind.OpCode); if (this.InferredType != null) { output.Write(":", TextTokenKind.Operator); this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName); if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName) { output.Write("[", TextTokenKind.Operator); output.Write("exp", TextTokenKind.Keyword); output.Write(":", TextTokenKind.Operator); this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write("]", TextTokenKind.Operator); } } else if (this.ExpectedType != null) { output.Write("[", TextTokenKind.Operator); output.Write("exp", TextTokenKind.Keyword); output.Write(":", TextTokenKind.Operator); this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write("]", TextTokenKind.Operator); } output.Write("(", TextTokenKind.Operator); bool first = true; if (Operand != null) { if (Operand is ILLabel) { output.WriteReference(((ILLabel)Operand).Name, Operand, TextTokenKind.Label); } else if (Operand is ILLabel[]) { ILLabel[] labels = (ILLabel[])Operand; for (int i = 0; i < labels.Length; i++) { if (i > 0) { output.Write(",", TextTokenKind.Operator); output.WriteSpace(); } output.WriteReference(labels[i].Name, labels[i], TextTokenKind.Label); } } else if (Operand is IMethod && (Operand as IMethod).MethodSig != null) { IMethod method = (IMethod)Operand; if (method.DeclaringType != null) { method.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write("::", TextTokenKind.Operator); } output.WriteReference(method.Name, method, TextTokenKindUtils.GetTextTokenType(method)); } else if (Operand is IField) { IField field = (IField)Operand; field.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write("::", TextTokenKind.Operator); output.WriteReference(field.Name, field, TextTokenKindUtils.GetTextTokenType(field)); } else if (Operand is ILVariable) { var ilvar = (ILVariable)Operand; output.WriteReference(ilvar.Name, Operand, ilvar.IsParameter ? TextTokenKind.Parameter : TextTokenKind.Local); } else { DisassemblerHelpers.WriteOperand(output, Operand); } first = false; } foreach (ILExpression arg in this.Arguments) { if (!first) { output.Write(",", TextTokenKind.Operator); output.WriteSpace(); } arg.WriteTo(output, null); first = false; } output.Write(")", TextTokenKind.Operator); UpdateMemberMapping(memberMapping, startLoc, output.Location, this.GetSelfAndChildrenRecursiveILRanges()); }
public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) { var module = assembly.GetPEFileOrNull(); if (options.FullDecompilation && options.SaveAsProjectDirectory != null) { var decompiler = new ILSpyWholeProjectDecompiler(assembly, options); decompiler.DecompileProject(module, options.SaveAsProjectDirectory, new TextOutputWriter(output), options.CancellationToken); } else { AddReferenceAssemblyWarningMessage(module, output); AddReferenceWarningMessage(module, output); output.WriteLine(); base.DecompileAssembly(assembly, output, options); // don't automatically load additional assemblies when an assembly node is selected in the tree view using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) { IAssemblyResolver assemblyResolver = assembly.GetAssemblyResolver(); var typeSystem = new DecompilerTypeSystem(module, assemblyResolver, options.DecompilerSettings); var globalType = typeSystem.MainModule.TypeDefinitions.FirstOrDefault(); if (globalType != null) { output.Write("// Global type: "); output.WriteReference(globalType, globalType.FullName); output.WriteLine(); } var metadata = module.Metadata; var corHeader = module.Reader.PEHeaders.CorHeader; var entrypointHandle = MetadataTokenHelpers.EntityHandleOrNil(corHeader.EntryPointTokenOrRelativeVirtualAddress); if (!entrypointHandle.IsNil && entrypointHandle.Kind == HandleKind.MethodDefinition) { var entrypoint = typeSystem.MainModule.ResolveMethod(entrypointHandle, new Decompiler.TypeSystem.GenericContext()); if (entrypoint != null) { output.Write("// Entry point: "); output.WriteReference(entrypoint, entrypoint.DeclaringType.FullName + "." + entrypoint.Name); output.WriteLine(); } } output.WriteLine("// Architecture: " + GetPlatformDisplayName(module)); if ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.ILOnly) == 0) { output.WriteLine("// This assembly contains unmanaged code."); } string runtimeName = GetRuntimeDisplayName(module); if (runtimeName != null) { output.WriteLine("// Runtime: " + runtimeName); } var debugInfo = assembly.GetDebugInfoOrNull(); if (debugInfo != null) { output.WriteLine("// Debug info: " + debugInfo.Description); } output.WriteLine(); CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, options.DecompilerSettings); decompiler.CancellationToken = options.CancellationToken; SyntaxTree st; if (options.FullDecompilation) { st = decompiler.DecompileWholeModuleAsSingleFile(); } else { st = decompiler.DecompileModuleAndAssemblyAttributes(); } WriteCode(output, options.DecompilerSettings, st, decompiler.TypeSystem); } } }
public static void WriteTo(this ITypeDefOrRef type, ITextOutput writer, ILNameSyntax syntax, int depth) { if (depth++ > MAX_CONVERTTYPE_DEPTH || type == null) { return; } var ts = type as TypeSpec; if (ts != null && !(ts.TypeSig is FnPtrSig)) { WriteTo(((TypeSpec)type).TypeSig, writer, syntax, depth); return; } string typeFullName = type.FullName; string typeName = type.Name.String; if (ts != null) { var fnPtrSig = ts.TypeSig as FnPtrSig; typeFullName = DnlibExtensions.GetFnPtrFullName(fnPtrSig); typeName = DnlibExtensions.GetFnPtrName(fnPtrSig); } TypeSig typeSig = null; string name = type.DefinitionAssembly.IsCorLib() ? PrimitiveTypeName(typeFullName, type.Module, out typeSig) : null; if (syntax == ILNameSyntax.ShortTypeName) { if (name != null) { WriteKeyword(writer, name, typeSig.ToTypeDefOrRef()); } else { writer.WriteReference(Escape(typeName), type, TextTokenHelper.GetTextTokenType(type)); } } else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) { WriteKeyword(writer, name, typeSig.ToTypeDefOrRef()); } else { if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) { writer.Write(DnlibExtensions.IsValueType(type) ? "valuetype" : "class", TextTokenType.Keyword); writer.WriteSpace(); } if (type.DeclaringType != null) { type.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName, depth); writer.Write('/', TextTokenType.Operator); writer.WriteReference(Escape(typeName), type, TextTokenHelper.GetTextTokenType(type)); } else { if (!(type is TypeDef) && type.Scope != null && !(type is TypeSpec)) { writer.Write('[', TextTokenType.Operator); writer.Write(Escape(type.Scope.GetScopeName()), TextTokenType.ILModule); writer.Write(']', TextTokenType.Operator); } if (ts != null || MustEscape(typeFullName)) { writer.WriteReference(Escape(typeFullName), type, TextTokenHelper.GetTextTokenType(type)); } else { WriteNamespace(writer, type.Namespace); if (!string.IsNullOrEmpty(type.Namespace)) { writer.Write('.', TextTokenType.Operator); } writer.WriteReference(IdentifierEscaper.Escape(type.Name), type, TextTokenHelper.GetTextTokenType(type)); } } } }
public static void WriteTo(this Instruction instruction, ITextOutput writer, DisassemblerOptions options, uint baseRva, long baseOffs, IInstructionBytesReader byteReader, MethodDef method) { if (options != null && (options.ShowTokenAndRvaComments || options.ShowILBytes)) { writer.Write("/* ", TextTokenType.Comment); bool needSpace = false; if (options.ShowTokenAndRvaComments) { ulong fileOffset = (ulong)baseOffs + instruction.Offset; writer.WriteReference(string.Format("0x{0:X8}", fileOffset), new AddressReference(options.OwnerModule == null ? null : options.OwnerModule.Location, false, fileOffset, (ulong)instruction.GetSize()), TextTokenType.Comment, false); needSpace = true; } if (options.ShowILBytes) { if (needSpace) { writer.Write(' ', TextTokenType.Comment); } if (byteReader == null) { writer.Write("??", TextTokenType.Comment); } else { int size = instruction.GetSize(); for (int i = 0; i < size; i++) { var b = byteReader.ReadByte(); if (b < 0) { writer.Write("??", TextTokenType.Comment); } else { writer.Write(string.Format("{0:X2}", b), TextTokenType.Comment); } } // Most instructions should be at most 5 bytes in length, but use 6 since // ldftn/ldvirtftn are 6 bytes long. The longest instructions are those with // 8 byte operands, ldc.i8 and ldc.r8: 9 bytes. const int MIN_BYTES = 6; for (int i = size; i < MIN_BYTES; i++) { writer.Write(" ", TextTokenType.Comment); } } } writer.Write(" */", TextTokenType.Comment); writer.WriteSpace(); } writer.WriteDefinition(DnlibExtensions.OffsetToString(instruction.GetOffset()), new InstructionReference(method, instruction), TextTokenType.Label, false); writer.Write(':', TextTokenType.Operator); writer.WriteSpace(); writer.WriteReference(instruction.OpCode.Name, instruction.OpCode, TextTokenType.OpCode); if (instruction.Operand != null) { int count = OPERAND_ALIGNMENT - instruction.OpCode.Name.Length; if (count <= 0) { count = 1; } writer.Write(spaces[count], TextTokenType.Text); if (instruction.OpCode == OpCodes.Ldtoken) { var member = instruction.Operand as IMemberRef; if (member != null && member.IsMethod) { writer.Write("method", TextTokenType.Keyword); writer.WriteSpace(); } else if (member != null && member.IsField) { writer.Write("field", TextTokenType.Keyword); writer.WriteSpace(); } } WriteOperand(writer, instruction.Operand, method); } if (options != null && options.GetOpCodeDocumentation != null) { var doc = options.GetOpCodeDocumentation(instruction.OpCode); if (doc != null) { writer.Write("\t", TextTokenType.Text); writer.Write("// " + doc, TextTokenType.Comment); } } }
public static void WriteOffsetReference(ITextOutput writer, Instruction instruction) { writer.WriteReference(dnlibExtensions.OffsetToString(instruction.Offset), instruction, true); }
public static void WriteTo(this TypeReference type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature) { ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature; if (type is PinnedType) { ((PinnedType)type).ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write(" pinned"); } else if (type is ArrayType) { ArrayType at = (ArrayType)type; at.ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write('['); writer.Write(string.Join(", ", at.Dimensions)); writer.Write(']'); } else if (type is GenericParameter) { writer.Write('!'); if (((GenericParameter)type).Owner.GenericParameterType == GenericParameterType.Method) { writer.Write('!'); } if (string.IsNullOrEmpty(type.Name) || type.Name[0] == '!' || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) { writer.Write(((GenericParameter)type).Position.ToString()); } else { writer.Write(Escape(type.Name)); } } else if (type is ByReferenceType) { ((ByReferenceType)type).ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write('&'); } else if (type is PointerType) { ((PointerType)type).ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write('*'); } else if (type is GenericInstanceType) { type.GetElementType().WriteTo(writer, syntaxForElementTypes); writer.Write('<'); var arguments = ((GenericInstanceType)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 OptionalModifierType) { ((OptionalModifierType)type).ElementType.WriteTo(writer, syntax); writer.Write(" modopt("); ((OptionalModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write(") "); } else if (type is RequiredModifierType) { ((RequiredModifierType)type).ElementType.WriteTo(writer, syntax); writer.Write(" modreq("); ((RequiredModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write(") "); } else { string name = PrimitiveTypeName(type.FullName); if (syntax == ILNameSyntax.ShortTypeName) { if (name != null) { writer.Write(name); } else { writer.WriteReference(Escape(type.Name), type); } } else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) { writer.Write(name); } else { if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) { writer.Write(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.IsDefinition && type.Scope != null && !(type is TypeSpecification)) { writer.Write("[{0}]", Escape(type.Scope.Name)); } writer.WriteReference(Escape(type.FullName), type); } } } }
public static void WriteTo(this XMethodReference method, ITextOutput writer) { if (method.HasThis) { writer.Write("instance "); } method.ReturnType.WriteTo(writer, AstNameSyntax.SignatureNoNamedTypeParameters); writer.Write(' '); if (method.DeclaringType != null) { method.DeclaringType.WriteTo(writer, AstNameSyntax.TypeName); writer.Write("::"); } writer.WriteReference(Escape(method.Name), method); var gim = method as XGenericInstanceMethod; if (gim != null) { writer.Write('<'); for (int i = 0; i < gim.GenericArguments.Count; i++) { if (i > 0) writer.Write(", "); gim.GenericArguments[i].WriteTo(writer); } writer.Write('>'); } writer.Write("("); var parameters = method.Parameters; for (int i = 0; i < parameters.Count; ++i) { if (i > 0) writer.Write(", "); parameters[i].ParameterType.WriteTo(writer, AstNameSyntax.SignatureNoNamedTypeParameters); } writer.Write(")"); }
public static void WriteOperand(ITextOutput writer, object operand, MethodDef method = null) { Instruction targetInstruction = operand as Instruction; if (targetInstruction != null) { WriteOffsetReference(writer, targetInstruction, method); return; } IList <Instruction> targetInstructions = operand as IList <Instruction>; if (targetInstructions != null) { WriteLabelList(writer, targetInstructions, method); return; } Local variable = operand as Local; if (variable != null) { if (string.IsNullOrEmpty(variable.Name)) { writer.WriteReference(variable.Index.ToString(), variable, TextTokenType.Number); } else { writer.WriteReference(Escape(variable.Name), variable, TextTokenType.Local); } return; } Parameter paramRef = operand as Parameter; if (paramRef != null) { if (string.IsNullOrEmpty(paramRef.Name)) { if (paramRef.IsHiddenThisParameter) { writer.WriteReference("<hidden-this>", paramRef, TextTokenType.Parameter); } else { writer.WriteReference(paramRef.MethodSigIndex.ToString(), paramRef, TextTokenType.Parameter); } } else { writer.WriteReference(Escape(paramRef.Name), paramRef, TextTokenType.Parameter); } return; } MemberRef memberRef = operand as MemberRef; if (memberRef != null) { if (memberRef.IsMethodRef) { memberRef.WriteMethodTo(writer); } else { memberRef.WriteFieldTo(writer); } return; } MethodDef methodDef = operand as MethodDef; if (methodDef != null) { methodDef.WriteMethodTo(writer); return; } FieldDef fieldDef = operand as FieldDef; if (fieldDef != null) { fieldDef.WriteFieldTo(writer); return; } ITypeDefOrRef typeRef = operand as ITypeDefOrRef; if (typeRef != null) { typeRef.WriteTo(writer, ILNameSyntax.TypeName); return; } IMethod m = operand as IMethod; if (m != null) { m.WriteMethodTo(writer); return; } MethodSig sig = operand as MethodSig; if (sig != null) { sig.WriteTo(writer); return; } string s = operand as string; if (s != null) { writer.Write("\"" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(s) + "\"", TextTokenType.String); } else if (operand is char) { writer.Write(((int)(char)operand).ToString(), TextTokenType.Number); } else if (operand is float) { float val = (float)operand; if (val == 0) { if (1 / val == float.NegativeInfinity) { // negative zero is a special case writer.Write("-0.0", TextTokenType.Number); } else { writer.Write("0.0", TextTokenType.Number); } } else if (float.IsInfinity(val) || float.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); writer.Write('(', TextTokenType.Operator); for (int i = 0; i < data.Length; i++) { if (i > 0) { writer.WriteSpace(); } writer.Write(data[i].ToString("X2"), TextTokenType.Number); } writer.Write(')', TextTokenType.Operator); } else { writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture), TextTokenType.Number); } } else if (operand is double) { double val = (double)operand; if (val == 0) { if (1 / val == double.NegativeInfinity) { // negative zero is a special case writer.Write("-0.0", TextTokenType.Number); } else { writer.Write("0.0", TextTokenType.Number); } } else if (double.IsInfinity(val) || double.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); writer.Write('(', TextTokenType.Operator); for (int i = 0; i < data.Length; i++) { if (i > 0) { writer.WriteSpace(); } writer.Write(data[i].ToString("X2"), TextTokenType.Number); } writer.Write(')', TextTokenType.Operator); } else { writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture), TextTokenType.Number); } } else if (operand is bool) { writer.Write((bool)operand ? "true" : "false", TextTokenType.Keyword); } else { s = ToInvariantCultureString(operand); writer.Write(s, TextTokenHelper.GetTextTokenType(operand)); } }
public override void WriteTo(ITextOutput output) { if (Operand is ILVariable && ((ILVariable)Operand).IsGenerated) { if (Code == ILCode.Stloc && this.InferredType == null) { output.Write(((ILVariable)Operand).Name); output.Write(" = "); Arguments.First().WriteTo(output); return; } else if (Code == ILCode.Ldloc) { output.Write(((ILVariable)Operand).Name); if (this.InferredType != null) { output.Write(':'); this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName); if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName) { output.Write("[exp:"); this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write(']'); } } return; } } if (this.Prefixes != null) { foreach (var prefix in this.Prefixes) { output.Write(prefix.Code.GetName()); output.Write(". "); } } output.Write(Code.GetName()); if (this.InferredType != null) { output.Write(':'); this.InferredType.WriteTo(output, ILNameSyntax.ShortTypeName); if (this.ExpectedType != null && this.ExpectedType.FullName != this.InferredType.FullName) { output.Write("[exp:"); this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write(']'); } } else if (this.ExpectedType != null) { output.Write("[exp:"); this.ExpectedType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write(']'); } output.Write('('); bool first = true; if (Operand != null) { if (Operand is ILLabel) { output.WriteReference(((ILLabel)Operand).Name, Operand); } else if (Operand is ILLabel[]) { ILLabel[] labels = (ILLabel[])Operand; for (int i = 0; i < labels.Length; i++) { if (i > 0) { output.Write(", "); } output.WriteReference(labels[i].Name, labels[i]); } } else if (Operand is MethodReference) { MethodReference method = (MethodReference)Operand; if (method.DeclaringType != null) { method.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write("::"); } output.WriteReference(method.Name, method); } else if (Operand is FieldReference) { FieldReference field = (FieldReference)Operand; field.DeclaringType.WriteTo(output, ILNameSyntax.ShortTypeName); output.Write("::"); output.WriteReference(field.Name, field); } else { DisassemblerHelpers.WriteOperand(output, Operand); } first = false; } foreach (ILExpression arg in this.Arguments) { if (!first) { output.Write(", "); } arg.WriteTo(output); first = false; } output.Write(')'); }
public static void WriteTo(this TypeReference type, ITextOutput writer, bool onlyName = false, bool shortName = false) { if (type is PinnedType) { writer.Write("pinned "); ((PinnedType)type).ElementType.WriteTo(writer, onlyName, shortName); } else if (type is ArrayType) { ArrayType at = (ArrayType)type; at.ElementType.WriteTo(writer, onlyName, shortName); writer.Write('['); writer.Write(string.Join(", ", at.Dimensions)); writer.Write(']'); } else if (type is GenericParameter) { writer.Write('!'); if (((GenericParameter)type).Owner.GenericParameterType == GenericParameterType.Method) writer.Write('!'); writer.Write(type.Name); } else if (type is ByReferenceType) { ((ByReferenceType)type).ElementType.WriteTo(writer, onlyName, shortName); writer.Write('&'); } else if (type is PointerType) { ((PointerType)type).ElementType.WriteTo(writer, onlyName, shortName); writer.Write('*'); } else if (type is GenericInstanceType) { type.GetElementType().WriteTo(writer, onlyName, shortName); writer.Write('<'); var arguments = ((GenericInstanceType)type).GenericArguments; for (int i = 0; i < arguments.Count; i++) { if (i > 0) writer.Write(", "); arguments[i].WriteTo(writer, onlyName, shortName); } writer.Write('>'); } else if (type is OptionalModifierType) { writer.Write("modopt("); ((OptionalModifierType)type).ModifierType.WriteTo(writer, true, shortName); writer.Write(") "); ((OptionalModifierType)type).ElementType.WriteTo(writer, onlyName, shortName); } else if (type is RequiredModifierType) { writer.Write("modreq("); ((RequiredModifierType)type).ModifierType.WriteTo(writer, true, shortName); writer.Write(") "); ((RequiredModifierType)type).ElementType.WriteTo(writer, onlyName, shortName); } else { string name = PrimitiveTypeName(type); if (name != null) { writer.Write(name); } else { if (!onlyName) writer.Write(type.IsValueType ? "valuetype " : "class "); if (type.DeclaringType != null) { type.DeclaringType.WriteTo(writer, true, shortName); writer.Write('/'); writer.WriteReference(Escape(type.Name), type); } else { if (!type.IsDefinition && type.Scope != null && !shortName && !(type is TypeSpecification)) writer.Write("[{0}]", Escape(type.Scope.Name)); writer.WriteReference(shortName ? type.Name : type.FullName, type); } } } }
public override void DecompileField(FieldDef field, ITextOutput output, DecompilationOptions options) { output.WriteReference(IdentifierEscaper.Escape(field.FieldType.GetFullName()), field.FieldType.ToTypeDefOrRef(), TextTokenHelper.GetTextTokenType(field.FieldType)); output.WriteSpace(); output.WriteDefinition(IdentifierEscaper.Escape(field.Name), field, TextTokenHelper.GetTextTokenType(field), false); var c = field.Constant; if (c != null) { output.WriteSpace(); output.Write('=', TextTokenType.Operator); output.WriteSpace(); if (c.Value == null) output.Write("null", TextTokenType.Keyword); else { switch (c.Type) { case ElementType.Boolean: if (c.Value is bool) output.Write((bool)c.Value ? "true" : "false", TextTokenType.Keyword); else goto default; break; case ElementType.Char: output.Write(string.Format("'{0}'", c.Value), TextTokenType.Char); break; case ElementType.I1: case ElementType.U1: case ElementType.I2: case ElementType.U2: case ElementType.I4: case ElementType.U4: case ElementType.I8: case ElementType.U8: case ElementType.R4: case ElementType.R8: case ElementType.I: case ElementType.U: output.Write(string.Format("{0}", c.Value), TextTokenType.Number); break; case ElementType.String: output.Write(string.Format("{0}", c.Value), TextTokenType.String); break; default: output.Write(string.Format("{0}", c.Value), TextTokenType.Text); break; } } } }
public static void WriteOffsetReference(ITextOutput writer, Instruction instruction, MethodDef method, TextTokenType tokenType = TextTokenType.Label) { var r = instruction == null ? null : method == null ? (object)instruction : new InstructionReference(method, instruction); writer.WriteReference(DnlibExtensions.OffsetToString(instruction.GetOffset()), r, tokenType); }
public static void WriteTo(this MethodReference method, ITextOutput writer) { if (method.HasThis) writer.Write("instance "); method.ReturnType.WriteTo(writer); writer.Write(' '); if (method.DeclaringType != null) { method.DeclaringType.WriteTo(writer, true); writer.Write("::"); } writer.WriteReference(method.Name, method); writer.Write("("); var parameters = method.Parameters; for(int i = 0; i < parameters.Count; ++i) { if (i > 0) writer.Write(", "); parameters[i].ParameterType.WriteTo(writer); } writer.Write(")"); }
public static void WriteTo(this Instruction instruction, ITextOutput writer, DisassemblerOptions options, uint baseRva, long baseOffs, IInstructionBytesReader byteReader, MethodDef method) { if (options != null && (options.ShowTokenAndRvaComments || options.ShowILBytes)) { writer.Write("/* ", TextTokenType.Comment); bool needSpace = false; if (options.ShowTokenAndRvaComments) { ulong fileOffset = (ulong)baseOffs + instruction.Offset; writer.WriteReference(string.Format("0x{0:X8}", fileOffset), new AddressReference(options.OwnerModule == null ? null : options.OwnerModule.Location, false, fileOffset, (ulong)instruction.GetSize()), TextTokenType.Comment, false); needSpace = true; } if (options.ShowILBytes) { if (needSpace) writer.Write(' ', TextTokenType.Comment); if (byteReader == null) writer.Write("??", TextTokenType.Comment); else { int size = instruction.GetSize(); for (int i = 0; i < size; i++) { var b = byteReader.ReadByte(); if (b < 0) writer.Write("??", TextTokenType.Comment); else writer.Write(string.Format("{0:X2}", b), TextTokenType.Comment); } // Most instructions should be at most 5 bytes in length, but use 6 since // ldftn/ldvirtftn are 6 bytes long. The longest instructions are those with // 8 byte operands, ldc.i8 and ldc.r8: 9 bytes. const int MIN_BYTES = 6; for (int i = size; i < MIN_BYTES; i++) writer.Write(" ", TextTokenType.Comment); } } writer.Write(" */", TextTokenType.Comment); writer.WriteSpace(); } writer.WriteDefinition(DnlibExtensions.OffsetToString(instruction.GetOffset()), new InstructionReference(method, instruction), TextTokenType.Label, false); writer.Write(':', TextTokenType.Operator); writer.WriteSpace(); writer.WriteReference(instruction.OpCode.Name, instruction.OpCode, TextTokenType.OpCode); if (instruction.Operand != null) { int count = OPERAND_ALIGNMENT - instruction.OpCode.Name.Length; if (count <= 0) count = 1; writer.Write(spaces[count], TextTokenType.Text); if (instruction.OpCode == OpCodes.Ldtoken) { var member = instruction.Operand as IMemberRef; if (member != null && member.IsMethod) { writer.Write("method", TextTokenType.Keyword); writer.WriteSpace(); } else if (member != null && member.IsField) { writer.Write("field", TextTokenType.Keyword); writer.WriteSpace(); } } WriteOperand(writer, instruction.Operand, method); } if (options != null && options.GetOpCodeDocumentation != null) { var doc = options.GetOpCodeDocumentation(instruction.OpCode); if (doc != null) { writer.Write("\t", TextTokenType.Text); writer.Write("// " + doc, TextTokenType.Comment); } } }
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(); }
internal static void WriteKeyword(ITextOutput writer, string name, ITypeDefOrRef tdr) { var parts = name.Split(' '); for (int i = 0; i < parts.Length; i++) { if (i > 0) writer.WriteSpace(); if (tdr != null) writer.WriteReference(parts[i], tdr, TextTokenType.Keyword); else writer.Write(parts[i], TextTokenType.Keyword); } }
public override void Decompile(FieldDef field, ITextOutput output, DecompilationContext ctx) { output.WriteReference(IdentifierEscaper.Escape(field.FieldType.GetFullName()), field.FieldType.ToTypeDefOrRef(), TextTokenKindUtils.GetTextTokenType(field.FieldType)); output.WriteSpace(); output.WriteDefinition(IdentifierEscaper.Escape(field.Name), field, TextTokenKindUtils.GetTextTokenType(field), false); var c = field.Constant; if (c != null) { output.WriteSpace(); output.Write("=", TextTokenKind.Operator); output.WriteSpace(); if (c.Value == null) { output.Write("null", TextTokenKind.Keyword); } else { switch (c.Type) { case ElementType.Boolean: if (c.Value is bool) { output.Write((bool)c.Value ? "true" : "false", TextTokenKind.Keyword); } else { goto default; } break; case ElementType.Char: output.Write(string.Format("'{0}'", c.Value), TextTokenKind.Char); break; case ElementType.I1: case ElementType.U1: case ElementType.I2: case ElementType.U2: case ElementType.I4: case ElementType.U4: case ElementType.I8: case ElementType.U8: case ElementType.R4: case ElementType.R8: case ElementType.I: case ElementType.U: output.Write(string.Format("{0}", c.Value), TextTokenKind.Number); break; case ElementType.String: output.Write(string.Format("{0}", c.Value), TextTokenKind.String); break; default: output.Write(string.Format("{0}", c.Value), TextTokenKind.Text); break; } } } }
static void WriteTo(this IField field, ITextOutput writer) { var signature = field.FieldSig; signature.Type.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); writer.Write(' '); field.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write("::"); writer.WriteReference(Escape(field.Name), field); }
public static void WriteOperand(ITextOutput writer, object operand) { if (operand == null) throw new ArgumentNullException("operand"); Instruction targetInstruction = operand as Instruction; if (targetInstruction != null) { WriteOffsetReference(writer, targetInstruction); return; } Instruction[] targetInstructions = operand as Instruction[]; if (targetInstructions != null) { WriteLabelList(writer, targetInstructions); return; } VariableReference variableRef = operand as VariableReference; if (variableRef != null) { writer.WriteReference(variableRef.Index.ToString(), variableRef); return; } MethodReference methodRef = operand as MethodReference; if (methodRef != null) { methodRef.WriteTo(writer); return; } TypeReference typeRef = operand as TypeReference; if (typeRef != null) { typeRef.WriteTo(writer); return; } FieldReference fieldRef = operand as FieldReference; if (fieldRef != null) { fieldRef.WriteTo(writer); return; } string s = operand as string; if (s != null) { writer.Write("\"" + s.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\""); return; } s = ToInvariantCultureString(operand); writer.Write(s); }
public static void WriteOperand(ITextOutput writer, object operand) { if (operand == null) throw new ArgumentNullException("operand"); Instruction targetInstruction = operand as Instruction; if (targetInstruction != null) { WriteOffsetReference(writer, targetInstruction); return; } Instruction[] targetInstructions = operand as Instruction[]; if (targetInstructions != null) { WriteLabelList(writer, targetInstructions); return; } Local local = operand as Local; if (local != null) { if (string.IsNullOrEmpty(local.Name)) writer.WriteReference("[" + local.Index.ToString() + "]", local, true); else writer.WriteReference(Escape(local.Name), local, true); return; } Parameter param = operand as Parameter; if (param != null) { if (string.IsNullOrEmpty(param.Name)) writer.WriteReference("[" + param.Index.ToString() + "]", param, true); else writer.WriteReference(Escape(param.Name), param, true); return; } IMethod methodRef = operand as IMethod; if (methodRef != null && dnlibExtensions.IsMethod(methodRef)) { methodRef.WriteTo(writer); writer.WriteComment(" // 0x" + methodRef.MDToken.Raw.ToString("x8")); return; } ITypeDefOrRef typeRef = operand as ITypeDefOrRef; if (typeRef != null) { typeRef.WriteTo(writer, ILNameSyntax.TypeName); writer.WriteComment(" // 0x" + typeRef.MDToken.Raw.ToString("x8")); return; } IField fieldRef = operand as IField; if (fieldRef != null && dnlibExtensions.IsField(fieldRef)) { fieldRef.WriteTo(writer); writer.WriteComment(" // 0x" + fieldRef.MDToken.Raw.ToString("x8")); return; } string s = operand as string; if (s != null) { writer.WriteLiteral("\"" + NRefactory.CSharp.CSharpOutputVisitor.ConvertString(s) + "\""); } else if (operand is char) { writer.WriteLiteral(((int)(char)operand).ToString()); } else if (operand is float) { float val = (float)operand; if (val == 0) { if (1 / val == float.NegativeInfinity) { // negative zero is a special case writer.WriteLiteral("-"); } writer.WriteLiteral("0.0"); } else if (float.IsInfinity(val) || float.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); writer.Write('('); for (int i = 0; i < data.Length; i++) { if (i > 0) writer.WriteLiteral(" "); writer.WriteLiteral(data[i].ToString("X2")); } writer.Write(')'); } else { writer.WriteLiteral(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture)); } } else if (operand is double) { double val = (double)operand; if (val == 0) { if (1 / val == double.NegativeInfinity) { // negative zero is a special case writer.WriteLiteral("-"); } writer.WriteLiteral("0.0"); } else if (double.IsInfinity(val) || double.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); writer.Write('('); for (int i = 0; i < data.Length; i++) { if (i > 0) writer.WriteLiteral(" "); writer.WriteLiteral(data[i].ToString("X2")); } writer.Write(')'); } else { writer.WriteLiteral(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture)); } } else if (operand is bool) { writer.WriteLiteral((bool)operand ? "true" : "false"); } else { s = ToInvariantCultureString(operand); writer.WriteLiteral(s); } }
public static void WriteTo(this TypeReference type, ITextOutput writer, bool onlyName = false, bool shortName = false) { if (type is PinnedType) { writer.Write("pinned "); ((PinnedType)type).ElementType.WriteTo(writer, onlyName, shortName); } else if (type is ArrayType) { ArrayType at = (ArrayType)type; at.ElementType.WriteTo(writer, onlyName, shortName); writer.Write('['); writer.Write(string.Join(", ", at.Dimensions)); writer.Write(']'); } else if (type is GenericParameter) { writer.Write('!'); if (((GenericParameter)type).Owner.GenericParameterType == GenericParameterType.Method) { writer.Write('!'); } writer.Write(type.Name); } else if (type is ByReferenceType) { ((ByReferenceType)type).ElementType.WriteTo(writer, onlyName, shortName); writer.Write('&'); } else if (type is PointerType) { ((PointerType)type).ElementType.WriteTo(writer, onlyName, shortName); writer.Write('*'); } else if (type is GenericInstanceType) { type.GetElementType().WriteTo(writer, onlyName, shortName); writer.Write('<'); var arguments = ((GenericInstanceType)type).GenericArguments; for (int i = 0; i < arguments.Count; i++) { if (i > 0) { writer.Write(", "); } arguments[i].WriteTo(writer, onlyName, shortName); } writer.Write('>'); } else if (type is OptionalModifierType) { writer.Write("modopt("); ((OptionalModifierType)type).ModifierType.WriteTo(writer, true, shortName); writer.Write(") "); ((OptionalModifierType)type).ElementType.WriteTo(writer, onlyName, shortName); } else if (type is RequiredModifierType) { writer.Write("modreq("); ((RequiredModifierType)type).ModifierType.WriteTo(writer, true, shortName); writer.Write(") "); ((RequiredModifierType)type).ElementType.WriteTo(writer, onlyName, shortName); } else { string name = PrimitiveTypeName(type); if (name != null) { writer.Write(name); } else { if (!onlyName) { writer.Write(type.IsValueType ? "valuetype " : "class "); } if (type.DeclaringType != null) { type.DeclaringType.WriteTo(writer, true, shortName); writer.Write('/'); writer.WriteReference(Escape(type.Name), type); } else { if (!type.IsDefinition && type.Scope != null && !shortName && !(type is TypeSpecification)) { writer.Write("[{0}]", Escape(type.Scope.Name)); } writer.WriteReference(shortName ? type.Name : type.FullName, type); } } } }
public static void WriteOperand(ITextOutput writer, object operand) { if (operand == null) { throw new ArgumentNullException("operand"); } Instruction targetInstruction = operand as Instruction; if (targetInstruction != null) { WriteOffsetReference(writer, targetInstruction); return; } Instruction[] targetInstructions = operand as Instruction[]; if (targetInstructions != null) { WriteLabelList(writer, targetInstructions); return; } VariableReference variableRef = operand as VariableReference; if (variableRef != null) { writer.WriteReference(variableRef.Index.ToString(), variableRef); return; } MethodReference methodRef = operand as MethodReference; if (methodRef != null) { methodRef.WriteTo(writer); return; } TypeReference typeRef = operand as TypeReference; if (typeRef != null) { typeRef.WriteTo(writer); return; } FieldReference fieldRef = operand as FieldReference; if (fieldRef != null) { fieldRef.WriteTo(writer); return; } string s = operand as string; if (s != null) { writer.Write("\"" + s.Replace("\\", "\\\\").Replace("\"", "\\\"") + "\""); return; } s = ToInvariantCultureString(operand); writer.Write(s); }
public static void WriteTo(this MethodReference method, ITextOutput writer) { if (method.ExplicitThis) { writer.Write("instance explicit "); } else if (method.HasThis) { writer.Write("instance "); } method.ReturnType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); writer.Write(' '); if (method.DeclaringType != null) { method.DeclaringType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write("::"); } MethodDefinition md = method as MethodDefinition; if (md != null && md.IsCompilerControlled) { writer.WriteReference(Escape(method.Name + "$PST" + method.MetadataToken.ToInt32().ToString("X8")), method); } else { writer.WriteReference(Escape(method.Name), method); } GenericInstanceMethod gim = method as GenericInstanceMethod; if (gim != null) { writer.Write('<'); for (int i = 0; i < gim.GenericArguments.Count; i++) { if (i > 0) writer.Write(", "); gim.GenericArguments[i].WriteTo(writer); } writer.Write('>'); } writer.Write("("); var parameters = method.Parameters; for(int i = 0; i < parameters.Count; ++i) { if (i > 0) writer.Write(", "); parameters[i].ParameterType.WriteTo(writer, ILNameSyntax.SignatureNoNamedTypeParameters); } writer.Write(")"); }
public static void WriteOperand(ITextOutput writer, object operand) { if (operand == null) { throw new ArgumentNullException("operand"); } Instruction targetInstruction = operand as Instruction; if (targetInstruction != null) { WriteOffsetReference(writer, targetInstruction); return; } Instruction[] targetInstructions = operand as Instruction[]; if (targetInstructions != null) { WriteLabelList(writer, targetInstructions); return; } VariableReference variableRef = operand as VariableReference; if (variableRef != null) { if (string.IsNullOrEmpty(variableRef.Name)) { writer.WriteReference(variableRef.Index.ToString(), variableRef); } else { writer.WriteReference(Escape(variableRef.Name), variableRef); } return; } ParameterReference paramRef = operand as ParameterReference; if (paramRef != null) { if (string.IsNullOrEmpty(paramRef.Name)) { writer.WriteReference(paramRef.Index.ToString(), paramRef); } else { writer.WriteReference(Escape(paramRef.Name), paramRef); } return; } MethodReference methodRef = operand as MethodReference; if (methodRef != null) { methodRef.WriteTo(writer); return; } TypeReference typeRef = operand as TypeReference; if (typeRef != null) { typeRef.WriteTo(writer, ILNameSyntax.TypeName); return; } FieldReference fieldRef = operand as FieldReference; if (fieldRef != null) { fieldRef.WriteTo(writer); return; } string s = operand as string; if (s != null) { writer.Write("\"" + NRefactory.CSharp.TextWriterTokenWriter.ConvertString(s) + "\""); } else if (operand is char) { writer.Write(((int)(char)operand).ToString()); } else if (operand is float) { float val = (float)operand; if (val == 0) { if (1 / val == float.NegativeInfinity) { // negative zero is a special case writer.Write('-'); } writer.Write("0.0"); } else if (float.IsInfinity(val) || float.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); writer.Write('('); for (int i = 0; i < data.Length; i++) { if (i > 0) { writer.Write(' '); } writer.Write(data[i].ToString("X2")); } writer.Write(')'); } else { writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture)); } } else if (operand is double) { double val = (double)operand; if (val == 0) { if (1 / val == double.NegativeInfinity) { // negative zero is a special case writer.Write('-'); } writer.Write("0.0"); } else if (double.IsInfinity(val) || double.IsNaN(val)) { byte[] data = BitConverter.GetBytes(val); writer.Write('('); for (int i = 0; i < data.Length; i++) { if (i > 0) { writer.Write(' '); } writer.Write(data[i].ToString("X2")); } writer.Write(')'); } else { writer.Write(val.ToString("R", System.Globalization.CultureInfo.InvariantCulture)); } } else if (operand is bool) { writer.Write((bool)operand ? "true" : "false"); } else { s = ToInvariantCultureString(operand); writer.Write(s); } }
public static void WriteTo(this TypeReference type, ITextOutput writer, ILNameSyntax syntax = ILNameSyntax.Signature) { ILNameSyntax syntaxForElementTypes = syntax == ILNameSyntax.SignatureNoNamedTypeParameters ? syntax : ILNameSyntax.Signature; if (type is PinnedType) { ((PinnedType)type).ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write(" pinned"); } else if (type is ArrayType) { ArrayType at = (ArrayType)type; at.ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write('['); writer.Write(string.Join(", ", at.Dimensions)); writer.Write(']'); } else if (type is GenericParameter) { writer.Write('!'); if (((GenericParameter)type).Owner.GenericParameterType == GenericParameterType.Method) writer.Write('!'); if (string.IsNullOrEmpty(type.Name) || type.Name[0] == '!' || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) writer.Write(((GenericParameter)type).Position.ToString()); else writer.Write(Escape(type.Name)); } else if (type is ByReferenceType) { ((ByReferenceType)type).ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write('&'); } else if (type is PointerType) { ((PointerType)type).ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write('*'); } else if (type is GenericInstanceType) { type.GetElementType().WriteTo(writer, syntaxForElementTypes); writer.Write('<'); var arguments = ((GenericInstanceType)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 OptionalModifierType) { ((OptionalModifierType)type).ElementType.WriteTo(writer, syntax); writer.Write(" modopt("); ((OptionalModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write(") "); } else if (type is RequiredModifierType) { ((RequiredModifierType)type).ElementType.WriteTo(writer, syntax); writer.Write(" modreq("); ((RequiredModifierType)type).ModifierType.WriteTo(writer, ILNameSyntax.TypeName); writer.Write(") "); } else { string name = PrimitiveTypeName(type.FullName); if (syntax == ILNameSyntax.ShortTypeName) { if (name != null) writer.Write(name); else writer.WriteReference(Escape(type.Name), type); } else if ((syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) && name != null) { writer.Write(name); } else { if (syntax == ILNameSyntax.Signature || syntax == ILNameSyntax.SignatureNoNamedTypeParameters) writer.Write(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.IsDefinition && type.Scope != null && !(type is TypeSpecification)) writer.Write("[{0}]", Escape(type.Scope.Name)); writer.WriteReference(Escape(type.FullName), type); } } } }
static void WriteTo(this XFieldReference field, ITextOutput writer) { field.FieldType.WriteTo(writer, AstNameSyntax.SignatureNoNamedTypeParameters); writer.Write(' '); field.DeclaringType.WriteTo(writer, AstNameSyntax.TypeName); writer.Write("::"); writer.WriteReference(Escape(field.Name), field); }
public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options) { var module = assembly.GetPEFileOrNull(); if (module == null) { return(null); } if (options.FullDecompilation && options.SaveAsProjectDirectory != null) { if (!WholeProjectDecompiler.CanUseSdkStyleProjectFormat(module)) { options.DecompilerSettings.UseSdkStyleProjectFormat = false; } var decompiler = new ILSpyWholeProjectDecompiler(assembly, options); return(decompiler.DecompileProject(module, options.SaveAsProjectDirectory, new TextOutputWriter(output), options.CancellationToken)); } else { AddReferenceAssemblyWarningMessage(module, output); AddReferenceWarningMessage(module, output); output.WriteLine(); base.DecompileAssembly(assembly, output, options); // don't automatically load additional assemblies when an assembly node is selected in the tree view IAssemblyResolver assemblyResolver = assembly.GetAssemblyResolver(loadOnDemand: options.FullDecompilation); var typeSystem = new DecompilerTypeSystem(module, assemblyResolver, options.DecompilerSettings); var globalType = typeSystem.MainModule.TypeDefinitions.FirstOrDefault(); if (globalType != null) { output.Write("// Global type: "); output.WriteReference(globalType, globalType.FullName); output.WriteLine(); } var metadata = module.Metadata; var corHeader = module.Reader.PEHeaders.CorHeader; var entrypointHandle = MetadataTokenHelpers.EntityHandleOrNil(corHeader.EntryPointTokenOrRelativeVirtualAddress); if (!entrypointHandle.IsNil && entrypointHandle.Kind == HandleKind.MethodDefinition) { var entrypoint = typeSystem.MainModule.ResolveMethod(entrypointHandle, new Decompiler.TypeSystem.GenericContext()); if (entrypoint != null) { output.Write("// Entry point: "); output.WriteReference(entrypoint, entrypoint.DeclaringType.FullName + "." + entrypoint.Name); output.WriteLine(); } } output.WriteLine("// Architecture: " + GetPlatformDisplayName(module)); if ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.ILOnly) == 0) { output.WriteLine("// This assembly contains unmanaged code."); } string runtimeName = GetRuntimeDisplayName(module); if (runtimeName != null) { output.WriteLine("// Runtime: " + runtimeName); } if ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.StrongNameSigned) != 0) { output.WriteLine("// This assembly is signed with a strong name key."); } if (module.Reader.ReadDebugDirectory().Any(d => d.Type == DebugDirectoryEntryType.Reproducible)) { output.WriteLine("// This assembly was compiled using the /deterministic option."); } if (metadata.IsAssembly) { var asm = metadata.GetAssemblyDefinition(); if (asm.HashAlgorithm != AssemblyHashAlgorithm.None) { output.WriteLine("// Hash algorithm: " + asm.HashAlgorithm.ToString().ToUpper()); } if (!asm.PublicKey.IsNil) { output.Write("// Public key: "); var reader = metadata.GetBlobReader(asm.PublicKey); while (reader.RemainingBytes > 0) { output.Write(reader.ReadByte().ToString("x2")); } output.WriteLine(); } } var debugInfo = assembly.GetDebugInfoOrNull(); if (debugInfo != null) { output.WriteLine("// Debug info: " + debugInfo.Description); } output.WriteLine(); CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, options.DecompilerSettings); decompiler.CancellationToken = options.CancellationToken; if (options.EscapeInvalidIdentifiers) { decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers()); } SyntaxTree st; if (options.FullDecompilation) { st = decompiler.DecompileWholeModuleAsSingleFile(); } else { st = decompiler.DecompileModuleAndAssemblyAttributes(); } WriteCode(output, options.DecompilerSettings, st, decompiler.TypeSystem); return(null); } }
public static void WriteTo(this XTypeReference type, ITextOutput writer, AstNameSyntax syntax = AstNameSyntax.Signature) { var syntaxForElementTypes = syntax == AstNameSyntax.ShortTypeName ? AstNameSyntax.ShortTypeName : syntax == AstNameSyntax.SignatureNoNamedTypeParameters ? syntax : AstNameSyntax.Signature; if (type is XArrayType) { var at = (XArrayType)type; at.ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write('['); writer.Write(string.Join(", ", at.Dimensions)); writer.Write(']'); } else if (type is XGenericParameter) { writer.Write('!'); if (((XGenericParameter)type).Owner is XMethodReference) writer.Write('!'); if (string.IsNullOrEmpty(type.Name) || type.Name[0] == '!' || syntax == AstNameSyntax.SignatureNoNamedTypeParameters) writer.Write(((XGenericParameter)type).Position.ToString()); else writer.Write(Escape(type.Name)); } else if (type is XByReferenceType) { ((XByReferenceType)type).ElementType.WriteTo(writer, syntaxForElementTypes); writer.Write('&'); } else if (type is XGenericInstanceType) { type.GetElementType().WriteTo(writer, syntaxForElementTypes); writer.Write('<'); var arguments = ((XGenericInstanceType)type).GenericArguments; for (int i = 0; i < arguments.Count; i++) { if (i > 0) writer.Write(", "); arguments[i].WriteTo(writer, syntaxForElementTypes); } writer.Write('>'); } else { string name = PrimitiveTypeName(type.FullName); if (syntax == AstNameSyntax.ShortTypeName) { if (name != null) writer.Write(name); else writer.WriteReference(Escape(type.Name), type); } else if ((syntax == AstNameSyntax.Signature || syntax == AstNameSyntax.SignatureNoNamedTypeParameters) && name != null) { writer.Write(name); } else { if (syntax == AstNameSyntax.Signature || syntax == AstNameSyntax.SignatureNoNamedTypeParameters) writer.Write(type.IsValueType ? "valuetype " : "class "); var typeAsMember = type as IXMemberReference; if ((typeAsMember != null) && (typeAsMember.DeclaringType != null)) { typeAsMember.DeclaringType.WriteTo(writer, AstNameSyntax.TypeName); writer.Write('/'); writer.WriteReference(Escape(type.Name), type); } else { writer.WriteReference(Escape(type.FullName), type); } } } }
public static void WriteOffsetReference(ITextOutput writer, ILInstruction instruction) { writer.WriteReference(/*CecilExtensions.OffsetToString*/(instruction.Offset.ToString()), instruction); }