Example #1
0
        private static unsafe bool ApplyUser32SetTimerPatch()
        {
            IntPtr original = PEUtils.GetExportedFunctionPointerForModule("USER32.dll", "SetTimer");

            MelonLogger.Msg($"User32::SetTimer original: 0x{(long)original:X}");

            if (original == IntPtr.Zero)
            {
                MelonLogger.Error("Failed to find USER32.dll::SetTimer");
                return(false);
            }

            // We get a native function pointer to User32SetTimerDetour from our current class
            //IntPtr detourPtr = typeof(Core).GetMethod("User32SetTimerDetour", BindingFlags.NonPublic | BindingFlags.Static).MethodHandle.GetFunctionPointer();
            IntPtr detourPtr = Marshal.GetFunctionPointerForDelegate((User32SetTimerDelegate)User32SetTimerDetour);

            if (detourPtr == IntPtr.Zero)
            {
                MelonLogger.Error("Failed to find User32SetTimerDetour");
                return(false);
            }

            // And we patch SetTimer to replace it by our hook
            MelonLogger.Msg($"Applying USER32.dll::SetTimer Hook at 0x{original.ToInt64():X}");
            MelonUtils.NativeHookAttach((IntPtr)(&original), detourPtr);
            MelonLogger.Msg($"Creating delegate for original USER32.dll::SetTimer (0x{original.ToInt64():X})");
            user32SetTimerOriginal = (User32SetTimerDelegate)Marshal.GetDelegateForFunctionPointer(original, typeof(User32SetTimerDelegate));
            MelonLogger.Msg("Applied USER32.dll::SetTimer patch");

            return(true);
        }