Skip to content

Commit

Permalink
Windows 11 24H2 changed some low-level call hierarchies.
Browse files Browse the repository at this point in the history
This is a compatibility change, works on 23H2 and 24H2. Since in 24H2 GetModuleHandle no longer down-calls to LdrGetDllHandleEx, have to hook the GetModuleHandle() routines also.
  • Loading branch information
Richard Fortier committed Dec 1, 2024
1 parent 2430e13 commit e7d869b
Showing 1 changed file with 29 additions and 1 deletion.
30 changes: 29 additions & 1 deletion Code/immersive_launcher/stubs/FileMapping.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ std::wstring s_OverridePath;
DWORD(WINAPI* RealGetModuleFileNameW)(HMODULE, LPWSTR, DWORD) = nullptr;
DWORD(WINAPI* RealGetModuleFileNameA)(HMODULE, LPSTR, DWORD) = nullptr;
HMODULE(WINAPI* RealGetModuleHandleW)(LPCWSTR) = nullptr;
HMODULE(WINAPI* RealGetModuleHandleA)(LPSTR) = nullptr;
HMODULE(WINAPI* RealGetModuleHandleA)(LPCSTR) = nullptr;
NTSTATUS(WINAPI* RealLdrLoadDll)(const wchar_t*, uint32_t*, UNICODE_STRING*, HANDLE*) = nullptr;
NTSTATUS(WINAPI* RealLdrGetDllHandle)(PWSTR, PULONG, PUNICODE_STRING, PVOID*) = nullptr;
NTSTATUS(WINAPI* RealLdrGetDllFullName)(HMODULE, PUNICODE_STRING) = nullptr;
Expand Down Expand Up @@ -87,6 +87,28 @@ bool IsLocalModulePath(HMODULE aHmod)
return buf.find(s_OverridePath) != std::wstring::npos;
}

// some mods do GetModuleHandle("SkyrimSE.exe") for some reason instead of GetModuleHandle(nullptr)
HMODULE WINAPI TP_GetModuleHandleW(LPCWSTR lpModuleName)
{
constexpr auto pTarget = TARGET_NAME L".exe";
auto targetSize = std::wcslen(pTarget);

if (lpModuleName && std::wcsncmp(pTarget, lpModuleName, targetSize) == 0)
lpModuleName = nullptr;
return RealGetModuleHandleW(lpModuleName);
}

// some mods do GetModuleHandle("SkyrimSE.exe") for some reason instead of GetModuleHandle(nullptr)
HMODULE WINAPI TP_GetModuleHandleA(LPCSTR lpModuleName)
{
constexpr LPCSTR pTarget = "SkyrimSE.exe";
constexpr auto targetSize = sizeof("SkyrimSE.exe");

if (lpModuleName && std::strncmp(pTarget, lpModuleName, targetSize) == 0)
lpModuleName = nullptr;
return RealGetModuleHandleA(lpModuleName);
}

// some mods do GetModuleHandle("SkyrimSE.exe") for some reason instead of GetModuleHandle(nullptr)
NTSTATUS WINAPI TP_LdrGetDllHandle(PWSTR DllPath, PULONG DllCharacteristics, PUNICODE_STRING DllName, PVOID* DllHandle)
{
Expand Down Expand Up @@ -300,6 +322,12 @@ void CoreStubsInit()
// TODO(Vince): we need some check if usvfs already fucked with this?
// MH_CreateHookApi(L"ntdll.dll", "LdrGetDllFullName", &TP_LdrGetDllFullName, (void**)&RealLdrGetDllFullName);
VALIDATE(MH_CreateHookApi(L"ntdll.dll", "LdrLoadDll", &TP_LdrLoadDll, (void**)&RealLdrLoadDll));

// Starting with Windows 11 24H2 the call stack has changed and GetModuleHandle() no longer
// downcalls to LdrGetDllHandleEx, so we have to hook this too.
VALIDATE(MH_CreateHookApi(L"kernel32.dll", "GetModuleHandleW", &TP_GetModuleHandleW, (void**)&RealGetModuleHandleW));
VALIDATE(MH_CreateHookApi(L"kernel32.dll", "GetModuleHandleA", &TP_GetModuleHandleA, (void**)&RealGetModuleHandleA));

VALIDATE(MH_EnableHook(nullptr));
}

Expand Down

0 comments on commit e7d869b

Please sign in to comment.