Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reverse patches appears to be broken #111

Open
Meivyn opened this issue May 21, 2024 · 1 comment
Open

Reverse patches appears to be broken #111

Meivyn opened this issue May 21, 2024 · 1 comment

Comments

@Meivyn
Copy link
Contributor

Meivyn commented May 21, 2024

Followup of #79 (comment).

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;
        }
    }
}
@crpz1
Copy link

crpz1 commented Jan 9, 2025

Chiming in to say that I'm also having this problem while trying to fix another problem. With a similar setup to above, I get Invalid IL errors whenever ldarg.0 is encountered in the instruction list. Patching the method to use any other instruction in its place results in the above mentioned stack trace.

HarmonyLib.HarmonyException: IL Compile Error (unknown location) ---> System.InvalidProgramException: Invalid IL code in (wrapper dynamic-method) AtlyssUIShortcuts.Patches.PlayerInteractPatch:DMD<AtlyssUIShortcuts.Patches.PlayerInteractPatch::AwakeReversePatch> (): IL_0000: ldarg.0


  at (wrapper managed-to-native) System.RuntimeMethodHandle.GetFunctionPointer(intptr)
  at System.RuntimeMethodHandle.GetFunctionPointer () [0x00000] in <75633565436c42f0a6426b33f0132ade>:0
  at MonoMod.RuntimeDetour.Platforms.DetourRuntimeILPlatform.GetFunctionPointer (System.Reflection.MethodBase method, System.RuntimeMethodHandle handle) [0x00000] in <4e2760c7517c4ea79c633d67e84b319f>:0
  at MonoMod.RuntimeDetour.Platforms.DetourRuntimeILPlatform.GetNativeStart (System.Reflection.MethodBase method) [0x0004d] in <4e2760c7517c4ea79c633d67e84b319f>:0
  at MonoMod.RuntimeDetour.DetourHelper.GetNativeStart (System.Reflection.MethodBase method) [0x00005] in <4e2760c7517c4ea79c633d67e84b319f>:0
  at MonoMod.RuntimeDetour.Detour._TopApply () [0x00025] in <4e2760c7517c4ea79c633d67e84b319f>:0
  at MonoMod.RuntimeDetour.Detour._RefreshChain (System.Reflection.MethodBase method) [0x00149] in <4e2760c7517c4ea79c633d67e84b319f>:0
  at MonoMod.RuntimeDetour.Detour.Apply () [0x00053] in <4e2760c7517c4ea79c633d67e84b319f>:0
  at MonoMod.RuntimeDetour.Detour..ctor (System.Reflection.MethodBase from, System.Reflection.MethodBase to, MonoMod.RuntimeDetour.DetourConfig& config) [0x002e1] in <4e2760c7517c4ea79c633d67e84b319f>:0
  at (wrapper dynamic-method) MonoMod.RuntimeDetour.ILHook+Context.DMD<MonoMod.RuntimeDetour.ILHook+Context::Refresh>(MonoMod.RuntimeDetour.ILHook/Context)
  at (wrapper dynamic-method) MonoMod.Utils.DynamicMethodDefinition.Trampoline<MonoMod.RuntimeDetour.ILHook+Context::Refresh>?-1965818678(object)
  at HarmonyLib.Internal.RuntimeFixes.StackTraceFixes.OnILChainRefresh (System.Object self) [0x00000] in <474744d65d8e460fa08cd5fd82b5d65f>:0
  at MonoMod.RuntimeDetour.ILHook.Apply () [0x00059] in <4e2760c7517c4ea79c633d67e84b319f>:0
  at HarmonyLib.PatchFunctions.ReversePatch (HarmonyLib.HarmonyMethod standin, System.Reflection.MethodBase original, System.Reflection.MethodInfo postTranspiler, System.Reflection.MethodInfo postManipulator) [0x0015d] in <474744d65d8e460fa08cd5fd82b5d65f>:0
   --- End of inner exception stack trace ---
  at HarmonyLib.PatchClassProcessor.ReportException (System.Exception exception, System.Reflection.MethodBase original) [0x00045] in <474744d65d8e460fa08cd5fd82b5d65f>:0
  at HarmonyLib.PatchClassProcessor.Patch () [0x00095] in <474744d65d8e460fa08cd5fd82b5d65f>:0
  at HarmonyLib.Harmony.<PatchAll>b__11_0 (System.Type type) [0x00007] in <474744d65d8e460fa08cd5fd82b5d65f>:0
  at HarmonyLib.CollectionExtensions.Do[T] (System.Collections.Generic.IEnumerable`1[T] sequence, System.Action`1[T] action) [0x00014] in <474744d65d8e460fa08cd5fd82b5d65f>:0
  at HarmonyLib.Harmony.PatchAll (System.Reflection.Assembly assembly) [0x00006] in <474744d65d8e460fa08cd5fd82b5d65f>:0
  at HarmonyLib.Harmony.PatchAll () [0x0001b] in <474744d65d8e460fa08cd5fd82b5d65f>:0
  at AtlyssUIShortcuts.AtlyssUIShortcuts.Awake () [0x00033] in <c09efbae08994db699a4430e9ea358c2>:0

The following is my patch:

[HarmonyPatch(typeof(PlayerInteract))]
class PlayerInteractPatch
{

    [HarmonyPatch("Awake")]
    [HarmonyReversePatch]
    private static void AwakeReversePatch()
    {
        return;
    }
}

Patch that results in System.ArgumentOutOfRangeException:

[HarmonyPatch("Awake")]
[HarmonyReversePatch]
private static void AwakeReversePatch()
{
    IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions)
    {
        var list = Transpilers.Manipulator(instructions,
            item => item.opcode == OpCodes.Ldarg_0,
            item =>
            {
                item.opcode = OpCodes.Ldarg;
                item.operand = 0;
            }
        );

        return list;
    }

    return;
}

And finally the method being patched:

64qel8av5j 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants