Reputation: 181
I need to allocate a certain space in memory, and I have been using VirtualAlloc
for this.
However, I have increasingly noticed that VirtualAlloc
returns an address that exceeds 32 bits, though always less than 33 bits.
The consequence is that when I copy data to this memory address, the computer crashes into a BSOD.
I am using 64-bit windows and a 64-bit Python. I suspect that the program that copies data to the memory is only equipped to handle 32 bits. Is there is a way to enforce VirtualAlloc
to provide an address within 32 bits?
I am using Python
, specifically the ctypes
package to call VirtualAlloc
, see code below.
Executing this code multiple times changes the address, so repeatedly calling the function below will eventually result in an address below 32 bits. However, I am looking for the cause of and a fail-safe solution to the problem. Any help would be greatly appreciated.
import ctypes
mem_commit = 0x1000
page_readwrite = 0x4
size_bytes = 200000 # Allocation sizes are usually around this value
ctypes.windll.kernel32.VirtualAlloc.argtypes = [
ctypes.c_void_p, ctypes.c_long, ctypes.c_long, ctypes.c_long]
ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_int
addr = ctypes.windll.kernel32.VirtualAlloc(
0, ctypes.c_long(size_bytes), mem_commit, page_readwrite)
Note that I free up the memory afterwards using VirtualFree
.
Upvotes: 1
Views: 1275
Reputation: 140
It is possible to enforce a memory allocation with VirtualAlloc
starting on a 32-bits address memory as long as there is enough free space at this range. Looking in the msdoc we have the following function signature:
LPVOID VirtualAlloc(
LPVOID lpAddress,
SIZE_T dwSize,
DWORD flAllocationType,
DWORD flProtect
);
And the following description for lpAddress
:
The starting address of the region to allocate [...] If this parameter is NULL, the system determines where to allocate the region.
So you can choose the address with this parameter. In your case, you specified 0 for lpAddress
and it is considered as NULL value.
Furthermore, you must consider that if you choose the memory address you have to ensure that the space is free or VirtualAlloc
will not give you the space.
Also, you use mem_commit
without mem_reserve
and the msdoc says:
Attempting to commit a specific address range by specifying MEM_COMMIT without MEM_RESERVE and a non-NULL lpAddress fails unless the entire range has already been reserved.
A better option would be to use 0x3000 (MEM_COMMIT|MEM_RESERVE) for flAllocationType
Finally, you certainly could use a 64-bits address but you set the result type of VirtualAlloc
to c_int
and on Windows, this is an alias for a signed 32 bits c_long
. So a 64-bits address returned by VirtualAlloc
would be truncated thus you would use a wrong address to copy your data.
Upvotes: 0