static void Main(string[] args) { try { var path = args.Length >= 1 ? args[0] : "Ibasa.dll"; var symbolReader = new Mono.Cecil.Pdb.PdbReaderProvider(); var readerParameters = new ReaderParameters() { SymbolReaderProvider = symbolReader, ReadSymbols = true, }; var writerParameters = new WriterParameters() { WriteSymbols = true, }; AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(path, readerParameters); Console.WriteLine("Loaded {0}.", path); GenerateMemoryType(assembly.MainModule); Console.WriteLine("Saving new dll."); assembly.Write(path, writerParameters); } catch (Exception e) { Console.WriteLine("InteropBuilder failed with: {0}", e); } }
public void save(string newFilename, bool updateMaxStack) { var writerParams = new WriterParameters() { UpdateMaxStack = updateMaxStack, }; module.Write(newFilename, writerParams); }
public void ProcessAssemblyFromStream(Stream inputStream, ReaderParameters readerParams, Stream outputStream, WriterParameters writerParams) { var assemblyDef = AssemblyDefinition.ReadAssembly(inputStream, readerParams); Process(assemblyDef); if (outputStream != null) { assemblyDef.Write(outputStream, writerParams); } }
private static void GenerateInterop(String filePath, String keyFilePath) { Console.WriteLine("Generating Interop..."); String pdbFile = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".pdb"); ReaderParameters readerParams = new ReaderParameters(); WriterParameters writerParams = new WriterParameters(); if(keyFilePath != null) writerParams.StrongNameKeyPair = new StrongNameKeyPair(File.Open(keyFilePath, FileMode.Open)); // if(File.Exists(pdbFile)) { // readerParams.SymbolReaderProvider = new PdbReaderProvider(); // readerParams.ReadSymbols = true; // writerParams.WriteSymbols = true; // } AssemblyDefinition assemblyDef = AssemblyDefinition.ReadAssembly(filePath, readerParams); ((BaseAssemblyResolver) assemblyDef.MainModule.AssemblyResolver).AddSearchDirectory(Path.GetDirectoryName(filePath)); AssemblyDefinition mscorLib = null; foreach(AssemblyNameReference assemblyNameReference in assemblyDef.MainModule.AssemblyReferences) { if(assemblyNameReference.Name.ToLower() == "mscorlib") { mscorLib = assemblyDef.MainModule.AssemblyResolver.Resolve(assemblyNameReference); break; } else if(assemblyNameReference.Name == "System.Runtime") { ((BaseAssemblyResolver) assemblyDef.MainModule.AssemblyResolver).AddSearchDirectory(Path.Combine(GetProgramFilesFolder(), @"Reference Assemblies\Microsoft\Framework\.NETCore\v4.5")); mscorLib = assemblyDef.MainModule.AssemblyResolver.Resolve(assemblyNameReference); break; } } if(mscorLib == null) throw new InvalidOperationException("Missing mscorlib.dll"); m_mscorLib = mscorLib; for(int i = 0; i < assemblyDef.CustomAttributes.Count; i++) { CustomAttribute attr = assemblyDef.CustomAttributes[i]; if(attr.AttributeType.FullName == typeof(System.Runtime.CompilerServices.CompilationRelaxationsAttribute).FullName) { assemblyDef.CustomAttributes.RemoveAt(i); i--; } } foreach(TypeDefinition typeDef in assemblyDef.MainModule.Types) { PatchType(typeDef); } RemoveInteropClass(assemblyDef); assemblyDef.Write(filePath, writerParams); Console.WriteLine("Interop Generation complete."); }
static void WriteAssembly( AssemblyDefinition assembly, string targetPath, StrongNameKeyPair snk ) { WriterParameters wp = new WriterParameters() { WriteSymbols = true, StrongNameKeyPair = snk }; assembly.Write( targetPath, wp ); }
public static WriterParameters GetWriterParameters(Mono.Cecil.ReaderParameters readParams) { WriterParameters parameters = new WriterParameters(); if (readParams.SymbolReaderProvider is PdbReaderProvider) { parameters.SymbolWriterProvider = new PdbWriterProvider(); return parameters; } if (readParams.SymbolReaderProvider is MdbReaderProvider) { parameters.SymbolWriterProvider = new MdbWriterProvider(); } return parameters; }
public void Save(string path) { Console.WriteLine($"Saving {Name} to {path}"); var writerParameters = new WriterParameters(); if (File.Exists(Path.ChangeExtension(path, "pdb"))) { writerParameters.WriteSymbols = true; } Module.Write(path, writerParameters); Console.WriteLine($"{Name} saved"); }
public virtual void WriteModule() { var assemblyPath = AssemblyFilePath; var stopwatch = Stopwatch.StartNew(); Logger.LogDebug($" Writing assembly to '{assemblyPath}'."); var parameters = new WriterParameters { StrongNameKeyPair = StrongNameKeyPair, WriteSymbols = true, SymbolWriterProvider = debugWriterProvider, }; ModuleDefinition.Write(assemblyPath, parameters); Logger.LogDebug($" Finished writing assembly {stopwatch.ElapsedMilliseconds}ms."); }
public void WriteModule() { var assemblyPath = AssemblyFilePath; var stopwatch = Stopwatch.StartNew(); Logger.LogInfo(string.Format("\tWriting assembly to '{0}'.", assemblyPath)); var parameters = new WriterParameters { StrongNameKeyPair = StrongNameKeyPair, WriteSymbols = true, SymbolWriterProvider = debugWriterProvider, }; ModuleDefinition.Write(assemblyPath, parameters); Logger.LogInfo(string.Format("\tFinished writing assembly {0}ms.", stopwatch.ElapsedMilliseconds)); }
public InMemoryTests() { beforeAssemblyPath = Path.GetFullPath(@"..\..\..\AssemblyToProcess\bin\Debug\AssemblyToProcess.dll"); var directoryName = Path.GetDirectoryName(@"..\..\..\Debug\"); #if (!DEBUG) beforeAssemblyPath = beforeAssemblyPath.Replace("Debug", "Release"); directoryName = directoryName.Replace("Debug", "Release"); #endif afterAssemblyPath = beforeAssemblyPath.Replace(".dll", "InMemory.dll"); File.Copy(beforeAssemblyPath, afterAssemblyPath, true); File.Copy(beforeAssemblyPath.Replace(".dll", ".pdb"), afterAssemblyPath.Replace(".dll", ".pdb"), true); var readerParams = new ReaderParameters() { ReadSymbols = true }; moduleDefinition = ModuleDefinition.ReadModule(afterAssemblyPath, readerParams); var references = new List<string> { beforeAssemblyPath.Replace("AssemblyToProcess", "AssemblyToReference"), beforeAssemblyPath.Replace("AssemblyToProcess", "AssemblyToReferencePreEmbed"), Path.ChangeExtension(beforeAssemblyPath.Replace("AssemblyToProcess", "ExeToReference"), "exe"), Path.Combine(directoryName, "AssemblyToReferenceMixed.dll"), }; var assemblyToReferenceDirectory = Path.GetDirectoryName(beforeAssemblyPath.Replace("AssemblyToProcess", "AssemblyToReference")); var assemblyToReferenceResources = Directory.GetFiles(assemblyToReferenceDirectory, "*.resources.dll", SearchOption.AllDirectories); references.AddRange(assemblyToReferenceResources); using (var weavingTask = new ModuleWeaver { ModuleDefinition = moduleDefinition, AssemblyResolver = new MockAssemblyResolver(), Config = XElement.Parse("<Costura Unmanaged32Assemblies='AssemblyToReferenceMixed' PreloadOrder='AssemblyToReferenceNative' />"), ReferenceCopyLocalPaths = references, AssemblyFilePath = beforeAssemblyPath }) { weavingTask.Execute(); var writerParams = new WriterParameters() { WriteSymbols = true }; moduleDefinition.Write(afterAssemblyPath, writerParams); } isolatedPath = Path.Combine(Path.GetTempPath(), "CosturaIsolatedMemory.dll"); File.Copy(afterAssemblyPath, isolatedPath, true); File.Copy(afterAssemblyPath.Replace(".dll", ".pdb"), isolatedPath.Replace(".dll", ".pdb"), true); assembly = Assembly.LoadFile(isolatedPath); }
public void WriteModule() { ModuleDefinition.Types.Add(new TypeDefinition(null, "ProcessedByFody", TypeAttributes.NotPublic | TypeAttributes.Abstract | TypeAttributes.Interface)); var assemblyPath = AssemblyFilePath; var stopwatch = Stopwatch.StartNew(); Logger.LogInfo(string.Format("\tWriting assembly to '{0}'.", assemblyPath)); var parameters = new WriterParameters { StrongNameKeyPair = StrongNameKeyPair, WriteSymbols = true, SymbolWriterProvider = debugWriterProvider, }; ModuleDefinition.Write(assemblyPath, parameters); Logger.LogInfo(string.Format("\tFinished writing assembly {0}ms.", stopwatch.ElapsedMilliseconds)); }
private RewriterResults RewriteImpl () { if (!this.options.Rewrite) { return RewriterResults.Warning ("Not asked to rewrite"); } if (!this.options.Assembly.IsSet) { return RewriterResults.Error ("No assembly given to rewrite"); } var readerParameters = new ReaderParameters (); if (options.Debug) readerParameters.ReadSymbols = true; var assembly = this.options.Assembly.IsFilename ? AssemblyDefinition.ReadAssembly (options.Assembly.Filename, readerParameters) : AssemblyDefinition.ReadAssembly (options.Assembly.Streams.Assembly, readerParameters); if (this.options.ForceAssemblyRename != null) { assembly.Name.Name = this.options.ForceAssemblyRename; } else if (this.options.OutputFile.IsSet && this.options.OutputFile.IsFilename) { assembly.Name.Name = Path.GetFileNameWithoutExtension(this.options.OutputFile.Filename); } var output = this.options.OutputFile.IsSet ? this.options.OutputFile : this.options.Assembly; var writerParameters = new WriterParameters (); if (options.WritePdbFile) { if (!options.Debug) { return RewriterResults.Error ("Must specify -debug if using -writePDBFile."); } writerParameters.WriteSymbols = true; } PerformRewrite rewriter = new PerformRewrite (this.options); rewriter.Rewrite (assembly); if (output.IsFilename) { assembly.Write (output.Filename, writerParameters); } else { assembly.Write (output.Streams.Assembly, writerParameters); } return new RewriterResults (warnings, errors); }
static AssemblyWeaver() { TestListener = new TestTraceListener(); Debug.Listeners.Clear(); Debug.Listeners.Add(TestListener); BeforeAssemblyPath = Path.GetFullPath(@"..\..\..\AssemblyToProcess\bin\Debug\AssemblyToProcess.dll"); var beforePdbPath = Path.ChangeExtension(BeforeAssemblyPath, "pdb"); #if (!DEBUG) BeforeAssemblyPath = BeforeAssemblyPath.Replace("Debug", "Release"); beforePdbPath = beforePdbPath.Replace("Debug", "Release"); #endif AfterAssemblyPath = BeforeAssemblyPath.Replace(".dll", "2.dll"); var afterPdbPath = beforePdbPath.Replace(".pdb", "2.pdb"); File.Copy(BeforeAssemblyPath, AfterAssemblyPath, true); if (File.Exists(beforePdbPath)) File.Copy(beforePdbPath, afterPdbPath, true); var assemblyResolver = new MockAssemblyResolver(); var readerParameters = new ReaderParameters(); var writerParameters = new WriterParameters(); if (File.Exists(afterPdbPath)) { readerParameters.ReadSymbols = true; writerParameters.WriteSymbols = true; } var moduleDefinition = ModuleDefinition.ReadModule(AfterAssemblyPath, readerParameters); var weavingTask = new ModuleWeaver { ModuleDefinition = moduleDefinition, AssemblyResolver = assemblyResolver, LogError = LogError, DefineConstants = new List<string> { "DEBUG" } // Always testing the debug weaver }; weavingTask.Execute(); moduleDefinition.Write(AfterAssemblyPath, writerParameters); Assembly = Assembly.LoadFile(AfterAssemblyPath); }
public PureDotNetAssemblyTests() { beforeAssemblyPath = Path.GetFullPath(@"..\..\..\AssemblyToProcessWithoutUnmanaged\bin\Debug\AssemblyToProcessWithoutUnmanaged.dll"); var directoryName = Path.GetDirectoryName(@"..\..\..\Debug\"); #if (!DEBUG) beforeAssemblyPath = beforeAssemblyPath.Replace("Debug", "Release"); directoryName = directoryName.Replace("Debug", "Release"); #endif afterAssemblyPath = beforeAssemblyPath.Replace(".dll", "InMemory.dll"); File.Copy(beforeAssemblyPath, afterAssemblyPath, true); File.Copy(beforeAssemblyPath.Replace(".dll", ".pdb"), afterAssemblyPath.Replace(".dll", ".pdb"), true); var readerParams = new ReaderParameters() { ReadSymbols = true }; moduleDefinition = ModuleDefinition.ReadModule(afterAssemblyPath, readerParams); var references = new List<string> { beforeAssemblyPath.Replace("AssemblyToProcessWithoutUnmanaged", "AssemblyToReference"), }; var assemblyToReferenceDirectory = Path.GetDirectoryName(beforeAssemblyPath.Replace("AssemblyToProcessWithoutUnmanaged", "AssemblyToReference")); var assemblyToReferenceResources = Directory.GetFiles(assemblyToReferenceDirectory, "*.resources.dll", SearchOption.AllDirectories); references.AddRange(assemblyToReferenceResources); // This should use ILTemplate instead of ILTemplateWithUnmanagedHandler. using (var weavingTask = new ModuleWeaver { ModuleDefinition = moduleDefinition, AssemblyResolver = new MockAssemblyResolver(), Config = XElement.Parse("<Costura />"), ReferenceCopyLocalPaths = references, AssemblyFilePath = beforeAssemblyPath }) { weavingTask.Execute(); var writerParams = new WriterParameters() { WriteSymbols = true }; moduleDefinition.Write(afterAssemblyPath, writerParams); } isolatedPath = Path.Combine(Path.GetTempPath(), "CosturaPureDotNetIsolatedMemory.dll"); File.Copy(afterAssemblyPath, isolatedPath, true); File.Copy(afterAssemblyPath.Replace(".dll", ".pdb"), isolatedPath.Replace(".dll", ".pdb"), true); assembly = Assembly.LoadFile(isolatedPath); }
public void WriteModule(string targetPath) { if (StrongNameKeyPair == null) { logger.LogMessage(string.Format("\tSaving assembly to '{0}'.", targetPath)); } else { logger.LogMessage(string.Format("\tSigning and saving assembly to '{0}'.", targetPath)); } var parameters = new WriterParameters { StrongNameKeyPair = StrongNameKeyPair, WriteSymbols = true, SymbolWriterProvider = GetSymbolWriterProvider(TargetPath) }; Module.Write(targetPath, parameters); }
public void Execute(string targetPath) { if (projectKeyReader.StrongNameKeyPair == null) { logger.LogMessage(string.Format("\tSaving assembly to '{0}'.", targetPath)); } else { logger.LogMessage(string.Format("\tSigning and saving assembly to '{0}'.", targetPath)); } var parameters = new WriterParameters { StrongNameKeyPair = projectKeyReader.StrongNameKeyPair, WriteSymbols = true, SymbolWriterProvider = GetSymbolWriterProvider(config.TargetPath) }; moduleReader.Module.Write(targetPath, parameters); }
private static void GenerateTypeInformation(string targetDir) { Directory.SetCurrentDirectory(targetDir); var file = targetDir+"Yggdrasil.Microframework.TestApp.exe"; var yggdrasilFile = @"C:\projects\yggdrasil\Source\Yggdrasil.Microframework.TestApp\bin\Debug\Yggdrasil.dll"; var yggdrasilTargetFile = targetDir + "Yggdrasil.dll"; if( yggdrasilFile != yggdrasilTargetFile ) File.Copy(yggdrasilFile, yggdrasilTargetFile, true); var yggdrasilAssembly = AssemblyDefinition.ReadAssembly("Yggdrasil.dll"); yggdrasilAssembly.MainModule.AssemblyReferences.Add(yggdrasilAssembly.Name); Console.WriteLine("Updating : " + file); var readerParameters = new ReaderParameters { ReadSymbols = true }; var assemblyDefinition = AssemblyDefinition.ReadAssembly(file); var typeMetaData = new TypeDefinition("Yggdrasil", "_TypeMetaData", TypeAttributes.Class | TypeAttributes.Public); assemblyDefinition.MainModule.Types.Add(typeMetaData); var types = GetAllTypes(assemblyDefinition); var constructor = GetStaticConstructor(assemblyDefinition, typeMetaData); AddTypeDefinitions(yggdrasilAssembly, assemblyDefinition, typeMetaData, types, constructor); // Generate array with configuration for all types var il = constructor.Body.GetILProcessor(); il.Append(Instruction.Create(OpCodes.Ret)); Console.WriteLine("Done updating : " + file + " at " + Directory.GetCurrentDirectory()); var writerParameters = new WriterParameters { WriteSymbols = true }; assemblyDefinition.Write(file, writerParameters); //+"_modified"); }
public void Execute() { ModuleDefinition.Types.Add(new TypeDefinition(null, "ProcessedByFody", TypeAttributes.NotPublic | TypeAttributes.Abstract | TypeAttributes.Interface)); var assemblyPath = InnerWeaver.AssemblyPath; Logger.LogInfo(string.Format("Saving assembly to '{0}'.", assemblyPath)); var parameters = new WriterParameters { StrongNameKeyPair = StrongNameKeyFinder.StrongNameKeyPair, WriteSymbols = true, SymbolWriterProvider = GetSymbolWriterProvider(assemblyPath) }; var startNew = Stopwatch.StartNew(); try { ModuleDefinition.Write(assemblyPath, parameters); } finally { startNew.Stop(); Logger.LogInfo(string.Format("Finished Saving {0}ms.", startNew.ElapsedMilliseconds)); } }
public void Run() { var assemblyLocation = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); var directory = Path.Combine(assemblyLocation, "AssemblyCompression"); var beforeAssemblyPath = Path.Combine(directory, "NServiceBus.Core.dll"); var moduleDefinition = ModuleDefinition.ReadModule(beforeAssemblyPath); CompressAssembly(moduleDefinition); var afterAssemblyPath = beforeAssemblyPath.Replace(".dll", "2.dll"); File.Delete(afterAssemblyPath); var writerParameters = new WriterParameters { WriteSymbols = true }; moduleDefinition.Write(afterAssemblyPath, writerParameters); var beforeSize = new FileInfo(beforeAssemblyPath).Length + new FileInfo(beforeAssemblyPath.Replace(".dll", ".pdb")).Length; Trace.WriteLine(string.Format("before {0} kbytes", beforeSize / 1024)); var afterSize = new FileInfo(afterAssemblyPath).Length + new FileInfo(afterAssemblyPath.Replace(".dll", ".pdb")).Length; Trace.WriteLine(string.Format("after {0} kbytes", afterSize / 1024)); Verifier.Verify(afterAssemblyPath); }
static void Main(string[] args) { if (args.Length == 0) throw new ArgumentException("Full path to the assembly to be processed is required."); string filename = args[0]; string targetAssemblyPath = Path.GetFullPath(filename); if (!File.Exists(targetAssemblyPath)) throw new FileNotFoundException("Assembly to be processed was not found: " + targetAssemblyPath); // Load and process the assembly Console.WriteLine("Loading assembly module from '{0}'...", targetAssemblyPath); var readerParameters = new ReaderParameters { ReadSymbols = true }; var module = ModuleDefinition.ReadModule(targetAssemblyPath, readerParameters); ProcessAssembly(module); Console.WriteLine("Saving assembly module to '{0}'...", targetAssemblyPath); var writerParameters = new WriterParameters { WriteSymbols = true }; module.Write(targetAssemblyPath, writerParameters); }
public static void Sign(this IFile sourceAssembly, IFile destinationAssembly, StrongNameKeyPair key, Version version = null) { var sourcePdbFile = sourceAssembly.Parent.GetFile(sourceAssembly.NameWithoutExtension + ".pdb"); var sourcePdbStream = (Stream)null; //sourcePdbFile.Exists ? sourcePdbFile.OpenRead() : null; using(var sourceStream = sourceAssembly.OpenRead()) { var readerParameters = new ReaderParameters(); if (sourcePdbStream != null) { readerParameters.SymbolStream = sourcePdbStream; readerParameters.ReadSymbols = true; } var assembly = AssemblyDefinition.ReadAssembly(sourceStream, readerParameters); var name = assembly.Name; name.HashAlgorithm = AssemblyHashAlgorithm.SHA1; name.PublicKey = key.PublicKey; if (version != null) name.Version = version; assembly.Name.HasPublicKey = true; var writerParameters = new WriterParameters() { StrongNameKeyPair = key }; var destinationPdbStream = sourcePdbStream != null ? destinationAssembly.Parent.GetFile(destinationAssembly.NameWithoutExtension + ".pdb").OpenWrite() : null; if (sourcePdbStream != null) { writerParameters.SymbolStream = destinationPdbStream; writerParameters.WriteSymbols = true; } using (var destinationStream = destinationAssembly.Open(FileMode.Create, FileAccess.ReadWrite, FileShare.None)) { assembly.Write(destinationStream, writerParameters); } if (sourcePdbStream != null) { sourcePdbStream.Close(); destinationPdbStream.Close(); } } }
public void RewriteMdbFile (string inputAssembly) { var assemblyName = new FileInfo (inputAssembly).Name; var readParams = new ReaderParameters () { SymbolReaderProvider = new MdbReaderProvider (), ReadSymbols = true, }; var assembly = AssemblyDefinition.ReadAssembly (inputAssembly, readParams); foreach (var m in assembly.Modules) { foreach (var t in m.Types) { ProcessType (t); foreach (var inner in t.NestedTypes) ProcessType (inner); } } var writeParms = new WriterParameters () { SymbolWriterProvider = new MdbWriterProvider (), WriteSymbols = true, }; var tmpdir = Path.GetTempPath (); var tmpAsm = tmpdir + assemblyName; string finalMdb = inputAssembly + ".mdb"; if (settings.OutputDirectory != null) finalMdb = Path.Combine (settings.OutputDirectory, assemblyName) + ".mdb"; assembly.Write (tmpAsm, writeParms); Console.WriteLine (tmpAsm); File.Delete (tmpAsm); File.Delete (finalMdb); Console.WriteLine ("Moving {0} to {1}", tmpAsm + ".mdb", finalMdb); new FileInfo (tmpAsm + ".mdb").MoveTo (finalMdb); }
public CompilerResult SetSourcePathInPdbFile(string pathToAssembly, string scriptName, string scriptPath) { try { var readerParameters = new ReaderParameters { ReadSymbols = true, SymbolReaderProvider = new PdbReaderProvider() }; var assemblyDef = AssemblyDefinition.ReadAssembly(pathToAssembly, readerParameters); var moduleDefinition = assemblyDef.Modules[0]; moduleDefinition.ReadSymbols(); var type = moduleDefinition.Types.FirstOrDefault(t => t.BaseType != null && t.BaseType.Name == typeof(DualityScript).Name); if (type == null) { Log.Editor.WriteError("Script file '{0}' has to contain a class that derives from DualityScript.", scriptName); return CompilerResult.PdbEditorError; } foreach (var method in type.Methods) { var instruction = method.Body.Instructions.FirstOrDefault(i => i.SequencePoint != null); if (instruction == null) continue; instruction.SequencePoint.Document.Url = scriptPath; } var writerParameters = new WriterParameters { WriteSymbols = true, SymbolWriterProvider = new PdbWriterProvider() }; assemblyDef.Write(pathToAssembly, writerParameters); } catch (Exception exception) { Log.Editor.WriteError("There was a problem editing the pdb file after compiling the script {0}, {1} Error: {2} {1} StackTrace: {3}", scriptName,Environment.NewLine, exception.Message, exception.StackTrace); return CompilerResult.PdbEditorError; } return CompilerResult.AssemblyExists; }
public WeaverHelper(string projectPath, Action<ModuleWeaver> configure = null ) { projectPath = Path.GetFullPath(Path.Combine(Environment.CurrentDirectory, @"..\..\..\", projectPath)); var assemblyPath = GetAssemblyPath(projectPath); var newAssembly = assemblyPath.Replace(".dll", "2.dll").Replace(".exe","2.exe"); var pdbFileName = Path.ChangeExtension(assemblyPath, "pdb"); var newPdbFileName = Path.ChangeExtension(newAssembly, "pdb"); File.Copy(assemblyPath, newAssembly, true); File.Copy(pdbFileName, newPdbFileName, true); var assemblyResolver = new TestAssemblyResolver(assemblyPath, projectPath); var moduleDefinition = ModuleDefinition.ReadModule(newAssembly, new ReaderParameters {AssemblyResolver = assemblyResolver}); var weavingTask = new ModuleWeaver { ModuleDefinition = moduleDefinition, AssemblyResolver = assemblyResolver, LogInfo = Console.WriteLine, LogError = Console.Error.WriteLine }; if (configure != null) { configure(weavingTask); } weavingTask.Execute(); var writerParameters = new WriterParameters { WriteSymbols = true }; moduleDefinition.Write(newAssembly,writerParameters); Assembly = Assembly.LoadFile(newAssembly); }
public void Foo() { ModuleDefinition moduleDefinition; using (var symbolStream = File.OpenRead(@"C:\Code\containsdynamiclocals.pdb")) { var readerParameters = new ReaderParameters { ReadSymbols = true, SymbolReaderProvider = new PdbReaderProvider(), SymbolStream = symbolStream }; moduleDefinition = ModuleDefinition.ReadModule(@"C:\Code\containsdynamiclocals.dll", readerParameters); } File.Delete(@"C:\Code\containsdynamiclocals2.dll"); File.Delete(@"C:\Code\containsdynamiclocals2.pdb"); var parameters = new WriterParameters { WriteSymbols = true, SymbolWriterProvider = new PdbWriterProvider(), }; moduleDefinition.Write(@"C:\Code\containsdynamiclocals2.dll", parameters); }
public static void PatchFile( string file ) { // Copy PDB from input assembly to output assembly if any var readerParameters = new ReaderParameters(); readerParameters.AssemblyResolver = new DefaultAssemblyResolver(); var writerParameters = new WriterParameters(); string pdbName = Path.ChangeExtension( file, "pdb" ); if( File.Exists( pdbName ) ) { readerParameters.SymbolReaderProvider = new PdbReaderProvider(); readerParameters.ReadSymbols = true; writerParameters.WriteSymbols = true; } AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(file, readerParameters); TypeDefinition interopTypeDefinition = null; Console.WriteLine( "SharpDX interop patch for: " + file ); foreach( var type in assembly.MainModule.Types ) { if( type.Name == "Interop" ) { interopTypeDefinition = type; break; } } if( interopTypeDefinition == null ) { Console.WriteLine( "Nothing to do, already patched." ); return; } foreach( var type in assembly.MainModule.Types ) { PatchType( type ); } assembly.MainModule.Types.Remove( interopTypeDefinition ); assembly.Write( file, writerParameters ); Console.WriteLine( "Done patching." ); }
public static void HotfixInject(string inject_assembly_path, IEnumerable <string> search_directorys, string id_map_file_path, IEnumerable <Type> cfg_check_types = null) { AssemblyDefinition assembly = null; try { #if HOTFIX_SYMBOLS_DISABLE assembly = AssemblyDefinition.ReadAssembly(inject_assembly_path); #else var readerParameters = new ReaderParameters { ReadSymbols = true }; assembly = AssemblyDefinition.ReadAssembly(inject_assembly_path, readerParameters); #endif init(assembly, search_directorys); if (assembly.MainModule.Types.Any(t => t.Name == "__XLUA_GEN_FLAG")) { Info("had injected!"); return; } assembly.MainModule.Types.Add(new TypeDefinition("__XLUA_GEN", "__XLUA_GEN_FLAG", Mono.Cecil.TypeAttributes.Class, objType)); Config(cfg_check_types); //var hotfixDelegateAttributeType = assembly.MainModule.Types.Single(t => t.FullName == "XLua.HotfixDelegateAttribute"); hotfix_bridges = (from method in delegateBridgeType.Methods where method.Name.StartsWith("__Gen_Delegate_Imp") select method).ToList(); var hotfixAttributeType = assembly.MainModule.Types.Single(t => t.FullName == "XLua.HotfixAttribute"); foreach (var type in (from module in assembly.Modules from type in module.Types select type)) { if (!injectType(assembly, hotfixAttributeType, type)) { return; } } #if HOTFIX_SYMBOLS_DISABLE assembly.Write(inject_assembly_path); Info("hotfix inject finish!(no symbols)"); #else var writerParameters = new WriterParameters { WriteSymbols = true }; assembly.Write(inject_assembly_path, writerParameters); Directory.CreateDirectory(Path.GetDirectoryName(id_map_file_path)); OutputIntKeyMapper(new FileStream(id_map_file_path, FileMode.Create, FileAccess.Write)); File.Copy(id_map_file_path, id_map_file_path + "." + DateTime.Now.ToString("yyyyMMddHHmmssfff")); Info("hotfix inject finish!"); #endif } catch (Exception e) { Error("Exception! " + e); } finally { if (assembly != null) { Clean(assembly); } } }
static bool Weave(string assName, IEnumerable <string> dependencies, string unityEngineDLLPath, string mirrorNetDLLPath, string outputDir) { using (DefaultAssemblyResolver asmResolver = new DefaultAssemblyResolver()) using (CurrentAssembly = AssemblyDefinition.ReadAssembly(assName, new ReaderParameters { ReadWrite = true, ReadSymbols = true, AssemblyResolver = asmResolver })) { asmResolver.AddSearchDirectory(Path.GetDirectoryName(assName)); asmResolver.AddSearchDirectory(Helpers.UnityEngineDLLDirectoryName()); asmResolver.AddSearchDirectory(Path.GetDirectoryName(unityEngineDLLPath)); asmResolver.AddSearchDirectory(Path.GetDirectoryName(mirrorNetDLLPath)); if (dependencies != null) { foreach (string path in dependencies) { asmResolver.AddSearchDirectory(path); } } SetupTargetTypes(); Readers.Init(CurrentAssembly); Writers.Init(CurrentAssembly); ModuleDefinition moduleDefinition = CurrentAssembly.MainModule; Console.WriteLine("Script Module: {0}", moduleDefinition.Name); // Process each NetworkBehaviour bool didWork = false; // We need to do 2 passes, because SyncListStructs might be referenced from other modules, so we must make sure we generate them first. for (int pass = 0; pass < 2; pass++) { System.Diagnostics.Stopwatch watch = System.Diagnostics.Stopwatch.StartNew(); foreach (TypeDefinition td in moduleDefinition.Types) { if (td.IsClass && td.BaseType.CanBeResolved()) { try { if (pass == 0) { didWork |= CheckSyncList(td); } else { didWork |= CheckNetworkBehaviour(td); didWork |= CheckMessageBase(td); } } catch (Exception ex) { Weaver.Error(ex.ToString()); throw ex; } } if (WeavingFailed) { return(false); } } watch.Stop(); Console.WriteLine("Pass: "******" took " + watch.ElapsedMilliseconds + " milliseconds"); } if (didWork) { // this must be done for ALL code, not just NetworkBehaviours try { PropertySiteProcessor.ProcessSitesModule(CurrentAssembly.MainModule); } catch (Exception e) { Log.Error("ProcessPropertySites exception: " + e); return(false); } if (WeavingFailed) { //Log.Error("Failed phase II."); return(false); } // write to outputDir if specified, otherwise perform in-place write WriterParameters writeParams = new WriterParameters { WriteSymbols = true }; if (outputDir != null) { CurrentAssembly.Write(Helpers.DestinationFileFor(outputDir, assName), writeParams); } else { CurrentAssembly.Write(writeParams); } } } return(true); }
public static TestResult ExecuteTestRun( this BaseModuleWeaver weaver, string assemblyPath, bool runPeVerify = true, Action <ModuleDefinition> afterExecuteCallback = null, Action <ModuleDefinition> beforeExecuteCallback = null, string assemblyName = null, IEnumerable <string> ignoreCodes = null) { assemblyPath = Path.Combine(CodeBaseLocation.CurrentDirectory, assemblyPath); var fodyTempDir = Path.Combine(Path.GetDirectoryName(assemblyPath), "fodytemp"); Directory.CreateDirectory(fodyTempDir); IoHelper.PurgeDirectory(fodyTempDir); string targetFileName; if (assemblyName == null) { assemblyName = Path.GetFileNameWithoutExtension(assemblyPath); targetFileName = Path.GetFileName(assemblyPath); } else { targetFileName = assemblyName + ".dll"; } var targetAssemblyPath = Path.Combine(fodyTempDir, targetFileName); using (var assemblyResolver = new MockAssemblyResolver()) { var typeCache = CacheTypes(weaver, assemblyResolver); var testStatus = new TestResult(); weaver.LogDebug = text => testStatus.AddMessage(text, MessageImportanceDefaults.Debug); weaver.LogInfo = text => testStatus.AddMessage(text, MessageImportanceDefaults.Info); weaver.LogMessage = (text, messageImportance) => testStatus.AddMessage(text, messageImportance); weaver.LogWarning = text => testStatus.AddWarning(text, null); weaver.LogWarningPoint = (text, sequencePoint) => testStatus.AddWarning(text, sequencePoint); weaver.LogError = text => testStatus.AddError(text, null); weaver.LogErrorPoint = (text, sequencePoint) => testStatus.AddError(text, sequencePoint); weaver.AssemblyFilePath = assemblyPath; weaver.FindType = typeCache.FindType; weaver.TryFindType = typeCache.TryFindType; weaver.ResolveAssembly = assemblyResolver.Resolve; var readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver, SymbolReaderProvider = new SymbolReaderProvider(), ReadWrite = false, ReadSymbols = true, }; using (var module = ModuleDefinition.ReadModule(assemblyPath, readerParameters)) { module.Assembly.Name.Name = assemblyName; weaver.ModuleDefinition = module; weaver.TypeSystem = new TypeSystem(typeCache.FindType, module); beforeExecuteCallback?.Invoke(module); weaver.Execute(); ReferenceCleaner.CleanReferences(module, weaver, weaver.LogDebug); afterExecuteCallback?.Invoke(module); var writerParameters = new WriterParameters { WriteSymbols = true }; module.Write(targetAssemblyPath, writerParameters); } if (runPeVerify) { List <string> ignoreList; if (ignoreCodes == null) { ignoreList = new List <string>(); } else { ignoreList = ignoreCodes.ToList(); } ignoreList.Add("0x80070002"); PeVerifier.ThrowIfDifferent(assemblyPath, targetAssemblyPath, ignoreList, Path.GetDirectoryName(assemblyPath)); } testStatus.Assembly = Assembly.Load(File.ReadAllBytes(targetAssemblyPath)); testStatus.AssemblyPath = targetAssemblyPath; return(testStatus); } }
/// <summary> /// The actual repacking process, called by main after parsing arguments. /// When referencing this assembly, call this after setting the merge properties. /// </summary> public void Repack() { var timer = new Stopwatch(); timer.Start(); Options.Validate(); PrintRepackHeader(); _reflectionHelper = new ReflectionHelper(this); ResolveSearchDirectories(); // Read input assemblies only after all properties are set. ReadInputAssemblies(); GlobalAssemblyResolver.RegisterAssemblies(MergedAssemblies); _platformFixer = new PlatformFixer(this, PrimaryAssemblyMainModule.Runtime); _mappingHandler = new MappingHandler(); bool hadStrongName = PrimaryAssemblyDefinition.Name.HasPublicKey; ModuleKind kind = PrimaryAssemblyMainModule.Kind; if (Options.TargetKind.HasValue) { switch (Options.TargetKind.Value) { case Kind.Dll: kind = ModuleKind.Dll; break; case Kind.Exe: kind = ModuleKind.Console; break; case Kind.WinExe: kind = ModuleKind.Windows; break; } } TargetRuntime runtime = ParseTargetPlatform(); // change assembly's name to correspond to the file we create string mainModuleName = Path.GetFileNameWithoutExtension(Options.OutputFile); if (TargetAssemblyDefinition == null) { AssemblyNameDefinition asmName = Clone(PrimaryAssemblyDefinition.Name); asmName.Name = mainModuleName; TargetAssemblyDefinition = AssemblyDefinition.CreateAssembly(asmName, mainModuleName, new ModuleParameters() { Kind = kind, Architecture = PrimaryAssemblyMainModule.Architecture, AssemblyResolver = GlobalAssemblyResolver, Runtime = runtime }); } else { // TODO: does this work or is there more to do? TargetAssemblyMainModule.Kind = kind; TargetAssemblyMainModule.Runtime = runtime; TargetAssemblyDefinition.Name.Name = mainModuleName; TargetAssemblyMainModule.Name = mainModuleName; } // set the main module attributes TargetAssemblyMainModule.Attributes = PrimaryAssemblyMainModule.Attributes; #if !NETSTANDARD TargetAssemblyMainModule.Win32ResourceDirectory = MergeWin32Resources(PrimaryAssemblyMainModule.Win32ResourceDirectory); #endif if (Options.Version != null) { TargetAssemblyDefinition.Name.Version = Options.Version; } _lineIndexer = new IKVMLineIndexer(this, Options.LineIndexation); var signingStep = new SigningStep(this, Options); var isUnixEnvironment = Environment.OSVersion.Platform == PlatformID.MacOSX || Environment.OSVersion.Platform == PlatformID.Unix; using (var sourceServerDataStep = GetSourceServerDataStep(isUnixEnvironment)) { List <IRepackStep> repackSteps = new List <IRepackStep> { signingStep, new ReferencesRepackStep(Logger, this), new TypesRepackStep(Logger, this, _repackImporter, Options), new ResourcesRepackStep(Logger, this, Options), new AttributesRepackStep(Logger, this, _repackImporter, Options), new ReferencesFixStep(Logger, this, _repackImporter, Options), new XamlResourcePathPatcherStep(Logger, this), sourceServerDataStep }; foreach (var step in repackSteps) { step.Perform(); } var parameters = new WriterParameters { #if !NETSTANDARD StrongNameKeyPair = signingStep.KeyPair, #endif WriteSymbols = Options.DebugInfo, }; // create output directory if it does not exist var outputDir = Path.GetDirectoryName(Options.OutputFile); if (!string.IsNullOrEmpty(outputDir) && !Directory.Exists(outputDir)) { Logger.Info("Output directory does not exist. Creating output directory: " + outputDir); Directory.CreateDirectory(outputDir); } TargetAssemblyDefinition.Write(Options.OutputFile, parameters); sourceServerDataStep.Write(); Logger.Info("Writing output assembly to disk"); // If this is an executable and we are on linux/osx we should copy file permissions from // the primary assembly if (hadStrongName && !TargetAssemblyDefinition.Name.HasPublicKey) { Options.StrongNameLost = true; } // nice to have, merge .config (assembly configuration file) & .xml (assembly documentation) ConfigMerger.Process(this); if (Options.XmlDocumentation) { DocumentationMerger.Process(this); } } Logger.Info($"Finished in {timer.Elapsed}"); }
private IEnumerable <Output> DoInject( string assemblyFile, string typeName, string methodName, string strongNameKeyPair, string[] assemblySearchDirs) { OutputCollection outputCollection = new OutputCollection(); try { if (String.IsNullOrWhiteSpace(assemblyFile)) { outputCollection.Add(OutputImportance.Error, "Must specify a valid assembly."); return(outputCollection); } if (String.IsNullOrWhiteSpace(typeName)) { typeName = "ModuleInitializer"; } if (String.IsNullOrWhiteSpace(methodName)) { methodName = "Initialize"; } StrongNameKeyPair snkpair; if (!String.IsNullOrWhiteSpace(strongNameKeyPair)) { if (!File.Exists(strongNameKeyPair)) { outputCollection.Add( OutputImportance.Error, "The '{0}' strong name keypair was not found.", strongNameKeyPair); return(outputCollection); } // Accessing public key requires UnmanagedCode security permission. try { SecurityPermission sp = new SecurityPermission(SecurityPermissionFlag.UnmanagedCode); sp.Demand(); } catch (Exception e) { outputCollection.Add( OutputImportance.Error, "Could not instrument '{0}' as cannot resign assembly, UnmanagedCode security permission denied.", strongNameKeyPair, e.Message); return(outputCollection); } try { /* * Turns out that if we get the strong name key pair directly using the StrongNameKeyPair(string filename) * constructor overload, then retrieving the public key fails due to file permissions. * Opening the filestream ourselves with read access, and reading the snk that way works, and allows * us to successfully resign (who knew?). */ using (FileStream fs = new FileStream(strongNameKeyPair, FileMode.Open, FileAccess.Read)) snkpair = new StrongNameKeyPair(fs); // Ensure we can access public key - this will be done by mono later so check works now. // ReSharper disable once UnusedVariable byte[] publicKey = snkpair.PublicKey; } catch (Exception e) { outputCollection.Add( OutputImportance.Error, "Error occurred whilst accessing public key from '{0}' strong name keypair. {1}", strongNameKeyPair, e.Message); return(outputCollection); } } else { // No resigning necessary. snkpair = null; } if (!File.Exists(assemblyFile)) { outputCollection.Add(OutputImportance.Error, "The '{0}' assembly was not found.", assemblyFile); return(outputCollection); } // Look for PDB file. string pdbFile = Path.ChangeExtension(assemblyFile, ".pdb"); // Create resolver for assemblies DefaultAssemblyResolver asmResolver = new DefaultAssemblyResolver(); // Add the search directories to the resolver string assemblyDir = Path.GetDirectoryName(Path.GetFullPath(assemblyFile)); asmResolver.AddSearchDirectory(Path.GetFullPath(assemblyDir)); foreach (string dir in assemblySearchDirs.Select(Path.GetFullPath).Distinct()) { if (!string.Equals(dir, assemblyDir)) { asmResolver.AddSearchDirectory(dir); } } // Read the assembly definition ReaderParameters readParams = new ReaderParameters(ReadingMode.Immediate); readParams.AssemblyResolver = asmResolver; bool hasPdb = false; if (File.Exists(pdbFile)) { readParams.ReadSymbols = true; readParams.SymbolReaderProvider = new PdbReaderProvider(); hasPdb = true; } AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(assemblyFile, readParams); if (assembly == null) { outputCollection.Add( OutputImportance.Error, "Failed to load assembly definition for '{0}'.", assemblyFile); return(outputCollection); } // Find the main module. ModuleDefinition module = assembly.MainModule; if (module == null) { outputCollection.Add( OutputImportance.Error, "Failed to load main module definition from assembly '{0}'.", assemblyFile); return(outputCollection); } if (module.Types == null) { outputCollection.Add( OutputImportance.Error, "Failed to load main module types from assembly '{0}'.", assemblyFile); return(outputCollection); } // Find the <Module> type definition // ReSharper disable once PossibleNullReferenceException TypeDefinition moduleType = module.Types.SingleOrDefault(t => t.Name == "<Module>"); if (moduleType == null) { outputCollection.Add( OutputImportance.Error, "Could not find type '<Module>' in assembly '{0}'.", assemblyFile); return(outputCollection); } // Find void type // ReSharper disable once PossibleNullReferenceException TypeReference voidRef = module.TypeSystem.Void; if (voidRef == null) { outputCollection.Add( OutputImportance.Error, "Could not find type 'void' in assembly '{0}'.", assemblyFile); return(outputCollection); } // Find the type definition // ReSharper disable once PossibleNullReferenceException TypeDefinition typeDefinition = module.Types.SingleOrDefault(t => t.Name == typeName); if (typeDefinition == null) { outputCollection.Add( OutputImportance.Warning, "Could not find type '{0}' in assembly '{1}'.", typeName, assemblyFile); return(outputCollection); } // Find the method MethodDefinition callee = typeDefinition.Methods != null ? typeDefinition.Methods.FirstOrDefault( // ReSharper disable PossibleNullReferenceException m => m.Name == methodName && m.Parameters.Count == 0) // ReSharper restore PossibleNullReferenceException : null; if (callee == null) { outputCollection.Add( OutputImportance.Warning, "Could not find method '{0}' with no parameters in type '{1}' in assembly '{2}'.", methodName, typeName, assemblyFile); return(outputCollection); } if (callee.IsPrivate) { outputCollection.Add( OutputImportance.Error, "Method '{0}' in type '{1}' in assembly '{2}' cannot be private as it can't be accessed by the Module Initializer.", methodName, typeName, assemblyFile); return(outputCollection); } if (!callee.IsStatic) { outputCollection.Add( OutputImportance.Error, "Method '{0}' in type '{1}' in assembly '{2}' cannot be an instance method as it can't be instantiated by the Module Initializer.", methodName, typeName, assemblyFile); return(outputCollection); } outputCollection.Add( OutputImportance.MessageHigh, "Method '{0}' in type '{1}' in assembly '{2}' will be called during Module initialization.", methodName, typeName, assemblyFile); // Create the module initializer. MethodDefinition cctor = new MethodDefinition( ".cctor", MethodAttributes.Static | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName, voidRef); // ReSharper disable PossibleNullReferenceException ILProcessor il = cctor.Body.GetILProcessor(); il.Append(il.Create(OpCodes.Call, callee)); il.Append(il.Create(OpCodes.Ret)); moduleType.Methods.Add(cctor); // ReSharper restore PossibleNullReferenceException WriterParameters writeParams = new WriterParameters(); if (hasPdb) { writeParams.WriteSymbols = true; writeParams.SymbolWriterProvider = new PdbWriterProvider(); } if (snkpair != null) { writeParams.StrongNameKeyPair = snkpair; outputCollection.Add( OutputImportance.MessageHigh, "Assembly '{0}' is being resigned by '{1}'.", assemblyFile, strongNameKeyPair); } else { outputCollection.Add( OutputImportance.MessageHigh, "Assembly '{0}' will not be resigned.", assemblyFile); } assembly.Write(assemblyFile, writeParams); return(outputCollection); } catch (Exception ex) { outputCollection.Add(OutputImportance.Error, "An unexpected error occurred. {0}", ex.Message); return(outputCollection); } }
static void RewriteAssembly(string assemblyLocation, Dictionary <string, string> resourcesStrings, CmdOptions options) { Stream pdbSymbols = null; var debugSymbols = Path.ChangeExtension(assemblyLocation, "pdb"); if (File.Exists(debugSymbols)) { pdbSymbols = File.Open(debugSymbols, FileMode.Open, FileAccess.ReadWrite); } var readerParameters = new ReaderParameters { ReadWrite = true, }; if (pdbSymbols != null) { readerParameters.ReadSymbols = true; readerParameters.SymbolReaderProvider = new PortablePdbReaderProvider(); readerParameters.SymbolStream = pdbSymbols; } using (var assembly = AssemblyDefinition.ReadAssembly(assemblyLocation, readerParameters)) { foreach (var module in assembly.Modules) { foreach (var type in module.GetTypes()) { foreach (var method in type.Methods) { if (!method.HasBody) { continue; } foreach (var instr in method.Body.Instructions) { if (instr.OpCode != OpCodes.Ldstr) { continue; } string value; if (resourcesStrings.TryGetValue((string)instr.Operand, out value)) { if (options.Verbose) { Console.WriteLine($"Replacing '{instr.Operand}' with '{value}'"); } instr.Operand = value; } } } } } var writerParameters = new WriterParameters(); if (pdbSymbols != null) { writerParameters.WriteSymbols = true; writerParameters.SymbolStream = pdbSymbols; writerParameters.SymbolWriterProvider = new PortablePdbWriterProvider(); pdbSymbols.Seek(0, SeekOrigin.Begin); } assembly.Write(writerParameters); } pdbSymbols?.Dispose(); }
public override bool RunTask() { if (SourceFiles.Length != DestinationFiles.Length) { throw new ArgumentException("source and destination count mismatch"); } var readerParameters = new ReaderParameters { ReadSymbols = true, }; var writerParameters = new WriterParameters { DeterministicMvid = Deterministic, }; var hasSystemPrivateCorelib = false; using (var resolver = new DirectoryAssemblyResolver(this.CreateTaskLogger(), loadDebugSymbols: true, loadReaderParameters: readerParameters)) { // Add SearchDirectories with ResolvedAssemblies foreach (var assembly in ResolvedAssemblies) { var path = Path.GetFullPath(Path.GetDirectoryName(assembly.ItemSpec)); if (Path.GetFileName(assembly.ItemSpec).Equals("System.Private.CoreLib.dll", StringComparison.OrdinalIgnoreCase)) { hasSystemPrivateCorelib = true; } if (!resolver.SearchDirectories.Contains(path)) { resolver.SearchDirectories.Add(path); } } // Set up the FixAbstractMethodsStep var step1 = new FixAbstractMethodsStep(resolver, new TypeDefinitionCache(), Log); // Set up the AddKeepAlivesStep var step2 = new AddKeepAlivesStep(resolver, new TypeDefinitionCache(), Log, hasSystemPrivateCorelib); for (int i = 0; i < SourceFiles.Length; i++) { var source = SourceFiles [i]; var destination = DestinationFiles [i]; AssemblyDefinition assemblyDefinition = null; var assemblyName = Path.GetFileNameWithoutExtension(source.ItemSpec); if (!MTProfile.IsSdkAssembly(assemblyName) && !MTProfile.IsProductAssembly(assemblyName)) { assemblyDefinition = resolver.GetAssembly(source.ItemSpec); step1.CheckAppDomainUsage(assemblyDefinition, (string msg) => Log.LogMessageFromText(msg, MessageImportance.High)); } // Only run the step on "MonoAndroid" assemblies if (MonoAndroidHelper.IsMonoAndroidAssembly(source) && !MonoAndroidHelper.IsSharedRuntimeAssembly(source.ItemSpec)) { if (assemblyDefinition == null) { assemblyDefinition = resolver.GetAssembly(source.ItemSpec); } if (step1.FixAbstractMethods(assemblyDefinition) || (AddKeepAlives && step2.AddKeepAlives(assemblyDefinition))) { Log.LogDebugMessage($"Saving modified assembly: {destination.ItemSpec}"); writerParameters.WriteSymbols = assemblyDefinition.MainModule.HasSymbols; assemblyDefinition.Write(destination.ItemSpec, writerParameters); continue; } } if (MonoAndroidHelper.CopyAssemblyAndSymbols(source.ItemSpec, destination.ItemSpec)) { Log.LogDebugMessage($"Copied: {destination.ItemSpec}"); } else { Log.LogDebugMessage($"Skipped unchanged file: {destination.ItemSpec}"); // NOTE: We still need to update the timestamp on this file, or this target would run again File.SetLastWriteTimeUtc(destination.ItemSpec, DateTime.UtcNow); } } } return(!Log.HasLoggedErrors); }
/// <summary> /// Patches the file. /// </summary> /// <param name="file">The file.</param> public bool PatchFile(string file) { file = Path.Combine(Environment.CurrentDirectory, file); var bak_bytes = File.ReadAllBytes(file); var fileTime = new FileTime(file); //var fileTimeInteropBuilder = new FileTime(Assembly.GetExecutingAssembly().Location); string checkFile = Path.GetFullPath(file) + ".check"; //string checkInteropBuilderFile = "InteropBuild.check"; // If checkFile and checkInteropBuilderFile up-to-date, then nothing to do if (fileTime.CheckFileUpToDate(checkFile)) { Log("Nothing to do. SharpDX patch was already applied for assembly [{0}]", file); return(false); } // Copy PDB from input assembly to output assembly if any var readerParameters = new ReaderParameters(); var resolver = new DefaultAssemblyResolver(); readerParameters.AssemblyResolver = resolver; var writerParameters = new WriterParameters(); var pdbName = Path.ChangeExtension(file, "pdb"); if (File.Exists(pdbName)) { var symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; readerParameters.ReadSymbols = true; writerParameters.WriteSymbols = true; } // Read Assembly assembly = AssemblyDefinition.ReadAssembly(file, readerParameters); resolver.AddSearchDirectory(Path.GetDirectoryName(file)); // Query the target framework in order to resolve correct assemblies and type forwarding var targetFrameworkAttr = assembly.CustomAttributes.FirstOrDefault( attribute => attribute.Constructor.FullName.Contains("System.Runtime.Versioning.TargetFrameworkAttribute")); if (targetFrameworkAttr != null && targetFrameworkAttr.ConstructorArguments.Count > 0 && targetFrameworkAttr.ConstructorArguments[0].Value != null) { var targetFramework = new FrameworkName(targetFrameworkAttr.ConstructorArguments[0].Value.ToString()); var netcoreAssemblyPath = string.Format(@"Reference Assemblies\Microsoft\Framework\{0}\v{1}", targetFramework.Identifier, targetFramework.Version); netcoreAssemblyPath = Path.Combine(ProgramFilesx86(), netcoreAssemblyPath); if (Directory.Exists(netcoreAssemblyPath)) { resolver.AddSearchDirectory(netcoreAssemblyPath); } } // Import void* and int32 voidType = assembly.MainModule.TypeSystem.Void.Resolve(); voidPointerType = new PointerType(assembly.MainModule.Import(voidType)); intType = assembly.MainModule.Import(assembly.MainModule.TypeSystem.Int32.Resolve()); // Import SharpDX.Utilities::SizeOf<T> sizeofMethod = assembly.MainModule.Types.First(type => type.Name == "Utilities" && type.Namespace == "SharpDX").Methods.First(method => method.Name == "SizeOf"); // Remove CompilationRelaxationsAttribute for (int i = 0; i < assembly.CustomAttributes.Count; i++) { var customAttribute = assembly.CustomAttributes[i]; if (customAttribute.AttributeType.FullName == typeof(CompilationRelaxationsAttribute).FullName) { assembly.CustomAttributes.RemoveAt(i); i--; } } Log("SharpDX interop patch for assembly [{0}]", file); foreach (var type in assembly.MainModule.Types) { PatchType(type); } // Remove All Interop classes foreach (var type in classToRemoveList) { assembly.MainModule.Types.Remove(type); } var outputFilePath = file; try { assembly.Write(outputFilePath, writerParameters); } catch (Exception) { File.WriteAllBytes(file, bak_bytes); throw; } fileTime = new FileTime(file); // Update Check file fileTime.UpdateCheckFile(checkFile); //fileTimeInteropBuilder.UpdateCheckFile(checkInteropBuilderFile); Log("SharpDX patch done for assembly [{0}]", file); return(true); }
public static void MethodInstrument(string targetAssembly, string src, string dst) { var inputAssembly = targetAssembly; var path = Path.GetDirectoryName(inputAssembly); var assemblyResolver = new DefaultAssemblyResolver(); var assemblyLocation = Path.GetDirectoryName(inputAssembly); assemblyResolver.AddSearchDirectory(assemblyLocation); var readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver }; var writerParameters = new WriterParameters(); var origPdb = Path.ChangeExtension(inputAssembly, "pdb"); bool existpdb = false; if (File.Exists(origPdb)) { existpdb = true; var symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; readerParameters.ReadSymbols = true; //var symbolWriterProvider = new PdbWriterProvider(); //writerParameters.SymbolWriterProvider = symbolWriterProvider; writerParameters.WriteSymbols = true; } else { Logger.Debug(".pdb file is unavailable."); } var assemblyDefinition = AssemblyDefinition.ReadAssembly(inputAssembly, readerParameters); var module = assemblyDefinition.MainModule; //Mono.Collections.Generic.Collection<ModuleDefinition> modules = assemblyDefinition.Modules; //var module2 = ModuleDefinition.ReadModule(inputAssembly, readerParameters); //---------------------- bool isChanged = false; //---------------------------- foreach (var typeDefinition in module.Types) { if (typeDefinition.IsInterface) { continue; } foreach (var methodDefinition in typeDefinition.Methods) { ILProcessor ilprocessor = methodDefinition.Body.GetILProcessor(); Mono.Collections.Generic.Collection <Mono.Cecil.Cil.Instruction> allinstructions = methodDefinition.Body.Instructions; int instructioncnt = allinstructions.Count; for (int i = 0; i < instructioncnt; i++) { Mono.Cecil.Cil.Instruction instruction = allinstructions[i]; string instructpresent = instruction.ToString(); OpCode code = instruction.OpCode; string codepresent = code.Name; var operand = instruction.Operand; string methodname = ""; if (operand != null) { methodname = operand.ToString(); //with parameter } if ((code == OpCodes.Callvirt || code == OpCodes.Call) && //codepresent.Contains("call") (isSameMethod(methodname, src))) //or (operand as MethodReference == module.Import(src as MethodInfo)) { Logger.Debug(codepresent + " " + methodname); //debug //---------------------- remove --------------------------// /**** remove instruction in case of no replacing method is provided ****/ //TODO: 1. I note the stack depth after the call and start removing instructions, beginning with the Code.Call // and moving backward until I get to that stack depth again. // 2. return value handling ilprocessor.Remove(instruction); instructioncnt--; if (allinstructions[i].OpCode == OpCodes.Pop) //TODO: just for test { ilprocessor.Remove(allinstructions[i]); instructioncnt--; } i--; if (dst == "") { continue; } //---------------------- replace (remove + insert) ------------------------// /**** create new MethodInfo ****/ string m_type = getNamespace(dst); string m_name = getMethodName(dst); string [] m_para = getParameters(dst); MethodInfo writeLineMethod; //e.g. MethodInfo writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }); if (m_para != null) { int paraCnt = m_para.Length; Type[] m_para_type = new Type[paraCnt]; for (int k = 0; k < paraCnt; k++) { m_para_type[k] = Type.GetType(m_para[k]); } writeLineMethod = Type.GetType(m_type).GetMethod(m_name, m_para_type); } else //the method does not have input parameters { writeLineMethod = Type.GetType(m_type).GetMethod(m_name, new Type[] { }); } if (writeLineMethod == null) { throw new InvalidFileFormatException("no MethodInfo is created -- possibly a wrong method delaration."); } /*** Import the new (e.g. Console.WriteLine() method) ***/ MethodReference writeLine; writeLine = module.Import(writeLineMethod); //convert "MethodInfo/MethodDefinition" to "MethodReference" /*** Creates the CIL instruction for calling the new method (e.g. Console.WriteLine(string value) method) ***/ Mono.Cecil.Cil.Instruction callWriteLine; callWriteLine = ilprocessor.Create(OpCodes.Call, writeLine); /*** replace old instruction ***/ //TODO: 1. for simple-type parameters, create one instance and push to stack; // otherwise just a null object?!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! // 2. return value handling ilprocessor.InsertAfter(allinstructions[i], callWriteLine); //----------------------------------------------// isChanged = true; } } //foreach instruction of a method } //foreach method of a type/class } //foreach type/class of loaded assembly if (isChanged) { var temporaryFileName = Path.Combine(path, string.Format("{0}_temp{1}", Path.GetFileNameWithoutExtension(inputAssembly), Path.GetExtension(inputAssembly))); var backupFileName = Path.Combine(path, string.Format("{0}_orig{1}", Path.GetFileNameWithoutExtension(inputAssembly), Path.GetExtension(inputAssembly))); var tmpPdb = Path.Combine(path, string.Format("{0}_temp{1}", Path.GetFileNameWithoutExtension(inputAssembly), ".pdb")); var backupPdb = Path.Combine(path, string.Format("{0}_orig{1}", Path.GetFileNameWithoutExtension(inputAssembly), ".pdb")); //write an assembly with symbol file being rewritten //module.Write(temporaryFileName, writerParameters); assemblyDefinition.Write(temporaryFileName, writerParameters); File.Replace(temporaryFileName, inputAssembly, backupFileName); if (existpdb) { File.Replace(tmpPdb, origPdb, backupPdb); } //TODO: add snkfile in configuration file and parse ([email protected]) // If you have access to the key pair, you can ask Cecil to sign it directly. //if (snkFile != "") //{ //sn -R inputAssembly snkFile //} } }
public void Write(Stream stream, WriterParameters parameters) { main_module.Write(stream, parameters); }
static void Main(string[] args) { string input = null; string output = null; string keyPairContainer = null; var options = new Mono.Options.OptionSet() { { "i|input=", i => input = i }, { "o|output:", o => output = o }, { "k|key:", k => keyPairContainer = k }, }; try { var extra = options.Parse(args); var pdb = Path.ChangeExtension(input, "pdb"); var mdb = Path.ChangeExtension(input, "mdb"); ISymbolReaderProvider provider = null; if (File.Exists(pdb)) { provider = new Mono.Cecil.Pdb.PdbReaderProvider(); } else if (File.Exists(mdb)) { provider = new Mono.Cecil.Mdb.MdbReaderProvider(); } var assemblyResolver = new DefaultAssemblyResolver(); assemblyResolver.AddSearchDirectory(System.IO.Path.GetDirectoryName(input)); var readParameters = new ReaderParameters() { AssemblyResolver = assemblyResolver, ReadingMode = ReadingMode.Immediate, ReadSymbols = true, SymbolReaderProvider = provider, }; var writeParameters = new WriterParameters() { WriteSymbols = true, }; if (keyPairContainer != null) { writeParameters.StrongNameKeyPair = new System.Reflection.StrongNameKeyPair(keyPairContainer); } if (output == null) { output = input; } Console.WriteLine("CilTK Rewriter"); Console.WriteLine("Reading assembly from {0}", input); Console.WriteLine("Writing assembly to {0}", output); InputAssembly = input; var assembly = Mono.Cecil.AssemblyDefinition.ReadAssembly(input, readParameters); var labelReplace = new LabelReplacer(); labelReplace.Visit(assembly); var infoReplace = new InfoReplacer(); infoReplace.Visit(assembly); var cilReplacer = new CilReplacer(labelReplace); cilReplacer.Visit(assembly); //remove references to Silk foreach (var module in assembly.Modules) { int index = -1; for (int i = 0; i < module.AssemblyReferences.Count; ++i) { if (module.AssemblyReferences[i].Name == "Silk") { index = i; break; } } if (index != -1) { module.AssemblyReferences.RemoveAt(index); } } //write to a temp file then copy to output to assist with debugging var temp = System.IO.Path.GetTempFileName(); assembly.Write(temp, writeParameters); System.IO.File.Copy(temp, output, true); } catch (Mono.Options.OptionException) { options.WriteOptionDescriptions(Console.Out); System.Environment.Exit(1); } }
public override bool RunTask() { if (SourceFiles.Length != DestinationFiles.Length) { throw new ArgumentException("source and destination count mismatch"); } var readerParameters = new ReaderParameters { ReadSymbols = true, }; var writerParameters = new WriterParameters { DeterministicMvid = true, }; using (var resolver = new DirectoryAssemblyResolver(this.CreateTaskLogger(), loadDebugSymbols: true, loadReaderParameters: readerParameters)) { // Add SearchDirectories with ResolvedAssemblies foreach (var assembly in ResolvedAssemblies) { var path = Path.GetFullPath(Path.GetDirectoryName(assembly.ItemSpec)); if (!resolver.SearchDirectories.Contains(path)) { resolver.SearchDirectories.Add(path); } } // Run the FixAbstractMethodsStep var step = new FixAbstractMethodsStep(resolver, Log); for (int i = 0; i < SourceFiles.Length; i++) { var source = SourceFiles [i]; var destination = DestinationFiles [i]; // Only run the step on "MonoAndroid" assemblies if (MonoAndroidHelper.IsMonoAndroidAssembly(source) && !MonoAndroidHelper.IsSharedRuntimeAssembly(source.ItemSpec)) { var assemblyDefinition = resolver.GetAssembly(source.ItemSpec); if (step.FixAbstractMethods(assemblyDefinition)) { Log.LogDebugMessage($"Saving modified assembly: {destination.ItemSpec}"); writerParameters.WriteSymbols = assemblyDefinition.MainModule.HasSymbols; assemblyDefinition.Write(destination.ItemSpec, writerParameters); continue; } } if (MonoAndroidHelper.CopyAssemblyAndSymbols(source.ItemSpec, destination.ItemSpec)) { Log.LogDebugMessage($"Copied: {destination.ItemSpec}"); } else { Log.LogDebugMessage($"Skipped unchanged file: {destination.ItemSpec}"); // NOTE: We still need to update the timestamp on this file, or this target would run again File.SetLastWriteTimeUtc(destination.ItemSpec, DateTime.UtcNow); } } } return(!Log.HasLoggedErrors); }
static bool Weave(string assName, IEnumerable <string> dependencies, string unityEngineDLLPath, string mirrorNetDLLPath, string outputDir) { using (DefaultAssemblyResolver asmResolver = new DefaultAssemblyResolver()) using (CurrentAssembly = AssemblyDefinition.ReadAssembly(assName, new ReaderParameters { ReadWrite = true, ReadSymbols = true, AssemblyResolver = asmResolver })) { asmResolver.AddSearchDirectory(Path.GetDirectoryName(assName)); asmResolver.AddSearchDirectory(Helpers.UnityEngineDllDirectoryName()); asmResolver.AddSearchDirectory(Path.GetDirectoryName(unityEngineDLLPath)); asmResolver.AddSearchDirectory(Path.GetDirectoryName(mirrorNetDLLPath)); if (dependencies != null) { foreach (string path in dependencies) { asmResolver.AddSearchDirectory(path); } } SetupTargetTypes(); System.Diagnostics.Stopwatch rwstopwatch = System.Diagnostics.Stopwatch.StartNew(); ReaderWriterProcessor.ProcessReadersAndWriters(CurrentAssembly); rwstopwatch.Stop(); Console.WriteLine("Find all reader and writers took " + rwstopwatch.ElapsedMilliseconds + " milliseconds"); ModuleDefinition moduleDefinition = CurrentAssembly.MainModule; Console.WriteLine("Script Module: {0}", moduleDefinition.Name); bool modified = WeaveModule(moduleDefinition); if (WeavingFailed) { return(false); } if (modified) { // this must be done for ALL code, not just NetworkBehaviours try { PropertySiteProcessor.ProcessSitesModule(CurrentAssembly.MainModule); } catch (Exception e) { Log.Error("ProcessPropertySites exception: " + e); return(false); } if (WeavingFailed) { return(false); } // write to outputDir if specified, otherwise perform in-place write WriterParameters writeParams = new WriterParameters { WriteSymbols = true }; if (outputDir != null) { CurrentAssembly.Write(Helpers.DestinationFileFor(outputDir, assName), writeParams); } else { CurrentAssembly.Write(writeParams); } } } return(true); }
public void InjectAssembly(string dllPath, string delegatePath, bool isWriteName) { m_IsWriteName = isWriteName; var readerParameters = new ReaderParameters { ReadSymbols = false }; AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(dllPath, readerParameters); m_NameLines.Clear(); foreach (var module in assembly.Modules) { List <TypeDefinition> types = module.Types.ToList(); TypeDefinition FunctionDelegate = types.Find((td) => { return(td.FullName.Contains("LCLFunctionDelegate")); }); if (FunctionDelegate != null) { m_DelegateFunctions = FunctionDelegate.NestedTypes.ToList().FindAll((_type) => { string name = _type.BaseType.Name; return(name == typeof(Delegate).Name || name == typeof(MulticastDelegate).Name); }); if (m_DelegateFunctions != null && m_DelegateFunctions.Count > 0) { break; } } } foreach (var module in assembly.Modules) { List <TypeDefinition> types = module.Types.ToList(); m_FieldDelegateNameTD = types.Find((td) => { return(td.FullName.Contains("LCLFieldDelegateName")); }); if (m_FieldDelegateNameTD != null) { break; } } foreach (var module in assembly.Modules) { foreach (var typ in module.Types) { if (typ.Namespace == null || !typ.Namespace.Contains("LCL")) { continue; } if (isWriteName) { if (!Filter.FilterType(typ)) { continue; } } foreach (var method in typ.Methods) { if (isWriteName) { if (!Filter.FilterMethod(method)) { continue; } } InjectMethod(typ, method); } } } if (!isWriteName) { var writerParameters = new WriterParameters { WriteSymbols = true }; assembly.Write(dllPath, writerParameters); if (assembly.MainModule.SymbolReader != null) { assembly.MainModule.SymbolReader.Dispose(); } } else { ILName.WritedFieldDelegateName(delegatePath, m_NameLines); } }
private static void TryWeaveAssembly(string assPath) { //check if assembly is editor only for applying the InitializeOnLoadMethodAttribute method instead of RuntimeInitializeOnLoadMethodAttribute. //used mainly assemblies that run tests. bool isEditor = CompilationPipeline.GetAssemblies().Any(a => a.flags == AssemblyFlags.EditorAssembly && assPath.EndsWith(a.outputPath)); using (var assembly = AssemblyDefinition.ReadAssembly(assPath, new ReaderParameters() { ReadWrite = true, ReadingMode = ReadingMode.Immediate, AssemblyResolver = new DefaultAssemblyResolver(), SymbolReaderProvider = new PdbReaderProvider(), //need to keep it in memory so we can write it back to the file. Otherwise it throws a sharing violation. InMemory = true, ReadSymbols = true })) { var sourceModule = assembly.MainModule; var injectionModule = assembly.MainModule; var attributeType = isEditor ? typeof(InitializeOnLoadMethodAttribute) : typeof(RuntimeInitializeOnLoadMethodAttribute); var construction = injectionModule.ImportReference(attributeType.GetConstructor(Type.EmptyTypes)); var customAttribute = new CustomAttribute(injectionModule.ImportReference(construction)); var containerParameter = new ParameterDefinition("container", ParameterAttributes.None, injectionModule.ImportReference(typeof(Container))); var constructorTypes = new List <TypeDefinition>(); var injectionTypes = new List <TypeDefinition>(); foreach (var type in sourceModule.GetTypes()) { var injectRef = sourceModule.ImportReference(typeof(InjectAttribute)); if (NeedsConstructor(type, injectRef)) { constructorTypes.Add(type); Debug.Log($"Baking Factory for type: {type.FullName}"); } if (NeedsFields(type, injectRef)) { injectionTypes.Add(type); Debug.Log($"Baking Injector for type: {type.FullName}"); } } if (constructorTypes.Count > 0) { var injectAttributeRef = injectionModule.ImportReference(typeof(InjectAttribute)); var factoryMethods = new List <KeyValuePair <TypeReference, MethodDefinition> >(); var injectionMethods = new List <KeyValuePair <TypeReference, MethodDefinition> >(); //type where all static injection baking processing is done. var typeAdder = new TypeDefinition("Injection", "Baker", TypeAttributes.Class | TypeAttributes.Public, injectionModule.TypeSystem.Object); injectionModule.Types.Add(typeAdder); //method where all registration is done. var bakerMethod = new MethodDefinition("BakeInjection", MethodAttributes.Static | MethodAttributes.Private | MethodAttributes.HideBySig, injectionModule.TypeSystem.Void); typeAdder.Methods.Add(bakerMethod); //create factories for constructor marked with the inject attribute. foreach (var type in constructorTypes) { ExposeType(type); var typeRef = injectionModule.ImportReference(type); var factoryMethod = new MethodDefinition(type.Name + "FactoryMethod", MethodAttributes.Static | MethodAttributes.Assembly, injectionModule.TypeSystem.Object); factoryMethod.Parameters.Add(containerParameter); type.Methods.Add(factoryMethod); CreateFactoryMethodBody(factoryMethod, type, injectionModule, injectAttributeRef); factoryMethods.Add(new KeyValuePair <TypeReference, MethodDefinition>(typeRef, factoryMethod)); } //create injection static methods that resolve each field marked with inject attribute. foreach (var type in injectionTypes) { ExposeType(type); var typeRef = injectionModule.ImportReference(type); var injectionMethod = new MethodDefinition(type.Name + "InjectionMethod", MethodAttributes.Static | MethodAttributes.Assembly, injectionModule.TypeSystem.Void); injectionMethod.Parameters.Add(new ParameterDefinition("instance", ParameterAttributes.None, injectionModule.TypeSystem.Object)); injectionMethod.Parameters.Add(containerParameter); type.Methods.Add(injectionMethod); CreateInjectionMethodBody(injectionMethod, type, injectionModule, injectAttributeRef); injectionMethods.Add(new KeyValuePair <TypeReference, MethodDefinition>(typeRef, injectionMethod)); } CreateBakeMethodBody(bakerMethod, factoryMethods, injectionMethods, injectionModule); bakerMethod.CustomAttributes.Add(customAttribute); var writeParams = new WriterParameters() { //write symbols for debugging to work WriteSymbols = true, SymbolWriterProvider = new PdbWriterProvider() }; assembly.Write(assPath, writeParams); } } }
void Rewrite(string file, string keyfile, IEnumerable <string> options) { // Specify assembly read and write parameters // We want to keep a valid symbols file (pdb or mdb) var read_params = new ReaderParameters(); var write_params = new WriterParameters(); var pdb = Path.ChangeExtension(file, "pdb"); var mdb = Path.ChangeExtension(file, "mdb"); ISymbolReaderProvider provider = null; if (File.Exists(pdb)) { provider = new Mono.Cecil.Pdb.PdbReaderProvider(); } else if (File.Exists(mdb)) { provider = new Mono.Cecil.Mdb.MdbReaderProvider(); } read_params.SymbolReaderProvider = provider; read_params.ReadSymbols = true; write_params.WriteSymbols = true; if (!String.IsNullOrEmpty(keyfile) && File.Exists(keyfile)) { keyfile = Path.GetFullPath(keyfile); var fs = new FileStream(keyfile, FileMode.Open); var keypair = new System.Reflection.StrongNameKeyPair(fs); fs.Close(); write_params.StrongNameKeyPair = keypair; } else { Console.Error.WriteLine("No keyfile specified or keyfile missing."); } // Load assembly and process all modules var assembly = AssemblyDefinition.ReadAssembly(file, read_params); var rewritten = assembly.CustomAttributes.FirstOrDefault(a => a.AttributeType.Name == "RewrittenAttribute"); if (rewritten == null) { foreach (var module in assembly.Modules) { foreach (var reference in module.AssemblyReferences) { var resolved = module.AssemblyResolver.Resolve(reference); if (reference.Name == "mscorlib") { mscorlib = resolved; } } } if (mscorlib == null) { Console.Error.WriteLine("Failed to locate mscorlib"); return; } TypeMarshal = mscorlib.MainModule.GetType("System.Runtime.InteropServices.Marshal"); TypeStringArray = mscorlib.MainModule.GetType("System.String").MakeArrayType().Resolve(); TypeStringBuilder = mscorlib.MainModule.GetType("System.Text.StringBuilder"); TypeVoid = mscorlib.MainModule.GetType("System.Void"); TypeIntPtr = mscorlib.MainModule.GetType("System.IntPtr"); TypeInt32 = mscorlib.MainModule.GetType("System.Int32"); TypeBindingsBase = assembly.Modules.Select(m => m.GetType("OpenTK.BindingsBase")).First(); foreach (var module in assembly.Modules) { foreach (var type in module.Types) { Rewrite(type, options); } } } else { Console.Error.WriteLine("Error: assembly has already been rewritten"); } // Save rewritten assembly assembly.Write(file, write_params); }
static bool Weave(string assName, IEnumerable <string> dependencies) { using (DefaultAssemblyResolver asmResolver = new DefaultAssemblyResolver()) using (CurrentAssembly = AssemblyDefinition.ReadAssembly(assName, new ReaderParameters { ReadWrite = true, ReadSymbols = true, AssemblyResolver = asmResolver })) { asmResolver.AddSearchDirectory(Path.GetDirectoryName(assName)); asmResolver.AddSearchDirectory(Helpers.UnityEngineDllDirectoryName()); if (dependencies != null) { foreach (string path in dependencies) { asmResolver.AddSearchDirectory(path); } } // fix "No writer found for ..." error // https://github.com/vis2k/Mirror/issues/2579 // -> when restarting Unity, weaver would try to weave a DLL // again // -> resulting in two GeneratedNetworkCode classes (see ILSpy) // -> the second one wouldn't have all the writer types setup if (ContainsGeneratedCodeClass(CurrentAssembly.MainModule)) { //Log.Warning($"Weaver: skipping {CurrentAssembly.Name} because already weaved"); return(true); } WeaverTypes.SetupTargetTypes(CurrentAssembly); CreateGeneratedCodeClass(); // WeaverList depends on WeaverTypes setup because it uses Import WeaveLists = new WeaverLists(); System.Diagnostics.Stopwatch rwstopwatch = System.Diagnostics.Stopwatch.StartNew(); // Need to track modified from ReaderWriterProcessor too because it could find custom read/write functions or create functions for NetworkMessages bool modified = ReaderWriterProcessor.Process(CurrentAssembly); rwstopwatch.Stop(); Console.WriteLine($"Find all reader and writers took {rwstopwatch.ElapsedMilliseconds} milliseconds"); ModuleDefinition moduleDefinition = CurrentAssembly.MainModule; Console.WriteLine($"Script Module: {moduleDefinition.Name}"); modified |= WeaveModule(moduleDefinition); if (WeavingFailed) { return(false); } if (modified) { PropertySiteProcessor.Process(moduleDefinition); // add class that holds read/write functions moduleDefinition.Types.Add(GeneratedCodeClass); ReaderWriterProcessor.InitializeReaderAndWriters(CurrentAssembly); // write to outputDir if specified, otherwise perform in-place write WriterParameters writeParams = new WriterParameters { WriteSymbols = true }; CurrentAssembly.Write(writeParams); } } return(true); }
public static byte[] ToByteArray([NotNull] this AssemblyDefinition assemblyDefinition, WriterParameters writerParameters = null) { if (assemblyDefinition == null) { throw new ArgumentNullException(nameof(assemblyDefinition)); } using var srcStream = new MemoryStream(); assemblyDefinition.Write(srcStream, writerParameters ?? new WriterParameters()); return(srcStream.ToArray()); }
//[UnityEditor.MenuItem("XLua/Hotfix Inject In Editor", false, 3)] public static void HotfixInject() { #if HOTFIX_DEBUG_SYMBOLS var readerParameters = new ReaderParameters { ReadSymbols = true }; AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(INTERCEPT_ASSEMBLY_PATH, readerParameters); #else AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(INTERCEPT_ASSEMBLY_PATH); #endif init(assembly); if (assembly.MainModule.Types.Any(t => t.Name == "__XLUA_GEN_FLAG")) { return; } assembly.MainModule.Types.Add(new TypeDefinition("__XLUA_GEN", "__XLUA_GEN_FLAG", Mono.Cecil.TypeAttributes.Class, objType)); var hotfixDelegateAttributeType = assembly.MainModule.Types.Single(t => t.FullName == "XLua.HotfixDelegateAttribute"); hotfix_delegates = (from module in assembly.Modules from type in module.Types where type.CustomAttributes.Any(ca => ca.AttributeType == hotfixDelegateAttributeType) select type).ToList(); var hotfixAttributeType = assembly.MainModule.Types.Single(t => t.FullName == "XLua.HotfixAttribute"); foreach (var type in (from module in assembly.Modules from type in module.Types select type)) { CustomAttribute hotfixAttr = type.CustomAttributes.FirstOrDefault(ca => ca.AttributeType == hotfixAttributeType); if (hotfixAttr != null) { int hotfixType = (int)hotfixAttr.ConstructorArguments[0].Value; FieldReference stateTable = null; if (hotfixType == 1) { if (type.IsAbstract && type.IsSealed) { throw new InvalidOperationException(type.FullName + " is static, can not be mark as Stateful!"); } var stateTableDefinition = new FieldDefinition("__Hitfix_xluaStateTable", Mono.Cecil.FieldAttributes.Private, luaTableType); type.Fields.Add(stateTableDefinition); stateTable = stateTableDefinition.GetGeneric(); } foreach (var method in type.Methods) { if (method.Name != ".cctor" && !method.IsAbstract) { if ((method.HasGenericParameters || GenericInOut(assembly, method)) ? !InjectGenericMethod(assembly, method, hotfixType, stateTable) : !InjectMethod(assembly, method, hotfixType, stateTable)) { return; } } } } } #if HOTFIX_DEBUG_SYMBOLS var writerParameters = new WriterParameters { WriteSymbols = true }; assembly.Write(INTERCEPT_ASSEMBLY_PATH, writerParameters); #else assembly.Write(INTERCEPT_ASSEMBLY_PATH); #endif Debug.Log("hotfix inject finish!"); }
protected virtual void WriteAssembly(AssemblyDefinition assembly, string directory, WriterParameters writerParameters) { foreach (var module in assembly.Modules) { // Write back pure IL even for crossgen-ed assemblies if (module.IsCrossgened()) { module.Attributes |= ModuleAttributes.ILOnly; module.Attributes ^= ModuleAttributes.ILLibrary; module.Architecture = CalculateArchitecture(module.Architecture); } } assembly.Write(GetAssemblyFileName(assembly, directory), writerParameters); }
protected virtual void WriteAssembly(AssemblyDefinition assembly, string directory, WriterParameters writerParameters) { foreach (var module in assembly.Modules) { // Write back pure IL even for crossgen-ed assemblies if (module.IsCrossgened()) { module.Attributes |= ModuleAttributes.ILOnly; module.Attributes ^= ModuleAttributes.ILLibrary; module.Architecture = CalculateArchitecture(module.Architecture); } } string outputName = GetAssemblyFileName(assembly, directory); try { assembly.Write(outputName, writerParameters); } catch (Exception e) { throw new OutputException($"Failed to write '{outputName}", e); } }
/// <summary> /// Invoked for each assemby that has been compiled. /// </summary> private void WeaveAssembly(string assemblyPath) { if (string.IsNullOrEmpty(assemblyPath)) { return; } string name = Path.GetFileNameWithoutExtension(assemblyPath); m_Log.Info(name, "Starting", false); if (!m_IsEnabled) { m_Log.Info(name, "Aborted due to weaving being disabled.", false); return; } if (!m_RequiredScriptingSymbols.isActive) { m_Log.Info(name, "Aborted due to non-matching script symbols.", false); return; } string filePath = Path.Combine(Constants.ProjectRoot, assemblyPath); if (!File.Exists(filePath)) { m_Log.Error(name, "Unable to find assembly at path '" + filePath + "'.", true); return; } using (FileStream assemblyStream = new FileStream(assemblyPath, FileMode.Open, FileAccess.ReadWrite)) { using (ModuleDefinition moduleDefinition = ModuleDefinition.ReadModule(assemblyStream, GetReaderParameters())) { m_Components.Initialize(this); m_Components.VisitModule(moduleDefinition, m_Log); // Save WriterParameters writerParameters = new WriterParameters() { WriteSymbols = true, SymbolWriterProvider = new Mono.Cecil.Pdb.NativePdbWriterProvider() }; moduleDefinition.Write(GetWriterParameters()); } } m_Log.Info("Weaver Settings", "Weaving Successfully Completed", false); // Stats m_Log.Info(name, "Time ms: " + m_Timer.ElapsedMilliseconds, false); m_Log.Info(name, "Types: " + m_Components.totalTypesVisited, false); m_Log.Info(name, "Methods: " + m_Components.totalMethodsVisited, false); m_Log.Info(name, "Fields: " + m_Components.totalFieldsVisited, false); m_Log.Info(name, "Properties: " + m_Components.totalPropertiesVisited, false); m_Log.Info(name, "Complete", false); // save any changes to our weavedAssembly objects EditorUtility.SetDirty(this); AssetDatabase.SaveAssets(); }
public override ILPostProcessResult Process(ICompiledAssembly compiledAssembly) { if (!WillProcess(compiledAssembly)) { return(null); } using (var marker = new EntitiesILPostProcessorProfileMarker(compiledAssembly.Name)) { var diagnostics = new List <DiagnosticMessage>(); bool madeAnyChange = false; Defines = compiledAssembly.Defines; var assemblyDefinition = AssemblyDefinitionFor(compiledAssembly); var postProcessors = FindAllEntitiesILPostProcessors(); TypeDefinition[] componentSystemTypes; try { using (marker.CreateChildMarker("GetAllComponentTypes")) componentSystemTypes = assemblyDefinition.MainModule.GetAllTypes().Where(type => type.IsComponentSystem()).ToArray(); using (marker.CreateChildMarker("InjectOnCreateForCompiler")) { foreach (var systemType in componentSystemTypes) { InjectOnCreateForCompiler(systemType); madeAnyChange = true; } } } catch (FoundErrorInUserCodeException e) { diagnostics.AddRange(e.DiagnosticMessages); return(null); } foreach (var postProcessor in postProcessors) { postProcessor.Initialize(Defines, _ReferencesEntities, _ReferencesJobs); if (!postProcessor.WillProcess()) { continue; } using (marker.CreateChildMarker(postProcessor.GetType().Name)) { diagnostics.AddRange(postProcessor.PostProcess(assemblyDefinition, componentSystemTypes, out var madeChange)); madeAnyChange |= madeChange; } } var unmanagedComponentSystemTypes = assemblyDefinition.MainModule.GetAllTypes().Where((x) => x.TypeImplements(typeof(ISystemBase))).ToArray(); foreach (var postProcessor in postProcessors) { diagnostics.AddRange(postProcessor.PostProcessUnmanaged(assemblyDefinition, unmanagedComponentSystemTypes, out var madeChange)); madeAnyChange |= madeChange; } // Hack to remove Entities => Entities circular references var selfName = assemblyDefinition.Name.FullName; foreach (var referenceName in assemblyDefinition.MainModule.AssemblyReferences) { if (referenceName.FullName == selfName) { assemblyDefinition.MainModule.AssemblyReferences.Remove(referenceName); break; } } if (!madeAnyChange || diagnostics.Any(d => d.DiagnosticType == DiagnosticType.Error)) { return(new ILPostProcessResult(null, diagnostics)); } using (marker.CreateChildMarker("WriteAssembly")) { var pe = new MemoryStream(); var pdb = new MemoryStream(); var writerParameters = new WriterParameters { SymbolWriterProvider = new PortablePdbWriterProvider(), SymbolStream = pdb, WriteSymbols = true }; assemblyDefinition.Write(pe, writerParameters); return(new ILPostProcessResult(new InMemoryAssembly(pe.ToArray(), pdb.ToArray()), diagnostics)); } } }
private void Rewrite() { // Specify assembly read and write parameters // We want to keep a valid symbols file (pdb or mdb) var read_params = new ReaderParameters(); var write_params = new WriterParameters(); #if NET_CORE var defaultResolver = new DefaultAssemblyResolver(); defaultResolver.AddSearchDirectory(Path.GetDirectoryName(Options.TargetAssembly)); read_params.AssemblyResolver = defaultResolver; #else read_params.AssemblyResolver = new OpenTKAssemblyResolver(); #endif read_params.ReadSymbols = true; read_params.ReadWrite = true; write_params.WriteSymbols = true; #if !NET_CORE if (!String.IsNullOrEmpty(Options.StrongNameKey) && File.Exists(Options.StrongNameKey)) { string absoluteKeyFilePath = Path.GetFullPath(Options.StrongNameKey); using (var fs = new FileStream(absoluteKeyFilePath, FileMode.Open, FileAccess.Read)) { var keypair = new System.Reflection.StrongNameKeyPair(fs); write_params.StrongNameKeyPair = keypair; } } else { Console.Error.WriteLine("No keyfile specified or keyfile missing."); } #endif // Load assembly and process all modules try { using (AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(Options.TargetAssembly, read_params)) { var rewritten = assembly.CustomAttributes.FirstOrDefault(a => a.AttributeType.Name == "RewrittenAttribute"); if (rewritten == null) { foreach (var module in assembly.Modules) { foreach (var reference in module.AssemblyReferences) { try { var resolved = module.AssemblyResolver.Resolve(reference); if (reference.Name == CoreLibName) { mscorlib = resolved; } } catch (Exception e) { Console.Error.WriteLine(e.ToString()); } } } if (mscorlib == null) { Console.Error.WriteLine($"Failed to locate {CoreLibName}"); return; } TypeMarshal = GetType(mscorlib.MainModule, "System.Runtime.InteropServices.Marshal"); TypeVoid = GetType(mscorlib.MainModule, "System.Void"); TypeIntPtr = GetType(mscorlib.MainModule, "System.IntPtr"); TypeInt32 = GetType(mscorlib.MainModule, "System.Int32"); TypeBindingsBase = assembly.Modules.Select(m => GetType(m, "OpenTK.BindingsBase")).First(); foreach (var module in assembly.Modules) { foreach (var type in module.Types) { Rewrite(type); } } } else { Console.Error.WriteLine("Error: assembly has already been rewritten"); } // Save rewritten assembly assembly.Write(write_params); } } catch (InvalidOperationException inex) { Console.WriteLine("Failed to load the assembly. It may already have been rewritten, and the debug symbols no longer match."); Console.WriteLine(inex); } }
internal static int Clean(PurifyOptions opts) { var files = GetAssemblyFiles(opts.WorkDir).Where(f => !f.Contains(".OS.")).ToArray(); log.Info($"Found {files.Length} files!"); var resolv = new DefaultAssemblyResolver(); resolv.AddSearchDirectory(opts.WorkDir); var rparam = new ReaderParameters { AssemblyResolver = resolv }; var wparam = new WriterParameters(); var halDir = Path.Combine(opts.CodeDir); halDir = Directory.CreateDirectory(halDir).FullName; foreach (var file in files) { using (var stream = new MemoryStream(File.ReadAllBytes(file))) { var ass = AssemblyDefinition.ReadAssembly(stream, rparam); log.Info($" - '{ass.FullName}'"); var methods = CollectPInvokes(ass).ToList(); if (!methods.Any()) { continue; } var apiName = ass.Name.Name + ".OS.Api"; var apiCS = Path.Combine(halDir, apiName + ".cs"); var implName = ass.Name.Name + ".OS.Impl"; var implCS = Path.Combine(halDir, implName + ".cs"); using (var pinvoke = File.CreateText(apiCS)) { var nsp = Noast.Create <INamespace>(apiName); nsp.AddUsing("System"); nsp.AddUsing("System.Runtime.InteropServices"); nsp.AddUsing("System.Runtime.InteropServices.ComTypes"); nsp.AddUsing("System.Text"); var cla = Noast.Create <IInterface>("IPlatform", nsp); foreach (var meth in methods.Select(m => m.Item1)) { cla.Methods.Add(meth); } pinvoke.Write(nsp); } string f; var apiCSAss = Compiler.CreateAssembly(string.Empty, apiName, new[] { apiCS }); File.Copy(apiCSAss.Location, f = Path.Combine(halDir, apiName + ".dll"), true); log.Info($" --> '{Path.GetFileName(apiCS)}' ({Path.GetFileName(f)})"); var apiAssDef = AssemblyDefinition.ReadAssembly(f, rparam); using (var pinvoke = File.CreateText(implCS)) { var nsp = Noast.Create <INamespace>(implName); nsp.AddUsing("System"); nsp.AddUsing("System.Runtime.InteropServices"); nsp.AddUsing("System.Runtime.InteropServices.ComTypes"); nsp.AddUsing("System.Text"); var cla = Noast.Create <IClass>("Win32Platform", nsp).With(Visibility.Internal); cla.AddImplements(apiName + ".IPlatform"); foreach (var meth in methods.Select(m => m.Item1).SelectMany(DelegateInterface)) { cla.Methods.Add(meth); } cla = Noast.Create <IClass>("MonoPlatform", nsp).With(Visibility.Internal); cla.AddImplements(apiName + ".IPlatform"); foreach (var meth in methods.Select(m => m.Item1).SelectMany(ImplementInterface)) { cla.Methods.Add(meth); } cla = Noast.Create <IClass>("Platforms", nsp).With(Visibility.Public).With(Modifier.Static); cla.Methods.Add(CreateSwitchMethod()); pinvoke.Write(nsp); } var implCSAss = Compiler.CreateAssembly(string.Empty, implName, new[] { implCS }, new[] { f }); File.Copy(implCSAss.Location, f = Path.Combine(halDir, implName + ".dll"), true); log.Info($" --> '{Path.GetFileName(implCS)}' ({Path.GetFileName(f)})"); var implAssDef = AssemblyDefinition.ReadAssembly(f, rparam); var iplat = apiAssDef.GetAllTypes().First(t => t.Name == "IPlatform"); var platfs = implAssDef.GetAllTypes().First(t => t.Name == "Platforms"); var platGet = platfs.Methods.First(); PurifyCalls(methods.Select(m => m.Item2), platGet, iplat); log.InfoFormat(" added '{0}'!", CopyTypeRef(apiCSAss, opts.WorkDir)); log.InfoFormat(" added '{0}'!", CopyTypeRef(implCSAss, opts.WorkDir)); ass.Write(file, wparam); } } resolv.Dispose(); return(0); }
private void Rewrite(string file, string keyfile, IEnumerable <string> options) { IEnumerable <string> optionsEnumerated = options as IList <string> ?? options.ToList(); dllimport = optionsEnumerated.Contains("-dllimport"); // Specify assembly read and write parameters // We want to keep a valid symbols file (pdb or mdb) var read_params = new ReaderParameters(); var write_params = new WriterParameters(); read_params.ReadSymbols = true; read_params.ReadWrite = true; write_params.WriteSymbols = true; if (!String.IsNullOrEmpty(keyfile) && File.Exists(keyfile)) { keyfile = Path.GetFullPath(keyfile); using (var fs = new FileStream(keyfile, FileMode.Open, FileAccess.Read)) { var keypair = new System.Reflection.StrongNameKeyPair(fs); write_params.StrongNameKeyPair = keypair; } } else { Console.Error.WriteLine("No keyfile specified or keyfile missing."); } // Load assembly and process all modules try { using (AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly(file, read_params)) { var rewritten = assembly.CustomAttributes.FirstOrDefault(a => a.AttributeType.Name == "RewrittenAttribute"); if (rewritten == null) { foreach (var module in assembly.Modules) { foreach (var reference in module.AssemblyReferences) { try { var resolved = module.AssemblyResolver.Resolve(reference); if (reference.Name == "mscorlib") { mscorlib = resolved; } } catch (Exception e) { Console.Error.WriteLine(e.ToString()); } } } if (mscorlib == null) { Console.Error.WriteLine("Failed to locate mscorlib"); return; } TypeMarshal = mscorlib.MainModule.GetType("System.Runtime.InteropServices.Marshal"); TypeVoid = mscorlib.MainModule.GetType("System.Void"); TypeIntPtr = mscorlib.MainModule.GetType("System.IntPtr"); TypeInt32 = mscorlib.MainModule.GetType("System.Int32"); TypeBindingsBase = assembly.Modules.Select(m => m.GetType("OpenTK.BindingsBase")).First(); foreach (var module in assembly.Modules) { foreach (var type in module.Types) { Rewrite(type, optionsEnumerated); } } } else { Console.Error.WriteLine("Error: assembly has already been rewritten"); } // Save rewritten assembly assembly.Write(write_params); } } catch (InvalidOperationException inex) { Console.WriteLine("Failed to load the assembly. It may already have been rewritten, and the debug symbols no longer match."); Console.WriteLine(inex); } }
protected virtual void WriteAssembly(AssemblyDefinition assembly, string directory, WriterParameters writerParameters) { foreach (var module in assembly.Modules) { // Write back pure IL even for crossgen-ed assemblies if (module.IsCrossgened()) { module.Attributes |= ModuleAttributes.ILOnly; module.Attributes ^= ModuleAttributes.ILLibrary; module.Architecture = CalculateArchitecture(module.Architecture); } } string outputName = GetAssemblyFileName(assembly, directory); try { assembly.Write(outputName, writerParameters); } catch (Exception e) { throw new LinkerFatalErrorException(MessageContainer.CreateErrorMessage(null, DiagnosticId.FailedToWriteOutput, outputName), e); } }
static void TryWeaveAssembly(string assemblyAssetPath) { var settings = ReflectionBakingInternalUtil.TryGetEnabledSettingsInstance(); if (settings == null) { return; } if (settings.AllGeneratedAssemblies && settings.ExcludeAssemblies.Contains(assemblyAssetPath)) { return; } if (!settings.AllGeneratedAssemblies && !settings.IncludeAssemblies.Contains(assemblyAssetPath)) { return; } var stopwatch = new Stopwatch(); stopwatch.Start(); var assemblyFullPath = ReflectionBakingInternalUtil.ConvertAssetPathToSystemPath(assemblyAssetPath); var readerParameters = new ReaderParameters { AssemblyResolver = new UnityAssemblyResolver(), // Is this necessary? //ReadSymbols = true, }; var module = ModuleDefinition.ReadModule(assemblyFullPath, readerParameters); var assemblyRefNames = module.AssemblyReferences.Select(x => x.Name.ToLower()).ToList(); if (!assemblyRefNames.Contains("zenject-usage")) { // Zenject-usage is used by the generated methods // Important that we do this check otherwise we can corrupt some dlls that don't have access to it return; } var assemblyName = Path.GetFileNameWithoutExtension(assemblyAssetPath); var assembly = AppDomain.CurrentDomain.GetAssemblies() .Where(x => x.GetName().Name == assemblyName).OnlyOrDefault(); Assert.IsNotNull(assembly, "Could not find unique assembly '{0}' in currently loaded list of assemblies", assemblyName); int numTypesChanged = ReflectionBakingModuleEditor.WeaveAssembly( module, assembly, settings.NamespacePatterns); if (numTypesChanged > 0) { var writerParams = new WriterParameters() { // Required for other tools which using Mono.Cecil for IL modification WriteSymbols = true }; module.Write(assemblyFullPath, writerParams); Debug.Log("Added reflection baking to '{0}' types in assembly '{1}', took {2:0.00} seconds" .Fmt(numTypesChanged, Path.GetFileName(assemblyAssetPath), stopwatch.Elapsed.TotalSeconds)); } }
private static void Main(string[] args) { string calliAttributeName = "CalliAttribute"; string removeTypeAttributeName = "RemoveTypeAttribute"; string filename = null; string pdbfile = null; MessageIntegration.Info("CSCli started."); MessageIntegration.Info("CSCli was copied from http://www.codeproject.com/Articles/644130/NET-COM-Interop-using-Postbuild."); MessageIntegration.Info(String.Empty); //new line MessageIntegration.Info(String.Format("CSCli-Argments: [{0}].", String.Concat(args.Select(x => x + " ")).Trim())); /* * Parse parameters */ foreach (var a in args) { if (a.StartsWith("-file:")) { filename = a.Substring("-file:".Length); MessageIntegration.Info("Filename: " + filename); } else if (a.StartsWith("-c:")) { calliAttributeName = a.Substring("-c:".Length); } else if (a.StartsWith("-r:")) { removeTypeAttributeName = a.Substring("-r:".Length); } else if (a.StartsWith("-pdb:")) { pdbfile = a.Substring("-pdb:".Length); } else { MessageIntegration.WriteWarning(String.Format("Unknown parameter: \"{0}\".", a)); } } /* * Load and process assembly */ if (!File.Exists(filename)) { MessageIntegration.WriteError(String.Format("Could not find file \"{0}\".", filename)); Environment.Exit(-1); } WriterParameters wp = new WriterParameters(); ReaderParameters rp = new ReaderParameters(); var strongNameKey = Path.ChangeExtension(filename, "snk"); if (File.Exists(strongNameKey)) { MessageIntegration.Info("Signing with Key : " + strongNameKey); wp.StrongNameKeyPair = new StrongNameKeyPair(File.OpenRead(strongNameKey)); } //check whether the pdbfile has been passed through application parameters if (pdbfile == null) { //if not use the default pdbfilepath by changing the extension of the assembly to .pdb pdbfile = Path.ChangeExtension(filename, "pdb"); } //check whether the original pdb-file exists bool generatePdb = File.Exists(pdbfile); //if the original pdb-file exists -> prepare for rewriting the symbols file wp.WriteSymbols = generatePdb; rp.ReadSymbols = generatePdb; if (rp.ReadSymbols) { rp.SymbolReaderProvider = new PdbReaderProvider(); } MessageIntegration.Info("Generating pdb: " + generatePdb.ToString()); //open assembly var assembly = AssemblyDefinition.ReadAssembly(filename, rp); //add the directory assembly directory as search directory to resolve referenced assemblies ((BaseAssemblyResolver)assembly.MainModule.AssemblyResolver).AddSearchDirectory(Path.GetDirectoryName(filename)); //path the assembly AssemblyPatcher patcher = new AssemblyPatcher(assembly, calliAttributeName, removeTypeAttributeName); if (patcher.PatchAssembly()) { try { //if the assembly was patched successfully -> replace the old assembly file with the new, patched assembly file //the symbols file will be created automatically File.Delete(filename); assembly.Write(filename, wp); } catch (Exception ex) { MessageIntegration.WriteError("Creating new assembly failed: " + ex.ToString()); Environment.Exit(-1); } MessageIntegration.Info(String.Format("CSCli patched assembly \"{0}\" successfully.", Path.GetFileName(filename))); Environment.Exit(0); } else { MessageIntegration.WriteError(String.Format("\"{0}\" could not be patched.", filename)); Environment.Exit(-1); } }
public static int Main(string[] args) { if (args.Length < 3 || args.Length > 4) { Console.WriteLine("Utility for retargetting some Rebex .NET 4.0 assemblies to .NET Core and .NET 2.0"); Console.WriteLine("Warning: This is not a general purpose utility; it only supports a single Rebex assembly (Rebex.Ed25519)"); Console.WriteLine(); Console.WriteLine("Usage:"); Console.WriteLine("\tretarget input_assembly output_assembly framework [keypath]"); return(1); } string input = args[0]; string output = args[1]; string framework = args[2]; string frameworkName = null; string keyPath = (args.Length == 4) ? args[3] : null; bool remap = false; string corlibVersion = "4.0.0.0"; string corlibToken = "b77a5c561934e089"; switch (framework) { case "core-1.0": case Standard16: framework = Standard16; remap = true; break; case "net-4.0": case Net40: framework = Net40; frameworkName = ".NET Framework 4"; break; case "net-2.0": framework = null; corlibVersion = "2.0.0.0"; break; case "netcf-2.0": framework = null; corlibVersion = "2.0.0.0"; corlibToken = "969db8053d3322ac"; break; default: Console.WriteLine("Framework not supported: " + framework); return(2); } var parameters = new WriterParameters(); if (keyPath != null) { // load signing key var rsa = new RSACryptoServiceProvider(); rsa.ImportCspBlob(File.ReadAllBytes(keyPath)); parameters.StrongNameKeyPair = new StrongNameKeyPair(rsa.ExportCspBlob(true)); } var asm = AssemblyDefinition.ReadAssembly(input); asm.MainModule.Attributes = ModuleAttributes.ILOnly; for (int i = 0; i < asm.CustomAttributes.Count; i++) { var a = asm.CustomAttributes[i]; //Console.WriteLine(a.AttributeType.FullName); switch (a.AttributeType.FullName) { case "System.CLSCompliantAttribute": if (remap) { asm.CustomAttributes.RemoveAt(i); i--; } continue; case "System.Runtime.Versioning.TargetFrameworkAttribute": if (framework == null) { // remove the attribute for .NET Framework asm.CustomAttributes.RemoveAt(i); i--; continue; } a.ConstructorArguments.Add(new CustomAttributeArgument(a.ConstructorArguments[0].Type, framework)); a.ConstructorArguments.RemoveAt(0); a.Properties.Clear(); if (frameworkName != null) { a.Properties.Add(new Mono.Cecil.CustomAttributeNamedArgument("FrameworkDisplayName", new CustomAttributeArgument(a.ConstructorArguments[0].Type, frameworkName))); } break; } } if (framework == null) { asm.SecurityDeclarations.Clear(); asm.MainModule.Runtime = TargetRuntime.Net_2_0; } var asnCore = AssemblyNameReference.Parse("mscorlib, Version=" + corlibVersion + ", Culture=neutral, PublicKeyToken=" + corlibToken); var asnCptCsp = AssemblyNameReference.Parse("System.Security.Cryptography.Csp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); var asnCptAlgorithms = AssemblyNameReference.Parse("System.Security.Cryptography.Algorithms, Version=4.2.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); var asnCptPrimitives = AssemblyNameReference.Parse("System.Security.Cryptography.Primitives, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); var asnRuntime = AssemblyNameReference.Parse("System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"); asm.MainModule.AssemblyReferences.Clear(); asm.MainModule.AssemblyReferences.Add(asnCore); if (remap) { foreach (var r in asm.MainModule.GetTypeReferences()) { if (r.FullName.StartsWith("System.Security.Cryptography.Random")) { r.Scope = asnCptAlgorithms; } else if (r.FullName.StartsWith("System.Security.Cryptography.SHA")) { r.Scope = asnCptAlgorithms; } else if (r.FullName.StartsWith("System.Security.Cryptography.IncrementalHash")) { r.Scope = asnCptAlgorithms; } else if (r.FullName.StartsWith("System.Security.Cryptography.HashAlgorithmName")) { r.Scope = asnCptPrimitives; } else if (r.FullName.StartsWith("System.Security.Cryptography")) { r.Scope = asnCptCsp; } else { r.Scope = asnRuntime; } } //asm.MainModule.AssemblyReferences.Add(csp); asm.MainModule.AssemblyReferences.Add(asnCptAlgorithms); asm.MainModule.AssemblyReferences.Add(asnCptPrimitives); asm.MainModule.AssemblyReferences.Add(asnRuntime); } asm.Write(output, parameters); return(0); }
public void Write(string fileName, WriterParameters parameters) { main_module.Write(fileName, parameters); }
private static void GenerateInterop(String filePath, String keyFilePath) { Console.WriteLine("Generating Interop..."); String pdbFile = Path.Combine(Path.GetDirectoryName(filePath), Path.GetFileNameWithoutExtension(filePath) + ".pdb"); ReaderParameters readerParams = new ReaderParameters(); WriterParameters writerParams = new WriterParameters(); if (keyFilePath != null) { writerParams.StrongNameKeyPair = new StrongNameKeyPair(File.Open(keyFilePath, FileMode.Open)); } if (File.Exists(pdbFile)) { readerParams.SymbolReaderProvider = new PdbReaderProvider(); readerParams.ReadSymbols = true; writerParams.WriteSymbols = true; } AssemblyDefinition assemblyDef = AssemblyDefinition.ReadAssembly(filePath, readerParams); ((BaseAssemblyResolver)assemblyDef.MainModule.AssemblyResolver).AddSearchDirectory(Path.GetDirectoryName(filePath)); AssemblyDefinition mscorLib = null; foreach (AssemblyNameReference assemblyNameReference in assemblyDef.MainModule.AssemblyReferences) { if (assemblyNameReference.Name.ToLower() == "mscorlib") { mscorLib = assemblyDef.MainModule.AssemblyResolver.Resolve(assemblyNameReference); break; } else if (assemblyNameReference.Name == "System.Runtime") { ((BaseAssemblyResolver)assemblyDef.MainModule.AssemblyResolver).AddSearchDirectory(Path.Combine(GetProgramFilesFolder(), @"Reference Assemblies\Microsoft\Framework\.NETCore\v4.5")); mscorLib = assemblyDef.MainModule.AssemblyResolver.Resolve(assemblyNameReference); break; } } if (mscorLib == null) { throw new InvalidOperationException("Missing mscorlib.dll"); } m_mscorLib = mscorLib; for (int i = 0; i < assemblyDef.CustomAttributes.Count; i++) { CustomAttribute attr = assemblyDef.CustomAttributes[i]; if (attr.AttributeType.FullName == typeof(System.Runtime.CompilerServices.CompilationRelaxationsAttribute).FullName) { assemblyDef.CustomAttributes.RemoveAt(i); i--; } } foreach (TypeDefinition typeDef in assemblyDef.MainModule.Types) { PatchType(typeDef); } RemoveInteropClass(assemblyDef); string tempFile = Path.GetTempFileName(); assemblyDef.Write(tempFile, writerParams); assemblyDef.Dispose(); File.Delete(filePath); File.Copy(tempFile, filePath); Console.WriteLine("Interop Generation complete."); }
private WriterParameters GetWriterParameters() { var writerParameters = new WriterParameters(); if (_mode == PatchMode.Debug && File.Exists(PdbName)) { writerParameters.SymbolWriterProvider = new PdbWriterProvider(); writerParameters.WriteSymbols = true; } if (string.IsNullOrEmpty(_snkCertificatePath) || !SnkFileExists) return writerParameters; using (var file = File.OpenRead(_snkCertificatePath)) { writerParameters.StrongNameKeyPair = new StrongNameKeyPair(file); } return writerParameters; }
public static void HotfixInject(string inject_assembly_path, IEnumerable <string> search_directorys, IEnumerable <Type> cfg_check_types = null) { AssemblyDefinition assembly = null; try { #if HOTFIX_SYMBOLS_DISABLE assembly = AssemblyDefinition.ReadAssembly(inject_assembly_path); #else var readerParameters = new ReaderParameters { ReadSymbols = true }; assembly = AssemblyDefinition.ReadAssembly(inject_assembly_path, readerParameters); #endif init(assembly, search_directorys); if (assembly.MainModule.Types.Any(t => t.Name == "__XLUA_GEN_FLAG")) { Info("had injected!"); return; } assembly.MainModule.Types.Add(new TypeDefinition("__XLUA_GEN", "__XLUA_GEN_FLAG", Mono.Cecil.TypeAttributes.Class, objType)); Config(cfg_check_types); var hotfixDelegateAttributeType = assembly.MainModule.Types.Single(t => t.FullName == "XLua.HotfixDelegateAttribute"); hotfix_delegates = (from module in assembly.Modules from type in module.Types where type.CustomAttributes.Any(ca => ca.AttributeType == hotfixDelegateAttributeType) select type).ToList(); var hotfixAttributeType = assembly.MainModule.Types.Single(t => t.FullName == "XLua.HotfixAttribute"); foreach (var type in (from module in assembly.Modules from type in module.Types select type)) { if (!injectType(assembly, hotfixAttributeType, type)) { return; } } #if HOTFIX_SYMBOLS_DISABLE assembly.Write(inject_assembly_path); Info("hotfix inject finish!(no symbols)"); #else var writerParameters = new WriterParameters { WriteSymbols = true }; assembly.Write(inject_assembly_path, writerParameters); Info("hotfix inject finish!"); #endif } catch (Exception e) { Error("Exception! " + e); } finally { if (assembly != null) { Clean(assembly); } } }