public void createMethod(MethodBase realMethod) { if (realMethodToNewMethod.ContainsKey(realMethod)) { return; } var newMethodInfo = new NewMethodInfo(realMethod, newMethodInfos.Count, getDelegateMethodName(realMethod), getDelegateMethodName(realMethod)); newMethodInfos.Add(newMethodInfo); delegateNameToNewMethodInfo[newMethodInfo.delegateMethodName] = newMethodInfo; delegateNameToNewMethodInfo[newMethodInfo.rewrittenMethodName] = newMethodInfo; realMethodToNewMethod[realMethod] = newMethodInfo; var moduleInfo = Resolver.loadAssembly(realMethod.Module); var methodInfo = moduleInfo.getMethod(realMethod); if (!methodInfo.hasInstructions()) { throw new ApplicationException(string.Format("Method {0} ({1:X8}) has no body", methodInfo.methodDef, methodInfo.methodDef.MDToken.Raw)); } var codeGenerator = new CodeGenerator(this, newMethodInfo.delegateMethodName); codeGenerator.setMethodInfo(methodInfo); newMethodInfo.delegateType = codeGenerator.DelegateType; var blocks = new Blocks(methodInfo.methodDef); foreach (var block in blocks.MethodBlocks.getAllBlocks()) { update(block, newMethodInfo); } IList <Instruction> allInstructions; IList <ExceptionHandler> allExceptionHandlers; blocks.getCode(out allInstructions, out allExceptionHandlers); newMethodInfo.delegateInstance = codeGenerator.generate(allInstructions, allExceptionHandlers); }
public void CreateMethod(MethodBase realMethod) { if (realMethodToNewMethod.ContainsKey(realMethod)) { return; } var newMethodInfo = new NewMethodInfo(realMethod, newMethodInfos.Count, GetDelegateMethodName(realMethod), GetDelegateMethodName(realMethod)); newMethodInfos.Add(newMethodInfo); delegateNameToNewMethodInfo[newMethodInfo.delegateMethodName] = newMethodInfo; delegateNameToNewMethodInfo[newMethodInfo.rewrittenMethodName] = newMethodInfo; realMethodToNewMethod[realMethod] = newMethodInfo; var moduleInfo = Resolver.LoadAssembly(realMethod.Module); var methodInfo = moduleInfo.GetMethod(realMethod); if (!methodInfo.HasInstructions()) { throw new ApplicationException($"Method {methodInfo.methodDef} ({methodInfo.methodDef.MDToken.Raw:X8}) has no body"); } var codeGenerator = new CodeGenerator(this, newMethodInfo.delegateMethodName); codeGenerator.SetMethodInfo(methodInfo); newMethodInfo.delegateType = codeGenerator.DelegateType; var blocks = new Blocks(methodInfo.methodDef); foreach (var block in blocks.MethodBlocks.GetAllBlocks()) { Update(block, newMethodInfo); } blocks.GetCode(out var allInstructions, out var allExceptionHandlers); newMethodInfo.delegateInstance = codeGenerator.Generate(allInstructions, allExceptionHandlers); }
void update(Block block, NewMethodInfo currentMethodInfo) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; if (instr.OpCode == OpCodes.Newobj) { var ctor = (IMethod)instr.Operand; var ctorTypeFullName = ctor.DeclaringType.FullName; if (ctorTypeFullName == "System.Diagnostics.StackTrace") { insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtFixStackTrace"); i += 2; continue; } else if (ctorTypeFullName == "System.Diagnostics.StackFrame") { insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtFixStackFrame"); i += 2; continue; } } if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt) { var calledMethod = (IMethod)instr.Operand; if (calledMethod.DeclaringType.DefinitionAssembly.IsCorLib()) { var calledMethodFullName = calledMethod.FullName; if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)") { block.replace(i, 1, OpCodes.Nop.ToInstruction()); insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg"); i += 2; continue; } else if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" || calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" || calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()") { block.replace(i, 1, OpCodes.Nop.ToInstruction()); insertLoadThis(block, i + 1); block.insert(i + 2, OpCodes.Ldc_I4.ToInstruction(currentMethodInfo.delegateIndex)); insertCallOurMethod(block, i + 3, "rtGetAssembly"); i += 3; continue; } } var method = Resolver.getMethod((IMethod)instr.Operand); if (method != null) { createMethod(method.methodBase); var newMethodInfo = realMethodToNewMethod[method.methodBase]; block.replace(i, 1, OpCodes.Nop.ToInstruction()); int n = i + 1; // Pop all pushed args to a temp array var mparams = getParameters(method.methodDef); if (mparams.Count > 0) { block.insert(n++, OpCodes.Ldc_I4.ToInstruction(mparams.Count)); var objectType = method.methodDef.DeclaringType.Module.CorLibTypes.Object; block.insert(n++, OpCodes.Newarr.ToInstruction(objectType)); block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray))); for (int j = mparams.Count - 1; j >= 0; j--) { var argType = mparams[j]; if (argType.RemovePinnedAndModifiers().IsValueType) { block.insert(n++, OpCodes.Box.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef)); } block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObj))); block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray))); block.insert(n++, OpCodes.Ldc_I4.ToInstruction(j)); block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObj))); block.insert(n++, OpCodes.Stelem_Ref.ToInstruction()); } } // Push delegate instance insertLoadThis(block, n++); block.insert(n++, OpCodes.Ldc_I4.ToInstruction(newMethodInfo.delegateIndex)); insertCallOurMethod(block, n++, "rtGetDelegateInstance"); block.insert(n++, create(OpCodes.Castclass, new Operand(Operand.Type.ReflectionType, newMethodInfo.delegateType))); // Push all popped args if (mparams.Count > 0) { for (int j = 0; j < mparams.Count; j++) { block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray))); block.insert(n++, OpCodes.Ldc_I4.ToInstruction(j)); block.insert(n++, OpCodes.Ldelem_Ref.ToInstruction()); var argType = mparams[j]; if (argType.RemovePinnedAndModifiers().IsValueType) { block.insert(n++, OpCodes.Unbox_Any.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef)); } else { // Don't cast it to its correct type. This will sometimes cause // an exception in some EF obfuscated assembly since we'll be // trying to cast a System.Reflection.AssemblyName type to some // other type. // block.insert(n++, Instruction.Create(OpCodes.Castclass, argType.ToTypeDefOrRef())); } } } insertLoadThis(block, n++); block.insert(n++, create(OpCodes.Call, new Operand(Operand.Type.NewMethod, method.methodBase))); i = n - 1; continue; } } } }
void update(Block block, NewMethodInfo currentMethodInfo) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; if (instr.OpCode == OpCodes.Newobj) { var ctor = (IMethod)instr.Operand; var ctorTypeFullName = ctor.DeclaringType.FullName; if (ctorTypeFullName == "System.Diagnostics.StackTrace") { insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtFixStackTrace"); i += 2; continue; } else if (ctorTypeFullName == "System.Diagnostics.StackFrame") { insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtFixStackFrame"); i += 2; continue; } } if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt) { var calledMethod = (IMethod)instr.Operand; if (calledMethod.DeclaringType.DefinitionAssembly.IsCorLib()) { var calledMethodFullName = calledMethod.FullName; if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)") { block.replace(i, 1, OpCodes.Nop.ToInstruction()); insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg"); i += 2; continue; } else if (calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" || calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" || calledMethodFullName == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()") { block.replace(i, 1, OpCodes.Nop.ToInstruction()); insertLoadThis(block, i + 1); block.insert(i + 2, OpCodes.Ldc_I4.ToInstruction(currentMethodInfo.delegateIndex)); insertCallOurMethod(block, i + 3, "rtGetAssembly"); i += 3; continue; } } var method = Resolver.getMethod((IMethod)instr.Operand); if (method != null) { createMethod(method.methodBase); var newMethodInfo = realMethodToNewMethod[method.methodBase]; block.replace(i, 1, OpCodes.Nop.ToInstruction()); int n = i + 1; // Pop all pushed args to a temp array var mparams = getParameters(method.methodDef); if (mparams.Count > 0) { block.insert(n++, OpCodes.Ldc_I4.ToInstruction(mparams.Count)); var objectType = method.methodDef.DeclaringType.Module.CorLibTypes.Object; block.insert(n++, OpCodes.Newarr.ToInstruction(objectType)); block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray))); for (int j = mparams.Count - 1; j >= 0; j--) { var argType = mparams[j]; if (argType.RemovePinnedAndModifiers().IsValueType) block.insert(n++, OpCodes.Box.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef)); block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObj))); block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray))); block.insert(n++, OpCodes.Ldc_I4.ToInstruction(j)); block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObj))); block.insert(n++, OpCodes.Stelem_Ref.ToInstruction()); } } // Push delegate instance insertLoadThis(block, n++); block.insert(n++, OpCodes.Ldc_I4.ToInstruction(newMethodInfo.delegateIndex)); insertCallOurMethod(block, n++, "rtGetDelegateInstance"); block.insert(n++, create(OpCodes.Castclass, new Operand(Operand.Type.ReflectionType, newMethodInfo.delegateType))); // Push all popped args if (mparams.Count > 0) { for (int j = 0; j < mparams.Count; j++) { block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray))); block.insert(n++, OpCodes.Ldc_I4.ToInstruction(j)); block.insert(n++, OpCodes.Ldelem_Ref.ToInstruction()); var argType = mparams[j]; if (argType.RemovePinnedAndModifiers().IsValueType) block.insert(n++, OpCodes.Unbox_Any.ToInstruction(((TypeDefOrRefSig)argType).TypeDefOrRef)); else { // Don't cast it to its correct type. This will sometimes cause // an exception in some EF obfuscated assembly since we'll be // trying to cast a System.Reflection.AssemblyName type to some // other type. // block.insert(n++, Instruction.Create(OpCodes.Castclass, argType.ToTypeDefOrRef())); } } } insertLoadThis(block, n++); block.insert(n++, create(OpCodes.Call, new Operand(Operand.Type.NewMethod, method.methodBase))); i = n - 1; continue; } } } }
public void createMethod(MethodBase realMethod) { if (realMethodToNewMethod.ContainsKey(realMethod)) return; var newMethodInfo = new NewMethodInfo(realMethod, newMethodInfos.Count, getDelegateMethodName(realMethod), getDelegateMethodName(realMethod)); newMethodInfos.Add(newMethodInfo); delegateNameToNewMethodInfo[newMethodInfo.delegateMethodName] = newMethodInfo; delegateNameToNewMethodInfo[newMethodInfo.rewrittenMethodName] = newMethodInfo; realMethodToNewMethod[realMethod] = newMethodInfo; var moduleInfo = Resolver.loadAssembly(realMethod.Module); var methodInfo = moduleInfo.getMethod(realMethod); if (!methodInfo.hasInstructions()) throw new ApplicationException(string.Format("Method {0} ({1:X8}) has no body", methodInfo.methodDef, methodInfo.methodDef.MDToken.Raw)); var codeGenerator = new CodeGenerator(this, newMethodInfo.delegateMethodName); codeGenerator.setMethodInfo(methodInfo); newMethodInfo.delegateType = codeGenerator.DelegateType; var blocks = new Blocks(methodInfo.methodDef); foreach (var block in blocks.MethodBlocks.getAllBlocks()) update(block, newMethodInfo); IList<Instruction> allInstructions; IList<ExceptionHandler> allExceptionHandlers; blocks.getCode(out allInstructions, out allExceptionHandlers); newMethodInfo.delegateInstance = codeGenerator.generate(allInstructions, allExceptionHandlers); }
void update(Block block, NewMethodInfo currentMethodInfo) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; if (instr.OpCode == OpCodes.Newobj) { var ctor = (MethodReference)instr.Operand; if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackTrace")) { insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtFixStackTrace"); i += 2; continue; } else if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackFrame")) { insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtFixStackFrame"); i += 2; continue; } } if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt) { var calledMethod = (MethodReference)instr.Operand; if (DotNetUtils.isSameAssembly(calledMethod.DeclaringType, "mscorlib")) { if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)") { block.replace(i, 1, Instruction.Create(OpCodes.Nop)); insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg"); i += 2; continue; } else if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" || calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" || calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()") { block.replace(i, 1, Instruction.Create(OpCodes.Nop)); insertLoadThis(block, i + 1); block.insert(i + 2, Instruction.Create(OpCodes.Ldc_I4, currentMethodInfo.delegateIndex)); insertCallOurMethod(block, i + 3, "rtGetAssembly"); i += 3; continue; } } var method = Resolver.getMethod((MethodReference)instr.Operand); if (method != null) { createMethod(method.methodBase); var newMethodInfo = realMethodToNewMethod[method.methodBase]; block.replace(i, 1, Instruction.Create(OpCodes.Nop)); int n = i + 1; // Pop all pushed args to a temp array var mparams = getParameters(method.methodDefinition); if (mparams.Count > 0) { block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, mparams.Count)); var objectType = method.methodDefinition.Module.TypeSystem.Object; block.insert(n++, Instruction.Create(OpCodes.Newarr, objectType)); block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray))); for (int j = mparams.Count - 1; j >= 0; j--) { var argType = mparams[j]; if (argType.IsValueType) { block.insert(n++, Instruction.Create(OpCodes.Box, argType)); } block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObj))); block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray))); block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j)); block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObj))); block.insert(n++, Instruction.Create(OpCodes.Stelem_Ref)); } } // Push delegate instance insertLoadThis(block, n++); block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, newMethodInfo.delegateIndex)); insertCallOurMethod(block, n++, "rtGetDelegateInstance"); block.insert(n++, create(OpCodes.Castclass, new Operand(Operand.Type.ReflectionType, newMethodInfo.delegateType))); // Push all popped args if (mparams.Count > 0) { for (int j = 0; j < mparams.Count; j++) { block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray))); block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j)); block.insert(n++, Instruction.Create(OpCodes.Ldelem_Ref)); var argType = mparams[j]; if (argType.IsValueType) { block.insert(n++, Instruction.Create(OpCodes.Unbox_Any, argType)); } else { // Don't cast it to its correct type. This will sometimes cause // an exception in some EF obfuscated assembly since we'll be // trying to cast a System.Reflection.AssemblyName type to some // other type. // block.insert(n++, Instruction.Create(OpCodes.Castclass, argType)); } } } insertLoadThis(block, n++); block.insert(n++, create(OpCodes.Call, new Operand(Operand.Type.NewMethod, method.methodBase))); i = n - 1; continue; } } } }
void update(Block block, NewMethodInfo currentMethodInfo) { var instrs = block.Instructions; for (int i = 0; i < instrs.Count; i++) { var instr = instrs[i]; if (instr.OpCode == OpCodes.Newobj) { var ctor = (MethodReference)instr.Operand; if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackTrace")) { insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtFixStackTrace"); i += 2; continue; } else if (MemberReferenceHelper.verifyType(ctor.DeclaringType, "mscorlib", "System.Diagnostics.StackFrame")) { insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtFixStackFrame"); i += 2; continue; } } if (instr.OpCode == OpCodes.Call || instr.OpCode == OpCodes.Callvirt) { var calledMethod = (MethodReference)instr.Operand; if (DotNetUtils.isSameAssembly(calledMethod.DeclaringType, "mscorlib")) { if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetAssembly(System.Type)") { block.replace(i, 1, Instruction.Create(OpCodes.Nop)); insertLoadThis(block, i + 1); insertCallOurMethod(block, i + 2, "static_rtGetAssembly_TypeArg"); i += 2; continue; } else if (calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetCallingAssembly()" || calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetEntryAssembly()" || calledMethod.ToString() == "System.Reflection.Assembly System.Reflection.Assembly::GetExecutingAssembly()") { block.replace(i, 1, Instruction.Create(OpCodes.Nop)); insertLoadThis(block, i + 1); block.insert(i + 2, Instruction.Create(OpCodes.Ldc_I4, currentMethodInfo.delegateIndex)); insertCallOurMethod(block, i + 3, "rtGetAssembly"); i += 3; continue; } } var method = Resolver.getMethod((MethodReference)instr.Operand); if (method != null) { createMethod(method.methodBase); var newMethodInfo = realMethodToNewMethod[method.methodBase]; block.replace(i, 1, Instruction.Create(OpCodes.Nop)); int n = i + 1; // Pop all pushed args to a temp array var mparams = getParameters(method.methodDefinition); if (mparams.Count > 0) { block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, mparams.Count)); var objectType = method.methodDefinition.Module.TypeSystem.Object; block.insert(n++, Instruction.Create(OpCodes.Newarr, objectType)); block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObjArray))); for (int j = mparams.Count - 1; j >= 0; j--) { var argType = mparams[j]; if (argType.IsValueType) block.insert(n++, Instruction.Create(OpCodes.Box, argType)); block.insert(n++, create(OpCodes.Stloc, new Operand(Operand.Type.TempObj))); block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray))); block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j)); block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObj))); block.insert(n++, Instruction.Create(OpCodes.Stelem_Ref)); } } // Push delegate instance insertLoadThis(block, n++); block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, newMethodInfo.delegateIndex)); insertCallOurMethod(block, n++, "rtGetDelegateInstance"); block.insert(n++, create(OpCodes.Castclass, new Operand(Operand.Type.ReflectionType, newMethodInfo.delegateType))); // Push all popped args if (mparams.Count > 0) { for (int j = 0; j < mparams.Count; j++) { block.insert(n++, create(OpCodes.Ldloc, new Operand(Operand.Type.TempObjArray))); block.insert(n++, Instruction.Create(OpCodes.Ldc_I4, j)); block.insert(n++, Instruction.Create(OpCodes.Ldelem_Ref)); var argType = mparams[j]; if (argType.IsValueType) block.insert(n++, Instruction.Create(OpCodes.Unbox_Any, argType)); else { // Don't cast it to its correct type. This will sometimes cause // an exception in some EF obfuscated assembly since we'll be // trying to cast a System.Reflection.AssemblyName type to some // other type. // block.insert(n++, Instruction.Create(OpCodes.Castclass, argType)); } } } insertLoadThis(block, n++); block.insert(n++, create(OpCodes.Call, new Operand(Operand.Type.NewMethod, method.methodBase))); i = n - 1; continue; } } } }