コード例 #1
0
ファイル: ResultChecker.cs プロジェクト: mikem8361/runtime
 public ResultChecker(BaseAssemblyResolver originalsResolver,
                      ReaderParameters originalReaderParameters, ReaderParameters linkedReaderParameters)
 {
     _originalsResolver        = originalsResolver;
     _originalReaderParameters = originalReaderParameters;
     _linkedReaderParameters   = linkedReaderParameters;
 }
コード例 #2
0
        private static List <MethodDefinition> GetMethodsInsideAssembly(String assemblyToLoad, bool includeMethodDefinition, Func <MethodReference, bool> condition)
        {
            string directory = Path.GetDirectoryName(assemblyToLoad);
            BaseAssemblyResolver resolver = (GlobalAssemblyResolver.Instance as BaseAssemblyResolver);

            if (!resolver.GetSearchDirectories().Contains(directory))
            {
                resolver.AddSearchDirectory(directory);
            }

            var methods = new List <MethodDefinition>();

            foreach (MethodDefinition methodDefinition in GetMethods(assemblyToLoad))
            {
                if ((methodDefinition.HasBody || includeMethodDefinition) && (condition(methodDefinition)))
                {
                    //if (includeMethodsCalled)
                    //{
                    //    methodsCalled.Add(MethodDetailBuilder.Create(methodDefinition, GetMethodsCalledInsideMethod(methodDefinition, condition)));
                    //}
                    //else
                    //{
                    //    methodsCalled.Add(MethodDetailBuilder.Create(methodDefinition));
                    //}
                    methods.Add(methodDefinition);
                }
            }
            return(methods);
        }
コード例 #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="MonoCecilAssemblyLoader" /> class
 /// </summary>
 /// <param name="assemblyFolderPath">the path to search assemblies in</param>
 public MonoCecilAssemblyLoader(string assemblyFolderPath)
 {
     this.assemblyFolderPath = assemblyFolderPath;
     this.assemblyResolver   = new DefaultAssemblyResolver();
     this.assemblyResolver.AddSearchDirectory(this.assemblyFolderPath);
     this.allAssemblies = new HashSet <AssemblyDefinition>();
 }
コード例 #4
0
 internal static void ClearExtraResolvers(this BaseAssemblyResolver resolver)
 {
     if (_resolveDictionary.ContainsKey(resolver))
     {
         _resolveDictionary[resolver].Clear();
     }
 }
コード例 #5
0
 /// <summary>
 /// Creates a system of multiple assembly resolvers. The latest resolver is fired first. The list can be cleared.
 /// </summary>
 /// <param name="resolver"></param>
 /// <param name="handler"></param>
 internal static void RegisterSpecialResolveFailureHandler(this BaseAssemblyResolver resolver,
                                                           AssemblyResolveEventHandler handler)
 {
     if (_resolveDictionary.ContainsKey(resolver))
     {
         _resolveDictionary[resolver].Add(handler);
     }
     else
     {
         _resolveDictionary[resolver] = new List <AssemblyResolveEventHandler> {
             handler
         };
         resolver.ResolveFailure += (sender, name) => {
             foreach (var curHandler in _resolveDictionary[resolver].Reverse())
             {
                 var assembly = curHandler(sender, name);
                 if (assembly != null)
                 {
                     return(assembly);
                 }
             }
             return(null);
         };
     }
 }
コード例 #6
0
 public ResultChecker(BaseAssemblyResolver originalsResolver, BaseAssemblyResolver linkedResolver, PeVerifier peVerifier, ReaderParameters readerParameters)
 {
     _originalsResolver = originalsResolver;
     _linkedResolver    = linkedResolver;
     _peVerifier        = peVerifier;
     _readerParameters  = readerParameters;
 }
