#include "stdafx.h" #define GET_PROC_ADDRESS(hmod, functionName) reinterpret_cast(GetProcAddress((hmod), #functionName)) namespace { OSVERSIONINFO GetVersionEx2() { OSVERSIONINFO vi = {sizeof vi}; GetVersionEx(&vi); return vi; } static OSVERSIONINFO const vi = GetVersionEx2(); HMODULE GetKernelModule() { static HMODULE hmod = GetModuleHandle(TEXT("kernel32")); return hmod; } } extern "C" { BOOL WINAPI IsDebuggerPresent_Helper() { static auto IsDebuggerPresent_Real = GET_PROC_ADDRESS(GetKernelModule(), IsDebuggerPresent); if (IsDebuggerPresent_Real) { return IsDebuggerPresent_Real(); } else { return FALSE; } } void* WINAPI EncodePointer_Helper(void* p) { static auto EncodePointer_Real = GET_PROC_ADDRESS(GetKernelModule(), EncodePointer); if (EncodePointer_Real) { return EncodePointer_Real(p); } else { return reinterpret_cast(reinterpret_cast(p) ^ GetCurrentProcessId()); } } void* WINAPI DecodePointer_Helper(void* p) { static auto DecodePointer_Real = GET_PROC_ADDRESS(GetKernelModule(), DecodePointer); if (DecodePointer_Real) { return DecodePointer_Real(p); } else { return reinterpret_cast(reinterpret_cast(p) ^ GetCurrentProcessId()); } } BOOL WINAPI IsProcessorFeaturePresent_Helper(DWORD feture) { static auto IsProcessorFeaturePresent_Real = GET_PROC_ADDRESS(GetKernelModule(), IsProcessorFeaturePresent); if (IsProcessorFeaturePresent_Real) { 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) { static auto HeapSetInformation_Real = GET_PROC_ADDRESS(GetKernelModule(), HeapSetInformation); if (HeapSetInformation_Real) { return HeapSetInformation_Real(hHeap, hic, information, informationLength); } else { return TRUE; } } namespace { typedef decltype(InitializeCriticalSectionAndSpinCount)* PInitializeCriticalSectionAndSpinCount; // 関数内静的変数とSEHは両立できないようなので別の関数へ分離 BOOL WINAPI InitializeCriticalSectionAndSpinCount_Helper2(PInitializeCriticalSectionAndSpinCount pfn, LPCRITICAL_SECTION lpcs, DWORD spinCount) { __try { if (pfn != nullptr) { BOOL ret = pfn(lpcs, spinCount); return vi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS ? TRUE : ret; } else { ::InitializeCriticalSection(lpcs); return TRUE; } } __except(EXCEPTION_EXECUTE_HANDLER) { } ::SetLastError(ERROR_OUTOFMEMORY); return FALSE; } } BOOL WINAPI InitializeCriticalSectionAndSpinCount_Helper(LPCRITICAL_SECTION lpcs, DWORD spinCount) { static auto InitializeCriticalSectionAndSpinCount_Real = GET_PROC_ADDRESS(GetKernelModule(), InitializeCriticalSectionAndSpinCount); return InitializeCriticalSectionAndSpinCount_Helper2(InitializeCriticalSectionAndSpinCount_Real, lpcs, spinCount); } // 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) { static auto InterlockedPushEntrySList_Real = GET_PROC_ADDRESS(GetKernelModule(), InterlockedPushEntrySList); assert(InterlockedPushEntrySList_Real != nullptr); return InterlockedPushEntrySList_Real(head, entry); } PSLIST_ENTRY WINAPI InterlockedPopEntrySList_Helper(PSLIST_HEADER head) { static auto InterlockedPopEntrySList_Real = GET_PROC_ADDRESS(GetKernelModule(), InterlockedPopEntrySList); assert(InterlockedPopEntrySList_Real != nullptr); return InterlockedPopEntrySList_Real(head); } }