Beispiel #1
0
        private static SyntaxTree Decompile(Type type)
        {
            var decompiler = new CSharpDecompiler(type.Assembly.Location, new DecompilerSettings());
            var typeInfo   = decompiler.TypeSystem.MainModule.Compilation.FindType(type).GetDefinition();

            return(Parse(decompiler.DecompileTypeAsString(typeInfo.FullTypeName)));
        }
Beispiel #2
0
        private async Task <Document> DecompileSymbolAsync(Document temporaryDocument, ISymbol symbol, CancellationToken cancellationToken)
        {
            // Get the name of the type the symbol is in
            var containingOrThis = symbol.GetContainingTypeOrThis();
            var fullName         = GetFullReflectionName(containingOrThis);

            var compilation = await temporaryDocument.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            // TODO: retrieve path to actual assembly instead of reference assembly
            var reference = compilation.GetMetadataReference(symbol.ContainingAssembly);
            // Load the assembly.
            var ad = AssemblyDefinition.ReadAssembly(reference.Display, new ReaderParameters()
            {
                AssemblyResolver = new RoslynAssemblyResolver(compilation)
            });

            // Initialize a decompiler with default settings.
            var decompiler   = new CSharpDecompiler(ad.MainModule, new DecompilerSettings());
            var fullTypeName = new FullTypeName(fullName);

            // Try to decompile; if an exception is thrown the caller will handle it
            var text = decompiler.DecompileTypeAsString(fullTypeName);

            return(temporaryDocument.WithText(SourceText.From(text)));
        }
Beispiel #3
0
        private Document PerformDecompilation(Document document, string fullName, Compilation compilation, string assemblyLocation)
        {
            // Load the assembly.
            var file = new PEFile(assemblyLocation, PEStreamOptions.PrefetchEntireImage);

            var logger = new StringBuilder();

            // Initialize a decompiler with default settings.
            var decompiler = new CSharpDecompiler(file, new AssemblyResolver(compilation, logger), new DecompilerSettings());

            // Escape invalid identifiers to prevent Roslyn from failing to parse the generated code.
            // (This happens for example, when there is compiler-generated code that is not yet recognized/transformed by the decompiler.)
            decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());

            var fullTypeName = new FullTypeName(fullName);

            // Try to decompile; if an exception is thrown the caller will handle it
            var text = decompiler.DecompileTypeAsString(fullTypeName);

            text += "#if false // " + CSharpEditorResources.Decompilation_log + Environment.NewLine;
            text += logger.ToString();
            text += "#endif" + Environment.NewLine;

            return(document.WithText(SourceText.From(text)));
        }
Beispiel #4
0
        public void DecompileType(ITypeDefinition type)
        {
            var path = ToFileName(type);

            FileUtil.EnsureDirectory($"{projectDir}/{Path.GetDirectoryName(path)}");
            var text = decompiler.DecompileTypeAsString(type.FullTypeName);

            File.WriteAllText($"{projectDir}/{path}", text);
        }
Beispiel #5
0
        public static string Decompile(Type type)
        {
            var fileName   = type.Assembly.Location;
            var decompiler = new CSharpDecompiler(fileName, new DecompilerSettings()
            {
                ThrowOnAssemblyResolveErrors = false
            });
            var name = new FullTypeName(type.FullName);

            return(decompiler.DecompileTypeAsString(name));
        }
Beispiel #6
0
        static void Decompile(string assemblyFileName, TextWriter output, string typeName = null)
        {
            CSharpDecompiler decompiler = GetDecompiler(assemblyFileName);

            if (typeName == null)
            {
                output.Write(decompiler.DecompileWholeModuleAsString());
            }
            else
            {
                var name = new FullTypeName(typeName);
                output.Write(decompiler.DecompileTypeAsString(name));
            }
        }
