HarmonyX icon indicating copy to clipboard operation
HarmonyX copied to clipboard

Cannot unpatch extern method patch

Open alexhaffner opened this issue 2 years ago • 1 comments

Hey! I'm using HarmonyX with unity (in editor directly), trying to patch & unpatch in play mode. After I call Harmony.UnpatchAll(); the methods still seems to be patched.

public class DestroyPatch
{
    [HarmonyPostfix]
    [HarmonyPatch(nameof(Object.Destroy), new Type[] { typeof(Object), typeof(float) })]
    public static void PrefixA(Object obj, float t)
    {
        Debug.Log("Destroy(Object obj, float t) called");
    }
    
    [HarmonyPostfix]
    [HarmonyPatch(nameof(Object.DestroyImmediate), new Type[] { typeof(Object), typeof(bool) })]
    public static void PrefixB(Object obj, bool allowDestroyingAssets)
    {
        Debug.Log("DestroyImmediate(Object obj, bool allowDestroyingAssets) called");
    }
}

Both are extern calls. I don't have issues with "normal" methods.

Looking into UnpatchConditional, it seems that HasMethodBody returns 0, and thus those methods are skipped and never unpatched.

Thanks!

alexhaffner avatar Nov 30 '23 21:11 alexhaffner

Having this issue as well.

As a workaround (and ironically), a patch can fix this, but this might have unforeseen consequences, so use at your own risk:

/// <summary>
/// This may or may not completely crash the game, here be dragons
/// </summary>
[HarmonyPatch(typeof(MethodBaseExtensions), nameof(MethodBaseExtensions.HasMethodBody))]
[HarmonyPrefix]
private static bool OnUnpatch(ref bool __result)
{
    // TODO: Perform some checks so this only targets the methods we want, instead of literally everything
    __result = true;

    return false;
}

DaXcess avatar Jan 05 '25 20:01 DaXcess