Inheritance: ISymbolReaderProvider
示例#1
1
        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;
        }
示例#2
0
 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);
 }
示例#3
0
        /// <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);
        }
    }
示例#5
0
        /// <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;
        }
示例#6
0
        /// <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);
        }
示例#7
0
        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;
        }
示例#9
0
 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;
 }
示例#10
0
 /// <summary>
 /// 
 /// </summary>
 /// <param name="assemblyPath"></param>
 /// <param name="currentPath"></param>
 /// <param name="savePath"></param>
 /// <returns></returns>
 public static bool BuildToFile(string assemblyPath, string currentPath, string savePath = null)
 {
     bool setSuccess = false;
     if (string.IsNullOrEmpty(savePath))
     {
         savePath = assemblyPath;
     }
     string pdbFile = Path.ChangeExtension(assemblyPath, "pdb");
     PdbReaderProvider readerProvider = null;
     PdbWriterProvider writerProvider = null;
     bool debug = false;
     if (File.Exists(pdbFile))
     {
         debug = true;
         readerProvider = new PdbReaderProvider();
         writerProvider = new PdbWriterProvider();
     }
     //huhu modify reason: Support for model debugging.
     var ass = AssemblyDefinition.ReadAssembly(assemblyPath, new ReaderParameters
     {
         SymbolReaderProvider = readerProvider,
         ReadSymbols = debug
     });
     BaseAssemblyResolver resolver = ass.MainModule.AssemblyResolver as BaseAssemblyResolver;
     if (resolver != null)
     {
         resolver.AddSearchDirectory(currentPath);
     }
     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;
 }
示例#11
0
        /// <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);
            }));
        });
    }
示例#13
0
        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);
        }
示例#14
0
        /// <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;
        }
示例#15
0
        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
                //}

            }

        }
示例#16
0
        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;
        }
示例#17
0
文件: Program.cs 项目: tritao/flood
        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);
        }