Example #1
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);
        }
Example #2
0
        public override bool Save(ViewModels.TabPageModel tabPage)
        {
            SaveFileDialog dlg = new SaveFileDialog();

            dlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(key));
            if (dlg.ShowDialog() == true)
            {
                using var data = OpenStream();
                using var fs   = dlg.OpenFile();
                data.CopyTo(fs);
            }
            return(true);
        }
Example #3
0
        public override bool Save(TabPageModel tabPage)
        {
            Stream s = Resource.TryOpenStream();

            if (s == null)
            {
                return(false);
            }
            SaveFileDialog dlg = new SaveFileDialog();

            dlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(Resource.Name));
            dlg.Filter   = Resources.ResourcesFileFilter;
            if (dlg.ShowDialog() == true)
            {
                s.Position = 0;
                switch (dlg.FilterIndex)
                {
                case 1:
                    using (var fs = dlg.OpenFile())
                    {
                        s.CopyTo(fs);
                    }
                    break;

                case 2:
                    try
                    {
                        using (var fs = dlg.OpenFile())
                            using (var writer = new ResXResourceWriter(fs))
                            {
                                foreach (var entry in new ResourcesFile(s))
                                {
                                    writer.AddResource(entry.Key, entry.Value);
                                }
                            }
                    }
                    catch (BadImageFormatException)
                    {
                        // ignore errors
                    }
                    catch (EndOfStreamException)
                    {
                        // ignore errors
                    }
                    break;
                }
            }

            return(true);
        }
Example #4
0
        /// <summary>
        /// 使用 ILSpy 反编译 Assembly。
        /// </summary>
        /// <param name="assemblyPath">Assembly 路径</param>
        /// <param name="outputPath">输出路径</param>
        private static void DecompileAssembly(string assemblyPath, string outputPath)
        {
            if (Directory.Exists(outputPath))
            {
                Directory.Delete(outputPath, true);
            }
            Directory.CreateDirectory(outputPath);

            WholeProjectDecompiler decompiler = new WholeProjectDecompiler();

            var module = new PEFile(assemblyPath);

            decompiler.AssemblyResolver = new UniversalAssemblyResolver(assemblyPath, false, module.Reader.DetectTargetFrameworkId(assemblyPath));
            decompiler.DecompileProject(module, outputPath);
        }
        public static void DecompileProject(string assemblyName, string outputDirectory)
        {
            Directory.CreateDirectory(outputDirectory);
            var assemblyFileName = Path.Combine(Program.ManagedDir, assemblyName);
            WholeProjectDecompiler decompiler = new WholeProjectDecompiler();
            var settings = decompiler.Settings;

            settings.OutVariables = false;
            Console.WriteLine($"Decompiling {assemblyName} - {decompiler.LanguageVersion}");
            var module = new PEFile(assemblyFileName);

            decompiler.AssemblyResolver = new UniversalAssemblyResolver(assemblyFileName, false, module.Reader.DetectTargetFrameworkId());
            decompiler.DecompileProject(module, outputDirectory);
            FixReferences(Path.Combine(outputDirectory, $"{module.Name}.csproj"));
        }
Example #6
0
        private IEnumerable <IGrouping <string, TypeDefinitionHandle> > GetCodeFiles(PEFile module)
        {
            var metadata = module.Metadata;

            return(module.Metadata.GetTopLevelTypeDefinitions().Where(td => projectDecompiler.IncludeTypeWhenDecompilingProject(module, td))
                   .GroupBy(h =>
            {
                var type = metadata.GetTypeDefinition(h);
                var path = WholeProjectDecompiler.CleanUpFileName(metadata.GetString(type.Name)) + ".cs";
                if (!string.IsNullOrEmpty(metadata.GetString(type.Namespace)))
                {
                    path = Path.Combine(WholeProjectDecompiler.CleanUpFileName(metadata.GetString(type.Namespace)), path);
                }
                return GetOutputPath(path, module);
            }, StringComparer.OrdinalIgnoreCase));
        }
		public void Execute(TextViewContext context)
		{
			// Get all assemblies in the selection that are stored inside a package.
			var selectedNodes = context.SelectedTreeNodes.OfType<AssemblyTreeNode>()
				.Where(asm => asm.PackageEntry != null).ToArray();
			// Get root assembly to infer the initial directory for the save dialog.
			var bundleNode = selectedNodes.FirstOrDefault()?.Ancestors().OfType<AssemblyTreeNode>()
				.FirstOrDefault(asm => asm.PackageEntry == null);
			if (bundleNode == null)
				return;
			var assembly = selectedNodes[0].PackageEntry;
			SaveFileDialog dlg = new SaveFileDialog();
			dlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(assembly.Name));
			dlg.Filter = ".NET assemblies|*.dll;*.exe;*.winmd" + Resources.AllFiles;
			dlg.InitialDirectory = Path.GetDirectoryName(bundleNode.LoadedAssembly.FileName);
			if (dlg.ShowDialog() != true)
				return;

			string fileName = dlg.FileName;
			string outputFolderOrFileName = fileName;
			if (selectedNodes.Length > 1)
				outputFolderOrFileName = Path.GetDirectoryName(outputFolderOrFileName);

			Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task<AvalonEditTextOutput>.Factory.StartNew(() => {
				AvalonEditTextOutput output = new AvalonEditTextOutput();
				Stopwatch stopwatch = Stopwatch.StartNew();
				stopwatch.Stop();

				if (selectedNodes.Length == 1)
				{
					SaveEntry(output, selectedNodes[0].PackageEntry, outputFolderOrFileName);
				}
				else
				{
					foreach (var node in selectedNodes)
					{
						var fileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(node.PackageEntry.Name));
						SaveEntry(output, node.PackageEntry, Path.Combine(outputFolderOrFileName, fileName));
					}
				}
				output.WriteLine(Resources.GenerationCompleteInSeconds, stopwatch.Elapsed.TotalSeconds.ToString("F1"));
				output.WriteLine();
				output.AddButton(null, Resources.OpenExplorer, delegate { Process.Start("explorer", "/select,\"" + fileName + "\""); });
				output.WriteLine();
				return output;
			}, ct)).Then(output => Docking.DockWorkspace.Instance.ShowText(output)).HandleExceptions();
		}
Example #8
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);
        }
Example #9
0
        internal static void GeneratePdbForAssembly(LoadedAssembly assembly)
        {
            var file = assembly.GetPEFileOrNull();

            if (!PortablePdbWriter.HasCodeViewDebugDirectoryEntry(file))
            {
                MessageBox.Show(string.Format(Resources.CannotCreatePDBFile, Path.GetFileName(assembly.FileName)));
                return;
            }
            SaveFileDialog dlg = new SaveFileDialog();

            dlg.FileName         = WholeProjectDecompiler.CleanUpFileName(assembly.ShortName) + ".pdb";
            dlg.Filter           = Resources.PortablePDBPdbAllFiles;
            dlg.InitialDirectory = Path.GetDirectoryName(assembly.FileName);
            if (dlg.ShowDialog() != true)
            {
                return;
            }
            DecompilationOptions options = new DecompilationOptions();
            string fileName = dlg.FileName;

            Docking.DockWorkspace.Instance.RunWithCancellation(ct => Task <AvalonEditTextOutput> .Factory.StartNew(() => {
                AvalonEditTextOutput output = new AvalonEditTextOutput();
                Stopwatch stopwatch         = Stopwatch.StartNew();
                using (FileStream stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
                {
                    try
                    {
                        var decompiler = new CSharpDecompiler(file, assembly.GetAssemblyResolver(), options.DecompilerSettings);
                        PortablePdbWriter.WritePdb(file, decompiler, options.DecompilerSettings, stream);
                    }
                    catch (OperationCanceledException)
                    {
                        output.WriteLine();
                        output.WriteLine(Resources.GenerationWasCancelled);
                        throw;
                    }
                }
                stopwatch.Stop();
                output.WriteLine(Resources.GenerationCompleteInSeconds, stopwatch.Elapsed.TotalSeconds.ToString("F1"));
                output.WriteLine();
                output.AddButton(null, Resources.OpenExplorer, delegate { Process.Start("explorer", "/select,\"" + fileName + "\""); });
                output.WriteLine();
                return(output);
            }, ct)).Then(output => Docking.DockWorkspace.Instance.ShowText(output)).HandleExceptions();
        }
        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);
        }
Example #11
0
        protected override void ProcessRecord()
        {
            string path = GetUnresolvedProviderPathFromPSPath(LiteralPath);

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

            try
            {
                WholeProjectDecompiler decompiler = new WholeProjectDecompiler();
                decompiler.DecompileProject(Decompiler.TypeSystem.MainModule.PEFile, path);

                WriteObject("Decompilation finished");
            } catch (Exception e) {
                WriteVerbose(e.ToString());
                WriteError(new ErrorRecord(e, ErrorIds.DecompilationFailed, ErrorCategory.OperationStopped, null));
            }
        }
Example #12
0
        public override bool Save(TabPageModel tabPage)
        {
            Stream s = Resource.TryOpenStream();

            if (s == null)
            {
                return(false);
            }
            SaveFileDialog dlg = new SaveFileDialog();

            dlg.FileName = Path.GetFileName(WholeProjectDecompiler.SanitizeFileName(Resource.Name));
            if (dlg.ShowDialog() == true)
            {
                s.Position = 0;
                using (var fs = dlg.OpenFile())
                {
                    s.CopyTo(fs);
                }
            }
            return(true);
        }
        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));
            }
        }
Example #14
0
 /// <summary>
 /// Cleans up a node name for use as a file name.
 /// </summary>
 internal static string CleanUpName(string text)
 {
     return(WholeProjectDecompiler.CleanUpFileName(text));
 }
