internal static (long FlagRva, long TokenRva) FindMetadataInitForMethod(MethodRewriteContext method, long gameAssemblyBase)
        {
            if (MetadataInitForMethodRva == 0)
            {
                FindMetadataInitForMethod(method.DeclaringType.AssemblyContext.GlobalContext, gameAssemblyBase);
            }

            var codeStart = (IntPtr)(gameAssemblyBase + method.FileOffset);
            var firstCall = XrefScannerLowLevel.JumpTargets(codeStart).FirstOrDefault();

            if (firstCall != MetadataInitForMethodFileOffset || firstCall == IntPtr.Zero)
            {
                return(0, 0);
            }

            var tokenPointer    = XrefScanUtilFinder.FindLastRcxReadAddressBeforeCallTo(codeStart, MetadataInitForMethodFileOffset);
            var initFlagPointer = XrefScanUtilFinder.FindByteWriteTargetRightAfterCallTo(codeStart, MetadataInitForMethodFileOffset);

            if (tokenPointer == IntPtr.Zero || initFlagPointer == IntPtr.Zero)
            {
                return(0, 0);
            }

            return((long)initFlagPointer - gameAssemblyBase - method.FileOffset + method.Rva, (long)tokenPointer - gameAssemblyBase - method.FileOffset + method.Rva);
        }
        private static void FindMetadataInitForMethod(RewriteGlobalContext context, long gameAssemblyBase)
        {
            var unityObjectCctor = context.Assemblies
                                   .Single(it => it.OriginalAssembly.Name.Name == "UnityEngine.CoreModule").GetTypeByName("UnityEngine.Object").OriginalType.Methods.Single(it => it.Name == ".cctor");

            MetadataInitForMethodFileOffset =
                (IntPtr)((long)XrefScannerLowLevel.JumpTargets((IntPtr)(gameAssemblyBase + unityObjectCctor.ExtractOffset())).First());
            MetadataInitForMethodRva = (long)MetadataInitForMethodFileOffset - gameAssemblyBase - unityObjectCctor.ExtractOffset() + unityObjectCctor.ExtractRva();
        }
        private static unsafe void FindMetadataInitForMethod()
        {
            var unityObjectCctor = AppDomain.CurrentDomain.GetAssemblies()
                                   .Single(it => it.GetSimpleName() == "UnityEngine.CoreModule").GetType("UnityEngine.Object")
                                   .GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).Single();
            var nativeMethodInfo = IL2CPP.il2cpp_method_get_from_reflection(unityObjectCctor.Pointer);

            ourMetadataInitForMethodPointer  = XrefScannerLowLevel.JumpTargets(*(IntPtr *)nativeMethodInfo).First();
            ourMetadataInitForMethodDelegate = Marshal.GetDelegateForFunctionPointer <InitMetadataForMethod>(ourMetadataInitForMethodPointer);
        }
        internal static unsafe bool CallMetadataInitForMethod(MethodBase method)
        {
            if (ourMetadataInitForMethodPointer == IntPtr.Zero)
            {
                FindMetadataInitForMethod();
            }

            var nativeMethodInfoObject = UnhollowerUtils.GetIl2CppMethodInfoPointerFieldForGeneratedMethod(method)?.GetValue(null);

            if (nativeMethodInfoObject == null)
            {
                return(false);
            }
            var nativeMethodInfo = (IntPtr)nativeMethodInfoObject;
            var codeStart        = *(IntPtr *)nativeMethodInfo;
            var firstCall        = XrefScannerLowLevel.JumpTargets(codeStart).FirstOrDefault();

            if (firstCall != ourMetadataInitForMethodPointer || firstCall == IntPtr.Zero)
            {
                return(false);
            }

            var tokenPointer    = XrefScanUtilFinder.FindLastRcxReadAddressBeforeCallTo(codeStart, ourMetadataInitForMethodPointer);
            var initFlagPointer = XrefScanUtilFinder.FindByteWriteTargetRightAfterCallTo(codeStart, ourMetadataInitForMethodPointer);

            if (tokenPointer == IntPtr.Zero || initFlagPointer == IntPtr.Zero)
            {
                return(false);
            }

            if (Marshal.ReadByte(initFlagPointer) == 0)
            {
                ourMetadataInitForMethodDelegate(Marshal.ReadInt32(tokenPointer));
                Marshal.WriteByte(initFlagPointer, 1);
            }

            return(true);
        }