Пример #1
0
        CSharpDecompiler GetDecompiler(string assemblyFileName)
        {
            var module   = new PEFile(assemblyFileName);
            var resolver = new UniversalAssemblyResolver(assemblyFileName, false, module.Reader.DetectTargetFrameworkId());

            foreach (var path in ReferencePaths)
            {
                resolver.AddSearchDirectory(path);
            }
            return(new CSharpDecompiler(assemblyFileName, resolver, GetSettings()));
        }
Пример #2
0
        private void DoDecompile(string path)
        {
            PEFile module                     = Decompiler.TypeSystem.MainModule.PEFile;
            var    assemblyResolver           = new UniversalAssemblyResolver(module.FileName, false, module.Reader.DetectTargetFrameworkId());
            WholeProjectDecompiler decompiler = new WholeProjectDecompiler(assemblyResolver);

            decompiler.ProgressIndicator = this;
            fileName  = module.FileName;
            completed = 0;
            decompiler.DecompileProject(module, path);
        }
Пример #3
0
        public static string FindAssemblyFile(AssemblyDefinition assemblyDefinition, string assemblyFile)
        {
            var assemblyResolver = new UniversalAssemblyResolver(assemblyFile, false,
                                                                 DetectTargetFrameworkId(assemblyDefinition, assemblyFile));

            if (IsReferenceAssembly(assemblyDefinition, assemblyFile))
            {
                assemblyResolver.RemoveSearchDirectory(Path.GetDirectoryName(assemblyFile));
            }
            return(assemblyResolver.FindAssemblyFile(
                       ICSharpCode.Decompiler.Metadata.AssemblyNameReference.Parse(assemblyDefinition.Name.FullName)));
        }
Пример #4
0
        /// <summary>
        /// If possible retrieves parameters to use for launching ILSpy instance.
        /// </summary>
        /// <returns>Parameters object or <c>null, if not applicable.</c></returns>
        public ILSpyParameters GetILSpyParameters()
        {
            if (resolvedPath != null)
            {
                return(new ILSpyParameters(new[] { $"{resolvedPath}" }));
            }
            else if (!string.IsNullOrWhiteSpace(fusionName))
            {
                return(new ILSpyParameters(new string[] { UniversalAssemblyResolver.GetAssemblyInGac(Decompiler.Metadata.AssemblyNameReference.Parse(fusionName)) }));
            }

            return(null);
        }
Пример #5
0
        static void DecompileAsProject(string assemblyFileName, string outputDirectory, string[] referencePaths)
        {
            var decompiler = new WholeProjectDecompiler();
            var module     = new PEFile(assemblyFileName);
            var resolver   = new UniversalAssemblyResolver(assemblyFileName, false, module.Reader.DetectTargetFrameworkId());

            foreach (var path in referencePaths)
            {
                resolver.AddSearchDirectory(path);
            }
            decompiler.AssemblyResolver = resolver;
            decompiler.DecompileProject(module, outputDirectory);
        }
        private static CSharpDecompiler CreateDecompiler(string assemblyPath)
        {
            UniversalAssemblyResolver resolver = new UniversalAssemblyResolver(assemblyPath, false, "netstandard");

            DecompilerSettings decompilerSettings = new DecompilerSettings()
            {
                ObjectOrCollectionInitializers = false
            };

            decompilerSettings.CSharpFormattingOptions.IndentationString = "    ";

            return(new CSharpDecompiler(assemblyPath, resolver, decompilerSettings));
        }
        private static CSharpDecompiler CreateDecompiler(string assemblyPath)
        {
            DecompilerSettings decompilerSettings = new DecompilerSettings(ICSharpCode.Decompiler.CSharp.LanguageVersion.Latest)
            {
                ObjectOrCollectionInitializers = false,
                UsingDeclarations       = false,
                CSharpFormattingOptions = { IndentationString = IndentedTextWriter.DefaultTabString }
            };

            UniversalAssemblyResolver resolver = new UniversalAssemblyResolver(assemblyPath, false, "netstandard");

            return(new CSharpDecompiler(assemblyPath, resolver, decompilerSettings));
        }
Пример #8
0
        void RunTest(string name, string asmPath, string sourcePath)
        {
            using (var fileStream = new FileStream(asmPath, FileMode.Open, FileAccess.Read)) {
                var module   = new PEFile(asmPath, fileStream);
                var resolver = new UniversalAssemblyResolver(asmPath, false, module.Reader.DetectTargetFrameworkId());
                resolver.RemoveSearchDirectory(".");
                resolver.AddSearchDirectory(Path.GetDirectoryName(asmPath));
                var    res        = module.Resources.First();
                Stream bamlStream = LoadBaml(res, name + ".baml");
                Assert.IsNotNull(bamlStream);
                XDocument document = BamlResourceEntryNode.LoadIntoDocument(module, resolver, bamlStream, CancellationToken.None);

                XamlIsEqual(File.ReadAllText(sourcePath), document.ToString());
            }
        }
Пример #9
0
        public static string FindAssemblyFile(Mono.Cecil.AssemblyDefinition assemblyDefinition, string assemblyFile)
        {
            string tfi = DetectTargetFrameworkId(assemblyDefinition, assemblyFile);
            UniversalAssemblyResolver assemblyResolver;

            if (IsReferenceAssembly(assemblyDefinition, assemblyFile))
            {
                assemblyResolver = new UniversalAssemblyResolver(null, throwOnError: false, tfi);
            }
            else
            {
                assemblyResolver = new UniversalAssemblyResolver(assemblyFile, throwOnError: false, tfi);
            }

            return(assemblyResolver.FindAssemblyFile(AssemblyNameReference.Parse(assemblyDefinition.Name.FullName)));
        }
