Skip to content

Instantly share code, notes, and snippets.

@rursache
Created September 2, 2026 10:54
Show Gist options
  • Select an option

  • Save rursache/51ef705aa4cfb8bdc898693262a81ff7 to your computer and use it in GitHub Desktop.

Select an option

Save rursache/51ef705aa4cfb8bdc898693262a81ff7 to your computer and use it in GitHub Desktop.
WoW WotLK 3.3.5 - WoWSilicon Mouse Drift Fix
/*
cursorwarp.c
i686 PE DLL, inject with WoWSilicon mod manager
build with
brew install mingw-w64
i686-w64-mingw32-gcc -shared -O2 -o cursorwarp.dll cursorwarp.c
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
static BOOL (WINAPI *pSetCursorPos)(int, int);
static int (WINAPI *pShowCursor)(BOOL);
static BOOL pending_show;
static int WINAPI HookShowCursor(BOOL show) {
if (show) { pending_show = TRUE; return 0; }
pending_show = FALSE;
return pShowCursor(FALSE);
}
static BOOL WINAPI HookSetCursorPos(int x, int y) {
BOOL ok = pSetCursorPos(x, y);
if (pending_show) { pending_show = FALSE; pShowCursor(TRUE); }
return ok;
}
static void PatchIAT(HMODULE mod, const char *dll, const char *name, void *hook) {
BYTE *base = (BYTE *)mod;
IMAGE_NT_HEADERS *nt = (IMAGE_NT_HEADERS *)(base + ((IMAGE_DOS_HEADER *)base)->e_lfanew);
IMAGE_IMPORT_DESCRIPTOR *imp = (IMAGE_IMPORT_DESCRIPTOR *)(base +
nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
for (; imp->Name; imp++) {
if (lstrcmpiA((char *)(base + imp->Name), dll)) continue;
IMAGE_THUNK_DATA *th = (IMAGE_THUNK_DATA *)(base + imp->FirstThunk);
IMAGE_THUNK_DATA *oth = (IMAGE_THUNK_DATA *)(base + imp->OriginalFirstThunk);
for (; oth->u1.AddressOfData; ++th, ++oth) {
if (oth->u1.Ordinal & IMAGE_ORDINAL_FLAG) continue;
IMAGE_IMPORT_BY_NAME *n = (IMAGE_IMPORT_BY_NAME *)(base + oth->u1.AddressOfData);
if (lstrcmpA((char *)n->Name, name)) continue;
DWORD old;
VirtualProtect(&th->u1.Function, 4, PAGE_EXECUTE_READWRITE, &old);
th->u1.Function = (DWORD)hook;
VirtualProtect(&th->u1.Function, 4, old, &old);
return;
}
}
}
BOOL WINAPI DllMain(HINSTANCE h, DWORD r, LPVOID p) {
if (r == DLL_PROCESS_ATTACH) {
HMODULE u = GetModuleHandleA("user32.dll");
pSetCursorPos = (void *)GetProcAddress(u, "SetCursorPos");
pShowCursor = (void *)GetProcAddress(u, "ShowCursor");
HMODULE wow = GetModuleHandleA(NULL);
PatchIAT(wow, "user32.dll", "SetCursorPos", HookSetCursorPos);
PatchIAT(wow, "user32.dll", "ShowCursor", HookShowCursor);
}
return TRUE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment