private static void CreatePatchedMethod(ILContext il) { ILCursor c = new ILCursor(il); // The original method uses System.Reflection.Emit. System.Type t_DynamicTools = GetHarmonyType("DynamicTools"); // Find and replace DynamicTools.CreateDynamicMethod if (!c.TryGotoNext(i => i.MatchCall(t_DynamicTools, "CreateDynamicMethod"))) { // Not the right method. Harmony defines two CreatePatchedMethod methods. il.MakeReadOnly(); return; } c.Next.OpCode = OpCodes.Call; c.Next.Operand = il.Import(typeof(HarmonyDetourBridge).GetMethod("CreateDMD", BindingFlags.NonPublic | BindingFlags.Static)); // Find the variable holding the "dynamic method" and update it. int varDMDi = -1; c.GotoNext(i => i.MatchStloc(out varDMDi)); VariableDefinition varDMD = il.Body.Variables[varDMDi]; varDMD.VariableType = il.Import(typeof(DynamicMethodDefinition)); // Find and replace patch.GetILGenerator c.GotoNext(i => i.MatchCallvirt<System.Reflection.Emit.DynamicMethod>("GetILGenerator")); c.Next.OpCode = OpCodes.Call; c.Next.Operand = il.Import(typeof(DynamicMethodDefinition).GetMethod("GetILGenerator", BindingFlags.Public | BindingFlags.Instance)); // Find and remove DynamicTools.PrepareDynamicMethod c.GotoNext(i => i.MatchCall(t_DynamicTools, "PrepareDynamicMethod")); c.Next.OpCode = OpCodes.Pop; c.Next.Operand = null; // Go to the next ldloc that loads the DynamicMethod. // No matter if it gets stored into a local variable or returned immediately, // grab it, store it separately and push null as a replacement. c.GotoNext(i => i.MatchLdloc(varDMDi)); c.Index++; c.EmitDelegate<Func<DynamicMethodDefinition, System.Reflection.Emit.DynamicMethod>>(dmd => { _LastWrapperDMD = dmd; return null; }); }