Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For what do I need to use VirtualAlloc/VirtualAllocEx?

For what do I need to use VirtualAlloc/VirtualAllocEx?

An example, one case that I found - if I allocated 4 GB of virtual memory, then if I do not use all of them, then I do not spend physical memory, and if I resize my array, I do not need to do new allocating and copying old data to new array.

struct T_custom_allocator; // which using VirtualAllocEx()
std::vector<int, T_custom_allocator> vec;
vec.reserve(4*1024*1024*1024);  // allocated virtual memory (physical memory is not used)
vec.resize(16384); // allocated 16KB of physical memory
// ...
vec.resize(32768); // allocated 32KB of physical memory 
                   // (no need to copy of first 16 KB of data)

And if I used standard allocator, I need to copy of data when I do resize:

std::vector<int> vec;
vec.resize(16384); // allocated 16KB of physical memory
// ...
vec.resize(32768); // allocated 32KB of physical memory 
                   // and need to copy of first 16 KB of data

Or with standatd allocator, I must spend 4GB of physical memory:

std::vector<int> vec;
vec.reserve(4*1024*1024*1024);  // allocated 4GB of physical memory
vec.resize(16384); // no need to do, except changing a local variable of size
// ...
vec.resize(32768); // no need to do, except changing a local variable of size

But, why this is better than realloc()? http://www.cplusplus.com/reference/cstdlib/realloc/

And are there any else cases to use VirtualAlloc[Ex] with benefits?

like image 850
Alex Avatar asked Jul 07 '13 15:07

Alex


People also ask

Why use VirtualAlloc?

With VirtualAlloc you can reserve 1gb address range. Later you can commit parts of it on demand - so that to given chunks of reserved addresses are assigned actual physical memory blocks. Reservation should never fail, while commit might fail if physical memory is short.

What does VirtualAlloc return?

If the function succeeds, the return value is the base address of the allocated region of pages. If the function fails, the return value is NULL.

What is Mem_commit?

NOTE3: The MEM_COMMIT flag will commit pages on a page size boundary, while using MEM_RESERVE or MEM_RESERVE|MEM_COMMIT will reserve or reserve+commit pages on a boundary greater than the page size, usually 64K on all versions of Windows since today. You can get this number by calling GetSystemInfo() .

Which API call is in charge of allocating memory in a remote process?

VirtualAlloc Ex is what one process can use to allocate memory in an address space of a different process.


2 Answers

Another use for VirtualAllocEx which hasn't been mentioned yet, is to allocate memory in another process' address space. Note that the first parameter is the handle to a process - the function allocates the memory within the virtual address space of that process.

I've used this before when injecting code into another process, by forcing a LoadLibrary call in the target process. The basic steps are as follows:

  1. Get the process id of the target process (e.g. with something like GetWindowThreadProcessId).
  2. Get a handle to the process with the appropriate permissions using OpenProcess.
  3. Allocate some memory in that process with VirtualAllocEx.
  4. Copy the name of your DLL into that memory with WriteProcessMemory.
  5. Get the address of the LoadLibrary function using GetProcAddress.
  6. Call CreateRemoteThread to start the LoadLibrary call in the target process, with the thread parameter being the memory you've allocated with VirtualAllocEx (containing the name of the DLL).

Not that you needed to know all of that, but I though it was an interesting use case.

like image 147
James Holderness Avatar answered Nov 11 '22 22:11

James Holderness


VirtualAlloc and VirtualAllocEx in very simplistic terms allocate raw pages, all other memory functions from malloc to GlobalAlloc all use VirtualAllocEx underneath. The problem with VirtualAlloc is that it is basically raw memory, there is no reallocation or relocation available. As such if your address space becomes fragmented you have no recourse but to release and rebuild.

The primary use case for VirtualAlloc is when you need to write your own memory manager, for say a SQL implementation where it can make a huge difference. Or if you were implementing a Just In Time Compiler (JIT), as you would need to be able to change the protection flags on the page you compile into from read/write to read/execute as to not trigger Data Execution Prevention.

like image 31
Mgetz Avatar answered Nov 11 '22 20:11

Mgetz