1

When passing 0x000'00000000 (NULL) as the first parameter of VirtualAlloc the system determines where to allocate the region, or if the function fails, the return value is NULL (0x000'00000000).

For a 64-bit process on 64-bit Windows, the virtual address space ranges from 0x000'00000000 through 0x7FFF'FFFFFFFF.

So how do I reserve a page starting at 0x000'00000000 without the function failing and system determining where to allocate the region?

err69
  • 317
  • 1
  • 7
  • 4
    You don't. Why are you trying to? – user3386109 Jun 08 '23 at 18:37
  • 1
    @user3386109 trying to store some process specific meta data in the first page – err69 Jun 08 '23 at 18:39
  • 3
    And what do you expect to be able to do with meta data in the first page, that you can't do with meta data in any other page? – user3386109 Jun 08 '23 at 18:42
  • 7
    Not possible, the first 64K of the address range is reserved. That's how null pointer dereferences get detected. – Hans Passant Jun 08 '23 at 18:46
  • The documentation says "If you are reserving memory, the function rounds this address down to the nearest multiple of the allocation granularity." So try passing an address of 1 instead of 0. Now it isn't NULL and doesn't mean "system choose for me", but it will round down and become 0. – Ben Voigt Jun 08 '23 at 19:26
  • @RemyLebeau: Note that the `lpAddress` parameter doesn't control what memory you get, it controls placement of the allocation (or reservation) into your own virtual address space. So we should speak not of "memory that the OS reserves" but "virtual address ranges that the OS reserves". The user/kernel address boundary at either 2GB or 3GB is documented, you'll get an error if you choose an address on the kernel side (but WOW64 doesn't reserve any of 32-bit address space for the kernel since it uses 64-bit addresses). – Ben Voigt Jun 08 '23 at 21:19
  • One would expect that if the 0 page is similarly reserved it would be documented, but it isn't specified in the same place. Maybe it's somewhere else. – Ben Voigt Jun 08 '23 at 21:20
  • related: https://stackoverflow.com/q/21911938/103167 – Ben Voigt Jun 08 '23 at 21:20
  • If this were possible, how do you plan to subsequently access address 0? C requires that a pointer with value 0 represents an invalid pointer. You cannot have a pointer that's both valid and invalid at the same time. – IInspectable Jun 09 '23 at 07:21
  • @IInspectable Technically, C requires that a NULL pointer represents an invalid pointer. Whether the byte value of a NULL pointer is 0 is implementation-defined (but the case on Windows.) And one could always access address 0 via operating system functions; WriteProcessMemory will not fail you. – Fulgen Jun 10 '23 at 21:54

1 Answers1

1

Taking your question literally, you asked to reserve a page and not commit it. That's easy; the operating system already does it for you on process startup to prevent that page being committed by accident and causing havoc with all the functions that use those 65536 addresses as special values, like the NULL pointer or integers disguised as string pointers like MAKEINTRESOURCE, or, as Hans Passant has mentioned in the comments, breaking the CLR's null pointer detection by treating every access violation in that page as a null pointer exception.

However, starting with Windows 8, you cannot unreserve that page anymore.

Fulgen
  • 351
  • 2
  • 13