#include "stdafx.h" #include #include #include "OSVersion.h" extern "C" { extern void* TrapTableFirst; extern FARPROC alias__imp__IsDebuggerPresent; extern FARPROC alias__imp__EncodePointer; extern FARPROC alias__imp__DecodePointer; extern FARPROC alias__imp__HeapSetInformation; extern FARPROC alias__imp__InitializeCriticalSectionAndSpinCount; extern FARPROC alias__imp__InterlockedCompareExchange; extern FARPROC alias__imp__IsProcessorFeaturePresent; extern FARPROC alias__imp__InterlockedPushEntrySList; extern FARPROC alias__imp__InterlockedPopEntrySList; extern void* TrapTableLast; } // extern "C" namespace { HMODULE GetKernelModule() { static HMODULE hmodKernel; if (hmodKernel == nullptr) { hmodKernel = GetModuleHandle(TEXT("kernel32")); } return hmodKernel; } BOOL WINAPI Alternative_IsDebuggerPresent() { ::SetLastError(ERROR_NOT_SUPPORTED); return FALSE; } void* WINAPI Alternative_EncodePointer(void* p) { return reinterpret_cast(reinterpret_cast(p) ^ __security_cookie); } #define Alternative_DecodePointer Alternative_EncodePointer BOOL WINAPI Alternative_HeapSetInformation(HANDLE hHeap, HEAP_INFORMATION_CLASS hic, void* information, SSIZE_T informationLength) { return TRUE; } #pragma warning(push) #pragma warning(disable: 6320 6322) BOOL WINAPI Alternative_InitializeCriticalSectionAndSpinCount(LPCRITICAL_SECTION lpcs, DWORD spinCount) { __try { ::InitializeCriticalSection(lpcs); return TRUE; } __except(EXCEPTION_EXECUTE_HANDLER) { } return FALSE; } #pragma warning(pop) __declspec(naked) long __stdcall Alternative_InterlockedCompareExchange(long volatile*, long, long) { __asm { mov ecx,[esp+4] mov edx,[esp+8] mov eax,[esp+12] lock cmpxchg [ecx],edx ret 12 } } BOOL WINAPI Alternative_IsProcessorFeaturePresent(DWORD /*feture*/) { // ATLからfeture = PF_NX_ENABLEDで呼ばれる return FALSE; } #define FUNCTION_INIT(name) \ if (auto f = ::GetProcAddress(GetKernelModule(), #name)) { \ alias__imp__ ## name = f; \ } else { \ alias__imp__ ## name = reinterpret_cast(Alternative_ ## name); \ } void InitializeOldWindowsHelper() { DWORD oldProtect; ::VirtualProtect(&TrapTableFirst, reinterpret_cast(&TrapTableLast) - reinterpret_cast(&TrapTableFirst), PAGE_READWRITE, &oldProtect); FUNCTION_INIT(IsDebuggerPresent); FUNCTION_INIT(EncodePointer); FUNCTION_INIT(DecodePointer); FUNCTION_INIT(HeapSetInformation); alias__imp__InitializeCriticalSectionAndSpinCount = ActiveBasic::Common::Is9x() ? reinterpret_cast(Alternative_InitializeCriticalSectionAndSpinCount) : ::GetProcAddress(GetKernelModule(), "InitializeCriticalSectionAndSpinCount"); FUNCTION_INIT(InterlockedCompareExchange); FUNCTION_INIT(IsProcessorFeaturePresent); alias__imp__InterlockedPushEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPushEntrySList"); alias__imp__InterlockedPopEntrySList = ::GetProcAddress(GetKernelModule(), "InterlockedPopEntrySList"); ::VirtualProtect(&TrapTableFirst, reinterpret_cast(&TrapTableLast) - reinterpret_cast(&TrapTableFirst), PAGE_READONLY, &oldProtect); } } // unnamed namespace extern "C" { #ifdef _UNICODE int wWinMainCRTStartup(); #define tWinMainCRTStartup wWinMainCRTStartup #else int WinMainCRTStartup(); #define tWinMainCRTStartup WinMainCRTStartup #endif void WinMainStartup_OldWindowsHelper() { __security_init_cookie(); InitializeOldWindowsHelper(); __asm { jmp tWinMainCRTStartup; } } } // extern "C"