Пример #10
0
        private static string DecompileTarget(string assemblyFileName)
        {
            string decompileDirectory = string.Empty;

            if (File.Exists(assemblyFileName))
            {
                decompileDirectory = FileUtilities.GetDecompileDirectory(assemblyFileName, false);
                ModuleDefinition       module     = null;
                WholeProjectDecompiler decompiler = null;

                if (Directory.Exists(decompileDirectory) && Directory.GetFiles(decompileDirectory).Count() > 0)
                {
                    module     = UniversalAssemblyResolver.LoadMainModule(assemblyFileName, false);
                    decompiler = new WholeProjectDecompiler();
                    decompiler.Settings.ThrowOnAssemblyResolveErrors = false;
                    decompileDirectory = FileUtilities.GetDecompileDirectory(assemblyFileName, false);

                    if (Directory.Exists(decompileDirectory) && Directory.GetFiles(decompileDirectory).Count() > 0)
                    {
                        ConsoleOutput.SystemMessage($"Already decompiled located here {decompileDirectory}");
                        return(decompileDirectory);
                    }
                    else
                    {
                        Directory.CreateDirectory(decompileDirectory);
                    }

                    try
                    {
                        ConsoleOutput.SystemMessage($"Decompiling {assemblyFileName} to {decompileDirectory}");
                        decompiler.DecompileProject(module, decompileDirectory);
                    }
                    catch (Exception ex)
                    {
                        var message = ex.InnerException != null ? ex.InnerException.Message : ex.Message;
                        ConsoleOutput.ErrorMessage($"Decompiling {assemblyFileName} threw an exception with the message {message}");
                    }
                }
                else
                {
                    ConsoleOutput.ErrorMessage($"The assembly '{assemblyFileName}' does not exist");
                }
            }

            return(decompileDirectory);
        }
Пример #11
0
 /// <summary>
 /// Instianciates a CSharpDecompiler from a given assemblyfilename and applies decompilersettings
 /// </summary>
 /// <param name="assemblyFileName">path for assemblyfile to decompile</param>
 /// <param name="settings">optional decompiler settings</param>
 /// <returns>Instance of CSharpDecompiler</returns>
 public CSharpDecompiler GetCSharpDecompiler(string assemblyFileName, DecompilerSettings settings = null)
 {
     if (settings == null)
     {
         settings = new DecompilerSettings();
     }
     using (var file = new FileStream(assemblyFileName, FileMode.Open, FileAccess.Read))
     {
         var module   = new PEFile(assemblyFileName, file, PEStreamOptions.PrefetchEntireImage);
         var resolver = new UniversalAssemblyResolver(assemblyFileName, false,
                                                      module.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchMetadata);
         resolver.AddSearchDirectory(Path.GetDirectoryName(module.FullName));
         var typeSystem = new DecompilerTypeSystem(module, resolver, settings);
         var decompiler = new CSharpDecompiler(typeSystem, settings);
         decompiler.DebugInfoProvider = DebugInfoLoader.LoadSymbols(module);
         return(decompiler);
     }
 }
Пример #12
0
        private static ReflectionDisassembler CreateDisassembler(string assemblyPath, MetadataModule module, ITextOutput textOutput)
        {
            var dis = new ReflectionDisassembler(textOutput, CancellationToken.None)
            {
                DetectControlStructure  = true,
                ShowSequencePoints      = false,
                ShowMetadataTokens      = true,
                ExpandMemberDefinitions = true,
            };
            var resolver = new UniversalAssemblyResolver(assemblyPath,
                                                         throwOnError: true,
                                                         targetFramework: module.PEFile.Reader.DetectTargetFrameworkId());

            dis.AssemblyResolver = resolver;
            dis.DebugInfo        = null;

            return(dis);
        }
        private void TestGeneratePdb([CallerMemberName] string testName = null)
        {
            const PdbToXmlOptions options = PdbToXmlOptions.IncludeEmbeddedSources | PdbToXmlOptions.ThrowOnError | PdbToXmlOptions.IncludeTokens | PdbToXmlOptions.ResolveTokens | PdbToXmlOptions.IncludeMethodSpans;

            string    xmlFile    = Path.Combine(TestCasePath, testName + ".xml");
            string    xmlContent = File.ReadAllText(xmlFile);
            XDocument document   = XDocument.Parse(xmlContent);
            var       files      = document.Descendants("file").ToDictionary(f => f.Attribute("name").Value, f => f.Value);

            Tester.CompileCSharpWithPdb(Path.Combine(TestCasePath, testName + ".expected"), files);

            string peFileName       = Path.Combine(TestCasePath, testName + ".expected.dll");
            string pdbFileName      = Path.Combine(TestCasePath, testName + ".expected.pdb");
            var    moduleDefinition = new PEFile(peFileName);
            var    resolver         = new UniversalAssemblyResolver(peFileName, false, moduleDefinition.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchEntireImage);
            var    decompiler       = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings());

            using (FileStream pdbStream = File.Open(Path.Combine(TestCasePath, testName + ".pdb"), FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                pdbStream.SetLength(0);
                PortablePdbWriter.WritePdb(moduleDefinition, decompiler, new DecompilerSettings(), pdbStream, noLogo: true);
                pdbStream.Position = 0;
                using (Stream peStream = File.OpenRead(peFileName))
                    using (Stream expectedPdbStream = File.OpenRead(pdbFileName))
                    {
                        using (StreamWriter writer = new StreamWriter(Path.ChangeExtension(pdbFileName, ".xml"), false, Encoding.UTF8))
                        {
                            PdbToXmlConverter.ToXml(writer, expectedPdbStream, peStream, options);
                        }
                        peStream.Position = 0;
                        using (StreamWriter writer = new StreamWriter(Path.ChangeExtension(xmlFile, ".generated.xml"), false, Encoding.UTF8))
                        {
                            PdbToXmlConverter.ToXml(writer, pdbStream, peStream, options);
                        }
                    }
            }
            string expectedFileName = Path.ChangeExtension(xmlFile, ".expected.xml");

            ProcessXmlFile(expectedFileName);
            string generatedFileName = Path.ChangeExtension(xmlFile, ".generated.xml");

            ProcessXmlFile(generatedFileName);
            Assert.AreEqual(Normalize(expectedFileName), Normalize(generatedFileName));
        }
        int DecompileAsProject(string assemblyFileName, string outputDirectory)
        {
            var decompiler = new WholeProjectDecompiler()
            {
                Settings = GetSettings()
            };
            var module   = new PEFile(assemblyFileName);
            var resolver = new UniversalAssemblyResolver(assemblyFileName, false, module.Reader.DetectTargetFrameworkId());

            foreach (var path in ReferencePaths)
            {
                resolver.AddSearchDirectory(path);
            }
            decompiler.AssemblyResolver = resolver;
            decompiler.DecompileProject(module, outputDirectory);
            module.Reader.Dispose();

            return(0);
        }
