private static IEnumerable<AssemblyClass> GenerateAssemblyMethodSource(string assemblyPath) { AssemblyDefinition assemblyDefinition = AssemblyDefinition.ReadAssembly (assemblyPath, new ReaderParameters (ReadingMode.Deferred) { ReadSymbols = true }); AstBuilder astBuilder = null; foreach (var defmod in assemblyDefinition.Modules) { foreach (var typeInAssembly in defmod.Types) { AssemblyClass klass = new AssemblyClass (); klass.name = typeInAssembly.Name; klass.namespase = typeInAssembly.Namespace; astBuilder = new AstBuilder (new DecompilerContext (assemblyDefinition.MainModule) { CurrentType = typeInAssembly }); astBuilder.AddType (typeInAssembly); StringWriter output = new StringWriter (); astBuilder.GenerateCode (new PlainTextOutput (output)); klass.source = output.ToString (); yield return klass; } } }
IEnumerable <Tuple <string, string> > WriteCodeFilesInProject(ModuleDefinition module, DecompilationOptions options, HashSet <string> directories) { var files = module.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy( delegate(TypeDefinition type) { string file = TextView.DecompilerTextView.CleanUpName(type.Name) + this.FileExtension; if (string.IsNullOrEmpty(type.Namespace)) { return(file); } else { string dir = TextView.DecompilerTextView.CleanUpName(type.Namespace); if (directories.Add(dir)) { Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dir)); } return(Path.Combine(dir, file)); } }, StringComparer.OrdinalIgnoreCase).ToList(); AstMethodBodyBuilder.ClearUnhandledOpcodes(); Parallel.ForEach( files, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate(IGrouping <string, TypeDefinition> file) { using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key))) { AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module); foreach (TypeDefinition type in file) { codeDomBuilder.AddType(type); } codeDomBuilder.RunTransformations(transformAbortCondition); GenerateCode(codeDomBuilder, new PlainTextOutput(w)); } }); AstMethodBodyBuilder.PrintNumberOfUnhandledOpcodes(); return(files.Select(f => Tuple.Create("Compile", f.Key)).Concat(WriteAssemblyInfo(module, options, directories))); }
private void FixGeneratedType() { var d = new DecompilerContext(DestinationType.Module); d.CurrentType = DestinationType; var visitor = new ObservableAstVisitor(); visitor.EnterInvocationExpression += exp => { var target = exp.Target; var methodInvoke = exp.Annotation <MethodReference>(); if (methodInvoke == null) { return; } for (var i = 0; i < exp.Arguments.Count; i++) { var arg = exp.Arguments.ToList()[i]; var argType = arg.Annotation <TypeInformation>().InferredType; var param = methodInvoke.Parameters[i]; var paramType = param.ParameterType; if (argType.IsValueType && !paramType.IsValueType) { var argILRange = arg.Annotation <List <ILRange> >(); var insts = GetInstructions(arg); var inst = GetInstruction(insts, argILRange[0].To); if (inst.Previous.OpCode.Code != Code.Box) { var box = Instruction.Create(OpCodes.Box, argType); insts.Insert(insts.IndexOf(inst), box); Console.WriteLine("Box inserted! Method Arg " + param.Name + " " + argType + " to " + paramType); } } } }; copier.Process(); var astBuilder = new AstBuilder(d); astBuilder.AddType(DestinationType); // astBuilder.RunTransformations(); astBuilder.SyntaxTree.AcceptVisitor(visitor); }
private static string GenerateTypeDescription(ModuleDefinition module, TypeDefinition type) { var context = new DecompilerContext(module); var astBuilder = new AstBuilder(context) { DecompileMethodBodies = false }; astBuilder.AddType(type); if (!(type.IsEnum || type.IsInterface || type.IsDelegate())) { var typeNode = astBuilder.SyntaxTree.GetTypes() .OfType <TypeDeclaration>().First(); // Remove nested types foreach (var node in typeNode.Children) { if (node is TypeDeclaration) { node.Remove(); } } // Remove non-public members foreach (var member in typeNode.Members) { if (!(member.HasModifier(Modifiers.Public) || member.HasModifier(Modifiers.Protected))) { member.Remove(); } } } astBuilder.RunTransformations(); AddXmlDocTransform.Run(astBuilder.SyntaxTree); var output = new PlainTextOutput(); astBuilder.GenerateCode(output); return(output.ToString()); }
static void DumpTypes(List <TypeDefinition> types, string baseDir) { var module = types.First().Module; var context = new DecompilerContext(module); context.Settings = new DecompilerSettings { ShowXmlDocumentation = true, UsingDeclarations = true, FullyQualifyAmbiguousTypeNames = true, FoldBraces = true, }; //Xamarin.iOS has AdErrorEventArgs and ADErrorEventArgs //which collide on case insensitive filesystem var fileCollision = new HashSet <string> (StringComparer.OrdinalIgnoreCase); foreach (var t in types) { var filename = t.Name; int i = 0; while (!fileCollision.Add(t.Namespace + "/" + filename)) { filename = t.Name + (++i); } var astBuilder = new AstBuilder(context); astBuilder.AddType(t); astBuilder.RunTransformations(); astBuilder.SyntaxTree.AcceptVisitor(new ContractVisitor(!keepInteropInfo)); var dir = Path.Combine(baseDir, t.Namespace); var file = Path.Combine(dir, filename + ".cs"); Directory.CreateDirectory(dir); using (var contract = new StreamWriter(file)) { astBuilder.GenerateCode(new PlainTextOutput(contract)); } } }
private static string Decompile(Assemblies.AssemblyDefinition asm, IEnumerable <TypeDefinition> types) { DecompilerSettings settings = new DecompilerSettings(); settings.FullyQualifyAmbiguousTypeNames = false; var ctx = new DecompilerContext(asm.MainModule) { Settings = settings }; var decompiler = new AstBuilder(ctx); foreach (var t in types) { decompiler.AddType(t); } new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit); var output = new StringWriter(); decompiler.GenerateCode(new PlainTextOutput(output)); return(output.ToString().Trim()); }
static AstBuilder CreateAstBuilder(DecompiledTypeReference name, CancellationToken cancellationToken = default(CancellationToken)) { ModuleDefinition module = GetModuleDefinitionFromCache(name.AssemblyFile); if (module == null) { throw new InvalidOperationException("Could not find assembly file"); } TypeDefinition typeDefinition = module.GetType(name.Type.ReflectionName); if (typeDefinition == null) { throw new InvalidOperationException("Could not find type"); } DecompilerContext context = new DecompilerContext(module); context.CancellationToken = cancellationToken; AstBuilder astBuilder = new AstBuilder(context); astBuilder.AddType(typeDefinition); return(astBuilder); }
private static void DecompileSourceFile(IGrouping <string, TypeDefinition> src, DecompilationOptions options) { var path = Path.Combine(options.SaveAsProjectDirectory, src.Key); CreateParentDirectory(path); using (var w = new StreamWriter(path)) { var builder = new AstBuilder( new DecompilerContext(src.First().Module) { CancellationToken = options.CancellationToken, Settings = options.DecompilerSettings }); foreach (var type in src) { builder.AddType(type); } builder.GenerateCode(new PlainTextOutput(w)); } }
IEnumerable <Tuple <string, string> > WriteCodeFilesInProject(ModuleDefinition module, DecompilationOptions options, HashSet <string> directories) { var files = module.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy( delegate(TypeDefinition type) { string file = CleanUpName(type.Name); if (string.IsNullOrEmpty(type.Namespace)) { return(file); } else { return(file); /*string dir = CleanUpName(type.Namespace); * if (OnlyIncludeNameSpace == null || OnlyIncludeNameSpace == type.Namespace) * { * if (directories.Add(dir)) * Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dir)); * }*/ //return Path.Combine(dir, file); } }, StringComparer.OrdinalIgnoreCase).ToList(); AstMethodBodyBuilder.ClearUnhandledOpcodes(); Parallel.ForEach( files, new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount }, delegate(IGrouping <string, TypeDefinition> file) { var path = options.SaveAsProjectDirectory; var t = file.First <TypeDefinition>(); string fname = file.Key; if (IsNeedWriteHpp(t, OnlyIncludeNameSpace)) { var HppPath = Path.Combine(path, "include"); HppPath = Path.Combine(HppPath, "QuantKit"); Directory.CreateDirectory(HppPath); using (StreamWriter w = new StreamWriter(Path.Combine(HppPath, file.Key + HppFileExtension))) { /* AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module); * foreach (TypeDefinition type in file) * { * codeDomBuilder.AddType(type); * } * PreProcess(module); * codeDomBuilder.RunTransformations(transformAbortCondition);*/ //WriteHppCode(t, FindDeclaration(t, codeDomBuilder), new PlainTextOutput(w)); WriteHppCode(t, new PlainTextOutput(w)); } } if (IsNeedWriteHxx(t, OnlyIncludeNameSpace)) { var HxxPath = Path.Combine(path, "src"); Directory.CreateDirectory(HxxPath); using (StreamWriter w = new StreamWriter(Path.Combine(HxxPath, file.Key + HxxFileExtension))) { AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module); foreach (TypeDefinition type in file) { codeDomBuilder.AddType(type); } PreProcess(module); codeDomBuilder.RunTransformations(transformAbortCondition); WriteHxxCode(t, new PlainTextOutput(w)); } } if (IsNeedWriteCpp(t, OnlyIncludeNameSpace)) { var CppPath = Path.Combine(path, "src"); Directory.CreateDirectory(CppPath); using (StreamWriter w = new StreamWriter(Path.Combine(CppPath, file.Key + CppFileExtension))) { AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module); foreach (TypeDefinition type in file) { codeDomBuilder.AddType(type); } PreProcess(module); codeDomBuilder.RunTransformations(transformAbortCondition); WriteCppCode(t, new PlainTextOutput(w)); } } /*using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key))) * { * AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module); * foreach (TypeDefinition type in file) * { * codeDomBuilder.AddType(type); * } * PreProcess(module); * codeDomBuilder.RunTransformations(transformAbortCondition); * GenerateCplusplusCode(codeDomBuilder, new PlainTextOutput(w), "SmartQuant"); * }*/ }); AstMethodBodyBuilder.PrintNumberOfUnhandledOpcodes(); return(files.Select(f => Tuple.Create("Compile", f.Key))); }
public override bool Execute(IList <Exception> thrownExceptions) { Logger = Logger ?? new Logger(null, Verbosity); Logger.LogLine(1, "Compiling Xaml"); Logger.LogLine(1, "\nAssembly: {0}", Assembly); if (!string.IsNullOrEmpty(DependencyPaths)) { Logger.LogLine(1, "DependencyPaths: \t{0}", DependencyPaths); } if (!string.IsNullOrEmpty(ReferencePath)) { Logger.LogLine(1, "ReferencePath: \t{0}", ReferencePath.Replace("//", "/")); } Logger.LogLine(3, "DebugSymbols:\"{0}\"", DebugSymbols); var skipassembly = true; //change this to false to enable XamlC by default bool success = true; if (!File.Exists(Assembly)) { Logger.LogLine(1, "Assembly file not found. Skipping XamlC."); return(true); } var resolver = new XamlCAssemblyResolver(); if (!string.IsNullOrEmpty(DependencyPaths)) { foreach (var dep in DependencyPaths.Split(';')) { Logger.LogLine(3, "Adding searchpath {0}", dep); resolver.AddSearchDirectory(dep); } } if (!string.IsNullOrEmpty(ReferencePath)) { var paths = ReferencePath.Replace("//", "/").Split(';'); foreach (var p in paths) { var searchpath = Path.GetDirectoryName(p); Logger.LogLine(3, "Adding searchpath {0}", searchpath); resolver.AddSearchDirectory(searchpath); } } var assemblyDefinition = AssemblyDefinition.ReadAssembly(Path.GetFullPath(Assembly), new ReaderParameters { AssemblyResolver = resolver, ReadSymbols = DebugSymbols }); CustomAttribute xamlcAttr; if (assemblyDefinition.HasCustomAttributes && (xamlcAttr = assemblyDefinition.CustomAttributes.FirstOrDefault( ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null) { var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value; if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip) { skipassembly = true; } if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile) { skipassembly = false; } } foreach (var module in assemblyDefinition.Modules) { var skipmodule = skipassembly; if (module.HasCustomAttributes && (xamlcAttr = module.CustomAttributes.FirstOrDefault( ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null) { var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value; if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip) { skipmodule = true; } if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile) { skipmodule = false; } } Logger.LogLine(2, " Module: {0}", module.Name); var resourcesToPrune = new List <EmbeddedResource>(); foreach (var resource in module.Resources.OfType <EmbeddedResource>()) { Logger.LogString(2, " Resource: {0}... ", resource.Name); string classname; if (!resource.IsXaml(out classname)) { Logger.LogLine(2, "skipped."); continue; } TypeDefinition typeDef = module.GetType(classname); if (typeDef == null) { Logger.LogLine(2, "no type found... skipped."); continue; } var skiptype = skipmodule; if (typeDef.HasCustomAttributes && (xamlcAttr = typeDef.CustomAttributes.FirstOrDefault( ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null) { var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value; if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip) { skiptype = true; } if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile) { skiptype = false; } } if (Type != null) { skiptype = !(Type == classname); } if (skiptype) { Logger.LogLine(2, "Has XamlCompilationAttribute set to Skip and not Compile... skipped"); continue; } var initComp = typeDef.Methods.FirstOrDefault(md => md.Name == "InitializeComponent"); if (initComp == null) { Logger.LogLine(2, "no InitializeComponent found... skipped."); continue; } Logger.LogLine(2, ""); CustomAttribute xamlFilePathAttr; var xamlFilePath = typeDef.HasCustomAttributes && (xamlFilePathAttr = typeDef.CustomAttributes.FirstOrDefault(ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlFilePathAttribute")) != null ? (string)xamlFilePathAttr.ConstructorArguments [0].Value : resource.Name; var initCompRuntime = typeDef.Methods.FirstOrDefault(md => md.Name == "__InitComponentRuntime"); if (initCompRuntime != null) { Logger.LogLine(2, " __InitComponentRuntime already exists... not duplicating"); } else { Logger.LogString(2, " Duplicating {0}.InitializeComponent () into {0}.__InitComponentRuntime ... ", typeDef.Name); initCompRuntime = DuplicateMethodDef(typeDef, initComp, "__InitComponentRuntime"); Logger.LogLine(2, "done."); } Logger.LogString(2, " Parsing Xaml... "); var rootnode = ParseXaml(resource.GetResourceStream(), typeDef); if (rootnode == null) { Logger.LogLine(2, "failed."); continue; } Logger.LogLine(2, "done."); hasCompiledXamlResources = true; Logger.LogString(2, " Replacing {0}.InitializeComponent ()... ", typeDef.Name); Exception e; if (!TryCoreCompile(initComp, initCompRuntime, rootnode, out e)) { success = false; Logger.LogLine(2, "failed."); thrownExceptions?.Add(e); Logger.LogException(null, null, null, xamlFilePath, e); Logger.LogLine(4, e.StackTrace); continue; } Logger.LogLine(2, "done."); if (OptimizeIL) { Logger.LogString(2, " Optimizing IL... "); initComp.Body.OptimizeMacros(); Logger.LogLine(2, "done"); } if (OutputGeneratedILAsCode) { var filepath = Path.Combine(Path.GetDirectoryName(Assembly), typeDef.FullName + ".decompiled.cs"); Logger.LogString(2, " Decompiling {0} into {1}...", typeDef.FullName, filepath); var decompilerContext = new DecompilerContext(module); using (var writer = new StreamWriter(filepath)) { var output = new PlainTextOutput(writer); var codeDomBuilder = new AstBuilder(decompilerContext); codeDomBuilder.AddType(typeDef); codeDomBuilder.GenerateCode(output); } Logger.LogLine(2, "done"); } resourcesToPrune.Add(resource); } if (!KeepXamlResources) { if (resourcesToPrune.Any()) { Logger.LogLine(2, " Removing compiled xaml resources"); } foreach (var resource in resourcesToPrune) { Logger.LogString(2, " Removing {0}... ", resource.Name); module.Resources.Remove(resource); Logger.LogLine(2, "done"); } } Logger.LogLine(2, ""); } if (!hasCompiledXamlResources) { Logger.LogLine(1, "No compiled resources. Skipping writing assembly."); return(success); } Logger.LogString(1, "Writing the assembly... "); try { assemblyDefinition.Write(Assembly, new WriterParameters { WriteSymbols = DebugSymbols }); Logger.LogLine(1, "done."); } catch (Exception e) { Logger.LogLine(1, "failed."); Logger.LogException(null, null, null, null, e); thrownExceptions?.Add(e); Logger.LogLine(4, e.StackTrace); success = false; } return(success); }
private static string Decompile(Assemblies.AssemblyDefinition asm, IEnumerable<TypeDefinition> types) { DecompilerSettings settings = new DecompilerSettings(); settings.FullyQualifyAmbiguousTypeNames = false; var ctx = new DecompilerContext(asm.MainModule) { Settings = settings }; var decompiler = new AstBuilder(ctx); foreach (var t in types) { decompiler.AddType(t); } new Helpers.RemoveCompilerAttribute().Run(decompiler.CompilationUnit); var output = new StringWriter(); decompiler.GenerateCode(new PlainTextOutput(output)); return output.ToString().Trim(); }
private void DecompileSelectedNode() { if (treeView1.SelectedItem == null || !(((TreeViewItem)treeView1.SelectedItem).Tag is TypeDefinition)) { codeTextBox.Blocks.Clear(); return; } var ty = (TypeDefinition)(((TreeViewItem)treeView1.SelectedItem).Tag); var ctx = new DecompilerContext(ty.Module); var astBui = new AstBuilder(ctx); astBui.AddType(ty); astBui.RunTransformations(); var outp = new RichTextOutput(); astBui.GenerateCode(outp); //var rn = new Run { Text = outp.ToString() }; //var pa = new Paragraph(); //pa.Inlines.Add(rn); codeTextBox.Blocks.Clear(); //codeTextBox.Blocks.Add(pa); foreach (var b in outp.GetBlocks()) { codeTextBox.Blocks.Add(b); } codeTextBox.Selection.Select(codeTextBox.ContentStart, codeTextBox.ContentStart); }
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()); }
public bool Compile() { LogLine(1, "Compiling Xaml"); LogLine(1, "\nAssembly: {0}", Assembly); if (!string.IsNullOrEmpty(DependencyPaths)) { LogLine(1, "DependencyPaths: \t{0}", DependencyPaths); } if (!string.IsNullOrEmpty(ReferencePath)) { LogLine(1, "ReferencePath: \t{0}", ReferencePath.Replace("//", "/")); } LogLine(3, "DebugSymbols:\"{0}\"", DebugSymbols); var skipassembly = true; //change this to false to enable XamlC by default bool success = true; if (!File.Exists(Assembly)) { LogLine(1, "Assembly file not found. Skipping XamlC."); return(true); } var resolver = new XamlCAssemblyResolver(); if (!string.IsNullOrEmpty(DependencyPaths)) { foreach (var dep in DependencyPaths.Split(';')) { LogLine(3, "Adding searchpath {0}", dep); resolver.AddSearchDirectory(dep); } } if (!string.IsNullOrEmpty(ReferencePath)) { var paths = ReferencePath.Replace("//", "/").Split(';'); foreach (var p in paths) { var searchpath = Path.GetDirectoryName(p); LogLine(3, "Adding searchpath {0}", searchpath); resolver.AddSearchDirectory(searchpath); // LogLine (3, "Referencing {0}", p); // resolver.AddAssembly (p); } } var assemblyDefinition = AssemblyDefinition.ReadAssembly(Path.GetFullPath(Assembly), new ReaderParameters { AssemblyResolver = resolver, ReadSymbols = DebugSymbols }); CustomAttribute xamlcAttr; if (assemblyDefinition.HasCustomAttributes && (xamlcAttr = assemblyDefinition.CustomAttributes.FirstOrDefault( ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null) { var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value; if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip) { skipassembly = true; } if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile) { skipassembly = false; } } foreach (var module in assemblyDefinition.Modules) { var skipmodule = skipassembly; if (module.HasCustomAttributes && (xamlcAttr = module.CustomAttributes.FirstOrDefault( ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null) { var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value; if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip) { skipmodule = true; } if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile) { skipmodule = false; } } LogLine(2, " Module: {0}", module.Name); var resourcesToPrune = new List <EmbeddedResource>(); foreach (var resource in module.Resources.OfType <EmbeddedResource>()) { LogString(2, " Resource: {0}... ", resource.Name); string classname; if (!resource.IsXaml(out classname)) { LogLine(2, "skipped."); continue; } TypeDefinition typeDef = module.GetType(classname); if (typeDef == null) { LogLine(2, "no type found... skipped."); continue; } var skiptype = skipmodule; if (typeDef.HasCustomAttributes && (xamlcAttr = typeDef.CustomAttributes.FirstOrDefault( ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null) { var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value; if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip) { skiptype = true; } if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile) { skiptype = false; } } if (skiptype) { LogLine(2, "Has XamlCompilationAttribute set to Skip and not Compile... skipped"); continue; } var initComp = typeDef.Methods.FirstOrDefault(md => md.Name == "InitializeComponent"); if (initComp == null) { LogLine(2, "no InitializeComponent found... skipped."); continue; } LogLine(2, ""); var initCompRuntime = typeDef.Methods.FirstOrDefault(md => md.Name == "__InitComponentRuntime"); if (initCompRuntime != null) { LogLine(2, " __InitComponentRuntime already exists... not duplicating"); } else { LogString(2, " Duplicating {0}.InitializeComponent () into {0}.__InitComponentRuntime ... ", typeDef.Name); initCompRuntime = DuplicateMethodDef(typeDef, initComp, "__InitComponentRuntime"); LogLine(2, "done."); } LogString(2, " Parsing Xaml... "); var rootnode = ParseXaml(resource.GetResourceStream(), typeDef); if (rootnode == null) { LogLine(2, "failed."); continue; } LogLine(2, "done."); hasCompiledXamlResources = true; try { LogString(2, " Replacing {0}.InitializeComponent ()... ", typeDef.Name); var body = new MethodBody(initComp); var il = body.GetILProcessor(); il.Emit(OpCodes.Nop); // Generating branching code for the Previewer // IL_0007: call class [mscorlib]System.Func`2<class [mscorlib]System.Type,string> class [Xamarin.Forms.Xaml.Internals]Xamarin.Forms.Xaml.XamlLoader::get_XamlFileProvider() // IL_000c: brfalse IL_0031 // IL_0011: call class [mscorlib]System.Func`2<class [mscorlib]System.Type,string> class [Xamarin.Forms.Xaml.Internals]Xamarin.Forms.Xaml.XamlLoader::get_XamlFileProvider() // IL_0016: ldarg.0 // IL_0017: call instance class [mscorlib]System.Type object::GetType() // IL_001c: callvirt instance !1 class [mscorlib]System.Func`2<class [mscorlib]System.Type, string>::Invoke(!0) // IL_0021: brfalse IL_0031 // IL_0026: ldarg.0 // IL_0027: call instance void class Xamarin.Forms.Xaml.UnitTests.XamlLoaderGetXamlForTypeTests::__InitComponentRuntime() // IL_002c: ret // IL_0031: nop var nop = Instruction.Create(OpCodes.Nop); var getXamlFileProvider = body.Method.Module.Import(body.Method.Module.Import(typeof(Xamarin.Forms.Xaml.Internals.XamlLoader)) .Resolve() .Properties.FirstOrDefault(pd => pd.Name == "XamlFileProvider") .GetMethod); il.Emit(OpCodes.Call, getXamlFileProvider); il.Emit(OpCodes.Brfalse, nop); il.Emit(OpCodes.Call, getXamlFileProvider); il.Emit(OpCodes.Ldarg_0); var getType = body.Method.Module.Import(body.Method.Module.Import(typeof(object)) .Resolve() .Methods.FirstOrDefault(md => md.Name == "GetType")); il.Emit(OpCodes.Call, getType); var func = body.Method.Module.Import(body.Method.Module.Import(typeof(Func <Type, string>)) .Resolve() .Methods.FirstOrDefault(md => md.Name == "Invoke")); func = func.ResolveGenericParameters(body.Method.Module.Import(typeof(Func <Type, string>)), body.Method.Module); il.Emit(OpCodes.Callvirt, func); il.Emit(OpCodes.Brfalse, nop); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Call, initCompRuntime); il.Emit(OpCodes.Ret); il.Append(nop); var visitorContext = new ILContext(il, body); rootnode.Accept(new XamlNodeVisitor((node, parent) => node.Parent = parent), null); rootnode.Accept(new ExpandMarkupsVisitor(visitorContext), null); rootnode.Accept(new PruneIgnoredNodesVisitor(), null); rootnode.Accept(new CreateObjectVisitor(visitorContext), null); rootnode.Accept(new SetNamescopesAndRegisterNamesVisitor(visitorContext), null); rootnode.Accept(new SetFieldVisitor(visitorContext), null); rootnode.Accept(new SetResourcesVisitor(visitorContext), null); rootnode.Accept(new SetPropertiesVisitor(visitorContext, true), null); il.Emit(OpCodes.Ret); initComp.Body = body; } catch (XamlParseException xpe) { LogLine(2, "failed."); LogError(null, null, null, resource.Name, xpe.XmlInfo.LineNumber, xpe.XmlInfo.LinePosition, 0, 0, xpe.Message, xpe.HelpLink, xpe.Source); LogLine(4, xpe.StackTrace); success = false; continue; } catch (XmlException xe) { LogLine(2, "failed."); LogError(null, null, null, resource.Name, xe.LineNumber, xe.LinePosition, 0, 0, xe.Message, xe.HelpLink, xe.Source); LogLine(4, xe.StackTrace); success = false; continue; } catch (Exception e) { LogLine(2, "failed."); LogError(null, null, null, resource.Name, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source); LogLine(4, e.StackTrace); success = false; continue; } LogLine(2, "done."); if (OptimizeIL) { LogString(2, " Optimizing IL... "); initComp.Body.OptimizeMacros(); LogLine(2, "done"); } if (OutputGeneratedILAsCode) { var filepath = Path.Combine(Path.GetDirectoryName(Assembly), typeDef.FullName + ".decompiled.cs"); LogString(2, " Decompiling {0} into {1}...", typeDef.FullName, filepath); var decompilerContext = new DecompilerContext(module); using (var writer = new StreamWriter(filepath)) { var output = new PlainTextOutput(writer); var codeDomBuilder = new AstBuilder(decompilerContext); codeDomBuilder.AddType(typeDef); codeDomBuilder.GenerateCode(output); } LogLine(2, "done"); } resourcesToPrune.Add(resource); } if (!KeepXamlResources) { if (resourcesToPrune.Any()) { LogLine(2, " Removing compiled xaml resources"); } foreach (var resource in resourcesToPrune) { LogString(2, " Removing {0}... ", resource.Name); module.Resources.Remove(resource); LogLine(2, "done"); } } LogLine(2, ""); } if (!hasCompiledXamlResources) { LogLine(1, "No compiled resources. Skipping writing assembly."); return(success); } LogString(1, "Writing the assembly... "); try { assemblyDefinition.Write(Assembly, new WriterParameters { WriteSymbols = DebugSymbols }); LogLine(1, "done."); } catch (Exception e) { LogLine(1, "failed."); LogError(null, null, null, null, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source); LogLine(4, e.StackTrace); success = false; } return(success); }
public static void Main(string[] args) { bool help = false; int verbosity = 1; string outputDir = "Decompiled"; string restrictType = null; IList <string> extra = null; var p = new OptionSet { { "h|?|help", "Print this help message", v => help = true }, { "d=", "Output directory", v => outputDir = v }, { "t=", "Only decompile this type", v => restrictType = v }, { "v=|verbosity=", "0 is quiet, 1 is normal, 2 is verbose", v => verbosity = int.Parse(v) }, }; try { extra = p.Parse(args); } catch (OptionException oe) { if (verbosity > 0) { Console.Error.WriteLine($"decompile.exe: argument error:{oe.Message}.\n{usageString}"); } Environment.Exit(0); } if (help) { ShowHelp(p); return; } if (extra.Count != 1) { if (verbosity > 0) { Console.Error.WriteLine($"decompile.exe: missing assembly parameter.\n{usageString}."); } Environment.Exit(0); } var assemblyPath = extra[0]; if (!File.Exists(assemblyPath)) { if (verbosity > 0) { Console.Error.WriteLine($"decompile.exe: assembly not found.\n{usageString}."); } Environment.Exit(0); } var resolver = new DecompilerResolver(); var dir = Path.GetDirectoryName(assemblyPath); if (!string.IsNullOrEmpty(dir)) { resolver.AddSearchDirectory(dir); } var directory = Directory.CreateDirectory(outputDir); var assemblyDef = AssemblyDefinition.ReadAssembly(Path.GetFullPath(assemblyPath), new ReaderParameters { AssemblyResolver = resolver }); var settings = new DecompilerSettings { }; var types = from moduleDef in assemblyDef.Modules from type in moduleDef.Types select type; foreach (var typeDef in types) { if (typeDef.IsSpecialName) { continue; } if (!string.IsNullOrEmpty(restrictType) && typeDef.FullName != restrictType) { continue; } var filepath = Path.Combine(directory.Name, typeDef.FullName + ".cs"); if (verbosity >= 2) { Console.Write($"Decompiling {typeDef.FullName} into {filepath}..."); } var decompilerContext = new DecompilerContext(typeDef.Module) { Settings = settings }; using (var writer = new StreamWriter(filepath)) { var output = new PlainTextOutput(writer); var builder = new AstBuilder(decompilerContext); builder.AddType(typeDef); builder.GenerateCode(output); } if (verbosity >= 2) { Console.WriteLine($"done."); } } }
public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options) { AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: type.Module); codeDomBuilder.AddType(type); RunTransformsAndGenerateCode(codeDomBuilder, output, options, type.Module); }
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); }
public bool Compile() { LogLine(1, "Compiling Xaml"); LogLine(1, "\nAssembly: {0}", Assembly); if (!string.IsNullOrEmpty(DependencyPaths)) { LogLine(1, "DependencyPaths: \t{0}", DependencyPaths); } if (!string.IsNullOrEmpty(ReferencePath)) { LogLine(1, "ReferencePath: \t{0}", ReferencePath.Replace("//", "/")); } LogLine(3, "DebugSymbols:\"{0}\"", DebugSymbols); var skipassembly = true; //change this to false to enable XamlC by default bool success = true; if (!File.Exists(Assembly)) { LogLine(1, "Assembly file not found. Skipping XamlC."); return(true); } var resolver = new XamlCAssemblyResolver(); if (!string.IsNullOrEmpty(DependencyPaths)) { foreach (var dep in DependencyPaths.Split(';')) { LogLine(3, "Adding searchpath {0}", dep); resolver.AddSearchDirectory(dep); } } if (!string.IsNullOrEmpty(ReferencePath)) { var paths = ReferencePath.Replace("//", "/").Split(';'); foreach (var p in paths) { var searchpath = Path.GetDirectoryName(p); LogLine(3, "Adding searchpath {0}", searchpath); resolver.AddSearchDirectory(searchpath); // LogLine (3, "Referencing {0}", p); // resolver.AddAssembly (p); } } var assemblyDefinition = AssemblyDefinition.ReadAssembly(Path.GetFullPath(Assembly), new ReaderParameters { AssemblyResolver = resolver, ReadSymbols = DebugSymbols }); CustomAttribute xamlcAttr; if (assemblyDefinition.HasCustomAttributes && (xamlcAttr = assemblyDefinition.CustomAttributes.FirstOrDefault( ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null) { var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value; if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip) { skipassembly = true; } if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile) { skipassembly = false; } } foreach (var module in assemblyDefinition.Modules) { var skipmodule = skipassembly; if (module.HasCustomAttributes && (xamlcAttr = module.CustomAttributes.FirstOrDefault( ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null) { var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value; if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip) { skipmodule = true; } if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile) { skipmodule = false; } } LogLine(2, " Module: {0}", module.Name); var resourcesToPrune = new List <EmbeddedResource>(); foreach (var resource in module.Resources.OfType <EmbeddedResource>()) { Log(2, " Resource: {0}... ", resource.Name); string classname; if (!resource.IsXaml(out classname)) { LogLine(2, "skipped."); continue; } TypeDefinition typeDef = module.GetType(classname); if (typeDef == null) { LogLine(2, "no type found... skipped."); continue; } var skiptype = skipmodule; if (typeDef.HasCustomAttributes && (xamlcAttr = typeDef.CustomAttributes.FirstOrDefault( ca => ca.AttributeType.FullName == "Xamarin.Forms.Xaml.XamlCompilationAttribute")) != null) { var options = (XamlCompilationOptions)xamlcAttr.ConstructorArguments[0].Value; if ((options & XamlCompilationOptions.Skip) == XamlCompilationOptions.Skip) { skiptype = true; } if ((options & XamlCompilationOptions.Compile) == XamlCompilationOptions.Compile) { skiptype = false; } } if (skiptype) { LogLine(2, "Has XamlCompilationAttribute set to Skip and not Compile... skipped"); continue; } var initComp = typeDef.Methods.FirstOrDefault(md => md.Name == "InitializeComponent"); if (initComp == null) { LogLine(2, "no InitializeComponent found... skipped."); continue; } LogLine(2, ""); Log(2, " Parsing Xaml... "); var rootnode = ParseXaml(resource.GetResourceStream(), typeDef); if (rootnode == null) { LogLine(2, "failed."); continue; } LogLine(2, "done."); hasCompiledXamlResources = true; try { Log(2, " Replacing {0}.InitializeComponent ()... ", typeDef.Name); var body = new MethodBody(initComp); var il = body.GetILProcessor(); il.Emit(OpCodes.Nop); var visitorContext = new ILContext(il, body); rootnode.Accept(new XamlNodeVisitor((node, parent) => node.Parent = parent), null); rootnode.Accept(new ExpandMarkupsVisitor(visitorContext), null); rootnode.Accept(new CreateObjectVisitor(visitorContext), null); rootnode.Accept(new SetNamescopesAndRegisterNamesVisitor(visitorContext), null); rootnode.Accept(new SetFieldVisitor(visitorContext), null); rootnode.Accept(new SetResourcesVisitor(visitorContext), null); rootnode.Accept(new SetPropertiesVisitor(visitorContext, true), null); il.Emit(OpCodes.Ret); initComp.Body = body; } catch (XamlParseException xpe) { LogLine(2, "failed."); LogError(null, null, null, resource.Name, xpe.XmlInfo.LineNumber, xpe.XmlInfo.LinePosition, 0, 0, xpe.Message, xpe.HelpLink, xpe.Source); LogLine(4, xpe.StackTrace); success = false; continue; } catch (XmlException xe) { LogLine(2, "failed."); LogError(null, null, null, resource.Name, xe.LineNumber, xe.LinePosition, 0, 0, xe.Message, xe.HelpLink, xe.Source); LogLine(4, xe.StackTrace); success = false; continue; } catch (Exception e) { LogLine(2, "failed."); LogError(null, null, null, resource.Name, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source); LogLine(4, e.StackTrace); success = false; continue; } LogLine(2, "done."); if (OptimizeIL) { Log(2, " Optimizing IL... "); initComp.Body.OptimizeMacros(); LogLine(2, "done"); } if (OutputGeneratedILAsCode) { var filepath = Path.Combine(Path.GetDirectoryName(Assembly), typeDef.FullName + ".decompiled.cs"); Log(2, " Decompiling {0} into {1}...", typeDef.FullName, filepath); var decompilerContext = new DecompilerContext(module); using (var writer = new StreamWriter(filepath)) { var output = new PlainTextOutput(writer); var codeDomBuilder = new AstBuilder(decompilerContext); codeDomBuilder.AddType(typeDef); codeDomBuilder.GenerateCode(output); } LogLine(2, "done"); } resourcesToPrune.Add(resource); } if (!KeepXamlResources) { if (resourcesToPrune.Any()) { LogLine(2, " Removing compiled xaml resources"); } foreach (var resource in resourcesToPrune) { Log(2, " Removing {0}... ", resource.Name); module.Resources.Remove(resource); LogLine(2, "done"); } } LogLine(2, ""); } if (!hasCompiledXamlResources) { LogLine(1, "No compiled resources. Skipping writing assembly."); return(success); } Log(1, "Writing the assembly... "); try { assemblyDefinition.Write(Assembly, new WriterParameters { WriteSymbols = DebugSymbols }); LogLine(1, "done."); } catch (Exception e) { LogLine(1, "failed."); LogError(null, null, null, null, 0, 0, 0, 0, e.Message, e.HelpLink, e.Source); LogLine(4, e.StackTrace); success = false; } return(success); }