egametang/ET · error · Exception

WRANING: you can not hook abstract method [{methodName}]

Error message

WRANING: you can not hook abstract method [{methodName}]

What it means

Thrown by MethodHook.CheckMethod() when targetMethod.IsAbstract is true. Abstract methods (including interface methods without an implementation) have no method body — no IL code and no native code to patch. Code patching hooks work by overwriting the prologue of the target method's compiled code, so hooking an abstract method is fundamentally impossible.

Source

Thrown at Packages/cn.etetet.hybridclr/Scripts/Editor/Share/3rds/UnityHook/MethodHook.cs:192

                    UnityEngine.Debug.Log($"New [{targetMethod.DeclaringType.Name}.{targetMethod.Name}]: {HookUtils.HexToString(_targetPtr.ToPointer(), 64, -16)}");
                    UnityEngine.Debug.Log($"New [{replacementMethod.DeclaringType.Name}.{replacementMethod.Name}]: {HookUtils.HexToString(_replacementPtr.ToPointer(), 64, -16)}");
                    if(proxyMethod != null)
                        UnityEngine.Debug.Log($"New [{proxyMethod.DeclaringType.Name}.{proxyMethod.Name}]: {HookUtils.HexToString(_proxyPtr.ToPointer(), 64, -16)}");
#endif
                }
            }

            isHooked = true;
        }

        private void CheckMethod()
        {
            if (targetMethod == null || replacementMethod == null)
                throw new Exception("MethodHook:targetMethod and replacementMethod and proxyMethod can not be null");

            string methodName = $"{targetMethod.DeclaringType.Name}.{targetMethod.Name}";
            if (targetMethod.IsAbstract)
                throw new Exception($"WRANING: you can not hook abstract method [{methodName}]");

#if UNITY_EDITOR && !UNITY_2020_3_OR_NEWER
            int minMethodBodySize = 10;

            {
                if ((targetMethod.MethodImplementationFlags & MethodImplAttributes.InternalCall) != MethodImplAttributes.InternalCall)
                {
                    int codeSize = targetMethod.GetMethodBody().GetILAsByteArray().Length; // GetMethodBody can not call on il2cpp
                    if (codeSize < minMethodBodySize)
                        UnityEngine.Debug.LogWarning($"WRANING: you can not hook method [{methodName}], cause its method body is too short({codeSize}), will random crash on IL2CPP release mode");
                }
            }

            if(proxyMethod != null)
            {
                methodName = $"{proxyMethod.DeclaringType.Name}.{proxyMethod.Name}";
                int codeSize = proxyMethod.GetMethodBody().GetILAsByteArray().Length;
                if (codeSize < minMethodBodySize)

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Hook the concrete implementation method instead of the abstract/interface declaration — find the class that actually implements the method.
  2. If you need to intercept all implementations, hook each override individually or use a higher-level interception pattern.
  3. Check targetMethod.DeclaringType.IsAbstract and targetMethod.IsAbstract before constructing the hook and skip or log a warning.
  4. If hooking a virtual method on a base class, ensure it has a body (non-abstract) — virtual methods with bodies can be hooked.

Example fix

// before — hooking an abstract method throws
var target = typeof(IRepository).GetMethod("Save");
var hook = new MethodHook(target, replacement);
hook.CheckMethod();

// after — hook the concrete implementation
var target = typeof(SqlRepository).GetMethod("Save"); // concrete override
var hook = new MethodHook(target, replacement);
hook.CheckMethod();
Defensive patterns

Strategy: validation

Validate before calling

if (targetMethod.IsAbstract)
{
    Debug.LogError($"Cannot hook abstract method '{targetMethod.DeclaringType.Name}.{targetMethod.Name}'. " +
        "Hook the concrete implementation instead.");
    return;
}

Type guard

static bool IsHookableMethod(MethodInfo method)
{
    return method != null && !method.IsAbstract;
}

Try / catch

try
{
    hook.CheckMethod();
}
catch (Exception ex) when (ex.Message.Contains("abstract method"))
{
    Debug.LogError($"Cannot hook abstract method. Find the concrete override on the implementing class " +
        $"and hook that instead. Target was: {targetMethod.DeclaringType.Name}.{targetMethod.Name}");
}

Prevention

When it happens

Trigger: CheckMethod() is called on a MethodHook whose targetMethod is an abstract method — e.g. a method declared on an abstract class without implementation, or an interface member. The IsAbstract property returns true and the exception fires.

Common situations: Attempting to hook an interface method instead of its concrete implementation; hooking an abstract base class method that has no body; the type was refactored and a previously-concrete method became abstract; confusion between the interface declaration and the implementing class's override.

Related errors


AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13). Data as JSON: /api/errors/c62ff304d613ce18. Report an issue: GitHub.