#include "stdafx.h" static OSVERSIONINFO GetVersionEx2() { OSVERSIONINFO vi = {sizeof vi}; GetVersionEx(&vi); return vi; } static OSVERSIONINFO const vi = GetVersionEx2(); static HMODULE hmodKernel; static HMODULE GetKernelModule() { if (hmodKernel == nullptr) { hmodKernel = GetModuleHandle(TEXT("kernel32")); } return hmodKernel; } #define KERNEL32 (GetKernelModule()) #define GET_PROC_ADDRESS(hmod, functionName) reinterpret_cast(GetProcAddress((hmod), #functionName)) #define DECLARE_REAL_HOLDER(name) static decltype(name)* name ## _Real extern "C" { BOOL WINAPI IsDebuggerPresent_Helper() { DECLARE_REAL_HOLDER(IsDebuggerPresent); static bool initialized; if (!initialized) { auto IsDebuggerPresent_Real = GET_PROC_ADDRESS(KERNEL32, IsDebuggerPresent); initialized = true; } if (IsDebuggerPresent_Real != nullptr) { return IsDebuggerPresent_Real(); } else { return FALSE; } } void* WINAPI EncodePointer_Helper(void* p) { DECLARE_REAL_HOLDER(EncodePointer); static bool initialized; if (!initialized) { auto EncodePointer_Real = GET_PROC_ADDRESS(KERNEL32, EncodePointer); initialized = true; } if (EncodePointer_Real != nullptr) { return EncodePointer_Real(p); } else { return reinterpret_cast(reinterpret_cast(p) ^ GetCurrentProcessId()); } } void* WINAPI DecodePointer_Helper(void* p) { DECLARE_REAL_HOLDER(DecodePointer); static bool initialized; if (!initialized) { auto DecodePointer_Real = GET_PROC_ADDRESS(KERNEL32, DecodePointer); initialized = true; } if (DecodePointer_Real != nullptr) { return DecodePointer_Real(p); } else { return reinterpret_cast(reinterpret_cast(p) ^ GetCurrentProcessId()); } } BOOL WINAPI IsProcessorFeaturePresent_Helper(DWORD feture) { DECLARE_REAL_HOLDER(IsProcessorFeaturePresent); static bool initialized; if (!initialized) { IsProcessorFeaturePresent_Real = GET_PROC_ADDRESS(KERNEL32, IsProcessorFeaturePresent); initialized = true; } if (IsProcessorFeaturePresent_Real != nullptr) { return IsProcessorFeaturePresent_Real(feture); } else { assert(feture == PF_NX_ENABLED); // ATLから呼ばれる return FALSE; } } BOOL WINAPI HeapSetInformation_Helper(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength) { DECLARE_REAL_HOLDER(HeapSetInformation); static bool initialized; if (!initialized) { HeapSetInformation_Real = GET_PROC_ADDRESS(KERNEL32, HeapSetInformation); initialized = true; } if (HeapSetInformation_Real != nullptr) { return HeapSetInformation_Real(hHeap, hic, information, informationLength); } else { return TRUE; } } BOOL WINAPI InitializeCriticalSectionAndSpinCount_Helper(LPCRITICAL_SECTION lpcs, DWORD spinCount) { DECLARE_REAL_HOLDER(InitializeCriticalSectionAndSpinCount); static bool initialized; if (!initialized) { InitializeCriticalSectionAndSpinCount_Real = GET_PROC_ADDRESS(KERNEL32, InitializeCriticalSectionAndSpinCount); initialized = true; } __try { if (InitializeCriticalSectionAndSpinCount_Real != nullptr) { OSVERSIONINFO vi = {sizeof vi}; ::GetVersionEx(&vi); BOOL ret = InitializeCriticalSectionAndSpinCount_Real(lpcs, spinCount); return vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ? TRUE : ret; } else { ::InitializeCriticalSection(lpcs); return TRUE; } } __except(EXCEPTION_EXECUTE_HANDLER) { } return FALSE; } // Interlocked(Push|Pop)EntrySListは、NXが有効な場合のみ呼ばれる。 // Windows XP以前はNX対応していないためInterlocked(Push|Pop)EntrySListが呼ばれることはない。 // そのため、GET_PROC_ADDRESSがnullptrを返すことはないと仮定している。 // なお、Interlocked(Push|Pop)EntrySListもWindows XPから搭載されている。 PSLIST_ENTRY WINAPI InterlockedPushEntrySList_Helper(PSLIST_HEADER head, PSLIST_ENTRY entry) { DECLARE_REAL_HOLDER(InterlockedPushEntrySList); if (InterlockedPushEntrySList_Real == nullptr) { InterlockedPushEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPushEntrySList); } assert(InterlockedPushEntrySList_Real != nullptr); return InterlockedPushEntrySList_Real(head, entry); } PSLIST_ENTRY WINAPI InterlockedPopEntrySList_Helper(PSLIST_HEADER head) { DECLARE_REAL_HOLDER(InterlockedPopEntrySList); if (InterlockedPopEntrySList_Real == nullptr) { InterlockedPopEntrySList_Real = GET_PROC_ADDRESS(KERNEL32, InterlockedPopEntrySList); } assert(InterlockedPopEntrySList_Real != nullptr); return InterlockedPopEntrySList_Real(head); } }