Created
April 21, 2024 19:35
-
-
Save MurylloEx/b255dd9e19f7794c8c90f595d031337b to your computer and use it in GitHub Desktop.
This function allocate a space near of a memory block that could be used by a trampoline function in hooking libraries.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Windows.h> | |
#define MAX_MEMORY_RANGE 0x40000000 | |
#define IS_POINTER_BETWEEN(P, MAX, MIN) (((ULONG_PTR)P < (ULONG_PTR)MAX) && ((ULONG_PTR)P > (ULONG_PTR)MIN)) | |
#define PAGE_EXECUTE_FLAGS \ | |
PAGE_EXECUTE | \ | |
PAGE_EXECUTE_READ | \ | |
PAGE_EXECUTE_READWRITE | \ | |
PAGE_EXECUTE_WRITECOPY | |
PVOID WINAPI VirtualAllocNearLowerPage( | |
IN HANDLE ProcessHandle, | |
IN PVOID Address, | |
IN PVOID MinAddress, | |
IN PVOID MaxAddress, | |
IN SIZE_T AllocationSize, | |
IN DWORD AllocationType, | |
IN DWORD AllocationProtection, | |
IN DWORD AllocationGranularity) | |
{ | |
MEMORY_BASIC_INFORMATION MemoryInfo = { 0 }; | |
ULONG_PTR BaseAddress = (ULONG_PTR)Address; | |
BaseAddress -= BaseAddress % AllocationGranularity; | |
BaseAddress -= AllocationGranularity; | |
while (VirtualQueryEx(ProcessHandle, (LPVOID)BaseAddress, &MemoryInfo, sizeof(MemoryInfo)) == sizeof(MemoryInfo)) | |
{ | |
if (!IS_POINTER_BETWEEN(BaseAddress, MaxAddress, MinAddress)) { | |
break; | |
} | |
if (!IS_POINTER_BETWEEN(BaseAddress, MaxAddress, AllocationGranularity)) { | |
break; | |
} | |
if (MemoryInfo.State == MEM_FREE) { | |
return VirtualAllocEx( | |
ProcessHandle, | |
(LPVOID)BaseAddress, | |
AllocationSize, | |
AllocationType, | |
AllocationProtection); | |
} | |
BaseAddress = (ULONG_PTR)MemoryInfo.BaseAddress - AllocationGranularity; | |
} | |
return NULL; | |
} | |
PVOID WINAPI VirtualAllocNearUpperPage( | |
IN HANDLE ProcessHandle, | |
IN PVOID Address, | |
IN PVOID MinAddress, | |
IN PVOID MaxAddress, | |
IN SIZE_T AllocationSize, | |
IN DWORD AllocationType, | |
IN DWORD AllocationProtection, | |
IN DWORD AllocationGranularity) | |
{ | |
MEMORY_BASIC_INFORMATION MemoryInfo = { 0 }; | |
ULONG_PTR BaseAddress = (ULONG_PTR)Address; | |
BaseAddress -= BaseAddress % AllocationGranularity; | |
BaseAddress += AllocationGranularity; | |
while (VirtualQueryEx(ProcessHandle, (LPVOID)BaseAddress, &MemoryInfo, sizeof(MemoryInfo)) == sizeof(MemoryInfo)) | |
{ | |
if (!IS_POINTER_BETWEEN(BaseAddress, MaxAddress, MinAddress)) { | |
break; | |
} | |
if (MemoryInfo.State == MEM_FREE) { | |
return VirtualAllocEx( | |
ProcessHandle, | |
(LPVOID)BaseAddress, | |
AllocationSize, | |
AllocationType, | |
AllocationProtection); | |
} | |
BaseAddress = (ULONG_PTR)MemoryInfo.BaseAddress + MemoryInfo.RegionSize; | |
BaseAddress += static_cast<ULONG_PTR>(AllocationGranularity) - 1; | |
BaseAddress -= BaseAddress % AllocationGranularity; | |
} | |
return NULL; | |
} | |
PVOID WINAPI VirtualAllocNearPage( | |
IN HANDLE ProcessHandle, | |
IN PVOID Address, | |
IN PVOID MinAddress, | |
IN PVOID MaxAddress, | |
IN SIZE_T AllocationSize, | |
IN DWORD AllocationType, | |
IN DWORD AllocationProtection, | |
IN DWORD AllocationGranularity) | |
{ | |
PVOID NearLowerPageAddress = VirtualAllocNearLowerPage( | |
ProcessHandle, | |
Address, | |
MinAddress, | |
MaxAddress, | |
AllocationSize, | |
AllocationType, | |
AllocationProtection, | |
AllocationGranularity); | |
if (NearLowerPageAddress) { | |
return NearLowerPageAddress; | |
} | |
PVOID NearUpperPageAddress = VirtualAllocNearUpperPage( | |
ProcessHandle, | |
Address, | |
MinAddress, | |
MaxAddress, | |
AllocationSize, | |
AllocationType, | |
AllocationProtection, | |
AllocationGranularity); | |
return NearUpperPageAddress; | |
} | |
PVOID WINAPI AllocateBlockNearPage( | |
IN HANDLE ProcessHandle, | |
IN PVOID Address, | |
IN DWORD AllocationType, | |
IN DWORD AllocationProtection) | |
{ | |
SYSTEM_INFO SystemInfo = { 0 }; | |
GetSystemInfo(&SystemInfo); | |
ULONG_PTR BaseAddress = (ULONG_PTR)Address; | |
ULONG_PTR MinAddress = (ULONG_PTR)SystemInfo.lpMinimumApplicationAddress; | |
ULONG_PTR MaxAddress = (ULONG_PTR)SystemInfo.lpMaximumApplicationAddress; | |
DWORD AllocationGranularity = SystemInfo.dwAllocationGranularity; | |
DWORD AllocationPageSize = SystemInfo.dwPageSize; | |
/* Look only for the +/- 1GB virtual memory around */ | |
if (MinAddress < BaseAddress - MAX_MEMORY_RANGE && BaseAddress > MAX_MEMORY_RANGE) | |
MinAddress = BaseAddress - MAX_MEMORY_RANGE; | |
/* Look only for the +/- 1GB virtual memory around */ | |
if (MaxAddress > BaseAddress + MAX_MEMORY_RANGE) | |
MaxAddress = BaseAddress + MAX_MEMORY_RANGE; | |
/* Subtract 1 page size from maximum address */ | |
MaxAddress -= static_cast<ULONG_PTR>(AllocationPageSize) - 1; | |
return VirtualAllocNearPage( | |
ProcessHandle, | |
Address, | |
(PVOID)MinAddress, | |
(PVOID)MaxAddress, | |
AllocationPageSize, | |
AllocationType, | |
AllocationProtection, | |
AllocationGranularity); | |
} | |
BOOL WINAPI IsExecutableAddress( | |
IN HANDLE ProcessHandle, | |
IN PVOID Address) | |
{ | |
MEMORY_BASIC_INFORMATION MemoryInfo = { 0 }; | |
if (VirtualQueryEx(ProcessHandle, Address, &MemoryInfo, sizeof(MemoryInfo)) != sizeof(MemoryInfo)) { | |
return FALSE; | |
} | |
return ((MemoryInfo.State == MEM_COMMIT) && (MemoryInfo.Protect & PAGE_EXECUTE_FLAGS)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment