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.
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.