egametang/ET · error · Exception
WRANING: you can not hook abstract method
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.
Solutions
- Hook the concrete implementation method instead of the abstract/interface declaration — find the class that actually implements the method.
- If you need to intercept all implementations, hook each override individually or use a higher-level interception pattern.
- Check targetMethod.DeclaringType.IsAbstract and targetMethod.IsAbstract before constructing the hook and skip or log a warning.
- 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
- Never attempt to hook interface methods or abstract declarations directly.
- Before hooking, check targetMethod.IsAbstract and redirect to the concrete implementation.
- When hooking virtual methods, verify they have a body (non-abstract overrides are fine).
- Use targetMethod.DeclaringType to determine if you are targeting an interface/abstract class by mistake.
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
- MethodHook:targetMethod and replacementMethod and…
- none of methods targetMethod or replacementMethod can be…
- address offset of target and replace must larger than ((1…
- address offset of target and replace must less than ((1 <<…
- address offset of target and replace must less than (1 <<…
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/c62ff304d613ce18.
Report an issue: GitHub.
Appendix: 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)