Esempio n. 1
0
        // this logic produces similar list of assemblies that IL2CPP will convert (it differs in the way it collects winmd files)
        public static IEnumerable <AssemblyDefinition> CollectAllAssemblies(string librariesFolder, RuntimeClassRegistry usedClasses)
        {
            var resolver = new DefaultAssemblyResolver();

            resolver.RemoveSearchDirectory(".");
            resolver.RemoveSearchDirectory("bin");
            resolver.AddSearchDirectory(librariesFolder);

            var usedDlls = usedClasses.GetUserAssemblies().Where(s => usedClasses.IsDLLUsed(s)).Select(file => AssemblyNameReference.Parse(Path.GetFileNameWithoutExtension(file)));

            return(CollectAssembliesRecursive(usedDlls.Select(dll => ResolveAssemblyReference(resolver, dll)).Where(a => a != null)));
        }
        public static IEnumerable <AssemblyDefinition> CollectAllAssemblies(string librariesFolder, RuntimeClassRegistry usedClasses)
        {
            DefaultAssemblyResolver resolver = new DefaultAssemblyResolver();

            resolver.RemoveSearchDirectory(".");
            resolver.RemoveSearchDirectory("bin");
            resolver.AddSearchDirectory(librariesFolder);
            IEnumerable <AssemblyNameReference> source = from s in usedClasses.GetUserAssemblies()
                                                         where usedClasses.IsDLLUsed(s)
                                                         select s into file
                                                         select AssemblyNameReference.Parse(Path.GetFileNameWithoutExtension(file));

            return(MonoAssemblyStripping.CollectAssembliesRecursive(from dll in source
                                                                    select MonoAssemblyStripping.ResolveAssemblyReference(resolver, dll) into a
                                                                    where a != null
                                                                    select a));
        }
Esempio n. 3
0
        void RunInternal(string dir, string fileToRoundtrip, Action <string> testAction)
        {
            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();
                    DefaultAssemblyResolver resolver = new DefaultAssemblyResolver();
                    resolver.AddSearchDirectory(inputDir);
                    resolver.RemoveSearchDirectory(".");
                    var module = ModuleDefinition.ReadModule(file, new ReaderParameters {
                        AssemblyResolver = resolver,
                        InMemory         = true
                    });
                    var decompiler = new TestProjectDecompiler(inputDir);
                    // 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}");
                    decompiler.DecompileProject(module, decompiledDir);
                    Console.WriteLine($"Decompiled {fileToRoundtrip} in {w.Elapsed.TotalSeconds:f2}");
                    projectFile = Path.Combine(decompiledDir, module.Assembly.Name.Name + ".csproj");
                }
                else
                {
                    File.Copy(file, Path.Combine(outputDir, relFile));
                }
            }
            Assert.IsNotNull(projectFile, $"Could not find {fileToRoundtrip}");

            Compile(projectFile, outputDir);
            testAction(outputDir);
        }
Esempio n. 4
0
        void RunTest(string name, string asmPath, string sourcePath)
        {
            var resolver = new DefaultAssemblyResolver();

            resolver.RemoveSearchDirectory(".");
            resolver.AddSearchDirectory(Path.GetDirectoryName(asmPath));
            var assembly = AssemblyDefinition.ReadAssembly(asmPath, new ReaderParameters {
                AssemblyResolver = resolver, InMemory = true
            });
            Resource res        = assembly.MainModule.Resources.First();
            Stream   bamlStream = LoadBaml(res, name + ".baml");

            Assert.IsNotNull(bamlStream);
            XDocument document = BamlResourceEntryNode.LoadIntoDocument(resolver, assembly, bamlStream, CancellationToken.None);

            XamlIsEqual(File.ReadAllText(sourcePath), document.ToString());
        }
Esempio n. 5
0
        static void ListContent(string assemblyFileName, TextWriter output, ISet <TypeKind> kinds)
        {
            DefaultAssemblyResolver resolver = new DefaultAssemblyResolver();

            resolver.AddSearchDirectory(Path.GetDirectoryName(assemblyFileName));
            resolver.RemoveSearchDirectory(".");

            var module = ModuleDefinition.ReadModule(assemblyFileName, new ReaderParameters {
                AssemblyResolver = resolver,
                InMemory         = true
            });

            var typeSystem = new DecompilerTypeSystem(module);

            foreach (var type in typeSystem.MainAssembly.GetAllTypeDefinitions())
            {
                if (!kinds.Contains(type.Kind))
                {
                    continue;
                }
                output.WriteLine($"{type.Kind} {type.FullName}");
            }
        }
