Skip to content

Instantly share code, notes, and snippets.

@MurylloEx
Created April 21, 2024 19:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MurylloEx/b255dd9e19f7794c8c90f595d031337b to your computer and use it in GitHub Desktop.
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.
#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