Example #15
0
        static void DecompileAsProject(string assemblyFileName, string outputDirectory)
        {
            WholeProjectDecompiler decompiler = new WholeProjectDecompiler();

            decompiler.DecompileProject(new PEFile(assemblyFileName), outputDirectory);
        }
Example #16
0
        public override ProjectId DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
        {
            var module = assembly.GetPEFileOrNull();

            if (module == null)
            {
                return(null);
            }
            if (options.FullDecompilation && options.SaveAsProjectDirectory != null)
            {
                if (!WholeProjectDecompiler.CanUseSdkStyleProjectFormat(module))
                {
                    options.DecompilerSettings.UseSdkStyleProjectFormat = false;
                }
                var decompiler = new ILSpyWholeProjectDecompiler(assembly, options);
                return(decompiler.DecompileProject(module, options.SaveAsProjectDirectory, new TextOutputWriter(output), options.CancellationToken));
            }
            else
            {
                AddReferenceAssemblyWarningMessage(module, output);
                AddReferenceWarningMessage(module, output);
                output.WriteLine();
                base.DecompileAssembly(assembly, output, options);

                // don't automatically load additional assemblies when an assembly node is selected in the tree view
                IAssemblyResolver assemblyResolver = assembly.GetAssemblyResolver(loadOnDemand: options.FullDecompilation);
                var typeSystem = new DecompilerTypeSystem(module, assemblyResolver, options.DecompilerSettings);
                var globalType = typeSystem.MainModule.TypeDefinitions.FirstOrDefault();
                if (globalType != null)
                {
                    output.Write("// Global type: ");
                    output.WriteReference(globalType, globalType.FullName);
                    output.WriteLine();
                }
                var metadata         = module.Metadata;
                var corHeader        = module.Reader.PEHeaders.CorHeader;
                var entrypointHandle = MetadataTokenHelpers.EntityHandleOrNil(corHeader.EntryPointTokenOrRelativeVirtualAddress);
                if (!entrypointHandle.IsNil && entrypointHandle.Kind == HandleKind.MethodDefinition)
                {
                    var entrypoint = typeSystem.MainModule.ResolveMethod(entrypointHandle, new Decompiler.TypeSystem.GenericContext());
                    if (entrypoint != null)
                    {
                        output.Write("// Entry point: ");
                        output.WriteReference(entrypoint, entrypoint.DeclaringType.FullName + "." + entrypoint.Name);
                        output.WriteLine();
                    }
                }
                output.WriteLine("// Architecture: " + GetPlatformDisplayName(module));
                if ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.ILOnly) == 0)
                {
                    output.WriteLine("// This assembly contains unmanaged code.");
                }
                string runtimeName = GetRuntimeDisplayName(module);
                if (runtimeName != null)
                {
                    output.WriteLine("// Runtime: " + runtimeName);
                }
                if ((corHeader.Flags & System.Reflection.PortableExecutable.CorFlags.StrongNameSigned) != 0)
                {
                    output.WriteLine("// This assembly is signed with a strong name key.");
                }
                if (module.Reader.ReadDebugDirectory().Any(d => d.Type == DebugDirectoryEntryType.Reproducible))
                {
                    output.WriteLine("// This assembly was compiled using the /deterministic option.");
                }
                if (metadata.IsAssembly)
                {
                    var asm = metadata.GetAssemblyDefinition();
                    if (asm.HashAlgorithm != AssemblyHashAlgorithm.None)
                    {
                        output.WriteLine("// Hash algorithm: " + asm.HashAlgorithm.ToString().ToUpper());
                    }
                    if (!asm.PublicKey.IsNil)
                    {
                        output.Write("// Public key: ");
                        var reader = metadata.GetBlobReader(asm.PublicKey);
                        while (reader.RemainingBytes > 0)
                        {
                            output.Write(reader.ReadByte().ToString("x2"));
                        }
                        output.WriteLine();
                    }
                }
                var debugInfo = assembly.GetDebugInfoOrNull();
                if (debugInfo != null)
                {
                    output.WriteLine("// Debug info: " + debugInfo.Description);
                }
                output.WriteLine();

                CSharpDecompiler decompiler = new CSharpDecompiler(typeSystem, options.DecompilerSettings);
                decompiler.CancellationToken = options.CancellationToken;
                if (options.EscapeInvalidIdentifiers)
                {
                    decompiler.AstTransforms.Add(new EscapeInvalidIdentifiers());
                }
                SyntaxTree st;
                if (options.FullDecompilation)
                {
                    st = decompiler.DecompileWholeModuleAsSingleFile();
                }
                else
                {
                    st = decompiler.DecompileModuleAndAssemblyAttributes();
                }
                WriteCode(output, options.DecompilerSettings, st, decompiler.TypeSystem);
                return(null);
            }
        }
Example #17
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);
        }