コード例 #7
0
ファイル: AnalyzeAssembly.cs プロジェクト: dbremner/smokey
        /// <summary>Check an assembly and return an array of violations.</summary>
        /// <remarks>OnlyType is used to check only the types that contain a string in the array which may be null.
        /// Severity is the minimum rule severity to use. IgnoreBreaks is true if we want to
        /// ignore rules that break binary compatibility. Note that this should only be called once:
        /// if you want to smoke multiple assemblies create a new AnalyzeAssembly object.</remarks>
        public Error[] Analyze(string imagePath, string[] onlyType, Severity severity, bool ignoreBreaks)
        {
            DBC.Assert(!m_analyzed, "Analyze can only be called once");                 // TODO: would be nice to relax this, maybe add an overload to allow another assembly to be checked with the same settings
            m_analyzed = true;

            Profile.Start("AssemblyFactory");
            AssemblyDefinition assemblyDef = AssemblyFactory.GetAssembly(imagePath);

            Profile.Stop("AssemblyFactory");

            string path = Path.GetFullPath(imagePath);                  // need to add a cecil search directory so that it finds assemblies in the same directory as the assembly we're checking
            string dir  = Path.GetDirectoryName(path);
            BaseAssemblyResolver resolver = assemblyDef.Resolver as BaseAssemblyResolver;

            DBC.Assert(resolver != null, "assemblyDef.Resolver isn't a BaseAssemblyResolver");
            resolver.AddSearchDirectory(dir);

            m_symbols = new SymbolTable();
            AssemblyCache cache = new AssemblyCache(m_symbols, assemblyDef, m_callback);

            var assembly = System.Reflection.Assembly.GetExecutingAssembly();

            m_checker.LoadRules(assembly, cache, severity, ignoreBreaks);

            Error[] errors = DoCheckAssembly(assemblyDef, cache, onlyType);

            return(errors);
        }
コード例 #8
0
        private static void AddSearchDirectories(BaseAssemblyResolver resolver)
        {
            //Add search directories based on platform
            if (platform == RuntimePlatform.WindowsEditor || platform == RuntimePlatform.OSXEditor)
            {
                resolver.AddSearchDirectory(Path.GetDirectoryName(typeof(UnityEngine.Object).Assembly.Location));
                resolver.AddSearchDirectory(Path.Combine(Directory.GetCurrentDirectory(), "Assets"));

                foreach (string directory in Directory.GetDirectories(Directory.GetCurrentDirectory(), "ModTool", SearchOption.AllDirectories))
                {
                    resolver.AddSearchDirectory(directory);
                }

                resolver.AddSearchDirectory(Directory.GetCurrentDirectory());
            }

            if (platform == RuntimePlatform.WindowsPlayer || platform == RuntimePlatform.LinuxPlayer || platform == RuntimePlatform.OSXPlayer)
            {
                foreach (string directory in Directory.GetDirectories(Directory.GetCurrentDirectory(), "Managed", SearchOption.AllDirectories))
                {
                    resolver.AddSearchDirectory(directory);
                }

                resolver.AddSearchDirectory(Directory.GetCurrentDirectory());
            }

            //android - extracted assemblies from apk in persistentDatapath/Assemblies
            if (platform == RuntimePlatform.Android)
            {
                resolver.AddSearchDirectory(Path.Combine(persistentDataPath, "Assemblies"));
            }
        }
コード例 #9
0
 public AssemblyProcessorContext(BaseAssemblyResolver assemblyResolver, AssemblyDefinition assembly, PlatformType platform, TextWriter log)
 {
     AssemblyResolver = assemblyResolver;
     Assembly         = assembly;
     Platform         = platform;
     Log = log;
 }
コード例 #10
0
        public static string GenerateSerializationAssembly(BaseAssemblyResolver assemblyResolver, AssemblyDefinition assembly, TextWriter log)
        {
            // Create the serializer code generator
            var serializerGenerator = new ComplexSerializerCodeGenerator(assemblyResolver, assembly, log);

            // Register default serialization profile (to help AOT generic instantiation of serializers)
            RegisterDefaultSerializationProfile(assemblyResolver, assembly, serializerGenerator, log);

            // Generate serializer code
            return(serializerGenerator.TransformText());
        }
