public ResultChecker(BaseAssemblyResolver originalsResolver, ReaderParameters originalReaderParameters, ReaderParameters linkedReaderParameters) { _originalsResolver = originalsResolver; _originalReaderParameters = originalReaderParameters; _linkedReaderParameters = linkedReaderParameters; }
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); }
/// <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>(); }
internal static void ClearExtraResolvers(this BaseAssemblyResolver resolver) { if (_resolveDictionary.ContainsKey(resolver)) { _resolveDictionary[resolver].Clear(); } }
/// <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); }; } }
public ResultChecker(BaseAssemblyResolver originalsResolver, BaseAssemblyResolver linkedResolver, PeVerifier peVerifier, ReaderParameters readerParameters) { _originalsResolver = originalsResolver; _linkedResolver = linkedResolver; _peVerifier = peVerifier; _readerParameters = readerParameters; }
/// <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); }
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")); } }
public AssemblyProcessorContext(BaseAssemblyResolver assemblyResolver, AssemblyDefinition assembly, PlatformType platform, TextWriter log) { AssemblyResolver = assemblyResolver; Assembly = assembly; Platform = platform; Log = log; }
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()); }
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); }
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(); }
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) { } } }
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); }
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); }
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); }
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); }
/// <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); }
/// <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); }
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); }
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); } }
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); }
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); }
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); }
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); } }
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(); }
public AssemblyProcessorContext(BaseAssemblyResolver assemblyResolver, AssemblyDefinition assembly, PlatformType platform) { AssemblyResolver = assemblyResolver; Assembly = assembly; Platform = platform; }
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; } } }