Пример #15
0
        public static CSharpDecompiler GetDecompilerForSnippet(string csharpText)
        {
            var syntaxTree  = SyntaxFactory.ParseSyntaxTree(csharpText);
            var compilation = CSharpCompilation.Create(
                "TestAssembly",
                new[] { syntaxTree },
                defaultReferences.Value,
                new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
            var peStream   = new MemoryStream();
            var emitResult = compilation.Emit(peStream);

            peStream.Position = 0;

            var moduleDefinition = new PEFile("TestAssembly.dll", peStream, PEStreamOptions.PrefetchEntireImage);
            var resolver         = new UniversalAssemblyResolver("TestAssembly.dll", false, moduleDefinition.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchEntireImage);
            var decompiler       = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings());

            return(decompiler);
        }
Пример #16
0
        public bool AddAssembly(string path)
        {
            try
            {
                var mainModule = UniversalAssemblyResolver.LoadMainModule(path);
                if (mainModule != null)
                {
                    _mainModules.Add(path, mainModule);
                    PopulateTokenToProviderMap(path);
                    return(true);
                }
            }
            catch (Exception ex)
            {
                _logger?.LogError("An exception occurred when reading assembly {assembly}: {exception}", path, ex);
            }

            return(false);
        }
Пример #17
0
        void RunTest(string name, string asmPath, string sourcePath)
        {
            using (var fileStream = new FileStream(asmPath, FileMode.Open, FileAccess.Read))
            {
                var module   = new PEFile(asmPath, fileStream);
                var resolver = new UniversalAssemblyResolver(asmPath, false, module.Reader.DetectTargetFrameworkId());
                resolver.RemoveSearchDirectory(".");
                resolver.AddSearchDirectory(Path.GetDirectoryName(asmPath));
                var    res        = module.Resources.First();
                Stream bamlStream = LoadBaml(res, name + ".baml");
                Assert.IsNotNull(bamlStream);

                BamlDecompilerTypeSystem typeSystem = new BamlDecompilerTypeSystem(module, resolver);
                var decompiler = new XamlDecompiler(typeSystem, new BamlDecompilerSettings());

                XDocument document = decompiler.Decompile(bamlStream).Xaml;

                XamlIsEqual(File.ReadAllText(sourcePath), document.ToString());
            }
        }
Пример #18
0
        public ReWriter(string filePath, bool useDepsJson = true)
        {
            References = new List <string>();
            _typeCache = new ConcurrentDictionary <string, Type>();
            _cache     = new ConcurrentDictionary <string, string>();
            var domain = DomainManagment.Random;

            OldPath = filePath;

            _complier = new AssemblyComplier
            {
                Domain       = domain,
                EnumCRTarget = ComplierResultTarget.File,
                AssemblyName = Path.GetFileNameWithoutExtension(filePath)
            };


            _pluginDomain = DomainManagment.Random;
            _assembly     = _pluginDomain.LoadStream(filePath);
            CSharpDecompiler _decomplier;

            if (useDepsJson)
            {
                var module   = new PEFile(filePath);
                var resolver = new UniversalAssemblyResolver(filePath, false, module.Reader.DetectTargetFrameworkId());
                _decomplier = new CSharpDecompiler(filePath, resolver, _setting);
            }
            else
            {
                _decomplier = new CSharpDecompiler(filePath, _setting);
            }


            foreach (var item in _assembly.ExportedTypes)
            {
                var temp = item.GetDevelopName();
                _typeCache[temp] = item;
                _cache[temp]     = _decomplier.DecompileTypeAsString(new FullTypeName(item.FullName));
            }
        }
        protected override void ProcessRecord()
        {
            string path = GetUnresolvedProviderPathFromPSPath(LiteralPath);

            if (!Directory.Exists(path))
            {
                WriteObject("Destination directory must exist prior to decompilation");
                return;
            }

            try
            {
                string                 assemblyFileName = Decompiler.TypeSystem.Compilation.MainAssembly.UnresolvedAssembly.Location; // just to keep the API "the same" across all cmdlets
                ModuleDefinition       module           = UniversalAssemblyResolver.LoadMainModule(assemblyFileName);
                WholeProjectDecompiler decompiler       = new WholeProjectDecompiler();
                decompiler.DecompileProject(module, path);

                WriteObject("Decompilation finished");
            } catch (Exception e) {
                WriteVerbose(e.ToString());
                WriteError(new ErrorRecord(e, ErrorIds.DecompilationFailed, ErrorCategory.OperationStopped, null));
            }
        }