コード例 #11
0
        public bool EnqueueBaseTypeBinding(TypeReference typeReference)
        {
            TypeDefinition typedef;

            BaseAssemblyResolver baseResolver = null;

            try
            {
                baseResolver = typeReference.Module.AssemblyResolver as BaseAssemblyResolver;
                if (baseResolver != null)
                {
                    // Sometimes the base resolver can't find assemblies that are copied
                    // locally.  Thanks to this handy event, we can try to resolve them
                    // ourselves - this has worked so far, but feels hacky.  Debugging
                    // Cecil + Fody is tricky, so root cause is unknown at present.
                    baseResolver.ResolveFailure += BaseResolverOnResolveFailure;
                }

                typedef = typeReference.Resolve();
            }
            catch (AssemblyResolutionException ex)
            {
                var format = "Failed to resolve type {0}: {1}";
                errorReporter.LogWarning(string.Format(format, typeReference.FullName, ex));
                return(false);
            }
            finally
            {
                if (baseResolver != null)
                {
                    baseResolver.ResolveFailure -= BaseResolverOnResolveFailure;
                }
            }

            var processorKey = GetModuleKey(typedef.Module);

            if (!modulesByAssembly.ContainsKey(processorKey))
            {
                return(false);
            }

            var usesStiletto =
                typedef.CustomAttributes.Any(Attributes.IsSingletonAttribute) ||
                typedef.Properties.Any(p => p.CustomAttributes.Any(Attributes.IsInjectAttribute)) ||
                typedef.Methods.Any(m => m.Name == ".ctor" && m.CustomAttributes.Any(Attributes.IsInjectAttribute));

            if (!usesStiletto)
            {
                return(false);
            }

            processors.First().EnqueueBaseType(typedef);
            return(true);
        }
コード例 #12
0
 public ResolvedInjecteeAssembly(
     AssemblyDefinition assemblyDefinition,
     IReadOnlyList <MethodDefinition> injecteeMethods,
     IReadOnlyList <ResolvedAllowedAssemblyReference> allowedAssemblyReferences = null,
     BaseAssemblyResolver assemblyResolver = null
     )
 {
     AssemblyDefinition        = assemblyDefinition ?? throw new ArgumentNullException(nameof(assemblyDefinition));
     InjecteeMethods           = injecteeMethods ?? throw new ArgumentNullException(nameof(allowedAssemblyReferences));
     AllowedAssemblyReferences = allowedAssemblyReferences ?? Array.Empty <ResolvedAllowedAssemblyReference>();
     AssemblyResolver          = assemblyResolver ?? new IgnoringExceptionsAssemblyResolver();
 }
コード例 #13
0
 private static void TryAddReference(BaseAssemblyResolver assemblyResolver, HashSet <string> assemblyLocations, List <MetadataReference> metadataReferences, string referenceName)
 {
     if (assemblyLocations.Add(referenceName))
     {
         try
         {
             metadataReferences.Add(CreateMetadataReference(assemblyResolver, assemblyResolver.Resolve(referenceName)));
         }
         catch (AssemblyResolutionException)
         {
         }
     }
 }
コード例 #14
0
        public AssemblyCollection(
            ReaderParameters readerParameters,
            BaseAssemblyResolver assemblyResolver)
        {
            ReaderParameters = readerParameters
                               ?? throw new ArgumentNullException(nameof(readerParameters));

            ReaderParameters.AssemblyResolver = assemblyResolver;
            ReaderParameters.MetadataResolver = new MetadataResolver(assemblyResolver);

            AssemblyResolver = assemblyResolver
                               ?? throw new ArgumentNullException(nameof(assemblyResolver));
        }
        private AssemblyDefinition LoadAssemblyDefinition(
            string assemblyPath,
            BaseAssemblyResolver assemblyResolver
            )
        {
            ReaderParameters parameters = new ReaderParameters();

            parameters.AssemblyResolver = assemblyResolver;
            parameters.ReadSymbols      = false;

            AssemblyDefinition assemblyDefinition = AssemblyDefinition.ReadAssembly(assemblyPath, parameters);

            return(assemblyDefinition);
        }
コード例 #16
0
ファイル: Publicizer.cs プロジェクト: Shirkie01/Nitrox
        private static AssemblyDefinition Publicize(string file, BaseAssemblyResolver dllResolver)
        {
            AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(file,
                                                                          new ReaderParameters
            {
                AssemblyResolver = dllResolver
            });
            List <TypeDefinition> allTypes = GetAllTypes(assembly.MainModule).ToList();

            foreach (TypeDefinition type in allTypes)
            {
                if (type == null)
                {
                    continue;
                }

                // Publicize type and nested types.
                if (!type.IsPublic || !type.IsNestedPublic)
                {
                    if (type.IsNested)
                    {
                        type.IsNestedPublic = true;
                    }
                    else
                    {
                        type.IsPublic = true;
                    }
                }
                // Publicize methods on type.
                foreach (MethodDefinition method in type.Methods)
                {
                    if (!method?.IsPublic ?? false)
                    {
                        method.IsPublic = true;
                    }
                }
            }

            // Publicize all fields (excludes fields if they would cause name conflicts on a type).
            foreach (FieldDefinition field in FilterBackingEventFields(allTypes))
            {
                if (!field?.IsPublic ?? false)
                {
                    field.IsPublic = true;
                }
            }

            return(assembly);
        }
