Skip to content

Commit 299f208

Browse files
Merge pull request #750 from rfortier/fix/Win11-24H2-compat
Windows 11 24H2 changed some low-level call hierarchies.
2 parents 584065f + ab0bac5 commit 299f208

File tree

2 files changed

+30
-1
lines changed

2 files changed

+30
-1
lines changed

Code/immersive_launcher/TargetConfig.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ static constexpr TargetConfig CurrentTarget{
2525
L"Skyrim Special Edition",
2626
489830, 0x40000000, 35410264};
2727
#define TARGET_NAME L"SkyrimSE"
28+
#define TARGET_NAME_A "SkyrimSE"
2829
#define PRODUCT_NAME L"Skyrim Together"
2930
#define SHORT_NAME L"Skyrim Special Edition"
3031

Code/immersive_launcher/stubs/FileMapping.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ std::wstring s_OverridePath;
2626
DWORD(WINAPI* RealGetModuleFileNameW)(HMODULE, LPWSTR, DWORD) = nullptr;
2727
DWORD(WINAPI* RealGetModuleFileNameA)(HMODULE, LPSTR, DWORD) = nullptr;
2828
HMODULE(WINAPI* RealGetModuleHandleW)(LPCWSTR) = nullptr;
29-
HMODULE(WINAPI* RealGetModuleHandleA)(LPSTR) = nullptr;
29+
HMODULE(WINAPI* RealGetModuleHandleA)(LPCSTR) = nullptr;
3030
NTSTATUS(WINAPI* RealLdrLoadDll)(const wchar_t*, uint32_t*, UNICODE_STRING*, HANDLE*) = nullptr;
3131
NTSTATUS(WINAPI* RealLdrGetDllHandle)(PWSTR, PULONG, PUNICODE_STRING, PVOID*) = nullptr;
3232
NTSTATUS(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)
91113
NTSTATUS 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

Comments
 (0)