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())); }
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); }
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))); }
/// <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); }
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)); }
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()); } }
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))); }
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); }
/// <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); } }
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); }
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); }
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); }
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()); } }
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)); } }
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); } }
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)); } }
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); }
/// <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(); } } } } } }
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); }
public EmbeddedAssemblyResolver(PEFile baseModule, string targetFramework) { this.baseModule = baseModule; _resolver = new UniversalAssemblyResolver(baseModule.FileName, true, targetFramework, PEStreamOptions.PrefetchMetadata); _resolver.AddSearchDirectory(Path.GetDirectoryName(baseModule.FileName)); }
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); } }