BepInEx / HarmonyX

Harmony built on top of MonoMod.RuntimeDetours with additional features
MIT License
329 stars 42 forks source link

Reverse patches appears to be broken #111

Open Meivyn opened 1 month ago

Meivyn commented 1 month ago

Followup of https://github.com/BepInEx/HarmonyX/pull/79#issuecomment-1979530297.

HarmonyLib.HarmonyException: IL Compile Error (unknown location) ---> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
  at Mono.Collections.Generic.Collection`1[T].get_Item (System.Int32 index) [0x00009] in <1f38765308444399b8db490e5065ff6f>:0
  at MonoMod.Utils.Cil.CecilILGenerator._EmitInlineVar (Mono.Cecil.Cil.OpCode opcode, System.Int32 index) [0x0004c] in <119a8e5581064dd58d95959152c2aa57>:0
  at MonoMod.Utils.Cil.CecilILGenerator.Emit (System.Reflection.Emit.OpCode opcode, System.Byte arg) [0x0001d] in <119a8e5581064dd58d95959152c2aa57>:0
  at (wrapper dynamic-method) MonoMod.Utils.DynamicMethodDefinition.EmitOpcodeWithOperand(MonoMod.Utils.Cil.CecilILGenerator,System.Reflection.Emit.OpCode,object)
  at (wrapper delegate-invoke) System.Action`3[MonoMod.Utils.Cil.CecilILGenerator,System.Reflection.Emit.OpCode,System.Object].invoke_void_T1_T2_T3(MonoMod.Utils.Cil.CecilILGenerator,System.Reflection.Emit.OpCode,object)
  at HarmonyLib.Internal.Util.EmitterExtensions.Emit (MonoMod.Utils.Cil.CecilILGenerator il, System.Reflection.Emit.OpCode opcode, System.Object operand) [0x00000] in <0d9c13022e544ce89c806f0f14d8e072>:0
  at HarmonyLib.Internal.Patching.ILManipulator.WriteTo (Mono.Cecil.Cil.MethodBody body, System.Reflection.MethodBase original) [0x0017a] in <0d9c13022e544ce89c806f0f14d8e072>:0
  at HarmonyLib.PatchFunctions+<>c__DisplayClass3_0.<ReversePatch>b__1 (MonoMod.Cil.ILContext ctx) [0x0016f] in <0d9c13022e544ce89c806f0f14d8e072>:0
  at MonoMod.Cil.ILContext.Invoke (MonoMod.Cil.ILContext+Manipulator manip) [0x00092] in <119a8e5581064dd58d95959152c2aa57>:0
  at MonoMod.RuntimeDetour.DetourManager+ManagedDetourState.InvokeManipulator (MonoMod.RuntimeDetour.DetourManager+ILHookEntry entry, Mono.Cecil.MethodDefinition def) [0x0001c] in <667886c0b83048cbaa73a76b37c17c40>:0
  at MonoMod.RuntimeDetour.DetourManager+ManagedDetourState.UpdateEndOfChain () [0x0008b] in <667886c0b83048cbaa73a76b37c17c40>:0
  at MonoMod.RuntimeDetour.DetourManager+ManagedDetourState.AddILHook (MonoMod.RuntimeDetour.DetourManager+SingleILHookState ilhook, System.Boolean takeLock) [0x00079] in <667886c0b83048cbaa73a76b37c17c40>:0
  at MonoMod.RuntimeDetour.ILHook.Apply () [0x00052] in <667886c0b83048cbaa73a76b37c17c40>:0
  at HarmonyLib.PatchFunctions.ReversePatch (HarmonyLib.HarmonyMethod standin, System.Reflection.MethodBase original, System.Reflection.MethodInfo postTranspiler, System.Reflection.MethodInfo postManipulator) [0x0016e] in <0d9c13022e544ce89c806f0f14d8e072>:0
   --- End of inner exception stack trace ---
  at HarmonyLib.PatchClassProcessor.ReportException (System.Exception exception, System.Reflection.MethodBase original) [0x00045] in <0d9c13022e544ce89c806f0f14d8e072>:0
  at HarmonyLib.PatchClassProcessor.Patch () [0x00095] in <0d9c13022e544ce89c806f0f14d8e072>:0
  at HarmonyLib.Harmony.<PatchAll>b__11_0 (System.Type type) [0x00007] in <0d9c13022e544ce89c806f0f14d8e072>:0
  at HarmonyLib.CollectionExtensions.Do[T] (System.Collections.Generic.IEnumerable`1[T] sequence, System.Action`1[T] action) [0x00014] in <0d9c13022e544ce89c806f0f14d8e072>:0
  at HarmonyLib.Harmony.PatchAll (System.Reflection.Assembly assembly) [0x00006] in <0d9c13022e544ce89c806f0f14d8e072>:0
  at HarmonyLib.Harmony.CreateAndPatchAll (System.Reflection.Assembly assembly, System.String harmonyInstanceId) [0x0006a] in <0d9c13022e544ce89c806f0f14d8e072>:0
  at BSPlugin5.Plugin..ctor (IPA.Logging.Logger logger, IPA.Loader.PluginMetadata metadata) [0x0000c] in C:\Users\Meivyn\RiderProjects\BSPlugin5\BSPlugin5\Plugin.cs:22
  at (wrapper dynamic-method) System.Object.lambda_method(System.Runtime.CompilerServices.Closure,IPA.Loader.PluginMetadata)
  at IPA.Loader.PluginExecutor.Create () [0x00009] in C:\Users\Meivyn\repos\BeatSaber-IPA-Reloaded\IPA.Loader\Loader\PluginExecutor.cs:57
  at IPA.Loader.PluginLoader.InitPlugin (IPA.Loader.PluginMetadata meta, System.Collections.Generic.IEnumerable`1[T] alreadyLoaded) [0x001ec] in C:\Users\Meivyn\repos\BeatSaber-IPA-Reloaded\IPA.Loader\Loader\PluginLoader.cs:957

I confirmed that this does happen on non-reorg as well (happens with v2.10.2).

The patched method looks like this:

image

The patch which is failing is simply returning the same instructions:

[HarmonyPatch(typeof(MainMenuViewController), nameof(MainMenuViewController.HandleMenuButton)]
internal class Patch
{
    [HarmonyReversePatch]
    private static void ReversePatch(MainMenuViewController.MenuButton menuButton)
    {
        throw new NotImplementedException("Reverse patch has not been executed.");

        IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
        {
            return instructions;
        }
    }
}