Beispiel #7
0
        private async Task <Document> DecompileSymbolAsync(Document temporaryDocument, ISymbol symbol, CancellationToken cancellationToken)
        {
            // Get the name of the type the symbol is in
            var containingOrThis = symbol.GetContainingTypeOrThis();
            var fullName         = GetFullReflectionName(containingOrThis);

            var compilation = await temporaryDocument.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            string assemblyLocation    = null;
            var    isReferenceAssembly = symbol.ContainingAssembly.GetAttributes().Any(attribute => attribute.AttributeClass.Name == nameof(ReferenceAssemblyAttribute) &&
                                                                                       attribute.AttributeClass.ToNameDisplayString() == typeof(ReferenceAssemblyAttribute).FullName);

            if (isReferenceAssembly)
            {
                try
                {
                    var fullAssemblyName = symbol.ContainingAssembly.Identity.GetDisplayName();
                    GlobalAssemblyCache.Instance.ResolvePartialName(fullAssemblyName, out assemblyLocation, preferredCulture: CultureInfo.CurrentCulture);
                }
                catch (Exception e) when(FatalError.ReportWithoutCrash(e))
                {
                }
            }

            if (assemblyLocation == null)
            {
                var reference = compilation.GetMetadataReference(symbol.ContainingAssembly);
                assemblyLocation = (reference as PortableExecutableReference)?.FilePath;
                if (assemblyLocation == null)
                {
                    throw new NotSupportedException(EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret);
                }
            }

            // Load the assembly.
            var ad = AssemblyDefinition.ReadAssembly(assemblyLocation, new ReaderParameters()
            {
                AssemblyResolver = new RoslynAssemblyResolver(compilation)
            });

            // Initialize a decompiler with default settings.
            var decompiler   = new CSharpDecompiler(ad.MainModule, new DecompilerSettings());
            var fullTypeName = new FullTypeName(fullName);

            // Try to decompile; if an exception is thrown the caller will handle it
            var text = decompiler.DecompileTypeAsString(fullTypeName);

            return(temporaryDocument.WithText(SourceText.From(text)));
        }
Beispiel #8
0
        private string GetStructCode(Type structInstance)
        {
            string           assemblyPath = structInstance.Assembly.Location;
            CSharpDecompiler cSharpDecompiler
                = new CSharpDecompiler(assemblyPath, new Amplifier.Decompiler.DecompilerSettings()
            {
                ThrowOnAssemblyResolveErrors = false, ForEachStatement = false
            });

            var tree = cSharpDecompiler.DecompileType(new FullTypeName(structInstance.FullName));

            string code = cSharpDecompiler.DecompileTypeAsString(new FullTypeName(structInstance.FullName));

            return(CodeTranslator.Translate(code).Trim() + ";");
        }
        public static string ToSourceCode(this Type source)
        {
            if (source.IsNested)
            {
                throw new NotSupportedException("Decompilation of nested types is not supported");
            }

            if (!source.IsClass)
            {
                throw new NotSupportedException("Decompilation of non-reference types is not supported");
            }

            var decompiler = new CSharpDecompiler(source.Assembly.Location, new DecompilerSettings());

            return(decompiler.DecompileTypeAsString(new FullTypeName(source.FullName)));
        }
Beispiel #10
0
        public bool DllCompare(string srcPath, string dstPath, out List <string> errorList)
        {
            errorList = new List <string>();
            string[] separators = { "\r\n" };

            var module           = ModuleDefinition.ReadModule(srcPath);
            var typeFullNameList = (from type in module.Types where type.IsPublic select type.FullName).ToList();

            var dllequal = true;

            foreach (var typeFullName in typeFullNameList)
            {
                try
                {
                    var name        = new FullTypeName(typeFullName);
                    var decompiler1 = new CSharpDecompiler(srcPath, new ICSharpCode.Decompiler.DecompilerSettings());
                    var x1          = decompiler1.DecompileTypeAsString(name);
                    var lines1      = x1.Split(separators, StringSplitOptions.None);

                    var decompiler2 = new CSharpDecompiler(dstPath, new ICSharpCode.Decompiler.DecompilerSettings());
                    var x2          = decompiler2.DecompileTypeAsString(name);
                    var lines2      = x2.Split(separators, StringSplitOptions.None);

                    if (lines1.Length != lines2.Length)
                    {
                        dllequal = false;
                        errorList.Add("\t" + srcPath + "\t" + typeFullName + "\t" + "(decompilable)");
                        continue;
                    }

                    if (!lines1.Where((t, i) => t != lines2[i]).Any())
                    {
                        continue;
                    }

                    dllequal = false;
                    errorList.Add("\t" + srcPath + "\t" + typeFullName + "\t" + "(decompilable)");
                }
                catch (Exception ex)
                {
                    errorList.Add("\t\t" + ex.Message);
                    return(false);
                }
            }

            return(dllequal);
        }
        private static Document PerformDecompilation(Document document, string fullName, Compilation compilation, MetadataReference?metadataReference, string assemblyLocation)
        {
            var logger   = new StringBuilder();
            var resolver = new AssemblyResolver(compilation, logger);

            // Load the assembly.
            PEFile?file = null;

            if (metadataReference is not null)
            {
                file = resolver.TryResolve(metadataReference, PEStreamOptions.PrefetchEntireImage);
            }

            if (file is null && assemblyLocation is null)
            {
                throw new NotSupportedException(FeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret);
            }

            file ??= new PEFile(assemblyLocation, PEStreamOptions.PrefetchEntireImage);

            // Initialize a decompiler with default settings.
            var decompiler = new CSharpDecompiler(file, resolver, new DecompilerSettings());

            // Escape invalid identifiers to prevent Roslyn from failing to parse the generated code.
            // (This happens for example, when there is compiler-generated code that is not yet recognized/transformed by the decompiler.)
            decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());

            var fullTypeName = new FullTypeName(fullName);

            // Try to decompile; if an exception is thrown the caller will handle it
            var text = decompiler.DecompileTypeAsString(fullTypeName);

            text += "#if false // " + CSharpEditorResources.Decompilation_log + Environment.NewLine;
            text += logger.ToString();
            text += "#endif" + Environment.NewLine;

            return(document.WithText(SourceText.From(text)));
        }
