コード例 #1
0
        //获取函数的特性
        private static AddCustomTrace getTraceAttribute(TypeDefinition type, MethodDefinition method)
        {
            Type inejectClassType = Type.GetType(type.FullName);

            if (inejectClassType == null)
            {
                throw new NullReferenceException("Class Type is null, Attribute: " + type.FullName);
            }

            MethodInfo methodinfo = inejectClassType.GetMethod(method.Name);

            if (methodinfo == null)
            {
                throw new NullReferenceException("methodinfo in class " + type.FullName + " is null, method name: " + method.Name);
            }

            AddCustomTrace attr = (AddCustomTrace)methodinfo.GetCustomAttributes(typeof(AddCustomTrace), true)[0];

            if (attr == null)
            {
                throw new NullReferenceException("attr AddCustomTrace on method " + method.Name + " is null");
            }

            return(attr);
        }
コード例 #2
0
        private static void Inject(ModuleDefinition module, MethodDefinition method, TypeDefinition type)
        {
            if (module == null)
            {
                throw new ArgumentNullException("input argument invalid, module is null");
            }
            if (method == null)
            {
                throw new ArgumentNullException("input argument invalid, method is null");
            }
            if (type == null)
            {
                throw new ArgumentNullException("input argument invalid, type is null");
            }

            //获取方法AddCustomTrace
            AddCustomTrace attr = getTraceAttribute(type, method);

            //判断功能是否开启
            if (attr.enable != true)
            {
                //Debug.Log(method.Name + " close add custom trace attribute.");
                return;
            }
            //获取特性名称
            String name = attr.name;

            //更改待注入函数局部变量表
            method.Body.InitLocals = true;
            var customTraceType    = module.ImportReference(typeof(CustomTrace));
            var customTraceTypeDef = new VariableDefinition(customTraceType);

            method.Body.Variables.Add(customTraceTypeDef);
            //准备注入的函数
            MethodReference getInstance      = module.ImportReference(typeof(APMS).GetMethod("getInstance"));
            MethodReference createInstance   = module.ImportReference(typeof(APMS).GetMethod("createCustomTrace", new Type[] { typeof(string) }));
            MethodReference customTraceStart = module.ImportReference(typeof(CustomTrace).GetMethod("start"));
            MethodReference customTraceEnd   = module.ImportReference(typeof(CustomTrace).GetMethod("stop"));
            //设置一些标签用于语句跳转
            Instruction first = method.Body.Instructions[0];

            // 开始注入IL代码
            var ilProcessor = method.Body.GetILProcessor();

            ilProcessor.InsertBefore(first, ilProcessor.Create(OpCodes.Nop));
            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Call, getInstance));

            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Ldstr, name));
            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Callvirt, createInstance));
            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Stloc, customTraceTypeDef));

            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Ldloc, customTraceTypeDef));
            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Callvirt, customTraceStart));
            ilProcessor.InsertBefore(first, ilProcessor.Create(OpCodes.Nop));

            //在每一个返回的地方插入stop函数,注意插入指令之后,method.Body.Instructions.Count会增加,需要调整i值
            for (int i = 0; i < method.Body.Instructions.Count; i++)
            {
                Instruction ins  = method.Body.Instructions[i];
                OpCode      code = ins.OpCode;
                if (ins.OpCode.Equals(OpCodes.Ret) || ins.OpCode.Equals(OpCodes.Throw))
                {
                    //Debug.Log("method: " + method.Name  + "i: " + i + " code: " + code);
                    ilProcessor.InsertBefore(ins, ilProcessor.Create(OpCodes.Nop));
                    ilProcessor.InsertBefore(ins, Instruction.Create(OpCodes.Ldloc, customTraceTypeDef));
                    ilProcessor.InsertBefore(ins, Instruction.Create(OpCodes.Callvirt, customTraceEnd));
                    ilProcessor.InsertBefore(ins, ilProcessor.Create(OpCodes.Nop));
                    i += 4;
                }
            }
        }
コード例 #3
0
        private static void Inject(ModuleDefinition module, MethodDefinition method, TypeDefinition type, AssemblyDefinition assembly)
        {
            if (module == null)
            {
                throw new ArgumentNullException("input argument invalid, module is null");
            }
            if (method == null)
            {
                throw new ArgumentNullException("input argument invalid, method is null");
            }
            if (type == null)
            {
                throw new ArgumentNullException("input argument invalid, type is null");
            }

            //get AddCustomTrace attribute in method
            AddCustomTrace attr = getTraceAttribute(type, method, assembly);

            //whether the function is turned on
            if (attr.enable != true)
            {
                return;
            }
            //get name of attribute
            String name = attr.name;

            //Change the local variable table of the function to be injected
            method.Body.InitLocals = true;
            var customTraceType    = module.ImportReference(typeof(CustomTrace));
            var customTraceTypeDef = new VariableDefinition(customTraceType);

            method.Body.Variables.Add(customTraceTypeDef);

            //Prepare functions to be injected
            MethodReference getInstance      = module.ImportReference(typeof(APMS).GetMethod("getInstance"));
            MethodReference createInstance   = module.ImportReference(typeof(APMS).GetMethod("createCustomTrace", new Type[] { typeof(string) }));
            MethodReference customTraceStart = module.ImportReference(typeof(CustomTrace).GetMethod("start"));
            MethodReference customTraceEnd   = module.ImportReference(typeof(CustomTrace).GetMethod("stop"));

            //Set some labels for statement jump
            Instruction first = method.Body.Instructions[0];

            // start injecting IL code
            var ilProcessor = method.Body.GetILProcessor();

            ilProcessor.InsertBefore(first, ilProcessor.Create(OpCodes.Nop));
            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Call, getInstance));

            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Ldstr, name));
            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Callvirt, createInstance));
            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Stloc, customTraceTypeDef));

            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Ldloc, customTraceTypeDef));
            ilProcessor.InsertBefore(first, Instruction.Create(OpCodes.Callvirt, customTraceStart));
            ilProcessor.InsertBefore(first, ilProcessor.Create(OpCodes.Nop));

            //Insert stop functions at every return. Note that after inserting the instruction,
            //method.Body.Instructions.Count increment,and need to adjust the value of i
            for (int i = 0; i < method.Body.Instructions.Count; i++)
            {
                Instruction ins  = method.Body.Instructions[i];
                OpCode      code = ins.OpCode;
                if (ins.OpCode.Equals(OpCodes.Ret) || ins.OpCode.Equals(OpCodes.Throw))
                {
                    //Debug.Log("method: " + method.Name  + "i: " + i + " code: " + code);
                    ilProcessor.InsertBefore(ins, ilProcessor.Create(OpCodes.Nop));
                    ilProcessor.InsertBefore(ins, Instruction.Create(OpCodes.Ldloc, customTraceTypeDef));
                    ilProcessor.InsertBefore(ins, Instruction.Create(OpCodes.Callvirt, customTraceEnd));
                    ilProcessor.InsertBefore(ins, ilProcessor.Create(OpCodes.Nop));
                    i += 4;
                }
            }
        }