コード例 #17
0
        private static AssemblyDefinition Publicize(string file, BaseAssemblyResolver dllResolver)
        {
            AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(file,
                                                                          new ReaderParameters
            {
                AssemblyResolver = dllResolver
            });
            var allTypes   = GetAllTypes(assembly.MainModule).ToList();
            var allMethods = allTypes.SelectMany(t => t.Methods);
            var allFields  = FilterBackingEventFields(allTypes);

            foreach (TypeDefinition type in allTypes)
            {
                if (type == null)
                {
                    continue;
                }
                if (type.IsPublic && type.IsNestedPublic)
                {
                    continue;
                }

                if (type.IsNested)
                {
                    type.IsNestedPublic = true;
                }
                else
                {
                    type.IsPublic = true;
                }
            }
            foreach (MethodDefinition method in allMethods)
            {
                if (!method?.IsPublic ?? false)
                {
                    method.IsPublic = true;
                }
            }
            foreach (FieldDefinition field in allFields)
            {
                if (!field?.IsPublic ?? false)
                {
                    field.IsPublic = true;
                }
            }

            return(assembly);
        }
コード例 #18
0
        public bool RemoveAssemblyResolveDir(string dir)
        {
            if (_resolveDirs.Contains(dir))
            {
                _resolveDirs.Remove(dir);

                BaseAssemblyResolver bar = GlobalAssemblyResolver.Instance as BaseAssemblyResolver;
                if (bar != null)
                {
                    bar.RemoveSearchDirectory(dir);
                }

                return(true);
            }
            return(false);
        }
コード例 #19
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="assemblyPath"></param>
        /// <param name="currentPath"></param>
        /// <param name="savePath"></param>
        /// <returns></returns>
        public static bool BuildToFile(string assemblyPath, string currentPath, string savePath = null)
        {
            bool setSuccess = false;

            if (string.IsNullOrEmpty(savePath))
            {
                savePath = assemblyPath;
            }
            string            pdbFile        = Path.ChangeExtension(assemblyPath, "pdb");
            PdbReaderProvider readerProvider = null;
            PdbWriterProvider writerProvider = null;
            bool debug = false;

            if (File.Exists(pdbFile))
            {
                debug          = true;
                readerProvider = new PdbReaderProvider();
                writerProvider = new PdbWriterProvider();
            }
            //huhu modify reason: Support for model debugging.
            var ass = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters
            {
                SymbolReaderProvider = readerProvider,
                ReadSymbols          = debug
            });
            BaseAssemblyResolver resolver = ass.MainModule.AssemblyResolver as BaseAssemblyResolver;

            if (resolver != null)
            {
                resolver.AddSearchDirectory(currentPath);
            }
            foreach (TypeDefinition type in ass.MainModule.GetTypes())
            {
                if (type.IsEnum)
                {
                    continue;
                }
                setSuccess = ProcessEntityType(type, setSuccess, currentPath);
            }
            //modify reason: no model.
            ass.Write(savePath, new WriterParameters
            {
                SymbolWriterProvider = writerProvider,
                WriteSymbols         = debug
            });
            return(true);
        }