Beispiel #12
0
        /// <summary>
        /// Compile this shader from the C# code.
        /// </summary>
        public string GetCSCode()
        {
            // - Prepare the decompiler by passing the target assembly
            CSharpDecompiler d = new CSharpDecompiler(GetType().Assembly.Location, new DecompilerSettings
            {
                MakeAssignmentExpressions = false
            });

            var tree = d.DecompileModuleAndAssemblyAttributes();


            // - We want to get only the shader's code
            var name = new FullTypeName(this.GetType().FullName);

            // - Decompile shader's binary in order to get the source code
            var shaderCs = d.DecompileTypeAsString(name);

            Regex defaultRe = new Regex(@"=.+default\(.+\)");
            Regex computeRe = new Regex(@"(?<=\[ComputeShader\().+(?=\)\])");
            Regex uintRe    = new Regex(@"[Uu]");

            shaderCs = defaultRe.Replace(shaderCs, "");

            var match = computeRe.Match(shaderCs);

            if (match.Success)
            {
                do
                {
                    shaderCs = shaderCs.Replace(match.Value, uintRe.Replace(match.Value, ""));

                    match = match.NextMatch();
                } while (match.Success);
            }

            return(shaderCs);
        }
Beispiel #13
0
        private void DecompileButtonClick1(object sender, EventArgs e)
        {
            string[] separators     = { "\t" };
            var      selecterString = this.InfoListBox.SelectedItem.ToString();
            var      part           = selecterString.Split(separators, StringSplitOptions.None);

            if ((part.Length == 6) && (part[5] == "(decompilable)"))
            {
                this.CheckButton.Enabled = false;
                var probePath = part[3];
                var fileName  = Path.GetFileName(probePath);
                if (fileName != null)
                {
                    var snapshotPath = Path.Combine(this.SnapshotDirectory, fileName);
                    var typeFullName = part[4];
                    this.SrcDirLabel.Text   = snapshotPath;
                    this.ProbeDirLabel.Text = probePath;

                    var name = new FullTypeName(typeFullName);

                    var snapshotDecompiler = new CSharpDecompiler(snapshotPath, new ICSharpCode.Decompiler.DecompilerSettings());
                    var probeDecompiler    = new CSharpDecompiler(probePath, new ICSharpCode.Decompiler.DecompilerSettings());

                    var snapshotText = snapshotDecompiler.DecompileTypeAsString(name);
                    var probeText    = probeDecompiler.DecompileTypeAsString(name);

                    this.ViewDiff(probeText, snapshotText);

                    this.tabControl1.SelectedIndex = 1;
                }
            }
            else
            {
                MessageBox.Show(@"Поставьте курсор на строку, помеченную (decompilable) и нажмите Decompile", @"Внимание!", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
        }
        private async Task <Document> DecompileSymbolAsync(Document temporaryDocument, ISymbol symbol, CancellationToken cancellationToken)
        {
            // Get the name of the type the symbol is in
            var containingOrThis = symbol.GetContainingTypeOrThis();
            var fullName         = GetFullReflectionName(containingOrThis);

            var compilation = await temporaryDocument.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            string assemblyLocation    = null;
            var    isReferenceAssembly = symbol.ContainingAssembly.GetAttributes().Any(attribute => attribute.AttributeClass.Name == nameof(ReferenceAssemblyAttribute) &&
                                                                                       attribute.AttributeClass.ToNameDisplayString() == typeof(ReferenceAssemblyAttribute).FullName);

            if (isReferenceAssembly)
            {
                try
                {
                    var fullAssemblyName = symbol.ContainingAssembly.Identity.GetDisplayName();
                    GlobalAssemblyCache.Instance.ResolvePartialName(fullAssemblyName, out assemblyLocation, preferredCulture: CultureInfo.CurrentCulture);
                }
                catch (Exception e) when(FatalError.ReportWithoutCrash(e))
                {
                }
            }

            if (assemblyLocation == null)
            {
                var reference = compilation.GetMetadataReference(symbol.ContainingAssembly);
                assemblyLocation = (reference as PortableExecutableReference)?.FilePath;
                if (assemblyLocation == null)
                {
                    throw new NotSupportedException(EditorFeaturesResources.Cannot_navigate_to_the_symbol_under_the_caret);
                }
            }

            // Load the assembly.
            var pefile = new PEFile(assemblyLocation, PEStreamOptions.PrefetchEntireImage);

            // Initialize a decompiler with default settings.
            var settings   = new DecompilerSettings(LanguageVersion.Latest);
            var decompiler = new CSharpDecompiler(pefile, new RoslynAssemblyResolver(compilation), settings);

            // Escape invalid identifiers to prevent Roslyn from failing to parse the generated code.
            // (This happens for example, when there is compiler-generated code that is not yet recognized/transformed by the decompiler.)
            decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());

            var fullTypeName = new FullTypeName(fullName);

            var decompilerVersion = FileVersionInfo.GetVersionInfo(typeof(CSharpDecompiler).Assembly.Location);

            // Add header to match output of metadata-only view.
            // (This also makes debugging easier, because you can see which assembly was decompiled inside VS.)
            var header = $"#region {FeaturesResources.Assembly} {pefile.FullName}" + Environment.NewLine
                         + $"// {assemblyLocation}" + Environment.NewLine
                         + $"// Decompiled with ICSharpCode.Decompiler {decompilerVersion.FileVersion}" + Environment.NewLine
                         + "#endregion" + Environment.NewLine;

            // Try to decompile; if an exception is thrown the caller will handle it
            var text = decompiler.DecompileTypeAsString(fullTypeName);

            return(temporaryDocument.WithText(SourceText.From(header + text)));
        }
        /// <summary>
        /// Disassembles.
        /// </summary>
        ///
        /// <param name="parm"> The parameter. </param>
        private void Disassemble(string parm)
        {
            CSharpDecompiler decompiler = new CSharpDecompiler(parm, new DecompilerSettings()
            {
                AlwaysUseBraces = true,
                LoadInMemory    = true,

                //RemoveDeadCode = true,
            });

            foreach (ITypeDefinition typeInAssembly in decompiler.TypeSystem.GetAllTypeDefinitions())
            {
                // Look at plublic classes in the MainAssembly only.
                //
                if (typeInAssembly.Accessibility == Accessibility.Public && typeInAssembly.ParentModule == decompiler.TypeSystem.MainModule)
                {
                    if (typeInAssembly.Kind != TypeKind.Interface)
                    {
                        host.AddResult(Severity.Info, true, $"T:{typeInAssembly.Namespace}.{typeInAssembly.Name}");

#warning Properties?
#warning Indexers show up in props (use .Select) with duplicate keys?

                        //Dictionary<String, String> props = typeInAssembly.Properties
                        //    .Where(p => !p.IsIndexer)
                        //    .ToDictionary(p => p.Name, p => p.ReturnType.Name);
                        //
                        //foreach (IMethod method in typeInAssembly.Methods)
                        //{

                        //}
                        foreach (IProperty prop in typeInAssembly.Properties)
                        {
                            if (prop.Accessibility == Accessibility.Public)
                            {
                                String sig = $"{prop.Accessibility} {prop.Name}";

                                if (prop.IsIndexer)
                                {
                                    sig += " []";
                                }
                                if (prop.CanGet)
                                {
                                    sig += " get;";
                                }
                                if (prop.CanSet)
                                {
                                    sig += " set;";
                                }

                                host.AddResult(Severity.Info, true, $"{sig}", 1);
                            }
                        }

                        foreach (IMethod method in typeInAssembly.Methods)
                        {
                            //Console.Write(method.FullName);
                            // https://stackoverflow.com/questions/1312166/print-full-signature-of-a-method-from-a-methodinfo
                            //
                            //if (props.ContainsKey($"Get{method.Name}") && props[method.Name] == method.ReturnType.Name)
                            //{
                            //    continue;
                            //}

                            //! See https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/accessibility-levels
                            //
                            if (method.Accessibility == Accessibility.Public)
                            {
                                String sig = Utils.MethodSignature(typeInAssembly, method);

                                host.AddResult(Severity.Info, true, $"{sig}", 1);
                            }
                        }

                        // Skip a lot of generated code for now.
                        //
                        if (typeInAssembly.Name.Equals("BaseSettings"))
                        {
                            FullTypeName name = new FullTypeName(typeInAssembly.FullName);

                            Console.WriteLine(decompiler.DecompileTypeAsString(name));
                        }
                    }
                }
            }
        }