@@ -26,7 +26,7 @@ std::wstring s_OverridePath;
2626DWORD (WINAPI* RealGetModuleFileNameW)(HMODULE, LPWSTR, DWORD) = nullptr ;
2727DWORD (WINAPI* RealGetModuleFileNameA)(HMODULE, LPSTR, DWORD) = nullptr ;
2828HMODULE (WINAPI* RealGetModuleHandleW)(LPCWSTR) = nullptr ;
29- HMODULE (WINAPI* RealGetModuleHandleA)(LPSTR ) = nullptr ;
29+ HMODULE (WINAPI* RealGetModuleHandleA)(LPCSTR ) = nullptr ;
3030NTSTATUS (WINAPI* RealLdrLoadDll)(const wchar_t *, uint32_t *, UNICODE_STRING*, HANDLE*) = nullptr ;
3131NTSTATUS (WINAPI* RealLdrGetDllHandle)(PWSTR, PULONG, PUNICODE_STRING, PVOID*) = nullptr ;
3232NTSTATUS (WINAPI* RealLdrGetDllFullName)(HMODULE, PUNICODE_STRING) = nullptr ;
@@ -87,6 +87,28 @@ bool IsLocalModulePath(HMODULE aHmod)
8787 return buf.find (s_OverridePath) != std::wstring::npos;
8888}
8989
90+ // some mods do GetModuleHandle("SkyrimSE.exe") for some reason instead of GetModuleHandle(nullptr)
91+ HMODULE WINAPI TP_GetModuleHandleW (LPCWSTR lpModuleName)
92+ {
93+ constexpr auto pTarget = TARGET_NAME L" .exe" ;
94+ auto targetSize = std::wcslen (pTarget);
95+
96+ if (lpModuleName && std::wcsncmp (pTarget, lpModuleName, targetSize) == 0 )
97+ lpModuleName = nullptr ;
98+ return RealGetModuleHandleW (lpModuleName);
99+ }
100+
101+ // some mods do GetModuleHandle("SkyrimSE.exe") for some reason instead of GetModuleHandle(nullptr)
102+ HMODULE WINAPI TP_GetModuleHandleA (LPCSTR lpModuleName)
103+ {
104+ constexpr auto pTarget = TARGET_NAME_A " .exe" ;
105+ constexpr auto targetSize = sizeof (TARGET_NAME_A " .exe" );
106+
107+ if (lpModuleName && std::strncmp (pTarget, lpModuleName, targetSize) == 0 )
108+ lpModuleName = nullptr ;
109+ return RealGetModuleHandleA (lpModuleName);
110+ }
111+
90112// some mods do GetModuleHandle("SkyrimSE.exe") for some reason instead of GetModuleHandle(nullptr)
91113NTSTATUS WINAPI TP_LdrGetDllHandle (PWSTR DllPath, PULONG DllCharacteristics, PUNICODE_STRING DllName, PVOID* DllHandle)
92114{
@@ -300,6 +322,12 @@ void CoreStubsInit()
300322 // TODO(Vince): we need some check if usvfs already fucked with this?
301323 // MH_CreateHookApi(L"ntdll.dll", "LdrGetDllFullName", &TP_LdrGetDllFullName, (void**)&RealLdrGetDllFullName);
302324 VALIDATE (MH_CreateHookApi (L" ntdll.dll" , " LdrLoadDll" , &TP_LdrLoadDll, (void **)&RealLdrLoadDll));
325+
326+ // Starting with Windows 11 24H2 the call stack has changed and GetModuleHandle() no longer
327+ // downcalls to LdrGetDllHandleEx, so we have to hook this too.
328+ VALIDATE (MH_CreateHookApi (L" kernel32.dll" , " GetModuleHandleW" , &TP_GetModuleHandleW, (void **)&RealGetModuleHandleW));
329+ VALIDATE (MH_CreateHookApi (L" kernel32.dll" , " GetModuleHandleA" , &TP_GetModuleHandleA, (void **)&RealGetModuleHandleA));
330+
303331 VALIDATE (MH_EnableHook (nullptr ));
304332}
305333
0 commit comments