Esempio n. 6
0
        public static void WeaveTestAssembly()
        {
            // Assembly has already been weaved as part of this run and doesn't need to be done again
            if (WeavedAssembly != null)
            {
                return;
            }

            var currentPath = AppDomain.CurrentDomain.BaseDirectory + @"\Obleak.Fody.Test.dll";

            var beforePath         = Path.GetFullPath(currentPath);
            var beforePdb          = beforePath.Replace(".dll", ".pdb");
            var weavedAssemblyPath = beforePath.Replace(".dll", "2.dll");
            var weavedPdbPath      = beforePath.Replace(".dll", "2.pdb");

            File.Copy(beforePath, weavedAssemblyPath, true);
            File.Copy(beforePdb, weavedPdbPath, true);

            var resolver = new DefaultAssemblyResolver();

            foreach (var dir in resolver.GetSearchDirectories())
            {
                resolver.RemoveSearchDirectory(dir);
            }

            resolver.AddSearchDirectory(AppDomain.CurrentDomain.BaseDirectory);

            var errors   = new List <string>();
            var warnings = new List <string>();

            using (var symbolStream = File.OpenRead(weavedPdbPath))
            {
                var readerParameters = new ReaderParameters
                {
                    AssemblyResolver     = resolver,
                    ReadSymbols          = true,
                    SymbolStream         = symbolStream,
                    SymbolReaderProvider = new PdbReaderProvider()
                };

                var moduleDefinition = ModuleDefinition.ReadModule(weavedAssemblyPath, readerParameters);

                var subscriptionWeavingTask = new ObleakSubscriptionWeaver
                {
                    ModuleDefinition = moduleDefinition,
                    LogInfo          = s => warnings.Add(s),
                    LogError         = s => errors.Add(s),
                };

                subscriptionWeavingTask.Execute();

                if (errors.Any())
                {
                    throw new Exception("Errors raised by the weaving process: " + string.Join(", ", errors));
                }

                var reactiveCommandObleakTask = new ObleakReactiveCommandWeaver
                {
                    ModuleDefinition = moduleDefinition,
                    LogInfo          = s => warnings.Add(s),
                    LogError         = s => errors.Add(s),
                };

                reactiveCommandObleakTask.Execute();

                if (errors.Any())
                {
                    throw new Exception("Errors raised by the weaving process: " + string.Join(", ", errors));
                }

                moduleDefinition.Write(weavedAssemblyPath);
            }
            WeavedAssembly = Assembly.LoadFile(weavedAssemblyPath);
        }
        private NAssemblySource LoadAssembly(ConfigSourceGroup group, string source)
        {
            var dirPath          = Path.GetDirectoryName(source);
            var assemblyResolver = new DefaultAssemblyResolver();

            // Remove any default search path
            assemblyResolver.RemoveSearchDirectory(".");
            assemblyResolver.RemoveSearchDirectory("bin");

            // Search from assembly directory
            assemblyResolver.AddSearchDirectory(dirPath);

            // Add additional search directory
            foreach (var searchDirectory in group.SearchDirectories)
            {
                assemblyResolver.AddSearchDirectory(searchDirectory);
            }

            var parameters = new ReaderParameters(ReadingMode.Immediate)
            {
                AssemblyResolver = assemblyResolver
            };

            assemblyResolver.ResolveFailure += (sender, reference) =>
            {
                var searchDirectories = assemblyResolver.GetSearchDirectories();
                foreach (var directory in searchDirectories)
                {
                    var tryPath = Path.Combine(directory, reference.Name + ".winmd");
                    if (!File.Exists(tryPath))
                    {
                        continue;
                    }

                    try
                    {
                        var winmdAssembly = AssemblyDefinition.ReadAssembly(tryPath, parameters);
                        if (winmdAssembly != null)
                        {
                            return(winmdAssembly);
                        }
                    }
                    catch
                    {
                        // Failed... fall thru and try the next one.
                    }
                }

                // Log an error if we can't find the assembly. Mono.Cecil will throw an exception just after returning from
                // this callback
                Logger.Error("Failed to resolve {0}", reference.FullName);
                return(null);
            };

            var assemblyDefinition = AssemblyDefinition.ReadAssembly(source, parameters);
            var assemblySource     = new NAssemblySource(assemblyDefinition)
            {
                Filename   = source,
                MergeGroup = group.MergeGroup
            };

            return(assemblySource);
        }
