本文整理汇总了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;
}
}
}
示例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();
//.........这里部分代码省略.........
示例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();
}
示例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();
}