Пример #20
0
        public void CustomPdbId()
        {
            // Generate a PDB for an assembly using a randomly-generated ID, then validate that the PDB uses the specified ID
            (string peFileName, string pdbFileName) = CompileTestCase(nameof(CustomPdbId));

            var moduleDefinition = new PEFile(peFileName);
            var resolver         = new UniversalAssemblyResolver(peFileName, false, moduleDefinition.Metadata.DetectTargetFrameworkId(), null, PEStreamOptions.PrefetchEntireImage);
            var decompiler       = new CSharpDecompiler(moduleDefinition, resolver, new DecompilerSettings());
            var expectedPdbId    = new BlobContentId(Guid.NewGuid(), (uint)Random.Shared.Next());

            using (FileStream pdbStream = File.Open(Path.Combine(TestCasePath, nameof(CustomPdbId) + ".pdb"), FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                pdbStream.SetLength(0);
                PortablePdbWriter.WritePdb(moduleDefinition, decompiler, new DecompilerSettings(), pdbStream, noLogo: true, pdbId: expectedPdbId);

                pdbStream.Position = 0;
                var metadataReader = MetadataReaderProvider.FromPortablePdbStream(pdbStream).GetMetadataReader();
                var generatedPdbId = new BlobContentId(metadataReader.DebugMetadataHeader.Id);

                Assert.AreEqual(expectedPdbId.Guid, generatedPdbId.Guid);
                Assert.AreEqual(expectedPdbId.Stamp, generatedPdbId.Stamp);
            }
        }
Пример #21
0
        public static Task <string> DecompileCSharp(string assemblyFileName, DecompilerSettings settings = null)
        {
            if (settings == null)
            {
                settings = new DecompilerSettings();
            }
            using (var file = new FileStream(assemblyFileName, FileMode.Open, FileAccess.Read))
            {
                var    module          = new PEFile(assemblyFileName, file, PEStreamOptions.PrefetchEntireImage);
                string targetFramework = module.Metadata.DetectTargetFrameworkId();
                var    resolver        = new UniversalAssemblyResolver(assemblyFileName, false,
                                                                       targetFramework, null, PEStreamOptions.PrefetchMetadata);
                resolver.AddSearchDirectory(targetFramework.Contains(".NETFramework") ? RefAsmPath : coreRefAsmPath);
                var typeSystem = new DecompilerTypeSystem(module, resolver, settings);
                CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, settings);
                decompiler.AstTransforms.Insert(0, new RemoveEmbeddedAttributes());
                decompiler.AstTransforms.Insert(0, new RemoveCompilerAttribute());
                decompiler.AstTransforms.Insert(0, new RemoveNamespaceMy());
                decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());
                var pdbFileName = Path.ChangeExtension(assemblyFileName, ".pdb");
                if (File.Exists(pdbFileName))
                {
                    decompiler.DebugInfoProvider = DebugInfoUtils.FromFile(module, pdbFileName);
                }
                var syntaxTree = decompiler.DecompileWholeModuleAsSingleFile(sortTypes: true);

                StringWriter            output           = new StringWriter();
                CSharpFormattingOptions formattingPolicy = CreateFormattingPolicyForTests();
                var visitor = new CSharpOutputVisitor(output, formattingPolicy);
                syntaxTree.AcceptVisitor(visitor);

                string fileName = Path.GetTempFileName();
                File.WriteAllText(fileName, output.ToString());

                return(Task.FromResult(fileName));
            }
        }
