Workaround the ntdll-Hide_Wine_Exports patch (#538)

This commit is contained in:
Michał Lewandowski
2025-06-23 13:17:14 +03:00
committed by GitHub
parent 5c0508ff6d
commit 1324f8d971
+44
View File
@@ -42,6 +42,46 @@ static std::vector<HMODULE> _asiHandles;
typedef const char*(CDECL* PFN_wine_get_version)(void);
typedef void (*PFN_InitializeASI)(void);
static inline void* ManualGetProcAddress(HMODULE hModule, const char* functionName)
{
if (!hModule)
return nullptr;
// Verify the alignment
auto dosHeader = (IMAGE_DOS_HEADER*) hModule;
if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return nullptr;
auto ntHeaders = (IMAGE_NT_HEADERS*) ((BYTE*) hModule + dosHeader->e_lfanew);
if (ntHeaders->Signature != IMAGE_NT_SIGNATURE)
return nullptr;
// Look at the export directory
IMAGE_DATA_DIRECTORY exportData = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT];
if (!exportData.VirtualAddress)
return nullptr;
auto exportDir = (IMAGE_EXPORT_DIRECTORY*) ((BYTE*) hModule + exportData.VirtualAddress);
DWORD* nameRvas = (DWORD*) ((BYTE*) hModule + exportDir->AddressOfNames);
WORD* ordinalTable = (WORD*) ((BYTE*) hModule + exportDir->AddressOfNameOrdinals);
DWORD* functionTable = (DWORD*) ((BYTE*) hModule + exportDir->AddressOfFunctions);
// Iterate over exported names
for (DWORD i = 0; i < exportDir->NumberOfNames; ++i)
{
const char* name = (const char*) hModule + nameRvas[i];
if (_stricmp(name, functionName) == 0)
{
WORD ordinal = ordinalTable[i];
DWORD funcRva = functionTable[ordinal];
return (BYTE*) hModule + funcRva;
}
}
return nullptr; // Not found
}
static bool IsRunningOnWine()
{
LOG_FUNC();
@@ -56,6 +96,10 @@ static bool IsRunningOnWine()
auto pWineGetVersion = (PFN_wine_get_version) KernelBaseProxy::GetProcAddress_()(ntdll, "wine_get_version");
// Workaround for the ntdll-Hide_Wine_Exports patch
if (!pWineGetVersion && KernelBaseProxy::GetProcAddress_()(ntdll, "wine_server_call") != nullptr)
pWineGetVersion = (PFN_wine_get_version) ManualGetProcAddress(ntdll, "wine_get_version");
if (pWineGetVersion)
{
LOG_INFO("Running on Wine {0}!", pWineGetVersion());