egametang/ET · error · Exception

MethodHook:targetMethod and replacementMethod and proxyMetho

Error message

MethodHook:targetMethod and replacementMethod and proxyMethod can not be null

What it means

Thrown by MethodHook.CheckMethod() when targetMethod or replacementMethod is null. This is a pre-installation validation method (note the message also mentions proxyMethod but the code only checks target and replacement — the message is imprecise). CheckMethod is called to validate the hook configuration before proceeding with installation.

Source

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

                    CreateCodePatcher();
                    _codePatcher.ApplyPatch();

#if ENABLE_HOOK_DEBUG
                    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)

View on GitHub (pinned to 5cab01f7a8)

Solutions

  1. Inspect which MethodInfo is null by logging targetMethod, replacementMethod before calling CheckMethod.
  2. Correct the reflection lookup — verify method name, type, BindingFlags, and parameter types.
  3. Ensure the target assembly is loaded before reflection.
  4. Consider that the message mentions proxyMethod but the check does not test it — do not be misled into only checking proxy.

Example fix

// before
hook.CheckMethod(); // throws if targetMethod or replacementMethod is null

// after — validate first with a clear diagnostic
if (targetMethod == null || replacementMethod == null)
{
    Debug.LogError($"Cannot hook: target={targetMethod?.Name ?? "null"}, replacement={replacementMethod?.Name ?? "null"}");
    return;
}
hook.CheckMethod();
Defensive patterns

Strategy: validation

Validate before calling

if (targetMethod == null || replacementMethod == null)
{
    Debug.LogError($"Cannot validate hook: " +
        $"target={targetMethod?.DeclaringType?.Name}.{targetMethod?.Name ?? "null"}, " +
        $"replacement={replacementMethod?.DeclaringType?.Name}.{replacementMethod?.Name ?? "null"}");
    return;
}

Type guard

static bool HasValidMethods(MethodInfo target, MethodInfo replacement)
{
    return target != null && replacement != null;
}

Try / catch

try
{
    hook.CheckMethod();
}
catch (Exception ex) when (ex.Message.Contains("can not be null"))
{
    Debug.LogError("MethodHook validation failed: a required MethodInfo is null. " +
        "Note: the message mentions proxyMethod but only target and replacement are checked.");
}

Prevention

When it happens

Trigger: CheckMethod() is invoked on a MethodHook where targetMethod or replacementMethod is null. The trigger is the same root cause as error 170: a failed reflection lookup left one of the required MethodInfo fields null.

Common situations: Same as 170: method renamed, wrong BindingFlags, signature mismatch on overloaded methods, assembly not loaded, or a typo in the method name string. The difference is this fires from the explicit CheckMethod path rather than DoInstall.

Related errors


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