コード例 #20
0
        /// <summary>
        /// Generates the Mono.Cecil TypeReference from its .NET <see cref="Type"/> counterpart.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="assemblyResolver">The assembly resolver.</param>
        /// <returns></returns>
        public static TypeReference GenerateTypeCecil(this Type type, BaseAssemblyResolver assemblyResolver)
        {
            var           assemblyDefinition = assemblyResolver.Resolve(type.Assembly.FullName);
            TypeReference typeReference;

            if (type.IsNested)
            {
                var declaringType = GenerateTypeCecil(type.DeclaringType, assemblyResolver);
                typeReference = declaringType.Resolve().NestedTypes.FirstOrDefault(x => x.Name == type.Name);
            }
            else if (type.IsArray)
            {
                var elementType = GenerateTypeCecil(type.GetElementType(), assemblyResolver);
                typeReference = new ArrayType(elementType, type.GetArrayRank());
            }
            else
            {
                typeReference = assemblyDefinition.MainModule.GetTypeResolved(type.IsGenericType ? type.GetGenericTypeDefinition().FullName : type.FullName);
            }

            if (typeReference == null)
            {
                throw new InvalidOperationException("Could not resolve cecil type.");
            }

            if (type.IsGenericType)
            {
                var genericInstanceType = new GenericInstanceType(typeReference);
                foreach (var argType in type.GetGenericArguments())
                {
                    TypeReference argTypeReference;
                    if (argType.IsGenericParameter)
                    {
                        argTypeReference = new GenericParameter(argType.Name, typeReference);
                    }
                    else
                    {
                        argTypeReference = GenerateTypeCecil(argType, assemblyResolver);
                    }
                    genericInstanceType.GenericArguments.Add(argTypeReference);
                }

                typeReference = genericInstanceType;
            }

            return(typeReference);
        }
コード例 #21
0
        public bool AddAssemblyResolveDir(string dir)
        {
            if (_resolveDirs.Contains(dir) || !Directory.Exists(dir))
            {
                return(false);
            }

            _resolveDirs.Add(dir);

            BaseAssemblyResolver bar = GlobalAssemblyResolver.Instance as BaseAssemblyResolver;

            if (bar != null)
            {
                bar.AddSearchDirectory(dir);
            }

            return(true);
        }
コード例 #22
0
ファイル: StructureMerger.cs プロジェクト: jma2400/cecil-old
        public override void VisitModuleReference(ModuleReference module)
        {
            string name = module.Name;

            name = name.ToLower();
            if (!BaseAssemblyResolver.OnMono())
            {
                if (!name.EndsWith(".dll"))
                {
                    name += ".dll";
                }
            }

            if (!ModuleReferencesContains(target.MainModule.ModuleReferences, name))
            {
                module.Name = name;
                target.MainModule.ModuleReferences.Add(module);
            }
        }
コード例 #23
0
        public static string GenerateBlackList(string librariesFolder, RuntimeClassRegistry usedClasses, string[] allAssemblies)
        {
            string text = "tmplink.xml";

            usedClasses.SynchronizeClasses();
            using (TextWriter textWriter = new StreamWriter(Path.Combine(librariesFolder, text)))
            {
                textWriter.WriteLine("<linker>");
                textWriter.WriteLine("<assembly fullname=\"UnityEngine\">");
                foreach (string current in usedClasses.GetAllManagedClassesAsString())
                {
                    textWriter.WriteLine(string.Format("<type fullname=\"UnityEngine.{0}\" preserve=\"{1}\"/>", current, usedClasses.GetRetentionLevel(current)));
                }
                textWriter.WriteLine("</assembly>");
                DefaultAssemblyResolver defaultAssemblyResolver = new DefaultAssemblyResolver();
                defaultAssemblyResolver.AddSearchDirectory(librariesFolder);
                for (int i = 0; i < allAssemblies.Length; i++)
                {
                    string path = allAssemblies[i];
                    BaseAssemblyResolver arg_CB_0     = defaultAssemblyResolver;
                    string           arg_CB_1         = Path.GetFileNameWithoutExtension(path);
                    ReaderParameters readerParameters = new ReaderParameters();
                    readerParameters.set_AssemblyResolver(defaultAssemblyResolver);
                    AssemblyDefinition assemblyDefinition = arg_CB_0.Resolve(arg_CB_1, readerParameters);
                    textWriter.WriteLine("<assembly fullname=\"{0}\">", assemblyDefinition.get_Name().get_Name());
                    if (assemblyDefinition.get_Name().get_Name().StartsWith("UnityEngine."))
                    {
                        foreach (string current2 in usedClasses.GetAllManagedClassesAsString())
                        {
                            textWriter.WriteLine(string.Format("<type fullname=\"UnityEngine.{0}\" preserve=\"{1}\"/>", current2, usedClasses.GetRetentionLevel(current2)));
                        }
                    }
                    MonoAssemblyStripping.GenerateBlackListTypeXML(textWriter, assemblyDefinition.get_MainModule().get_Types(), usedClasses.GetAllManagedBaseClassesAsString());
                    textWriter.WriteLine("</assembly>");
                }
                textWriter.WriteLine("</linker>");
            }
            return(text);
        }
        private AssemblyDefinitionCachedData GetAssemblyDefinitionCachedData(
            string assemblyPath,
            BaseAssemblyResolver assemblyResolver)
        {
            assemblyPath = Path.GetFullPath(assemblyPath);
            if (!_assemblyPathToAssemblyMap.TryGetValue(assemblyPath, out AssemblyDefinitionCachedData assemblyDefinitionData))
            {
                Log.DebugFormat("Loading assembly at path '{0}'", assemblyPath);

                AssemblyDefinition assemblyDefinition = LoadAssemblyDefinition(assemblyPath, assemblyResolver);
                assemblyDefinitionData = new AssemblyDefinitionCachedData(assemblyDefinition);
                Log.DebugFormat(
                    "Loaded assembly at path '{0}': {1} types, {2} methods",
                    assemblyPath,
                    assemblyDefinitionData.AllTypes.Count,
                    assemblyDefinitionData.AllMethods.Count
                    );
                _assemblyPathToAssemblyMap.Add(assemblyPath, assemblyDefinitionData);
            }

            return(assemblyDefinitionData);
        }
