LPVOID VirtualAllocWrapper::Alloc(LPVOID lpAddress, size_t dwSize, DWORD allocationType, DWORD protectFlags, bool isCustomHeapAllocation) { Assert(this == nullptr); LPVOID address = nullptr; #if defined(ENABLE_JIT_CLAMP) bool makeExecutable; if ((isCustomHeapAllocation) || (protectFlags & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE))) { makeExecutable = true; } else { makeExecutable = false; } AutoEnableDynamicCodeGen enableCodeGen(makeExecutable); #endif #if defined(_CONTROL_FLOW_GUARD) DWORD oldProtectFlags; if (AutoSystemInfo::Data.IsCFGEnabled() && isCustomHeapAllocation) { //We do the allocation in two steps - CFG Bitmap in kernel will be created only on allocation with EXECUTE flag. //We again call VirtualProtect to set to the requested protectFlags. DWORD allocProtectFlags = 0; if (AutoSystemInfo::Data.IsCFGEnabled()) { allocProtectFlags = PAGE_EXECUTE_RW_TARGETS_INVALID; } else { allocProtectFlags = PAGE_EXECUTE_READWRITE; } address = VirtualAlloc(lpAddress, dwSize, allocationType, allocProtectFlags); VirtualProtect(address, dwSize, protectFlags, &oldProtectFlags); } else #endif { address = VirtualAlloc(lpAddress, dwSize, allocationType, protectFlags); } return address; }
LPVOID VirtualAllocWrapper::AllocPages(LPVOID lpAddress, size_t pageCount, DWORD allocationType, DWORD protectFlags, bool isCustomHeapAllocation) { if (pageCount > AutoSystemInfo::MaxPageCount) { return nullptr; } size_t dwSize = pageCount * AutoSystemInfo::PageSize; LPVOID address = nullptr; #if defined(ENABLE_JIT_CLAMP) bool makeExecutable; if ((isCustomHeapAllocation) || (protectFlags & (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE))) { makeExecutable = true; } else { makeExecutable = false; } AutoEnableDynamicCodeGen enableCodeGen(makeExecutable); #endif #if defined(_CONTROL_FLOW_GUARD) DWORD oldProtectFlags = 0; if (AutoSystemInfo::Data.IsCFGEnabled() && isCustomHeapAllocation) { //We do the allocation in two steps - CFG Bitmap in kernel will be created only on allocation with EXECUTE flag. //We again call VirtualProtect to set to the requested protectFlags. DWORD allocProtectFlags = 0; if (AutoSystemInfo::Data.IsCFGEnabled()) { allocProtectFlags = PAGE_EXECUTE_RW_TARGETS_INVALID; } else { allocProtectFlags = PAGE_EXECUTE_READWRITE; } address = VirtualAlloc(lpAddress, dwSize, allocationType, allocProtectFlags); if (address == nullptr) { MemoryOperationLastError::RecordLastError(); return nullptr; } else if ((allocationType & MEM_COMMIT) == MEM_COMMIT) // The access protection value can be set only on committed pages. { BOOL result = VirtualProtect(address, dwSize, protectFlags, &oldProtectFlags); if (result == FALSE) { CustomHeap_BadPageState_fatal_error((ULONG_PTR)this); } } } else #endif { address = VirtualAlloc(lpAddress, dwSize, allocationType, protectFlags); if (address == nullptr) { MemoryOperationLastError::RecordLastError(); return nullptr; } } return address; }