本文整理汇总了C#中Mono.Cecil.Cil.MethodBody.SimplifyMacros方法的典型用法代码示例。如果您正苦于以下问题:C# MethodBody.SimplifyMacros方法的具体用法?C# MethodBody.SimplifyMacros怎么用?C# MethodBody.SimplifyMacros使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类Mono.Cecil.Cil.MethodBody
的用法示例。
在下文中一共展示了MethodBody.SimplifyMacros方法的6个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: RewriteObjectListToParamsCall
// The idea behind this method is to change method call from Method(obj1, obj2, obj3) to Method(param Object[] objs)
// To do that, we need to first pack all the objects to an array, then push the array onto the stack before calling the method.
// Creating an array is achieved by pushing number of elements on the stack, and using newarr instruction.
// Lastly, we need to pop the array back from the stack and store it in a local variable.
//
// Putting object to array is done by:
// Loading array to the stack, loading index to the stack, loading the reference to value on the stack
// and using stelem.ref to insert it to the array. stelem.ref instruction pops all three inserted values
// from the stack
//
// For example, we need to convert something like this:
//
// IL_0000: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
// IL_0005: stloc.0
// IL_0006: ldloc.0
// IL_0007: ldstr "{0}, {1}"
// IL_000c: ldstr "one"
// IL_0011: ldstr "two"
// IL_0016: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::AppendFormat(string, object[])
// IL_001b: pop
//
// To this:
//
// IL_0000: newobj instance void [mscorlib]System.Text.StringBuilder::.ctor()
// IL_0005: stloc.0
// IL_0006: ldloc.0
// IL_0007: ldstr "{0}, {1}\r\n"
// IL_000c: ldstr "one"
// IL_0011: ldstr "two"
// IL_0016: ldc.i4 2
// IL_001b: newarr [mscorlib]System.Object
// IL_0020: stloc 1
// IL_0024: stloc 2
// IL_0028: stloc 3
// IL_002c: ldloc 1
// IL_0030: ldc.i4 0
// IL_0035: ldloc 2
// IL_0039: stelem.ref
// IL_003a: ldloc 1
// IL_003e: ldc.i4 1
// IL_0043: ldloc 3
// IL_0047: stelem.ref
// IL_0048: ldloc 1
// IL_004c: callvirt instance class [mscorlib]System.Text.StringBuilder [mscorlib]System.Text.StringBuilder::AppendFormat(string, object[])
// IL_0051: pop
//
// 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++;
//.........这里部分代码省略.........
示例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", new[] { typeof(string) }));
stringEquals = module.Import(typeof(string).GetMethod("Equals", new[] { typeof(string) }));
// Copy method definition from base class
var base_assembly = AssemblyDefinition.ReadAssembly(Path.Combine(Interface.Oxide.ExtensionDirectory, "Oxide.Ext.CSharp.dll"));
var base_module = base_assembly.MainModule;
var base_type = module.Import(base_assembly.MainModule.GetType("Oxide.Plugins.CSharpPlugin")).Resolve();
var base_method = module.Import(base_type.Methods.First(method => method.Name == "DirectCallHook")).Resolve();
// Create method override based on virtual method signature
method = new MethodDefinition(base_method.Name, base_method.Attributes, base_module.Import(base_method.ReturnType)) { DeclaringType = type };
foreach (var parameter in base_method.Parameters)
{
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
//.........这里部分代码省略.........
示例3: Mutate
public void Mutate(Random rand, MethodBody body)
{
body.SimplifyMacros();
foreach (var i in body.Instructions)
{
FieldReference field = i.Operand as FieldReference;
if (field != null && field.DeclaringType.FullName == "Mutation")
{
switch (field.Name)
{
case "Key0I":
i.Operand = IntKeys[0]; goto case "I";
case "Key1I":
i.Operand = IntKeys[1]; goto case "I";
case "Key2I":
i.Operand = IntKeys[2]; goto case "I";
case "Key3I":
i.Operand = IntKeys[3]; goto case "I";
case "Key4I":
i.Operand = IntKeys[4]; goto case "I";
case "Key5I":
i.Operand = IntKeys[5]; goto case "I";
case "Key6I":
i.Operand = IntKeys[6]; goto case "I";
case "Key7I":
i.Operand = IntKeys[7]; goto case "I";
case "Key0L":
i.Operand = LongKeys[0]; goto case "L";
case "Key1L":
i.Operand = LongKeys[1]; goto case "L";
case "Key2L":
i.Operand = LongKeys[2]; goto case "L";
case "Key3L":
i.Operand = LongKeys[3]; goto case "L";
case "Key4L":
i.Operand = LongKeys[4]; goto case "L";
case "Key5L":
i.Operand = LongKeys[5]; goto case "L";
case "Key6L":
i.Operand = LongKeys[6]; goto case "L";
case "Key7L":
i.Operand = LongKeys[7]; goto case "L";
case "Key0S":
i.Operand = StringKeys[0]; goto case "S";
case "Key1S":
i.Operand = StringKeys[1]; goto case "S";
case "Key2S":
i.Operand = StringKeys[2]; goto case "S";
case "Key3S":
i.Operand = StringKeys[3]; goto case "S";
case "Key0Delayed":
if (IsDelayed)
{
i.Operand = DelayedKeys[0];
goto case "I";
}
else
Delayed0 = i;
break;
case "Key1Delayed":
if (IsDelayed)
{
i.Operand = DelayedKeys[1];
goto case "I";
}
else
Delayed1 = i;
break;
case "I":
i.OpCode = OpCodes.Ldc_I4; break;
case "L":
i.OpCode = OpCodes.Ldc_I8; break;
case "S":
i.OpCode = OpCodes.Ldstr; break;
}
}
MethodReference method = i.Operand as MethodReference;
if (method != null && method.DeclaringType.FullName == "Mutation")
{
if (method.Name == "Placeholder")
Placeholder = i;
else if (method.Name == "DeclaringType")
{
i.OpCode = OpCodes.Ldtoken;
i.Operand = body.Method.DeclaringType;
}
else if (method.Name == "Method")
{
var str = (string)i.Previous.Operand;
i.OpCode = OpCodes.Ldtoken;
i.Operand = body.Method.DeclaringType.Methods.Single(m => m.Name == str);
i.Previous.OpCode = OpCodes.Nop;
i.Previous.Operand = null;
}
else if (method.Name == "Break")
{
//.........这里部分代码省略.........
示例4: 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();
//.........这里部分代码省略.........
示例5: Convert
/// <summary>
/// Convert all synchronized methods.
/// </summary>
private static void Convert(MethodBody body)
{
var typeSystem = body.Method.Module.TypeSystem;
var monitorType = typeSystem.LookupType("System.Threading", "Monitor");
var enterMethod = new MethodReference("Enter", typeSystem.Void, monitorType);
enterMethod.Parameters.Add(new ParameterDefinition(typeSystem.Object));
var exitMethod = new MethodReference("Exit", typeSystem.Void, monitorType);
exitMethod.Parameters.Add(new ParameterDefinition(typeSystem.Object));
var firstInstr = body.Instructions[0];
// Expand macro's
body.SimplifyMacros();
// Prepare new return
var retSeq = new ILSequence();
retSeq.Emit(OpCodes.Nop);
retSeq.Emit(OpCodes.Ret);
// Monitor.Enter(this)
var initSeq = new ILSequence();
initSeq.Emit(OpCodes.Ldarg_0); // ld this
initSeq.Emit(OpCodes.Call, enterMethod);
initSeq.InsertTo(0, body);
// Leave sequence
var leaveSeq = new ILSequence();
leaveSeq.Emit(OpCodes.Nop);
leaveSeq.Emit(OpCodes.Leave, retSeq.First);
leaveSeq.AppendTo(body);
// Finally: Monitor.Exit(this)
var finallySeq = new ILSequence();
finallySeq.Emit(OpCodes.Ldarg_0); // ld this
finallySeq.Emit(OpCodes.Call, exitMethod);
finallySeq.Emit(OpCodes.Endfinally);
finallySeq.AppendTo(body);
// Replace Ret instructions
foreach (var instr in body.Instructions.Where(x => x.OpCode.Code == Mono.Cecil.Cil.Code.Ret))
{
if (instr.Next == leaveSeq.First)
{
instr.ChangeToNop();
}
else
{
instr.OpCode = OpCodes.Br;
instr.Operand = leaveSeq.First;
}
}
// Append ret sequence
retSeq.AppendTo(body);
// Update offsets
body.ComputeOffsets();
// Add try/finally block
var handler = new ExceptionHandler(ExceptionHandlerType.Finally);
handler.TryStart = firstInstr;
handler.TryEnd = finallySeq.First; // leaveSeq.Last;
handler.HandlerStart = finallySeq.First;
handler.HandlerEnd = retSeq.First; // finallySeq.Last;
body.ExceptionHandlers.Insert(0, handler);
}
示例6: 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();
}