コード例 #25
0
        public static string GenerateLinkXmlToPreserveDerivedTypes(string stagingArea, string librariesFolder, RuntimeClassRegistry usedClasses)
        {
            string fullPath = Path.GetFullPath(Path.Combine(stagingArea, "preserved_derived_types.xml"));
            DefaultAssemblyResolver resolver = new DefaultAssemblyResolver();

            resolver.AddSearchDirectory(librariesFolder);
            using (TextWriter textWriter = new StreamWriter(fullPath))
            {
                textWriter.WriteLine("<linker>");
                foreach (AssemblyDefinition current in MonoAssemblyStripping.CollectAssembliesRecursive((from s in usedClasses.GetUserAssemblies()
                                                                                                         where usedClasses.IsDLLUsed(s)
                                                                                                         select s).Select(delegate(string file)
                {
                    BaseAssemblyResolver arg_1F_0 = resolver;
                    string arg_1F_1 = Path.GetFileNameWithoutExtension(file);
                    ReaderParameters readerParameters = new ReaderParameters();
                    readerParameters.set_AssemblyResolver(resolver);
                    return(arg_1F_0.Resolve(arg_1F_1, readerParameters));
                })))
                {
                    if (!(current.get_Name().get_Name() == "UnityEngine"))
                    {
                        HashSet <TypeDefinition> hashSet = new HashSet <TypeDefinition>();
                        MonoAssemblyStripping.CollectBlackListTypes(hashSet, current.get_MainModule().get_Types(), usedClasses.GetAllManagedBaseClassesAsString());
                        if (hashSet.Count != 0)
                        {
                            textWriter.WriteLine("<assembly fullname=\"{0}\">", current.get_Name().get_Name());
                            foreach (TypeDefinition current2 in hashSet)
                            {
                                textWriter.WriteLine("<type fullname=\"{0}\" preserve=\"all\"/>", current2.get_FullName());
                            }
                            textWriter.WriteLine("</assembly>");
                        }
                    }
                }
                textWriter.WriteLine("</linker>");
            }
            return(fullPath);
        }
コード例 #26
0
        ModuleReference GetModuleReference(ModuleReferenceCollection members, ModuleReference module)
        {
            string name = module.Name;

            name = name.ToLower();
            if (!BaseAssemblyResolver.OnMono())
            {
                if (!name.EndsWith(".dll"))
                {
                    name += ".dll";
                }
            }

            foreach (ModuleReference mr in members)
            {
                if (mr.Name == name)
                {
                    return(mr);
                }
            }
            return(null);
        }