Пример #22
0
        void RunInternal(string dir, string fileToRoundtrip, Action <string> testAction, string snkFilePath = null)
        {
            if (!Directory.Exists(TestDir))
            {
                Assert.Ignore($"Assembly-roundtrip test ignored: test directory '{TestDir}' needs to be checked out separately." + Environment.NewLine +
                              $"git clone https://github.com/icsharpcode/ILSpy-tests \"{TestDir}\"");
            }
            string inputDir      = Path.Combine(TestDir, dir);
            string decompiledDir = inputDir + "-decompiled";
            string outputDir     = inputDir + "-output";

            if (inputDir.EndsWith("TestCases"))
            {
                // make sure output dir names are unique so that we don't get trouble due to parallel test execution
                decompiledDir += Path.GetFileNameWithoutExtension(fileToRoundtrip);
                outputDir     += Path.GetFileNameWithoutExtension(fileToRoundtrip);
            }
            ClearDirectory(decompiledDir);
            ClearDirectory(outputDir);
            string projectFile = null;

            foreach (string file in Directory.EnumerateFiles(inputDir, "*", SearchOption.AllDirectories))
            {
                if (!file.StartsWith(inputDir + Path.DirectorySeparatorChar, StringComparison.OrdinalIgnoreCase))
                {
                    Assert.Fail($"Unexpected file name: {file}");
                }
                string relFile = file.Substring(inputDir.Length + 1);
                Directory.CreateDirectory(Path.Combine(outputDir, Path.GetDirectoryName(relFile)));
                if (relFile.Equals(fileToRoundtrip, StringComparison.OrdinalIgnoreCase))
                {
                    Console.WriteLine($"Decompiling {fileToRoundtrip}...");
                    Stopwatch w = Stopwatch.StartNew();
                    using (var fileStream = new FileStream(file, FileMode.Open, FileAccess.Read)) {
                        PEFile module   = new PEFile(file, fileStream, PEStreamOptions.PrefetchEntireImage);
                        var    resolver = new UniversalAssemblyResolver(file, false, module.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchMetadata);
                        resolver.AddSearchDirectory(inputDir);
                        resolver.RemoveSearchDirectory(".");
                        var decompiler = new TestProjectDecompiler(inputDir);
                        decompiler.AssemblyResolver = resolver;
                        // Let's limit the roundtrip tests to C# 7.3 for now; because 8.0 is still in preview
                        // and the generated project doesn't build as-is.
                        decompiler.Settings = new DecompilerSettings(LanguageVersion.CSharp7_3);
                        // use a fixed GUID so that we can diff the output between different ILSpy runs without spurious changes
                        decompiler.ProjectGuid = Guid.Parse("{127C83E4-4587-4CF9-ADCA-799875F3DFE6}");
                        if (snkFilePath != null)
                        {
                            decompiler.StrongNameKeyFile = Path.Combine(inputDir, snkFilePath);
                        }
                        decompiler.DecompileProject(module, decompiledDir);
                        Console.WriteLine($"Decompiled {fileToRoundtrip} in {w.Elapsed.TotalSeconds:f2}");
                        projectFile = Path.Combine(decompiledDir, module.Name + ".csproj");
                    }
                }
                else
                {
                    File.Copy(file, Path.Combine(outputDir, relFile));
                }
            }
            Assert.IsNotNull(projectFile, $"Could not find {fileToRoundtrip}");

            Compile(projectFile, outputDir);
            testAction(outputDir);
        }
