当前位置: 首页>>代码示例>>C#>>正文


C# MethodBody.OptimizeMacros方法代码示例

本文整理汇总了C#中Mono.Cecil.Cil.MethodBody.OptimizeMacros方法的典型用法代码示例。如果您正苦于以下问题:C# MethodBody.OptimizeMacros方法的具体用法?C# MethodBody.OptimizeMacros怎么用?C# MethodBody.OptimizeMacros使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在Mono.Cecil.Cil.MethodBody的用法示例。


在下文中一共展示了MethodBody.OptimizeMacros方法的4个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: RewriteObjectListToParamsCall


//.........这里部分代码省略.........
        // Basically, just before the invalid function call we pack all the arguments (that are already on the stack,
        // ready to be passed to invalid function) to a newly created array and call a valid function instead passing
        // the array as argument
        //
        public void RewriteObjectListToParamsCall(MethodBody methodBody, int instructionIndex)
        {
            methodBody.SimplifyMacros();

            var parameterType = ParamsMethod.Parameters.Last().ParameterType;
            var arrayInfo = new VariableDefinition(parameterType);
            methodBody.InitLocals = true;
            methodBody.Variables.Add(arrayInfo);

            var instruction = methodBody.Instructions[instructionIndex];
            int numberOfObjects = (instruction.Operand as MethodReference).Parameters.Count - ParamsMethod.Parameters.Count + 1;

            // Firstly, let's create the object array

            // Push number of objects to the stack
            var instr = Instruction.Create(OpCodes.Ldc_I4, numberOfObjects);
            var firstInstruction = instr;
            methodBody.Instructions.Insert(instructionIndex, instr);
            instructionIndex++;

            // Create a new array
            instr = Instruction.Create(OpCodes.Newarr, ParamsMethod.Parameters.Last().ParameterType.GetElementType());
            methodBody.Instructions.Insert(instructionIndex, instr);
            instructionIndex++;

            // Store the newly created array to first variable slot
            instr = Instruction.Create(OpCodes.Stloc, arrayInfo);
            methodBody.Instructions.Insert(instructionIndex, instr);
            instructionIndex++;

            // At this point, all the references to objects that need to be packed to the array are on the stack.
            var objectInfo = new VariableDefinition[numberOfObjects];
            for (int i = 0; i < numberOfObjects; i++)
            {
                objectInfo[i] = new VariableDefinition(parameterType.GetElementType());
                methodBody.Variables.Add(objectInfo[i]);

                instr = Instruction.Create(OpCodes.Stloc, objectInfo[i]);
                methodBody.Instructions.Insert(instructionIndex, instr);
                instructionIndex++;
            }

            // Now that we got the references to objects in local variables rather than the stack, it's high time we insert them to the array
            // We need to load them in backwards order, because the last argument was taken off the stack first.
            for (int i = 0; i < numberOfObjects; i++)
            {
                // Load reference to the array to the stack
                instr = Instruction.Create(OpCodes.Ldloc, arrayInfo);
                methodBody.Instructions.Insert(instructionIndex, instr);
                instructionIndex++;

                // Load object index to the stack
                instr = Instruction.Create(OpCodes.Ldc_I4, numberOfObjects - i - 1);
                methodBody.Instructions.Insert(instructionIndex, instr);
                instructionIndex++;

                // Load reference to the object to the stack
                instr = Instruction.Create(OpCodes.Ldloc, objectInfo[i]);
                methodBody.Instructions.Insert(instructionIndex, instr);
                instructionIndex++;

                // Insert the object to the array
                if (parameterType.GetElementType().IsValueType)
                {
                    instr = Instruction.Create(OpCodes.Stelem_Any, parameterType.GetElementType());
                    methodBody.Instructions.Insert(instructionIndex, instr);
                    instructionIndex++;
                }
                else
                {
                    instr = Instruction.Create(OpCodes.Stelem_Ref);
                    methodBody.Instructions.Insert(instructionIndex, instr);
                    instructionIndex++;
                }
            }

            // Finally, load reference to the array to the stack so it can be inserted to the array
            instr = Instruction.Create(OpCodes.Ldloc, arrayInfo);
            methodBody.Instructions.Insert(instructionIndex, instr);

            instruction.Operand = ParamsMethod;
            ParamsMethod = null;
            MethodChanged = false;
            methodBody.OptimizeMacros();		// This, together with SimplifyMacros() before touching IL code, recalculates IL instruction offsets

            // If any other instruction is referencing the illegal call, we need to rewrite it to reference beginning of object packing instead
            // For example, there's a branch jump to call the method. We need to pack the objects anyway before calling the method
            foreach (var changeableInstruction in methodBody.Instructions)
            {
                if (changeableInstruction.Operand is Instruction &&
                    (changeableInstruction as Instruction).Operand == instruction)
                {
                    changeableInstruction.Operand = firstInstruction;
                }
            }
        }
开发者ID:Unity-Technologies,项目名称:ReferenceRewriter,代码行数:101,代码来源:RewriteTypeReferences.cs