コード例 #27
0
        internal static void ForceClearCache(this BaseAssemblyResolver resolver)
        {
            var asDefault = resolver as DefaultAssemblyResolver;

            if (asDefault == null)
            {
                throw new Exception($"Failed to clear the cache because the resolver type wasn't {nameof(DefaultAssemblyResolver)}.");
            }
            //sometimes old versions of assemblies get stuck in the cache. We want to kick them out, so we have to resort to this...
            var field = typeof(DefaultAssemblyResolver).GetField("cache", CommonBindingFlags.Everything);

            if (field == null)
            {
                throw new Exception($"Failed to clear the cache because the resolver didn't have a field called 'cache'.");
            }
            try {
                var cache = (IDictionary <string, AssemblyDefinition>)field.GetValue(resolver);
                cache.Clear();
            }
            catch (Exception ex) {
                throw new Exception($"Failed to clear the cache because an exception was thrown.", ex);
            }
        }
コード例 #28
0
        public static void Main(string[] args)
        {
            Logger.onLog          += onLoggerLog;
            Logger.showModuleNames = false;
            Logger.showTimestamps  = false;
            Logger.Begin("installer.log");

            asmResolver = new DefaultAssemblyResolver();

            FileInfo assemblyFilePath = getAssemblyFilePath();

            if (assemblyFilePath == null)
            {
                error("Couldn't find assembly");
                return;
            }
            if (!canOpenFile(assemblyFilePath))
            {
                error("Could not open file " + assemblyFilePath.FullName);
            }
            log("Found the file at " + assemblyFilePath.FullName);

            asmResolver.AddSearchDirectory(assemblyFilePath.Directory.FullName);

            string loaderFilePath = getLoaderFilePath();

            if (!canOpenFile(loaderFilePath))
            {
                error("Could not open file " + loaderFilePath);
            }

            string gamePath = assemblyFilePath.Directory.Parent.FullName;
            string fileName = Path.DirectorySeparatorChar + LOADER_ASSEMBLY_NAME;

            log("Finding files...");
            if (!File.Exists(gamePath + fileName))
            {
                File.Copy(loaderFilePath, gamePath + fileName);
            }
            loaderFilePath = gamePath + fileName;
            if (!canOpenFile(loaderFilePath))
            {
                error("Could not open file " + loaderFilePath);
            }

            // Load both modules
            log("Loading modules...");
            ModuleDefinition assemblyModule = ModuleDefinition.ReadModule(assemblyFilePath.FullName,
                                                                          new ReaderParameters {
                AssemblyResolver = asmResolver, ReadingMode = ReadingMode.Immediate
            });
            ModuleDefinition loaderModule = ModuleDefinition.ReadModule(loaderFilePath,
                                                                        new ReaderParameters {
                AssemblyResolver = asmResolver, ReadingMode = ReadingMode.Immediate
            });

            log("Finding loader entry point type...");
            // Find loader entry point type
            TypeDefinition loaderEntryPointType = loaderModule.GetType(LOADER_ENTRY_POINT_TYPE);

            if (loaderEntryPointType == null)
            {
                error("Could not find entry point type in loader: "
                      + LOADER_ENTRY_POINT_TYPE);
            }

            log("Injecting type import...");
            loaderEntryPointType = assemblyModule.ImportReference(loaderEntryPointType).Resolve();

            log("Finding loader entry point method...");
            // Find loader entry point method
            MethodReference loaderEntryPointMethod = loaderEntryPointType.Methods.FirstOrDefault(x =>
                                                                                                 x.Name == LOADER_ENTRY_POINT_METHOD
                                                                                                 );

            if (loaderEntryPointMethod == null)
            {
                error("Could not find entry point method in loader: "
                      + LOADER_ENTRY_POINT_TYPE + "." + LOADER_ENTRY_POINT_METHOD);
            }

            log("Injecting method import...");
            loaderEntryPointMethod = assemblyModule.ImportReference(loaderEntryPointMethod);

            log("Finding game entry point...");
            // Find assembly entry point type
            TypeDefinition assemblyEntryPointType = assemblyModule.GetType(ASSEMBLY_ENTRY_POINT_TYPE);

            if (assemblyEntryPointType == null)
            {
                error("Could not find entry point type in game: "
                      + ASSEMBLY_ENTRY_POINT_TYPE);
            }
            // Find assembly entry point method
            MethodDefinition assemblyEntryPointMethod = assemblyEntryPointType.Methods.FirstOrDefault(x =>
                                                                                                      x.Name == ASSEMBLY_ENTRY_POINT_METHOD
                                                                                                      );

            if (assemblyEntryPointMethod == null || !assemblyEntryPointMethod.HasBody)
            {
                error("Could not find entry point method in game: "
                      + ASSEMBLY_ENTRY_POINT_TYPE + "." + ASSEMBLY_ENTRY_POINT_METHOD);
            }

            log("Finding instruction...");
            ILProcessor methodILProcessor = assemblyEntryPointMethod.Body.GetILProcessor();
            Instruction entryPoint        = methodILProcessor.Create(OpCodes.Call, loaderEntryPointMethod);

            // Check if the entry point has already been injected
            if (findMatchingInstruction(assemblyEntryPointMethod.Body.Instructions, entryPoint) != -1)
            {
                error("Entry point already found, the loader has already been installed!");
            }

            FieldDefinition searchField         = assemblyEntryPointType.Fields.Single(x => x.Name == "wasInMultiplayer");
            Instruction     entryPointIndicator = methodILProcessor.Create(OpCodes.Stsfld, searchField);

            int entryPointIndex =
                findMatchingInstruction(assemblyEntryPointMethod.Body.Instructions, entryPointIndicator);

            if (entryPointIndex < 0)
            {
                error("Could not find entry point instruction");
            }

            log("Injecting entry point");
            assemblyEntryPointMethod.Body.Instructions.Insert(entryPointIndex + 1, entryPoint);
            // We should insert instructions to load any arguments we need here

            // Temporary dll path
            string tmpPath = AppDomain.CurrentDomain.BaseDirectory + Path.DirectorySeparatorChar + "tmp.dll";

            log("Saving to " + tmpPath);
            // Write assembly changes
            assemblyModule.Write(tmpPath);
            // Backup original assembly
            if (File.Exists(assemblyFilePath.FullName))
            {
                log("Backing up game assembly to " + assemblyFilePath + ".old");
                File.Move(assemblyFilePath.FullName, assemblyFilePath + ".old");
            }
            // Move modified assembly
            log("Moving new assembly");
            File.Move(tmpPath, assemblyFilePath.FullName);

            Logger.Info("Installer", "Installation complete\nPress any key to continue");
            Console.ReadLine();
        }
