Overview
The allocator::heap policy allocates memory for syscall stubs using a private heap created with the HEAP_CREATE_ENABLE_EXECUTE flag. This provides executable memory in a separate heap, isolated from the process’s default heap.
Method Signatures
Creates a private executable heap and allocates memory for syscall stubs static bool allocate (
size_t uRegionSize ,
const std :: span < const uint8_t > vecBuffer ,
void*& pOutRegion ,
HANDLE & hOutHeapHandle
)
Size of the region to allocate in bytes
vecBuffer
const std::span<const uint8_t>
required
Buffer containing the syscall stubs to copy into the heap
Output parameter receiving the base address of the allocated memory
Output parameter receiving the heap handle (must be saved for cleanup)
Returns true on successful allocation, false on failure
Destroys the private heap static void release ( void* /*region*/ , HANDLE hHeapHandle )
Unused (entire heap is destroyed)
Handle to the heap to destroy
Implementation Details
The allocation process:
Create a private heap with HEAP_CREATE_ENABLE_EXECUTE | HEAP_GROWABLE
Allocate memory from the heap using RtlAllocateHeap
Copy the syscall stubs into the allocated memory
Return the allocation address and heap handle
The heap handle must be preserved for cleanup. The Manager class stores it internally and passes it to release() in the destructor.
Source Code
From syscall.hpp:167-209:
struct heap
{
static bool allocate ( size_t uRegionSize , const std :: span < const uint8_t > vecBuffer ,
void*& pOutRegion , HANDLE & hOutHeapHandle )
{
HMODULE hNtdll = native :: getModuleBase ( hashing :: calculateHash ( "ntdll.dll" ));
if ( ! hNtdll)
return false ;
auto fRtlCreateHeap = reinterpret_cast < native :: RtlCreateHeap_t > (
native :: getExportAddress (hNtdll, SYSCALL_ID ( "RtlCreateHeap" )));
auto fRtlAllocateHeap = reinterpret_cast < native :: RtlAllocateHeap_t > (
native :: getExportAddress (hNtdll, SYSCALL_ID ( "RtlAllocateHeap" )));
if ( ! fRtlCreateHeap || ! fRtlAllocateHeap)
return false ;
hOutHeapHandle = fRtlCreateHeap (
HEAP_CREATE_ENABLE_EXECUTE | HEAP_GROWABLE,
nullptr , 0 , 0 , nullptr , nullptr
);
if ( ! hOutHeapHandle)
return false ;
pOutRegion = fRtlAllocateHeap (hOutHeapHandle, 0 , uRegionSize);
if ( ! pOutRegion) {
release ( nullptr , hOutHeapHandle);
hOutHeapHandle = nullptr ;
return false ;
}
std :: copy_n ( vecBuffer . data (), uRegionSize, static_cast < uint8_t *> (pOutRegion));
return true ;
}
static void release ( void* /*region*/ , HANDLE hHeapHandle )
{
if (hHeapHandle) {
HMODULE hNtdll = native :: getModuleBase ( hashing :: calculateHash ( "ntdll.dll" ));
if ( ! hNtdll)
return ;
auto fRtlDestroyHeap = reinterpret_cast < native :: RtlDestroyHeap_t > (
native :: getExportAddress (hNtdll, SYSCALL_ID ( "RtlDestroyHeap" )));
if (fRtlDestroyHeap)
fRtlDestroyHeap (hHeapHandle);
}
}
};
Usage Example
#include <syscalls-cpp/syscall.hpp>
// Use with gadget generation on x64
#if SYSCALL_PLATFORM_WINDOWS_64
SyscallHeapGadget syscallManager;
if ( ! syscallManager . initialize ()) {
std ::cerr << "Failed to initialize with heap allocator \n " ;
return 1 ;
}
#endif
// Or compose manually
using HeapDirectManager = syscall ::Manager <
syscall :: policies :: allocator ::heap,
syscall :: policies :: generator ::direct
> ;
HeapDirectManager manager;
manager . initialize ();
Security Properties
Isolation Syscall stubs are isolated in a separate heap, distinct from the process’s default heap and other allocations.
Executable The HEAP_CREATE_ENABLE_EXECUTE flag allows code execution directly from heap memory without additional protection changes.
Trade-offs
Aspect Description Security Medium—executable but mutable Performance Fast allocation (single heap operation) Complexity Simple, straightforward process Compatibility Windows 2000+ Memory Management Automatic cleanup via heap destruction
While faster than section-based allocation, heap memory can still be modified after allocation, making it less secure than SEC_NO_CHANGE sections.
See Also
allocator::section Immutable section-based allocation
allocator::memory Virtual memory allocation
Policy Composition Learn how to combine policies