Пример #23
0
        /// <summary>
        /// Saves this object as an Inno Setup formatted script
        /// </summary>
        /// <param name="textWriter"><see cref="TextWriter"/> with which script is written</param>
        public virtual void Save(TextWriter textWriter)
        {
            var thisType    = typeof(Installation);
            var derivedType = GetType();

            var entriesBuilder = new ParameterizedEntriesBuilder(textWriter);

            // list of methods referenced by constants
            var constReferencedMethods = new HashSet <InstallationMethod>();

            _constantReferencedMethod = methodInfo => constReferencedMethods.Add(new InstallationMethod(methodInfo));

            try
            {
                using (new Section(textWriter, "Setup"))
                {
                    var setupProperties = thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                          .Where(p => p.GetCustomAttribute <SetupDirectiveAttribute>() != null)
                                          .Select(p =>
                                                  new
                    {
                        Alias         = p.GetCustomAttribute <AliasAttribute>()?.Name,
                        Property      = derivedType.GetProperty(p.Name),
                        TypeConverter = p.GetCustomAttribute <TypeConverterAttribute>()
                    })
                                          .Where(p => p.Property.DeclaringType != thisType)
                                          .Select(p =>
                                                  new
                    {
                        p.Property,
                        Name = p.Alias ?? p.Property.Name,
                        p.TypeConverter
                    })
                                          .OrderBy(p => p.Name)
                                          .ToList();

                    WriteDirectives(textWriter, setupProperties.Select(p => (p.Name, p.Property, p.TypeConverter)));
                }

                var langOptionsProperties = thisType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
                                            .Where(p => p.GetCustomAttribute <LanguageDirectiveAttribute>() != null)
                                            .Select(p =>
                                                    new
                {
                    Alias         = p.GetCustomAttribute <AliasAttribute>()?.Name,
                    Property      = derivedType.GetProperty(p.Name),
                    TypeConverter = p.GetCustomAttribute <TypeConverterAttribute>()
                })
                                            .Where(p => derivedType.GetProperty(p.Property.Name).DeclaringType != thisType)
                                            .Select(p =>
                                                    new
                {
                    p.Property,
                    Name = p.Alias ?? p.Property.Name,
                    p.TypeConverter
                })
                                            .OrderBy(p => p.Name)
                                            .ToList();

                if (langOptionsProperties.Count > 0)
                {
                    using (new Section(textWriter, "LanguageOptions"))
                    {
                        WriteDirectives(textWriter, langOptionsProperties.Select(p => (p.Name, p.Property, p.TypeConverter)));
                    }
                }

                ParameterizedEntriesBuilderHandler?.Invoke(entriesBuilder);
            }
            finally
            {
                _constantReferencedMethod = null;
            }

            using (new Section(textWriter, "Code"))
            {
                textWriter.WriteLine("const");
                textWriter.WriteLine("   MB_ICONWARNING = $30;");
                textWriter.WriteLine("   MB_ICONINFORMATION = $40;");
                textWriter.WriteLine("   MB_ICONQUESTION = $20;");
                textWriter.WriteLine("   MB_ICONERROR = $10;");
                textWriter.WriteBlankLine();

                var decompilers = new Dictionary <string, CSharpDecompiler>();

                SyntaxTree GetSyntaxTree(string assemblyLocation, int metadataToken)
                {
                    var settings = new DecompilerSettings
                    {
                        UseDebugSymbols   = true,
                        NamedArguments    = false,
                        SwitchExpressions = false,
                        OutVariables      = false,
                        SeparateLocalVariableDeclarations = true,
                        LoadInMemory         = true,
                        ShowXmlDocumentation = false,
                        Discards             = false
                    };

                    var assemblyName = assemblyLocation;

                    var peFile = new PEFile(
                        assemblyName,
                        new FileStream(assemblyName, FileMode.Open, FileAccess.Read),
                        streamOptions: settings.LoadInMemory ? PEStreamOptions.PrefetchEntireImage : PEStreamOptions.Default,
                        metadataOptions: settings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None
                        );

                    var resolver = new UniversalAssemblyResolver(assemblyName, settings.ThrowOnAssemblyResolveErrors,
                                                                 peFile.DetectTargetFrameworkId(),
                                                                 settings.LoadInMemory ? PEStreamOptions.PrefetchMetadata : PEStreamOptions.Default,
                                                                 settings.ApplyWindowsRuntimeProjections ? MetadataReaderOptions.ApplyWindowsRuntimeProjections : MetadataReaderOptions.None);

                    var typeSystem = new DecompilerTypeSystem(peFile, resolver);

                    var decompiler = decompilers.Set(
                        assemblyName,
                        new CSharpDecompiler(typeSystem, settings)
                    {
                        DebugInfoProvider = new MetadataDebugInfoProvider(assemblyName)
                    }
                        );
                    var method = MetadataTokenHelpers.TryAsEntityHandle(metadataToken);

                    return(decompiler.Decompile(new List <EntityHandle>()
                    {
                        method.Value
                    }));
                }

                var eventHandlers = thisType.GetMethods(BindingFlags.Instance | BindingFlags.Public).Where(m => m.GetCustomAttribute <EventHandlerAttribute>() != null)
                                    .Select(m => new
                {
                    DerivedMethod   = derivedType.GetMethod(m.Name, BindingFlags.Public | BindingFlags.Instance),
                    InterfaceMethod = m
                })
                                    .Select(m =>
                {
                    if (m.DerivedMethod.DeclaringType != typeof(Installation))
                    {
                        return(new InstallationMethod(m.DerivedMethod, m.InterfaceMethod));
                    }

                    return(null);
                })
                                    .Where(m => m != null)
                                    .ToList();

                var allMethods = entriesBuilder.Methods
                                 .Concat(eventHandlers)
                                 .Concat(constReferencedMethods)
                                 .ToList();

                var aliasFactory = new Func <string, string>(name =>
                {
                    var method = allMethods.Single(m => m.Name == name);
                    return(method.GetAttribute <AliasAttribute>()?.Name);
                });

                bool encounteredInitializeSetup     = false;
                bool encounteredInitializeUninstall = false;
                var  referencedGlobalVariables      = new Dictionary <FieldInfo, string>();
                var  definedMethods  = new HashSet <string>();
                var  declaredMembers = new HashSet <MemberInfo>();
                var  namespaces      = new HashSet <string>();
                using var typeDefinitions = new Snippet();

                var type = derivedType;
                while (type != null && type != typeof(Installation))
                {
                    namespaces.Add(type.Namespace);
                    type = type.BaseType;
                }

                using (var snippet = new Snippet())
                {
                    foreach (var installationMethod in allMethods)
                    {
                        switch (installationMethod.Name)
                        {
                        case nameof(Installation.InitializeSetup):
                            encounteredInitializeSetup = true;
                            break;

                        case nameof(Installation.InitializeUninstall):
                            encounteredInitializeUninstall = true;
                            break;
                        }

                        if (!definedMethods.Add(installationMethod.UniqueId))
                        {
                            // already defined, probably via recursion when one method called another
                            continue;
                        }

                        var ast = GetSyntaxTree(installationMethod.AssemblyLocation, installationMethod.MetadataToken);

                        //ast.VisitChildren(new DiagnosticVisitor(Console.Out));

                        var methodDecl = ast.Children.OfType <MethodDeclaration>().Single();

                        using (var masterWriter = new TextCodeWriter(snippet, null, true))
                        {
                            var codeWriterFactory = new NestedCodeWriterFactory(masterWriter);

                            using (var methodWriter = codeWriterFactory.New())
                            {
                                var context = new PascalScriptVisitorContext(
                                    this,
                                    methodWriter,
                                    null,
                                    namespaces,
                                    mi => GetSyntaxTree(mi.DeclaringType.Assembly.Location, mi.MetadataToken),
                                    referencedGlobalVariables,
                                    aliasFactory,
                                    new TextCodeWriter(typeDefinitions, null, false),
                                    declaredMembers,
                                    () => codeWriterFactory.New(),
                                    derivedType.BaseType,
                                    definedMethods);

                                ast.VisitChildren(new PascalScriptVisitor(context));

                                methodWriter.WriteBlankLine();
                            }
                        }
                    }

                    using (var codeWriter = new TextCodeWriter(textWriter, null, true))
                    {
                        typeDefinitions.CopyTo(codeWriter);

                        var usedSwitches           = new HashSet <string>();
                        var variableInitialization = new List <(string name, string rhs)>();

                        // write global variables
                        if (referencedGlobalVariables.Count > 0)
                        {
                            codeWriter.WriteLine("var");

                            using (codeWriter.Indent())
                            {
                                foreach (var globalVariable in referencedGlobalVariables)
                                {
                                    codeWriter.WriteLine($"{globalVariable.Value}: {globalVariable.Key.FieldType.ToPascal()};");

                                    var defaultValue          = globalVariable.Key.GetValue(this);
                                    var formattedDefaultValue = defaultValue == null || globalVariable.Key.FieldType.IsStruct() ? null : PascalScriptVisitor.FormatPrimitive(defaultValue);
                                    var cmdLineAttr           = (globalVariable.Key.GetCustomAttribute <CommandLineParameterAttribute>());

                                    if (cmdLineAttr != null)
                                    {
                                        var name           = cmdLineAttr.SwitchName ?? globalVariable.Key.Name;
                                        var initialization = $"ExpandConstant('{{param:{name.ToLower()}";

                                        if (defaultValue != null)
                                        {
                                            defaultValue = defaultValue.GetType() == typeof(bool) ?
                                                           ((bool)defaultValue ? "1" : "0") :
                                                           formattedDefaultValue;

                                            initialization += $"|{defaultValue}";
                                        }

                                        initialization += "}')";

                                        if (globalVariable.Key.FieldType == typeof(bool))
                                        {
                                            initialization = $"({initialization} = '1')";
                                        }

                                        if (!usedSwitches.Add(name))
                                        {
                                            throw new NotSupportedException($"The command line parameter name {name} can be used only once");
                                        }

                                        variableInitialization.Add((globalVariable.Key.Name, initialization));
                                    }
                                    else if (formattedDefaultValue != null)
                                    {
                                        // FormatPrimitive() won't single quote the string
                                        if (defaultValue is string)
                                        {
                                            formattedDefaultValue = $"'{formattedDefaultValue}'";
                                        }

                                        variableInitialization.Add((globalVariable.Key.Name, formattedDefaultValue));
                                    }
                                }
                            }
                        }

                        codeWriter.WriteBlankLine();

                        // write body of code
                        snippet.CopyTo(codeWriter);

                        using (var globalVariableSnippet = new Snippet())
                        {
                            using (var globalVariableWriter = new TextCodeWriter(globalVariableSnippet, null, true))
                            {
                                variableInitialization.ForEach(init => globalVariableWriter.WriteLine($"{init.name} := {init.rhs};"));
                            }

                            if (encounteredInitializeSetup || variableInitialization.Count > 0)
                            {
                                // write InitializeSetup
                                codeWriter.WriteLine($"function {nameof(Installation.InitializeSetup)}: Boolean;");
                                codeWriter.WriteBegin();

                                using (codeWriter.Indent())
                                {
                                    // write variable initialization
                                    globalVariableSnippet.CopyTo(codeWriter);

                                    codeWriter.WriteBlankLine();
                                    codeWriter.WriteLine(encounteredInitializeSetup ? "Result := this_InitializeSetup();" : "Result := True;");
                                }

                                codeWriter.WriteEnd();
                            }

                            if (encounteredInitializeUninstall || variableInitialization.Count > 0)
                            {
                                // write InitializeSetup
                                codeWriter.WriteLine($"function {nameof(Installation.InitializeUninstall)}: Boolean;");
                                codeWriter.WriteBegin();

                                using (codeWriter.Indent())
                                {
                                    // write variable initialization
                                    globalVariableSnippet.CopyTo(codeWriter);

                                    codeWriter.WriteBlankLine();
                                    codeWriter.WriteLine(encounteredInitializeUninstall ? "Result := this_InitializeUninstall();" : "Result := True;");
                                }

                                codeWriter.WriteEnd();
                            }
                        }
                    }
                }
            }
        }