コード例 #29
0
 public AssemblyProcessorContext(BaseAssemblyResolver assemblyResolver, AssemblyDefinition assembly, PlatformType platform)
 {
     AssemblyResolver = assemblyResolver;
     Assembly         = assembly;
     Platform         = platform;
 }
コード例 #30
0
        static void LoadConfiguration(
            string[] args, out List <Regex> attributeNames, out List <string> dllFileNames, out bool parallel,
            out string?logFile, BaseAssemblyResolver assemblyResolver
            )
        {
            attributeNames = new List <Regex>();
            dllFileNames   = new List <string>();
            parallel       = false;
            logFile        = null;
            for (var i = 0; i < args.Length; i++)
            {
                switch (args[i])
                {
                case "-l":
                    logFile = args[i + 1];
                    i++;
                    break;

                case "-a":
                    // eg: -a ./Client/Temp/StagingArea/Data/Managed/Assembly-CSharp.dll
                    dllFileNames.Add(args[i + 1]);
                    i += 1;
                    break;

                case "-d":
                    assemblyResolver.AddSearchDirectory(args[i + 1]);

                    i += 1;
                    break;

                case "-p":
                    parallel = true;
                    break;

                case "-x":
                    // eg: -x ./Client/Assets/link.xml
                    var xmlFile = args[i + 1];
                    if (File.Exists(xmlFile))
                    {
                        try {
                            var xml      = XDocument.Load(xmlFile);
                            var attrRoot = xml.Element("strip-attribute");
                            if (attrRoot == null)
                            {
                                throw new Exception("Can't find root <strip-attribute> tag in the XML.");
                            }

                            var elements = attrRoot.Elements("type").ToArray();
                            for (var idx = 0; idx < elements.Length; idx++)
                            {
                                var typeElement = elements[idx];
                                var regex       = typeElement.Attribute("regex");
                                if (regex == null)
                                {
                                    throw new Exception($"Can't find regex attribute on <type> index {idx}");
                                }
                                attributeNames.Add(new Regex(regex.Value));
                            }
                        }
                        catch (Exception e) {
                            throw new Exception($"Parsing XML file error. File={xmlFile}", e);
                        }
                    }
                    else
                    {
                        throw new Exception($"File does not exist: {xmlFile}");
                    }

                    i += 1;
                    break;
                }
            }
        }