Skip to content

Commit

Permalink
Merge pull request #750 from rfortier/fix/Win11-24H2-compat
Browse files Browse the repository at this point in the history
Windows 11 24H2 changed some low-level call hierarchies.
  • Loading branch information
RobbeBryssinck authored Dec 2, 2024
2 parents 584065f + ab0bac5 commit 299f208
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 1 deletion.
1 change: 1 addition & 0 deletions Code/immersive_launcher/TargetConfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ static constexpr TargetConfig CurrentTarget{
L"Skyrim Special Edition",
489830, 0x40000000, 35410264};
#define TARGET_NAME L"SkyrimSE"
#define TARGET_NAME_A "SkyrimSE"
#define PRODUCT_NAME L"Skyrim Together"
#define SHORT_NAME L"Skyrim Special Edition"

Expand Down
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 auto pTarget = TARGET_NAME_A ".exe";
constexpr auto targetSize = sizeof(TARGET_NAME_A ".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 299f208

Please sign in to comment.