{"record":{"id":"fddb31feef6cce3d","repo":"egametang/ET","slug":"unsupported-runtime","errorCode":null,"errorMessage":"Unsupported runtime","messagePattern":"Unsupported runtime","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"critical","filePath":"Packages/cn.etetet.hybridclr/Scripts/Editor/Share/3rds/UnityHook/HookUtils.cs","lineNumber":23,"sourceCode":"using System.Runtime.InteropServices;\nusing System.Text;\nusing UnityEngine;\n\nnamespace MonoHook\n{\n    public static unsafe class HookUtils\n    {\n        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]\n        delegate void DelegateFlushICache(void* code, int size); // delegate * unmanaged[Cdecl] <void, byte, uint> native_flush_cache_fun_ptr; // unsupported at C# 8.0\n\n        static DelegateFlushICache flush_icache;\n        private static readonly long _Pagesize;\n        \n        static HookUtils()\n        {\n            PropertyInfo p_SystemPageSize = typeof(Environment).GetProperty(\"SystemPageSize\");\n            if (p_SystemPageSize == null)\n                throw new NotSupportedException(\"Unsupported runtime\");\n            _Pagesize = (int)p_SystemPageSize.GetValue(null, new object[0]);\n            SetupFlushICacheFunc();\n        }\n\n        public static void MemCpy(void* pDst, void* pSrc, int len)\n        {\n            byte* pDst_ = (byte*)pDst;\n            byte* pSrc_ = (byte*)pSrc;\n\n            for (int i = 0; i < len; i++)\n                *pDst_++ = *pSrc_++;\n        }\n\n        public static void MemCpy_Jit(void* pDst, byte[] src)\n        {\n            fixed (void* p = &src[0])\n            {\n                MemCpy(pDst, p, src.Length);","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.hybridclr/Scripts/Editor/Share/3rds/UnityHook/HookUtils.cs#L5-L41","documentation":"Thrown in HookUtils' static constructor (non-OSX build) when typeof(Environment).GetProperty(\"SystemPageSize\") returns null. The hooking subsystem needs the system page size to compute page-aligned addresses for mprotect/VirtualProtect calls. SystemPageSize was added in .NET Framework 4.0 / Mono 2.x; if the runtime is too old or stripped, the property is absent and hooking cannot proceed.","triggerScenarios":"The static constructor runs the first time any HookUtils member is accessed. If the current Mono or .NET runtime does not expose Environment.SystemPageSize, the constructor throws NotSupportedException, preventing the entire hooking subsystem from initializing.","commonSituations":"Running on a very old or custom Mono runtime bundled with an older Unity version; running on a stripped IL2CPP runtime where reflection on System.Environment is limited; an exotic platform whose runtime lacks the property; Unity version downgrade to one with an older Mono.","solutions":["Upgrade Unity to a version that ships a Mono runtime with Environment.SystemPageSize (most Unity 2018+ versions have it).","If you cannot upgrade, fork HookUtils to obtain the page size via an alternative: P/Invoke sysconf(_SC_PAGESIZE) on POSIX or GetSystemInfo on Windows.","Verify that the Mono runtime is not corrupted or stripped — reinstall Unity if necessary.","Disable the method-hooking feature if it is optional for your workflow and you cannot resolve the runtime issue."],"exampleFix":"// before\nPropertyInfo p = typeof(Environment).GetProperty(\"SystemPageSize\");\nif (p == null) throw new NotSupportedException(\"Unsupported runtime\");\n_Pagesize = (int)p.GetValue(null);\n\n// after — fallback to sysconf on POSIX\nPropertyInfo p = typeof(Environment).GetProperty(\"SystemPageSize\");\nif (p != null)\n    _Pagesize = (int)p.GetValue(null);\nelse\n    _Pagesize = sysconf(_SC_PAGESIZE); // P/Invoke fallback","handlingStrategy":"validation","validationCode":"// Check runtime compatibility before triggering the static constructor\nPropertyInfo prop = typeof(Environment).GetProperty(\"SystemPageSize\");\nif (prop == null)\n{\n    Debug.LogError(\"This runtime does not support Environment.SystemPageSize. \" +\n        \"Method hooking requires .NET Framework 4.0+ or Mono 2.x+. Upgrade Unity or Mono.\");\n    return;\n}","typeGuard":"static bool IsRuntimeSupported()\n{\n    return typeof(Environment).GetProperty(\"SystemPageSize\") != null;\n}","tryCatchPattern":"try\n{\n    // Trigger static constructor by accessing any HookUtils member\n    HookUtils.SetAddrFlagsToRWX(ptr, size);\n}\ncatch (NotSupportedException ex) when (ex.Message == \"Unsupported runtime\")\n{\n    Debug.LogError(\"HookUtils requires a runtime with Environment.SystemPageSize. \" +\n        \"Upgrade Unity or provide a patched HookUtils with a sysconf fallback.\");\n}","preventionTips":["Check Environment.SystemPageSize availability at startup before using any hook functionality.","Keep Unity updated to a version with a modern Mono runtime.","If targeting exotic platforms, fork HookUtils to add a sysconf-based page size fallback.","Gate hook features behind a runtime compatibility check in your initialization code."],"tags":["unityhook","runtime","mono","compatibility","page-size"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}