Пример #24
0
        public bool Decomple(string targetProj, string source, bool bConsole)
        {
            targetProj = Environment.ExpandEnvironmentVariables(targetProj);
            source     = Environment.ExpandEnvironmentVariables(source);
            string targetDirectory = Path.GetDirectoryName(targetProj);
            string targetName      = Path.GetFileNameWithoutExtension(targetProj);
            bool   bSuccess        = false;

            try
            {
                using (FileStream fs = new FileStream(source, FileMode.Open, FileAccess.Read))
                {
                    WholeProjectDecompiler decompiler                   = new WholeProjectDecompiler();
                    PEFile                    moduleDefinition          = new PEFile(source, fs, PEStreamOptions.PrefetchEntireImage);
                    CancellationToken         cancellationToken         = default(CancellationToken);
                    UniversalAssemblyResolver universalAssemblyResolver = new UniversalAssemblyResolver(source, false, moduleDefinition.Reader.DetectTargetFrameworkId(), PEStreamOptions.PrefetchEntireImage);
                    decompiler.AssemblyResolver = universalAssemblyResolver;
                    decompiler.DecompileProject(moduleDefinition, targetDirectory, cancellationToken);

                    // Set runtime to SB runtime
                    // Update case target name
                    // Copy and rename paths for dlls
                    string runtime;
                    try
                    {
                        string   sblPath                = MainWindow.InstallDir + "\\SmallBasicLibrary.dll";
                        Assembly sblAssembly            = Assembly.LoadFile(sblPath);
                        TargetFrameworkAttribute attrib = (TargetFrameworkAttribute)sblAssembly.GetCustomAttribute(typeof(TargetFrameworkAttribute));
                        runtime = attrib.FrameworkName.Substring(attrib.FrameworkName.Length - 4);
                    }
                    catch
                    {
                        runtime = "v4.5";
                    }

                    string      result = targetDirectory + "\\" + moduleDefinition.Name + ".csproj";
                    XmlDocument doc    = new XmlDocument();
                    doc.Load(result);
                    XmlNodeList elemList = doc.GetElementsByTagName("AssemblyName");
                    if (elemList.Count == 1 && elemList[0].InnerText == moduleDefinition.Name)
                    {
                        elemList[0].InnerText = targetName;
                    }
                    elemList = doc.GetElementsByTagName("TargetFrameworkVersion");
                    if (elemList.Count == 1)
                    {
                        elemList[0].InnerText = runtime;
                    }
                    elemList = doc.GetElementsByTagName("OutputType");
                    if (bConsole && elemList.Count == 1 && elemList[0].InnerText == "WinExe")
                    {
                        elemList[0].InnerText = "Exe";
                    }
                    elemList = doc.GetElementsByTagName("HintPath");
                    foreach (XmlNode xmlNode in elemList)
                    {
                        if (xmlNode.InnerText.EndsWith(".dll"))
                        {
                            string dll = targetDirectory + "\\" + Path.GetFileName(xmlNode.InnerText);
                            File.Copy(xmlNode.InnerText, dll);
                            xmlNode.InnerText = dll;
                        }
                    }
                    File.Delete(result);
                    doc.Save(targetProj);

                    //Set Main
                    string projectFile = targetDirectory + "\\_SmallBasicProgram.cs";
                    if (File.Exists(projectFile))
                    {
                        string prog = File.ReadAllText(projectFile);
                        prog = prog.Replace("static void _Main()", "static void Main()");
                        if (bConsole)
                        {
                            prog = prog.Replace("SmallBasicApplication.BeginProgram();", "SmallBasicApplication.BeginProgram();\r\n\t\t//Initialise and hide TextWindow for Console App\r\n\t\tTextWindow.Show();\r\n\t\tTextWindow.Hide();");
                        }
                        File.WriteAllText(projectFile, prog);
                    }
                }

                MainWindow.Errors.Add(new Error("Decompile : " + "Successfully decompiled assembly to " + targetProj));
                bSuccess = true;
            }
            catch (Exception ex)
            {
                MainWindow.Errors.Add(new Error("Decomple : " + ex.Message));
                bSuccess = false;
            }
            //Start VS or open containing folder
            //if (File.Exists(targetProj)) Process.Start(targetProj);
            //else if (Directory.Exists(targetDirectory)) Process.Start("explorer.exe", "\"" + targetDirectory + "\"");
            if (Directory.Exists(targetDirectory))
            {
                Process.Start("explorer.exe", "\"" + targetDirectory + "\"");
            }
            return(bSuccess);
        }