Esempio n. 8
0
        static void Main(string[] args)
        {
            var arguments = new Arguments();

            try
            {
                if (args.Length < 1)
                {
                    arguments.Usage();
                }
                arguments.Parse(args);
                isRemoving           = arguments.IsRemoving;
                isFailing            = arguments.IsFailing;
                preInvokeMethodName  = arguments.PreInvokeMethod;
                postInvokeMethodName = arguments.PostInvokeMethod;
                inputFilePath        = arguments.FilePaths[0];
                var outputFilePath = arguments.FilePaths.Count > 1 ? arguments.FilePaths[1] : inputFilePath;
                resolver = new DefaultAssemblyResolver();
                string inputFolderPath = Path.GetDirectoryName(inputFilePath);
                resolver.RemoveSearchDirectory(".");
                resolver.RemoveSearchDirectory("bin");
                var searchFolders = new List <string>();
                searchFolders.Add(inputFolderPath);
                searchFolders.AddRange(arguments.SearchFolderPaths);
                searchFolders.AddRange(arguments.Assemblies.Select(s => Path.GetDirectoryName(s)));
                if (arguments.FrameworkFolder != null)
                {
                    searchFolders.Add(arguments.FrameworkFolder);
                }
                else
                {
                    var nakedModule       = ModuleDefinition.ReadModule(inputFilePath);
                    var assemblyReference = nakedModule.AssemblyReferences.FirstOrDefault(a => a.Name == "mscorlib");
                    if (assemblyReference != null)
                    {
                        if (Enumerable.SequenceEqual(assemblyReference.PublicKeyToken, new byte[] { 0x7c, 0xec, 0x85, 0xd7, 0xbe, 0xa7, 0x79, 0x8e }))
                        {
                            // This is Silverlight.
                            string programFilesFolder = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
                            string silverlightFolder  = Path.Combine(programFilesFolder, "Microsoft Silverlight");
                            silverlightFolder = Directory.GetDirectories(silverlightFolder).OrderByDescending(s => s).First();
                            searchFolders.Add(silverlightFolder);
                            // The following also works.
                            //searchFolders.Add(@"C:\Program Files\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0");
                        }
                        else
                        {
                            // Assume it's the full .NET framework.
                            // TODO:  handle WP7.
                            string programFilesFolder = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86);
                            string frameworkFolder    = Path.Combine(programFilesFolder, @"Reference Assemblies\Microsoft\Framework\.NETFramework");
                            frameworkFolder = Directory.GetDirectories(frameworkFolder).OrderByDescending(s => s).First();
                            searchFolders.Add(frameworkFolder);
                        }
                    }
                }
                searchFolders = searchFolders.Select(s => Path.GetFullPath(s).ToLowerInvariant()).Distinct().ToList();
                searchFolders.ForEach(s => resolver.AddSearchDirectory(s));
                module = ReadModule(inputFilePath, resolver);
                var q = from p in arguments.Assemblies
                        let n = Path.GetFileNameWithoutExtension(p)
                                select resolver.Resolve(n).MainModule;

                modules      = new[] { module }.Concat(q).ToList();
                symbolReader = new SymbolReader(module);
                if (WeaveDependency() | WeaveNotify() | WeaveOnDemand() | WeaveInitialValue() | WeavePrePost() | WeaveXmlSerializable() | (arguments.IsRenaming && WeaveRename()))
                {
                    WriteModule(module, outputFilePath);
                }
            }
            catch (Exception ex)
            {
#if DEBUG
                Console.Error.WriteLine(ex);
#else
                Console.Error.WriteLine(ex.Message);
#endif
                Console.Error.Flush();
                Console.WriteLine();
                arguments.Usage(1);
            }
            if (HasFailed)
            {
                Environment.ExitCode = 1;
            }
        }
        private static bool TryProcessAssembly(string inputPath, string outputPath)
        {
            bool processed = false;

            try
            {
                var asmResolver = new DefaultAssemblyResolver();
                foreach (var path in asmResolver.GetSearchDirectories())
                {
                    asmResolver.RemoveSearchDirectory(path);
                }

                asmResolver.AddSearchDirectory(Path.GetDirectoryName(inputPath));
                using (var assemblyDefinition = AssemblyDefinition.ReadAssembly(inputPath, new ReaderParameters {
                    AssemblyResolver = asmResolver
                }))
                {
                    var lstDefinitionsDefs = new List <DefinitionItem>();
                    var moduleDefinition   = assemblyDefinition.MainModule;

                    // Extract direct definitions
                    foreach (var definition in Definitions)
                    {
                        if (definition.TargetAssembly != assemblyDefinition.Name.Name)
                        {
                            continue;
                        }

                        if (assemblyDefinition.Name.Version is not null)
                        {
                            var minVersion = new Version(definition.TargetMinimumMajor, definition.TargetMinimumMinor, definition.TargetMinimumPatch);
                            var maxVersion = new Version(definition.TargetMaximumMajor, definition.TargetMaximumMinor, definition.TargetMaximumPatch);

                            if (assemblyDefinition.Name.Version < minVersion)
                            {
                                continue;
                            }

                            if (assemblyDefinition.Name.Version > maxVersion)
                            {
                                continue;
                            }
                        }

                        var typeDefinition = moduleDefinition.Types.FirstOrDefault(t => t.FullName == definition.TargetType);
                        if (typeDefinition is null && moduleDefinition.HasExportedTypes)
                        {
                            var exportedType = moduleDefinition.ExportedTypes.FirstOrDefault(eType => eType.FullName == definition.TargetType);
                            if (exportedType is not null)
                            {
                                try
                                {
                                    typeDefinition = exportedType.Resolve();
                                }
                                catch
                                {
                                    // ...
                                }
                            }
                        }

                        if (typeDefinition is not null)
                        {
                            RetrieveMethodsInTypeDefinition(typeDefinition, definition, lstDefinitionsDefs, assemblyDefinition);
                        }
                    }

                    // Extract derived definitions
                    var assemblyReferences = moduleDefinition.AssemblyReferences;
                    foreach (var assemblyReference in assemblyReferences)
                    {
                        foreach (var definition in DerivedDefinitions)
                        {
                            if (definition.TargetAssembly != assemblyReference.Name)
                            {
                                continue;
                            }

                            var minVersion = new Version(definition.TargetMinimumMajor, definition.TargetMinimumMinor, definition.TargetMinimumPatch);
                            var maxVersion = new Version(definition.TargetMaximumMajor, definition.TargetMaximumMinor, definition.TargetMaximumPatch);

                            if (assemblyReference.Version < minVersion)
                            {
                                continue;
                            }

                            if (assemblyReference.Version > maxVersion)
                            {
                                continue;
                            }

                            var asmName = moduleDefinition.Assembly.FullName;

                            foreach (var typeDefinition in moduleDefinition.Types)
                            {
                                var baseTypeReference = typeDefinition.BaseType;
                                if (baseTypeReference != null && baseTypeReference.FullName == definition.TargetType)
                                {
                                    RetrieveMethodsInTypeDefinition(typeDefinition, definition, lstDefinitionsDefs, assemblyDefinition);
                                }
                            }
                        }
                    }

                    if (lstDefinitionsDefs.Count == 0)
                    {
                        return(false);
                    }

                    AnsiConsole.WriteLine($"{assemblyDefinition.Name.FullName} => {lstDefinitionsDefs.Count}");
                    if (ProcessDefinitions(moduleDefinition, lstDefinitionsDefs))
                    {
                        if ((moduleDefinition.Attributes & ModuleAttributes.ILLibrary) == ModuleAttributes.ILLibrary)
                        {
                            moduleDefinition.Architecture = TargetArchitecture.I386;
                            moduleDefinition.Attributes  &= ~ModuleAttributes.ILLibrary;
                            moduleDefinition.Attributes  |= ModuleAttributes.ILOnly;
                        }

                        assemblyDefinition.Write(outputPath);
                        processed = true;
                    }
                }
            }
            catch (BadImageFormatException)
            {
                return(false);
            }
            catch (Exception ex)
            {
                Utils.WriteError($"{inputPath}: {ex.Message}");
                return(false);
            }
            finally
            {
                if (!processed)
                {
                    File.Copy(inputPath, outputPath, true);
                }
            }

            return(true);

            void RetrieveMethodsInTypeDefinition(TypeDefinition typeDefinition, NativeCallTargetDefinition definition, List <DefinitionItem> lstDefinitionsDefs, AssemblyDefinition assemblyDefinition)
            {
                foreach (var mDefinition in typeDefinition.Methods.Where(m => m.Name == definition.TargetMethod))
                {
                    var lstParameters = mDefinition.Parameters;
                    if (lstParameters.Count != definition.TargetSignatureTypesLength - 1)
                    {
                        continue;
                    }

                    bool parameters = true;
                    var  ptr        = definition.TargetSignatureTypes;
                    for (var i = 0; i < definition.TargetSignatureTypesLength; i++)
                    {
                        var localPtr    = Marshal.ReadIntPtr(ptr);
                        var localString = Marshal.PtrToStringUni(localPtr);
                        ptr += Marshal.SizeOf(typeof(IntPtr));

                        if (localString == "_")
                        {
                            continue;
                        }

                        if (i == 0)
                        {
                            if (mDefinition.ReturnType.FullName != localString)
                            {
                                parameters = false;
                                break;
                            }
                        }
                        else if (lstParameters[i - 1].ParameterType.FullName != localString)
                        {
                            parameters = false;
                            break;
                        }
                    }

                    if (parameters)
                    {
                        var methodDefinition = mDefinition;
                        var integrationType  = TracerAssembly.GetType(definition.IntegrationType, false);
                        if (integrationType is not null)
                        {
                            lstDefinitionsDefs.Add(new DefinitionItem(assemblyDefinition, typeDefinition, methodDefinition, integrationType, definition));
                        }

                        break;
                    }
                }
            }
        }
Esempio n. 10
0
 public void RemoveSearchPath(string path)
 {
     assemblyResolver.RemoveSearchDirectory(path);
 }