A menudo (y sobre todo para hablantes del español) es confuso entender las diferencias entre los términos reserva, asignación y allocation o asignación de memoria cuando empezamos a estudiar como Windows gestiona y trabaja con la memoria del sistema.
Reserva
La reserva de memoria es una operación exclusivamente lógica que afecta al Espacio de Direccionamiento Virtual del proceso donde se realice la reserva.
El proceso solicita al gestor de memoria que aparte un rango contiguo y seguido de direcciones virtuales, como por ejemplo desde 0x00007FF600000000 hasta 0x00007FF600001000.
Durante esta fase, no se asigna nada de almacenamiento físico en el equipo. No se consume memoria RAM ni espacio en el archivo de paginación pagefile.sys. Aparte, ninguna otra función del proceso podrá usar este rango de direcciones reservado.
Las páginas de memoria quedarán en estado RESERVED. Esto significa que si un hilo intenta escribir información o datos en estas páginas, el procesador lanzará una excepción de violación de acceso porque el espacio está vacío a nivel de hardware (solo está reservado y no en estado COMMITTED).
La función VirtualAlloc es una API presente en Windows que se encarga de reservar la memoria mediante la flag MEM_RESERVE.
//Definicion de VirtualAlloc
LPVOID VirtualAlloc(
[in, optional] LPVOID lpAddress,
[in] SIZE_T dwSize,
[in] DWORD flAllocationType,
[in] DWORD flProtect
);Ejemplo de reserva
Programa de ejemplo utilizando VirtualAlloc y la flag MEM_RESERVE para reservar un rango de direcciones virtuales:
// Reservamos un bloque continuo de 1 Megabyte en el espacio virtual.
// Esto no consume RAM ni espacio en el archivo de paginación.
#include <windows.h>
PVOID pMemoriaReservada = VirtualAlloc(
NULL,
1024 * 1024, // Tamaño: 1 MB
MEM_RESERVE, // Operación de tipo reserva
PAGE_NOACCESS // No se puede leer ni escribir
);
if (pMemoriaReservada != NULL) {
// El espacio virtual está reservado. pMemoriaReservada contiene la dirección base. Si intentamos hacer memcpy(pMemoriaReservada, "datos", 5) el proceso crasheará.
}La siguiente imagen muestra la dirección base de la memoria reservada en nuestro programa:

Asignación
La asignación (o commit) de memoria da lugar cuando el espacio virtual reservado se vincula a recursos físicos del sistema operativo.
El Gestor de Memoria respalda las direcciones virtuales reservadas asignándole una fianza o cuota de almacenamiento del total del sistema en forma de memoria RAM física o en el disco duro a través de pagefile.sys.
En este punto, el sistema operativo garantiza que haya memoria física disponible para cargar los datos del proceso cuando sea necesario. Las páginas, consecuentemente, cambian al estado COMMITTED. Una vez reciben este estado, son accesibles y se rigen por las protecciones PAGE_READWRITE, PAGE_EXECUTE_READ, etc.
Al igual que con la reserva, es posible utilizar VirtualAlloc mediante el flag MEM_COMMIT para asignar memoria. Es posible reservar y asignar al mismo tiempo utilizando la combinación de las flags (MEM_RESERVE | MEM_COMMIT).
Ejemplo de asignación de memoria
Snippet de código utilizando VirtualAlloc y la flag MEM_COMMIT para asignar la memoria reservada:
// Asignamos la primera página (4 KB) dentro de la zona que ya teníamos reservada.
#include <windows.h>
PVOID pMemoriaAsignada = VirtualAlloc(
pMemoriaReservada, // Dirección base donde empieza nuestra reserva
4096, // Tamaño: 4 KB (1 página)
MEM_COMMIT, // Operación de tipo commit
PAGE_READWRITE // Protección: Ahora sí permitimos RW
);
if (pMemoriaAsignada != NULL) {
// El sistema operativo ha respaldado estos 4 KB con memoria física.
// Ahora es seguro escribir información en esta página:
char shellcode[4] = { 0x90, 0x90, 0x90, 0x90 };
memcpy(pMemoriaAsignada, shellcode, 4);
}Tras asignar la memoria correctamente, es posible ver el cambio de estado y las protecciones que presenta:

Posteriormente, se escribe la información en la sección de memoria:

Allocation (Alocación)
El término "alocación" no es una palabra nativa del castellano (es una adaptación del inglés Allocation). Se utiliza como un concepto genérico para describir el acto global de pedir memoria, independientemente del nivel de abstracción. Lo más parecido en español sería asignación.
Cuando utilizamos funciones de "alto nivel" como malloc en C, o APIs como , estamos realizando una asignación de memoria.
A diferencia de la reserva y asignación de memoria, estas funciones de alto nivel no interactúan directamente con las páginas del kernel, sino con el heap (montón en español) del proceso.
El subsistema de la librería de C o del gestor del heap de Windows toma un bloque de memoria que ya estaba previamente reservado y asignado a nivel de páginas por el sistema operativo, lo fragmenta y nos proporciona un puntero al tamaño exacto que hemos pedido (por ejemplo, 100 bytes).
Ejemplo de allocation (asignación)
Este es el uso convencional cuando se programa la lógica operativa del binario (por ejemplo, guardar una lista de procesos, configuraciones, strings de conexión, etc.).
No se interactua con las páginas del kernel, sino que se pide al gestor del Heap del propio proceso que proporcione un fragmento del total de la memoria que él ya controla.
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct Config {
int ID;
bool Activo;
};
void GestionarConfiguracion() {
// Solicitud de 64 bytes (o el tamaño de la struct) al gestor del heap del proceso
// No genera una llamada directa (syscall)
struct Config *miConfig = (struct Config*)malloc(sizeof(struct Config));
if (miConfig != NULL) {
miConfig->ID = 1;
miConfig->Activo = true;
// Liberación del fragmento asignado en el heap para prevenir fugas de memoria
free(miConfig);
}
}Bibliografía
- 01Geoff Chappell's Bloghttps://www.geoffchappell.com
- 02Locating modules via the PEB x64https://malwaretech.com/wiki/locating-modules-via-the-peb-x64
- 03Peb, teb & eathttps://www.m0n1x90.dev/blog/peb-teb-eat
- 04Vergilius Projecthttps://www.vergiliusproject.com
- 05Windows Internals Documentations - Microsofthttps://learn.microsoft.com/es-es/sysinternals/resources/windows-internals



