public static AssemblyDefinition GetAssemblyDef(string assemblyPath) { if (assemblies.ContainsKey(assemblyPath)) return assemblies[assemblyPath]; var assemblyResolver = new DefaultAssemblyResolver(); var assemblyLocation = Path.GetDirectoryName(assemblyPath); assemblyResolver.AddSearchDirectory(assemblyLocation); var readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver }; var pdbName = Path.ChangeExtension(assemblyPath, "pdb"); if (File.Exists(pdbName)) { var symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; readerParameters.ReadSymbols = true; } var assemblyDef = AssemblyDefinition.ReadAssembly(assemblyPath, readerParameters); assemblies.Add(assemblyPath,assemblyDef); return assemblyDef; }
private static ISymbolReader ReadAssemblyWithPdb(string toAnalyze) { var pdb = new PdbReaderProvider(); string pdbFile = Path.ChangeExtension(toAnalyze, "pdb"); var moduleToAnalyze = ModuleDefinition.ReadModule(toAnalyze); return pdb.GetSymbolReader(moduleToAnalyze, pdbFile); }
/// <summary> /// Patches the specified input PDB file. /// </summary> /// <param name="inputExeFile">The input PDB file.</param> /// <param name="outputPdbFile">The output PDB file.</param> /// <param name="sourcePathRewriter">The source path modifier.</param> /// <exception cref="System.ArgumentNullException">inputExeFile</exception> public static void Patch(string inputExeFile, string outputPdbFile, SourcePathRewriterDelegate sourcePathRewriter) { if (inputExeFile == null) throw new ArgumentNullException("inputExeFile"); if (outputPdbFile == null) throw new ArgumentNullException("outputPdbFile"); if (sourcePathRewriter == null) throw new ArgumentNullException("sourcePathRewriter"); // Copy PDB from input assembly to output assembly if any var inputPdbFile = Path.ChangeExtension(inputExeFile, "pdb"); if (!File.Exists(inputPdbFile)) { ShowMessage(string.Format("Warning file [{0}] does not exist", inputPdbFile), ConsoleColor.Yellow); return; } var symbolReaderProvider = new PdbReaderProvider(); var readerParameters = new ReaderParameters { SymbolReaderProvider = symbolReaderProvider, ReadSymbols = true }; // Read Assembly var assembly = AssemblyDefinition.ReadAssembly(inputExeFile, readerParameters); // Write back the assembly and pdb assembly.Write(inputExeFile, new WriterParameters {WriteSymbols = true, SourcePathRewriter = sourcePathRewriter}); }
private void LoadHotfixAssemblyWithPDB() { TextAsset dllAsset = LoadDLL(); TextAsset pdbAsset = LoadPDB(); if (_isEnableILRuntime) { _dllStream = new MemoryStream(dllAsset.bytes); _pdbStream = new MemoryStream(pdbAsset.bytes); var symbolReader = new Mono.Cecil.Pdb.PdbReaderProvider(); ILRDomain = new ILRuntime.Runtime.Enviorment.AppDomain(); ILRDomain.LoadAssembly(_dllStream, _pdbStream, symbolReader); } else { #if ENABLE_IL2CPP throw new NotImplementedException("You must enable ILRuntime when with IL2CPP mode."); #endif _monoAssembly = Assembly.Load(dllAsset.bytes, pdbAsset.bytes); } }
/// <summary> /// Patches the file. /// </summary> /// <param name="file">The file.</param> public bool PatchFile(string 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 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); ((BaseAssemblyResolver)assembly.MainModule.AssemblyResolver).AddSearchDirectory(Path.GetDirectoryName(file)); foreach (var assemblyNameReference in assembly.MainModule.AssemblyReferences) { if (assemblyNameReference.Name.ToLower() == "mscorlib") { mscorlibAssembly = assembly.MainModule.AssemblyResolver.Resolve(assemblyNameReference); break; } } // TODO: Temporary patch to handle correctly 4.5 Core profile if (mscorlibAssembly == null) { foreach (var assemblyNameReference in assembly.MainModule.AssemblyReferences) { if (assemblyNameReference.Name == "System.Runtime") { ((BaseAssemblyResolver)assembly.MainModule.AssemblyResolver).AddSearchDirectory( Path.Combine(ProgramFilesx86(),@"Reference Assemblies\Microsoft\Framework\.NETCore\v4.5")); mscorlibAssembly = assembly.MainModule.AssemblyResolver.Resolve(assemblyNameReference); break; } } } if (mscorlibAssembly == null) { LogError("Missing mscorlib.dll from assembly {0}", file); throw new InvalidOperationException("Missing mscorlib.dll from assembly"); } // Import void* and int32 from assembly using mscorlib specific version (2.0 or 4.0 depending on assembly) voidType = mscorlibAssembly.MainModule.GetType("System.Void"); voidPointerType = new PointerType(assembly.MainModule.Import(voidType)); intType = assembly.MainModule.Import( mscorlibAssembly.MainModule.GetType("System.Int32")); // 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; assembly.Write(outputFilePath, writerParameters); fileTime = new FileTime(file); // Update Check file fileTime.UpdateCheckFile(checkFile); //fileTimeInteropBuilder.UpdateCheckFile(checkInteropBuilderFile); Log("SharpDX patch done for assembly [{0}]", file); return true; }
/// <summary> /// 初始化 /// </summary> /// <param name="dllstr">dll文件</param> public void init(TextAsset dllstr) { if (isInit) { throw new Exception("CLRSharpManager试图重复初始化,如果确信要这么做请在clear()后调用此方法"); } env = new CLRSharp_Environment(new Logger()); MemoryStream msDll = new MemoryStream(dllstr.bytes); MemoryStream msPdb = null; PdbReaderProvider pdbReaderProvider = null; #if UNITY_EDITOR TextAsset pdb = Resources.Load<TextAsset>(GameConstant.MODULES + ".pdb"); msPdb = new MemoryStream(pdb.bytes); pdbReaderProvider = new PdbReaderProvider(); #endif env.LoadModule(msDll, msPdb, pdbReaderProvider); //step01建立一个线程上下文,用来模拟L#的线程模型,每个线程创建一个即可。 context = new ThreadContext(env); }
private static void Analysis(XmlTextWriter writer, ModuleDefinition module, string fullPath, bool withTypes) { try { module.ReadSymbols(); var provider = new PdbReaderProvider(); var reader = provider.GetSymbolReader(module, fullPath); } catch (FileNotFoundException fex) { // we don't want to fail on a missing pdb. // though we may place a breakpoint below. var debugException = fex; } Console.WriteLine("Parsing {0}", module.Name); writer.WriteStartElement("Assembly"); writer.WriteAttributeString("name", module.Assembly.Name.Name); writer.WriteAttributeString("version", module.Assembly.Name.Version.ToString()); writer.WriteStartElement("References"); foreach (var item in module.AssemblyReferences) { writer.WriteStartElement("Reference"); writer.WriteAttributeString("name", item.Name); writer.WriteAttributeString("fullName", item.FullName); writer.WriteAttributeString("version", item.Version.ToString()); writer.WriteEndElement(); if (!parsedAssemblies.Contains(item.FullName) && !assembliesToParse.Contains(item.FullName)) { assembliesToParse.Add(item.FullName); } } writer.WriteEndElement(); if (withTypes) { writer.WriteStartElement("TypeReferences"); foreach (var t in module.Types) { ParseType(writer, t); } writer.WriteEndElement(); } writer.WriteEndElement(); if (assembliesToParse.Contains(module.Assembly.Name.FullName)) { assembliesToParse.Remove(module.Assembly.Name.FullName); } parsedAssemblies.Add(module.Assembly.Name.FullName); }
/* /// <summary> /// Saves the debugger visualizer. /// </summary> /// <param name="aStream">A stream.</param> public void SaveDebuggerVisualizer(Stream aStream) { _debuggerVisualizerAssembly.Write(aStream, _writerParameters); } */ private static ReaderParameters GetReaderParameters(string assemblyPath) { var assemblyResolver = new DefaultAssemblyResolver(); var assemblyLocation = Path.GetDirectoryName(assemblyPath); assemblyResolver.AddSearchDirectory(assemblyLocation); var readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver }; var pdbName = Path.ChangeExtension(assemblyPath, "pdb"); if (!File.Exists(pdbName)) return readerParameters; var symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; readerParameters.ReadSymbols = true; return readerParameters; }
private ISymbolReader ResolveSymbolReader() { string symbolLocation = null; string pdbLocation = Path.ChangeExtension(AssemblyLocation, "pdb"); string mdbLocation = AssemblyLocation + ".mdb"; ISymbolReaderProvider provider = null; if (File.Exists(pdbLocation)) { symbolLocation = pdbLocation; provider = new PdbReaderProvider(); } else if (File.Exists(mdbLocation)) { symbolLocation = AssemblyLocation; provider = new MdbReaderProvider(); } if (provider == null) return null; var reader = provider.GetSymbolReader(Definition, symbolLocation); return reader; }
/// <summary> /// /// </summary> /// <param name="assemblyPath"></param> /// <param name="currentPath"></param> /// <param name="savePath"></param> /// <returns></returns> public static bool BuildToFile(string assemblyPath, string currentPath, string savePath = null) { bool setSuccess = false; if (string.IsNullOrEmpty(savePath)) { savePath = assemblyPath; } string pdbFile = Path.ChangeExtension(assemblyPath, "pdb"); PdbReaderProvider readerProvider = null; PdbWriterProvider writerProvider = null; bool debug = false; if (File.Exists(pdbFile)) { debug = true; readerProvider = new PdbReaderProvider(); writerProvider = new PdbWriterProvider(); } //huhu modify reason: Support for model debugging. var ass = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters { SymbolReaderProvider = readerProvider, ReadSymbols = debug }); BaseAssemblyResolver resolver = ass.MainModule.AssemblyResolver as BaseAssemblyResolver; if (resolver != null) { resolver.AddSearchDirectory(currentPath); } var types = ass.MainModule.Types.Where(p => !p.IsEnum).ToList(); foreach (TypeDefinition type in types) { setSuccess = ProcessEntityType(type, setSuccess, currentPath); } //modify reason: no model. ass.Write(savePath, new WriterParameters { SymbolWriterProvider = writerProvider, WriteSymbols = debug }); return true; }
/// <summary> /// /// </summary> /// <param name="assemblyPath"></param> /// <param name="outputAssembly"></param> /// <returns></returns> public static bool BuildToStream(string assemblyPath, out Stream outputAssembly) { bool setSuccess = false; string currentPath = Path.GetDirectoryName(assemblyPath); outputAssembly = new MemoryStream(); using (Stream stream = ReadAssembly(assemblyPath)) { string pdbFile = Path.ChangeExtension(assemblyPath, "pdb"); PdbReaderProvider readerProvider = null; PdbWriterProvider writerProvider = null; bool debug = false; if (File.Exists(pdbFile)) { debug = true; readerProvider = new PdbReaderProvider(); writerProvider = new PdbWriterProvider(); } var ass = AssemblyDefinition.ReadAssembly(stream, new ReaderParameters { SymbolReaderProvider = readerProvider, ReadSymbols = debug }); var types = ass.MainModule.Types.Where(p => !p.IsEnum).ToList(); foreach (TypeDefinition type in types) { setSuccess = ProcessEntityType(type, setSuccess, currentPath); } if (setSuccess) { ass.Write(outputAssembly, new WriterParameters { SymbolWriterProvider = writerProvider, WriteSymbols = debug }); return true; } } return false; }
/// <summary> /// /// </summary> /// <param name="dllBytes">dll 二进制数据</param> /// <param name="pdbBytes">pdb调试文件二进制数据,正式环境设置为null</param> /// public void Init(byte[] dllBytes, byte[] pdbBytes = null) { //首先实例化ILRuntime的AppDomain,AppDomain是一个应用程序域,每个AppDomain都是一个独立的沙盒 appDomain = new ILRuntime.Runtime.Enviorment.AppDomain(); #if ILRuntime_DEBUG //是否启动调试 appDomain.DebugService.StartDebugService(56000); appDomain.UnityMainThreadID = System.Threading.Thread.CurrentThread.ManagedThreadId; #endif System.IO.MemoryStream dllFs = new MemoryStream(dllBytes); Mono.Cecil.Cil.ISymbolReaderProvider symbolReaderProvider = null; if (pdbBytes == null) { appDomain.LoadAssembly(dllFs, null, symbolReaderProvider); } else { System.IO.MemoryStream pdbFs = new MemoryStream(pdbBytes); symbolReaderProvider = new Mono.Cecil.Pdb.PdbReaderProvider(); appDomain.LoadAssembly(dllFs, pdbFs, symbolReaderProvider); } //这里做一些ILRuntime的注册 //使用Couroutine时,C#编译器会自动生成一个实现了IEnumerator,IEnumerator<object>,IDisposable接口的类,因为这是跨域继承,所以需要写CrossBindAdapter(详细请看04_Inheritance教程),Demo已经直接写好,直接注册即可 //协程注册 appDomain.RegisterCrossBindingAdaptor(new CoroutineAdapter()); appDomain.RegisterCrossBindingAdaptor(new IGameHotFixInterfaceAdapter()); //各种委托参数注册 appDomain.DelegateManager.RegisterMethodDelegate <int>(); appDomain.DelegateManager.RegisterMethodDelegate <GameObject>(); appDomain.DelegateManager.RegisterMethodDelegate <GameObject, PointerEventData>(); appDomain.DelegateManager.RegisterMethodDelegate <System.Object>(); //UnityAction委托注册(ILRuntime必须转换为C#的事件委托) appDomain.DelegateManager.RegisterDelegateConvertor <UnityEngine.Events.UnityAction>((act) => { return(new UnityEngine.Events.UnityAction(() => { ((System.Action)act)(); })); }); //EventTriggerHandler封装的委托注册 appDomain.DelegateManager.RegisterDelegateConvertor <EventTriggerListener.VoidDelegate>((act) => { return(new EventTriggerListener.VoidDelegate((go) => { ((System.Action <GameObject>)act)(go); })); }); //EventTriggerHandler封装的委托注册 appDomain.DelegateManager.RegisterDelegateConvertor <EventTriggerListener.VoidDragDelegate>((act) => { return(new EventTriggerListener.VoidDragDelegate((go, dt) => { ((System.Action <GameObject, PointerEventData>)act)(go, dt); })); }); }
static void Analysis(XmlTextWriter writer, ModuleDefinition module, string fullPath, bool withTypes) { try { module.ReadSymbols(); var provider = new PdbReaderProvider(); var reader = provider.GetSymbolReader(module, fullPath); } catch (FileNotFoundException) { } Console.WriteLine("Parsing {0}", module.Name); writer.WriteStartElement("Assembly"); writer.WriteAttributeString("name", module.Assembly.Name.Name); writer.WriteAttributeString("version", module.Assembly.Name.Version.ToString()); writer.WriteStartElement("References"); foreach (var item in module.AssemblyReferences) { writer.WriteStartElement("Reference"); writer.WriteAttributeString("name", item.Name); writer.WriteAttributeString("fullName", item.FullName); writer.WriteAttributeString("version", item.Version.ToString()); writer.WriteEndElement(); if (!Parsed.Contains(item.FullName) && !ToParse.Contains(item.FullName)) { ToParse.Add(item.FullName); } } writer.WriteEndElement(); if (withTypes) { writer.WriteStartElement("TypeReferences"); foreach (var t in module.Types) { ParseType(writer, t); } writer.WriteEndElement(); if (designAnalysis) { GenerateTypeDesignMeasures(writer, module); } } writer.WriteEndElement(); if (ToParse.Contains(module.Assembly.Name.FullName)) { ToParse.Remove(module.Assembly.Name.FullName); } Parsed.Add(module.Assembly.Name.FullName); }
/// <summary> /// Patches the file. /// </summary> /// <param name="file">The file.</param> public bool PatchFile(string file) { file = Path.Combine(Environment.CurrentDirectory, 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()); // 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; assembly.Write(outputFilePath, writerParameters); 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 { Console.WriteLine(".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)) { Console.WriteLine(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 //} } }
private ReaderParameters GetReaderParameters() { var assemblyResolver = new DefaultAssemblyResolver(); var assemblyLocation = Path.GetDirectoryName(_assemblyLocation); assemblyResolver.AddSearchDirectory(assemblyLocation); var readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver }; if (!File.Exists(PdbName)) return readerParameters; var symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; readerParameters.ReadSymbols = _mode == PatchMode.Debug; readerParameters.ReadingMode = ReadingMode.Deferred; return readerParameters; }
private static void WeaveAssembly(string assemblyPath) { var assemblyResolver = new DefaultAssemblyResolver(); var assemblyLocation = Path.GetDirectoryName(assemblyPath); assemblyResolver.AddSearchDirectory(assemblyLocation); //if (!string.IsNullOrEmpty(HintPath)) //{ // assemblyResolver.AddSearchDirectory(HintPath); // } // var silverlightAssemblyPath = Environment.ExpandEnvironmentVariables(@”%ProgramFiles%\Reference Assemblies\Microsoft\Framework\Silverlight\v4.0\”); // assemblyResolver.AddSearchDirectory(silverlightAssemblyPath); var readerParameters = new ReaderParameters { AssemblyResolver = assemblyResolver }; var writerParameters = new WriterParameters(); var pdbName = Path.ChangeExtension(assemblyPath, "pdb"); if (File.Exists(pdbName)) { var symbolReaderProvider = new PdbReaderProvider(); readerParameters.SymbolReaderProvider = symbolReaderProvider; readerParameters.ReadSymbols = true; writerParameters.WriteSymbols = true; } var assemblyDefinition = AssemblyDefinition.ReadAssembly(assemblyPath, readerParameters); var weaver = new NotifierWeaver(); weaver.WeaveModule(assemblyDefinition.MainModule); assemblyDefinition.Write(assemblyPath, writerParameters); }