public void Decompile(Stream assemblyStream, TextWriter resultWriter) { // ReSharper disable once AgentHeisenbug.CallToNonThreadSafeStaticMethodInThreadSafeType var module = ModuleDefinition.ReadModule(assemblyStream); ((BaseAssemblyResolver)module.AssemblyResolver).AddSearchDirectory( Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) ); var context = new DecompilerContext(module) { Settings = { AnonymousMethods = false, YieldReturn = false, AsyncAwait = false, AutomaticProperties = false, ExpressionTrees = false } }; var ast = new AstBuilder(context); ast.AddAssembly(module.Assembly); RunTransforms(ast, context); // I cannot use GenerateCode as it re-runs all the transforms var userCode = GetUserCode(ast); WriteResult(resultWriter, userCode, context); }
private static void CompareAssemblyAgainstCSharp(string expectedCSharpCode, string asmFilePath) { var module = Utils.OpenModule(asmFilePath); try { try { module.LoadPdb(); } catch { } AstBuilder decompiler = new AstBuilder(DecompilerContext.CreateTestContext(module)); decompiler.AddAssembly(module, false, true, true); new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree); StringWriter output = new StringWriter(); // the F# assembly contains a namespace `<StartupCode$tmp6D55>` where the part after tmp is randomly generated. // remove this from the ast to simplify the diff var startupCodeNode = decompiler.SyntaxTree.Children.OfType<NamespaceDeclaration>().SingleOrDefault(d => d.Name.StartsWith("<StartupCode$", StringComparison.Ordinal)); if (startupCodeNode != null) startupCodeNode.Remove(); decompiler.GenerateCode(new PlainTextOutput(output)); var fullCSharpCode = output.ToString(); CodeAssert.AreEqual(expectedCSharpCode, output.ToString()); } finally { File.Delete(asmFilePath); File.Delete(Path.ChangeExtension(asmFilePath, ".pdb")); } }
AstBuilder CreateBuilder(IDnlibDef item, CancellationToken token) { ModuleDef moduleDef; DecompilerContext ctx; AstBuilder builder; if (item is ModuleDef) { var def = (ModuleDef)item; moduleDef = def; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); builder.AddAssembly(def, true); } else if (item is TypeDef) { var def = (TypeDef)item; moduleDef = def.Module; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); builder.DecompileMethodBodies = false; ctx.CurrentType = def; builder.AddType(def); } else if (item is MethodDef) { var def = (MethodDef)item; moduleDef = def.Module; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); ctx.CurrentType = def.DeclaringType; builder.AddMethod(def); } else if (item is FieldDef) { var def = (FieldDef)item; moduleDef = def.Module; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); ctx.CurrentType = def.DeclaringType; builder.AddField(def); } else if (item is PropertyDef) { var def = (PropertyDef)item; moduleDef = def.Module; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); ctx.CurrentType = def.DeclaringType; builder.AddProperty(def); } else if (item is EventDef) { var def = (EventDef)item; moduleDef = def.Module; builder = new AstBuilder(ctx = new DecompilerContext(moduleDef) { CancellationToken = token }); ctx.CurrentType = def.DeclaringType; builder.AddEvent(def); } else return null; ctx.Settings = new DecompilerSettings { UsingDeclarations = false }; return builder; }
/// <summary> /// Compiles and decompiles a source code. /// </summary> /// <param name="code">The source code to copile.</param> /// <returns>The decompilation result of compiled source code.</returns> static string RoundtripCode(string code) { AssemblyDefinition assembly = Compile(code); AstBuilder decompiler = new AstBuilder(new DecompilerContext()); decompiler.AddAssembly(assembly); decompiler.Transform(new Helpers.RemoveCompilerAttribute()); StringWriter output = new StringWriter(); decompiler.GenerateCode(new PlainTextOutput(output)); return output.ToString(); }
void Run(string compiledFile, string expectedOutputFile) { string expectedOutput = File.ReadAllText(Path.Combine(path, expectedOutputFile)); var assembly = AssemblyDefinition.ReadAssembly(Path.Combine(path, compiledFile)); AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule)); decompiler.AddAssembly(assembly); new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree); StringWriter output = new StringWriter(); decompiler.GenerateCode(new PlainTextOutput(output)); CodeAssert.AreEqual(expectedOutput, output.ToString()); }
public void DecompileFile(string input, TextWriter writer) { var assembly = AssemblyDefinition.ReadAssembly(input, new ReaderParameters() { AssemblyResolver = new IgnoringExceptionsAssemblyResolver() }); var decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule)); decompiler.AddAssembly(assembly); decompiler.GenerateCode(new PlainTextOutput(writer)); writer.Close(); }
public void Decompile() { AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly("Salient.JsonSchemaUtilities.dll"); DecompilerSettings settings = new DecompilerSettings(); settings.FullyQualifyAmbiguousTypeNames = false; AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule) { Settings = settings }); decompiler.AddAssembly(assembly); //new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit); StringWriter output = new StringWriter(); decompiler.GenerateCode(new PlainTextOutput(output)); var code = output.ToString(); }
/// <summary> /// Compiles and decompiles a source code. /// </summary> /// <param name="code">The source code to copile.</param> /// <returns>The decompilation result of compiled source code.</returns> static string RoundtripCode(string code) { DecompilerSettings settings = new DecompilerSettings(); settings.FullyQualifyAmbiguousTypeNames = false; AssemblyDefinition assembly = Compile(code); AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule) { Settings = settings }); decompiler.AddAssembly(assembly); new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit); StringWriter output = new StringWriter(); decompiler.GenerateCode(new PlainTextOutput(output)); return output.ToString(); }
protected static void AssertRoundtripCode(string fileName, bool optimize = false, bool useDebug = false, int compilerVersion = 4) { var code = RemoveIgnorableLines(File.ReadLines(fileName)); AssemblyDef assembly = CompileLegacy(code, optimize, useDebug, compilerVersion); AstBuilder decompiler = new AstBuilder(DecompilerContext.CreateTestContext(assembly.ManifestModule)); decompiler.AddAssembly(assembly); new Helpers.RemoveCompilerAttribute().Run(decompiler.SyntaxTree); StringWriter output = new StringWriter(); decompiler.GenerateCode(new PlainTextOutput(output)); CodeAssert.AreEqual(code, output.ToString()); }
static void TestFile(string fileName) { string code = File.ReadAllText(fileName); AssemblyDefinition assembly = Compile(code); AstBuilder decompiler = new AstBuilder(new DecompilerContext()); decompiler.AddAssembly(assembly); decompiler.Transform(new Helpers.RemoveCompilerAttribute()); StringWriter output = new StringWriter(); decompiler.GenerateCode(new PlainTextOutput(output)); StringWriter diff = new StringWriter(); if (!Compare(code, output.ToString(), diff)) { throw new Exception("Test failure." + Environment.NewLine + diff.ToString()); } }
private void DecompileModule(ClrModule module) { var assemblyDef = AssemblyDefinition.ReadAssembly(module.FileName); AstBuilder decompiler = new AstBuilder( new DecompilerContext(assemblyDef.MainModule)); decompiler.AddAssembly(assemblyDef); GenerateCode(decompiler); }
static void TestFile(string fileName, bool optimize) { string code = File.ReadAllText(fileName); AssemblyDefinition assembly = Compile(code, optimize); AstBuilder decompiler = new AstBuilder(new DecompilerContext(assembly.MainModule)); decompiler.AddAssembly(assembly); new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit); StringWriter output = new StringWriter(); decompiler.GenerateCode(new PlainTextOutput(output)); CodeAssert.AreEqual(code, output.ToString()); }
void Run(Config config) { if (config.ShowHelp) { Console.WriteLine ("Netjs compiler, Copyright 2014 Frank A. Krueger"); Console.WriteLine ("netjs [options] assembly-file"); return; } if (string.IsNullOrEmpty (config.MainAssembly)) { throw new Exception ("No assembly specified."); } var asmPath = Path.GetFullPath (config.MainAssembly); asmDir = Path.GetDirectoryName (asmPath); var outPath = Path.ChangeExtension (asmPath, ".ts"); Step ("Reading IL"); var parameters = new ReaderParameters { AssemblyResolver = this, }; var asm = AssemblyDefinition.ReadAssembly (asmPath, parameters); mscorlib = AssemblyDefinition.ReadAssembly (typeof(String).Assembly.Location, parameters); system = AssemblyDefinition.ReadAssembly (typeof(INotifyPropertyChanged).Assembly.Location, parameters); systemCore = AssemblyDefinition.ReadAssembly (typeof(Enumerable).Assembly.Location, parameters); Step ("Decompiling IL to C#"); var context = new DecompilerContext (asm.MainModule); context.Settings.ForEachStatement = false; context.Settings.ObjectOrCollectionInitializers = false; context.Settings.UsingStatement = false; context.Settings.AsyncAwait = false; context.Settings.AutomaticProperties = true; context.Settings.AutomaticEvents = true; context.Settings.QueryExpressions = false; context.Settings.AlwaysGenerateExceptionVariableForCatchBlocks = true; context.Settings.UsingDeclarations = false; context.Settings.FullyQualifyAmbiguousTypeNames = true; context.Settings.YieldReturn = false; var builder = new AstBuilder (context); builder.AddAssembly (asm); foreach (var a in referencedAssemblies.Values) { if (a != null) builder.AddAssembly (a); } builder.RunTransformations (); Step ("Translating C# to TypeScript"); new CsToTs ().Run (builder.SyntaxTree); Step ("Writing"); using (var outputWriter = new StreamWriter (outPath)) { var output = new PlainTextOutput (outputWriter); builder.GenerateCode (output, (s, e) => new TsOutputVisitor (s, e)); } Step ("Done"); }
string decompileAssembly(string path) { Step("Reading IL"); var parameters = new ReaderParameters { AssemblyResolver = this, }; var asm = AssemblyDefinition.ReadAssembly(path, parameters); mscorlib = AssemblyDefinition.ReadAssembly(typeof(String).Assembly.Location, parameters); system = AssemblyDefinition.ReadAssembly(typeof(INotifyPropertyChanged).Assembly.Location, parameters); systemCore = AssemblyDefinition.ReadAssembly(typeof(Enumerable).Assembly.Location, parameters); systemDrawing = AssemblyDefinition.ReadAssembly(typeof(System.Drawing.Bitmap).Assembly.Location, parameters); Step("Decompiling IL to C#"); var context = new DecompilerContext(asm.MainModule); context.Settings.ForEachStatement = false; context.Settings.ObjectOrCollectionInitializers = false; context.Settings.UsingStatement = false; context.Settings.AsyncAwait = false; context.Settings.AutomaticProperties = true; context.Settings.AutomaticEvents = true; context.Settings.QueryExpressions = false; context.Settings.AlwaysGenerateExceptionVariableForCatchBlocks = true; context.Settings.UsingDeclarations = true; context.Settings.FullyQualifyAmbiguousTypeNames = true; context.Settings.YieldReturn = false; var builder = new AstBuilder(context); builder.AddAssembly(asm); foreach (var a in referencedAssemblies.Values) { if (a != null) builder.AddAssembly(a); } /*{ var type = asm.MainModule.Types.ElementAt(16); Console.WriteLine(type + "::"); var astBuilder = new AstBuilder(new DecompilerContext(asm.MainModule) { CurrentType = type, Settings=context.Settings.Clone()}); astBuilder.AddType(type); astBuilder.RunTransformations(); var op = new PlainTextOutput(); astBuilder.GenerateCode(op); Console.WriteLine(op.ToString()); }*/ foreach (var transform in CreatePipeline(context)) { transform.Run(builder.SyntaxTree); } builder.SyntaxTree.AcceptVisitor(new InsertParenthesesVisitor { InsertParenthesesForReadability = true }); var str = new StringWriter(); var outputFormatter = new TextTokenWriter(new PlainTextOutput(str), context) { FoldBraces = context.Settings.FoldBraces }; builder.SyntaxTree.AcceptVisitor(new CSharpOutputVisitor(outputFormatter, context.Settings.CSharpFormattingOptions)); return str.GetStringBuilder().ToString(); }
void Run(Config config) { if (config.AssembliesToDecompile.Count == 0) { config.ShowHelp = true; } if (config.ShowHelp) { Console.WriteLine ("Netjs compiler, Copyright 2014-2016 Frank A. Krueger"); Console.WriteLine ("netjs [options] assembly-files"); Console.WriteLine (" --help, -h Show usage information"); Console.WriteLine (" --includerefs, -r Decompile referenced assemblies"); return; } string outPath = ""; var asmPaths = new List<string> (); foreach (var asmRelPath in config.AssembliesToDecompile) { var asmPath = Path.GetFullPath (asmRelPath); asmPaths.Add (asmPath); if (string.IsNullOrEmpty (outPath)) { outPath = Path.ChangeExtension (asmPath, ".ts"); } var asmDir = Path.GetDirectoryName (asmPath); if (!asmSearchPaths.Exists (x => x.Item1 == asmDir)) { asmSearchPaths.Add (Tuple.Create (asmDir, config.IncludeRefs)); } } Step ("Reading IL"); globalReaderParameters.AssemblyResolver = this; globalReaderParameters.ReadingMode = ReadingMode.Immediate; var libDir = Path.GetDirectoryName (typeof (String).Assembly.Location); asmSearchPaths.Add (Tuple.Create(libDir, false)); asmSearchPaths.Add (Tuple.Create(Path.Combine (libDir, "Facades"), false)); AssemblyDefinition firstAsm = null; foreach (var asmPath in asmPaths) { var asm = AssemblyDefinition.ReadAssembly (asmPath, globalReaderParameters); if (firstAsm == null) firstAsm = asm; referencedAssemblies[asm.Name.Name] = asm; decompileAssemblies.Add (asm); } Step ("Decompiling IL to C#"); var context = new DecompilerContext (firstAsm.MainModule); context.Settings.ForEachStatement = false; context.Settings.ObjectOrCollectionInitializers = false; context.Settings.UsingStatement = false; context.Settings.AsyncAwait = false; context.Settings.AutomaticProperties = true; context.Settings.AutomaticEvents = true; context.Settings.QueryExpressions = false; context.Settings.AlwaysGenerateExceptionVariableForCatchBlocks = true; context.Settings.UsingDeclarations = false; context.Settings.FullyQualifyAmbiguousTypeNames = true; context.Settings.YieldReturn = false; var builder = new AstBuilder (context); var decompiled = new HashSet<string> (); for (;;) { var a = decompileAssemblies.FirstOrDefault (x => !decompiled.Contains (x.FullName)); if (a != null) { Info (" Decompiling {0}", a.FullName); builder.AddAssembly (a); decompiled.Add (a.FullName); } else { break; } } builder.RunTransformations (); Step ("Translating C# to TypeScript"); new CsToTs ().Run (builder.SyntaxTree); Step ("Writing"); using (var outputWriter = new StreamWriter (outPath)) { var output = new PlainTextOutput (outputWriter); builder.GenerateCode (output, (s, e) => new TsOutputVisitor (s, e)); } Step ("Done"); }
public ICSharpCode.AvalonEdit.Document.TextDocument Decompile(object obj) { AvalonEditTextOutput aeto = new AvalonEditTextOutput(); AstBuilder ast = new AstBuilder(new DecompilerContext(ModuleDefinition.CreateModule("ash", ModuleKind.NetModule))); switch (obj.GetType().Name) { case "AssemblyDefinition": ast = new AstBuilder(new DecompilerContext((obj as AssemblyDefinition).MainModule) { Settings = new DecompilerSettings() }); try { ast.AddAssembly(obj as AssemblyDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.FullName); } break; case "TypeDefinition": ast = CreateAstBuilder((obj as TypeDefinition), true); try { ast.AddType(obj as TypeDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.FullName); } break; case "MethodDefinition": MethodDefinition method = (obj as MethodDefinition); ast = CreateAstBuilder(method.DeclaringType, true); if (method.IsConstructor && !method.IsStatic && !method.DeclaringType.IsValueType) { foreach (var field in method.DeclaringType.Fields) if (field.IsStatic == method.IsStatic) { try { ast.AddField(field); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } } foreach (var ctor in method.DeclaringType.Methods) if (ctor.IsConstructor && ctor.IsStatic == method.IsStatic) { try { ast.AddMethod(ctor); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } } } else { try { ast.AddMethod(obj as MethodDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } } break; case "PropertyDefinition": ast = CreateAstBuilder((obj as PropertyDefinition).DeclaringType, true); try { ast.AddProperty(obj as PropertyDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } break; case "FieldDefinition": ast = CreateAstBuilder((obj as FieldDefinition).DeclaringType, true); try { ast.AddField(obj as FieldDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } break; case "EventDefinition": ast = CreateAstBuilder((obj as EventDefinition).DeclaringType, true); try { ast.AddEvent(obj as EventDefinition); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly " + e.AssemblyReference.Name); } break; default: return new ICSharpCode.AvalonEdit.Document.TextDocument(); } try { ast.GenerateCode(aeto); } catch (AssemblyResolutionException e) { MessageBox.Show("Could not load assembly upon code generation:\r" + e.AssemblyReference.FullName); } return aeto.GetDocument(); }