cwindowsnt-native-api

Calling NtAllocateVirtualMemory Fails


I was playing with some windows NT Apis to get familiar with them and understand how they work. I tried to call NtAllocateVirtualMemory:

int main()
{
    char* myBuffer = NULL;
    long allocationSize = 1024;
    pNtAllocateVirtualMemory ntVirtualAlloc = (pNtAllocateVirtualMemory)GetProcAddress(GetModuleHandleA("ntdll"), "NtAllocateVirtualMemory");
    NTSTATUS st = ntVirtualAlloc(GetCurrentProcess(), &(PVOID)myBuffer, 0, &allocationSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    printf("%d", st);
    
}

But the api fails and returns NTSTATUS STATUS_INVALID_PARAMETER. I then checked the prototype more precisely from MSDN:

__kernel_entry NTSYSCALLAPI NTSTATUS NtAllocateVirtualMemory(
  [in]      HANDLE    ProcessHandle,
  [in, out] PVOID     *BaseAddress,
  [in]      ULONG_PTR ZeroBits,
  [in, out] PSIZE_T   RegionSize,
  [in]      ULONG     AllocationType,
  [in]      ULONG     Protect
);

Then I changed the allocationSize to long long and the code worked correctly.

My question is how exactly windows consider a pointer to long invalid but a pointer to long long valid? While both pointers have same size.


Solution

  • long allocationSize = 1024; reserves four bytes and stores 1024 there. The &allocationSize argument passes the address of those bytes to NtAllocateVirtualMemory. NtAllocateVirtualMemory loads eight bytes from that location. The contents of these eight bytes represent a different value than 1024, likely a very large number. NtAllocateVirtualMemory rejects this value as too large and reports an invalid parameter.