示例2: DirectCallMethod

            public DirectCallMethod(ModuleDefinition module, TypeDefinition type)
            {
                this.module = module;
                this.type = type;

                getLength = module.Import(typeof(string).GetMethod("get_Length", new Type[0]));
                getChars = module.Import(typeof(string).GetMethod("get_Chars", new[] { typeof(int) }));
                isNullOrEmpty = module.Import(typeof(string).GetMethod("IsNullOrEmpty"));

                // Copy method definition from base class
                var base_assembly = AssemblyDefinition.ReadAssembly("HookDispatch.exe");
                var base_module = base_assembly.MainModule;
                var base_type = base_assembly.MainModule.GetType("Oxide.Plugins.Plugin");
                var base_method = base_type.Methods.First(method => method.Name == "DirectCallHook");

                // Create method override based on virtual method signature
                method = new MethodDefinition(base_method.Name, base_method.Attributes, base_module.Import(base_method.ReturnType));
                foreach (var parameter in base_method.Parameters)
                    method.Parameters.Add(new ParameterDefinition(base_module.Import(parameter.ParameterType)) {Name = parameter.Name, IsOut = parameter.IsOut});

                method.ImplAttributes = base_method.ImplAttributes;
                method.SemanticsAttributes = base_method.SemanticsAttributes;

                // Replace the NewSlot attribute with ReuseSlot
                method.Attributes &= ~Mono.Cecil.MethodAttributes.NewSlot;
                method.Attributes |= Mono.Cecil.MethodAttributes.ReuseSlot;

                // Create new method body
                body = new Mono.Cecil.Cil.MethodBody(method);
                body.SimplifyMacros();
                method.Body = body;
                type.Methods.Add(method);

                // Create variables
                body.Variables.Add(new VariableDefinition("name_size", module.TypeSystem.Int32));
                body.Variables.Add(new VariableDefinition("i", module.TypeSystem.Int32));

                // Initialize return value to null
                AddInstruction(OpCodes.Ldarg_2);
                AddInstruction(OpCodes.Ldnull);
                AddInstruction(OpCodes.Stind_Ref);

                // Check for name null or empty
                AddInstruction(OpCodes.Ldarg_1);
                AddInstruction(OpCodes.Call, isNullOrEmpty);
                var empty = AddInstruction(OpCodes.Brfalse, body.Instructions[0]);
                Return(false);

                // Get method name length
                empty.Operand = AddInstruction(OpCodes.Ldarg_1);
                AddInstruction(OpCodes.Callvirt, getLength);
                AddInstruction(OpCodes.Stloc_0);

                // Initialize i counter variable to 0
                AddInstruction(OpCodes.Ldc_I4_0);
                AddInstruction(OpCodes.Stloc_1);

                // Find all hook methods defined by the plugin
                hookMethods = type.Methods.Where(m => !m.IsStatic && m.IsPrivate).ToDictionary(m => m.Name, m => m);

                // Build a hook method name trie
                var root_node = new Node();
                foreach (var method_name in hookMethods.Keys)
                {
                    var current_node = root_node;
                    for (var i = 1; i <= method_name.Length; i++)
                    {
                        var letter = method_name[i - 1];
                        Node next_node;
                        if (!current_node.Edges.TryGetValue(letter, out next_node))
                        {
                            next_node = new Node { Parent = current_node, Char = letter };
                            if (i == method_name.Length) next_node.Name = method_name;
                            current_node.Edges[letter] = next_node;
                        }
                        current_node = next_node;
                    }
                }

                // Build conditional method call logic from trie nodes
                var n = 1;
                foreach (var edge in root_node.Edges.Keys)
                    BuildNode(root_node.Edges[edge], n++);

                // No valid method was found
                endInstruction = Return(false);

                foreach (var instruction in jumpToEdgePlaceholderTargets.Keys)
                {
                    instruction.Operand = jumpToEdgePlaceholderTargets[instruction].FirstInstruction;
                }

                foreach (var instruction in jumpToEndPlaceholders)
                {
                    instruction.Operand = endInstruction;
                }

                //UpdateInstructions();

                body.OptimizeMacros();
//.........这里部分代码省略.........
开发者ID:Nogrod,项目名称:HookDispatch,代码行数:101,代码来源:Program.cs

示例3: DirectCallMethod


//.........这里部分代码省略.........
            {
                var new_param = new ParameterDefinition(parameter.Name, parameter.Attributes, base_module.Import(parameter.ParameterType))
                {
                    IsOut = parameter.IsOut,
                    Constant = parameter.Constant,
                    MarshalInfo = parameter.MarshalInfo,
                    IsReturnValue = parameter.IsReturnValue
                };
                foreach (var attribute in parameter.CustomAttributes)
                    new_param.CustomAttributes.Add(new CustomAttribute(module.Import(attribute.Constructor)));
                method.Parameters.Add(new_param);
            }

            foreach (var attribute in base_method.CustomAttributes)
                method.CustomAttributes.Add(new CustomAttribute(module.Import(attribute.Constructor)));

            method.ImplAttributes = base_method.ImplAttributes;
            method.SemanticsAttributes = base_method.SemanticsAttributes;

            // Replace the NewSlot attribute with ReuseSlot
            method.Attributes &= ~MethodAttributes.NewSlot;
            method.Attributes |= MethodAttributes.ReuseSlot;

            // Create new method body
            body = new MethodBody(method);
            body.SimplifyMacros();
            method.Body = body;
            type.Methods.Add(method);

            // Create variables
            body.Variables.Add(new VariableDefinition("name_size", module.TypeSystem.Int32));
            body.Variables.Add(new VariableDefinition("i", module.TypeSystem.Int32));

            // Initialize return value to null
            AddInstruction(OpCodes.Ldarg_2);
            AddInstruction(OpCodes.Ldnull);
            AddInstruction(OpCodes.Stind_Ref);

            // Check for name null or empty
            AddInstruction(OpCodes.Ldarg_1);
            AddInstruction(OpCodes.Call, isNullOrEmpty);
            var empty = AddInstruction(OpCodes.Brfalse, body.Instructions[0]);
            Return(false);

            // Get method name length
            empty.Operand = AddInstruction(OpCodes.Ldarg_1);
            AddInstruction(OpCodes.Callvirt, getLength);
            AddInstruction(OpCodes.Stloc_0);

            // Initialize i counter variable to 0
            AddInstruction(OpCodes.Ldc_I4_0);
            AddInstruction(OpCodes.Stloc_1);

            // Find all hook methods defined by the plugin
            foreach (var m in type.Methods.Where(m => !m.IsStatic && m.IsPrivate && !m.HasGenericParameters && !m.ReturnType.IsGenericParameter && m.DeclaringType == type && !m.IsSetter && !m.IsGetter))
            {
                //ignore compiler generated
                if (m.Name.Contains("<")) continue;
                if (!hookMethods.ContainsKey(m.Name)) hookMethods[m.Name] = m;
            }

            // Build a hook method name trie
            var root_node = new Node();
            foreach (var method_name in hookMethods.Keys)
            {
                var current_node = root_node;
                for (var i = 1; i <= method_name.Length; i++)
                {
                    var letter = method_name[i - 1];
                    Node next_node;
                    if (!current_node.Edges.TryGetValue(letter, out next_node))
                    {
                        next_node = new Node { Parent = current_node, Char = letter };
                        current_node.Edges[letter] = next_node;
                    }
                    if (i == method_name.Length) next_node.Name = method_name;
                    current_node = next_node;
                }
            }

            // Build conditional method call logic from trie nodes
            var n = 1;
            foreach (var edge in root_node.Edges.Keys)
                BuildNode(root_node.Edges[edge], n++);

            // No valid method was found
            endInstruction = Return(false);

            foreach (var instruction in jumpToEdgePlaceholderTargets.Keys)
            {
                instruction.Operand = jumpToEdgePlaceholderTargets[instruction].FirstInstruction;
            }

            foreach (var instruction in jumpToEndPlaceholders)
            {
                instruction.Operand = endInstruction;
            }

            body.OptimizeMacros();
        }