Пример #25
0
 public EmbeddedAssemblyResolver(PEFile baseModule, string targetFramework)
 {
     this.baseModule = baseModule;
     _resolver       = new UniversalAssemblyResolver(baseModule.FileName, true, targetFramework, PEStreamOptions.PrefetchMetadata);
     _resolver.AddSearchDirectory(Path.GetDirectoryName(baseModule.FileName));
 }
Пример #26
0
        public AssemblyList CreateDefaultList(string name, string?path = null, string?newName = null)
        {
            var list = new AssemblyList(this, newName ?? name);

            switch (name)
            {
            case DotNet4List:
                AddToListFromGAC("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Xaml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
                AddToListFromGAC("PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                break;

            case DotNet35List:
                AddToListFromGAC("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Core, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Data.DataSetExtensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Xml.Linq, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("PresentationCore, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("PresentationFramework, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("WindowsBase, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                break;

            case ASPDotNetMVC3List:
                AddToListFromGAC("mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.ComponentModel.DataAnnotations, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
                AddToListFromGAC("System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Data.DataSetExtensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
                AddToListFromGAC("System.EnterpriseServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
                AddToListFromGAC("System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
                AddToListFromGAC("System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("System.Web.ApplicationServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("System.Web.DynamicData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("System.Web.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("System.Web.Services, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
                AddToListFromGAC("System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35");
                AddToListFromGAC("System.Xml, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("System.Xml.Linq, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
                AddToListFromGAC("Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
                break;

            case object _ when path != null:
                foreach (var file in Directory.GetFiles(path, "*.dll"))
                {
                    var dllname = Path.GetFileName(file);
                    if (DoIncludeFile(dllname))
                    {
                        AddToListFromDirectory(file);
                    }
                }
                break;
            }
            return(list);

            void AddToListFromGAC(string fullName)
            {
                AssemblyNameReference reference = AssemblyNameReference.Parse(fullName);
                string?file = UniversalAssemblyResolver.GetAssemblyInGac(reference);

                if (file != null)
                {
                    list.OpenAssembly(file);
                }
            }

            void AddToListFromDirectory(string file)
            {
                if (File.Exists(file))
                {
                    list.OpenAssembly(file);
                }
            }

            bool DoIncludeFile(string fileName)
            {
                if (fileName == "Microsoft.DiaSymReader.Native.amd64.dll")
                {
                    return(false);
                }
                if (fileName.EndsWith("_cor3.dll", StringComparison.OrdinalIgnoreCase))
                {
                    return(false);
                }
                if (char.IsUpper(fileName[0]))
                {
                    return(true);
                }
                if (fileName == "netstandard.dll")
                {
                    return(true);
                }
                if (fileName == "mscorlib.dll")
                {
                    return(true);
                }
                return(false);
            }
        }