开发者ID:906507516,项目名称:Oxide,代码行数:101,代码来源:DirectCallMethod.cs

示例4: InnerProcess

        private void InnerProcess(MethodDefinition method, bool returnVoid, ReferenceContainer references)
        {
            body = method.Body;
            body.SimplifyMacros();

            if (body.Instructions.Count <= 3)
                return; // nothing to do (empty method)

            HandleReturnType(method, returnVoid, references);

            var ilProcessor = body.GetILProcessor();

            var firstInstruction = FirstInstructionSkipCtor(method);

            firstInstruction = RejigFirstInstruction(ilProcessor, firstInstruction);

            InjectContext(ilProcessor, firstInstruction, method, references);
            var returnInstruction = FixReturns();

            var beforeReturn = Instruction.Create(OpCodes.Nop);
            ilProcessor.InsertBefore(returnInstruction, beforeReturn);

            // exclude try-catch from constructors (lot's of pain otherwise)
            if (!method.IsConstructor)
            {
                var beginCatch = InjectIlForCatch(ilProcessor, beforeReturn, references);
                var beginFinally = InjectIlForFinaly(ilProcessor, beforeReturn, references);

                var catchHandler = new ExceptionHandler(ExceptionHandlerType.Catch)
                    {
                        TryStart = firstInstruction,
                        TryEnd = beginCatch,
                        CatchType = references.ExceptionType,
                        HandlerStart = beginCatch,
                        HandlerEnd = beginFinally,
                    };

                body.ExceptionHandlers.Add(catchHandler);

                var finallyHandler = new ExceptionHandler(ExceptionHandlerType.Finally)
                    {
                        TryStart = firstInstruction,
                        TryEnd = beginFinally,
                        HandlerStart = beginFinally,
                        HandlerEnd = beforeReturn,
                    };

                body.ExceptionHandlers.Add(finallyHandler);
            }
            else
            {
                InjectIlForDispose(ilProcessor, returnInstruction, references);
            }

            body.InitLocals = true;
            body.OptimizeMacros();
        }
开发者ID:mdabbagh88,项目名称:YALF,代码行数:57,代码来源:MethodProcessor.cs


注:本文中的Mono.Cecil.Cil.MethodBody.OptimizeMacros方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。