> Windows Syscalls
ntoskrnl.exeT1106T1055T1068

NtAllocateUserPhysicalPages

Asigna páginas de memoria física para Address Windowing Extensions (AWE).

Prototipo

NTSTATUS NtAllocateUserPhysicalPages(
  HANDLE      ProcessHandle,
  PULONG_PTR  NumberOfPages,
  PULONG_PTR  UserPfnArray
);

Argumentos

NameTypeDirDescription
ProcessHandleHANDLEinHandle al proceso que será dueño de las páginas físicas. Habitualmente NtCurrentProcess().
NumberOfPagesPULONG_PTRin/outEn entrada: número de páginas físicas solicitadas. En salida: número realmente asignado.
UserPfnArrayPULONG_PTRoutArreglo proporcionado por el llamante que recibe un identificador opaco de page-frame por página asignada.

IDs de syscalls por versión de Windows

Versión de WindowsID de syscallBuild
Win10 15070x71win10-1507
Win10 16070x71win10-1607
Win10 17030x72win10-1703
Win10 17090x72win10-1709
Win10 18030x72win10-1803
Win10 18090x72win10-1809
Win10 19030x72win10-1903
Win10 19090x72win10-1909
Win10 20040x73win10-2004
Win10 20H20x73win10-20h2
Win10 21H10x73win10-21h1
Win10 21H20x73win10-21h2
Win10 22H20x73win10-22h2
Win11 21H20x73win11-21h2
Win11 22H20x73win11-22h2
Win11 23H20x73win11-23h2
Win11 24H20x75win11-24h2
Server 20160x71winserver-2016
Server 20190x72winserver-2019
Server 20220x73winserver-2022
Server 20250x75winserver-2025

Módulo del kernel

ntoskrnl.exeNtAllocateUserPhysicalPages

APIs relacionadas

AllocateUserPhysicalPagesFreeUserPhysicalPagesMapUserPhysicalPagesNtMapUserPhysicalPagesNtFreeUserPhysicalPagesVirtualAlloc

Stub del syscall

4C 8B D1                  mov r10, rcx
B8 75 00 00 00            mov eax, 0x75
F6 04 25 08 03 FE 7F 01   test byte ptr [0x7FFE0308], 1
75 03                     jne short +3
0F 05                     syscall
C3                        ret
CD 2E                     int 2Eh
C3                        ret

Notas no documentadas

Parte de la familia de API Address Windowing Extensions (AWE). AWE permite a un proceso reservar una ventana fija de direcciones virtuales y luego mapear y re-mapear bajo demanda páginas físicas arbitrarias dentro de ella — eludiendo por completo el working-set y el archivo de paginación de Windows. Los valores PFN opacos devueltos en UserPfnArray *no* son PFN crudos; son handles del lado kernel que solo pueden ser consumidos por NtMapUserPhysicalPages y NtFreeUserPhysicalPages en el mismo proceso. El llamante debe poseer **SeLockMemoryPrivilege** (habitualmente otorgado solo a LocalSystem y a cuentas de servicio configuradas explícitamente), lo que es la barrera práctica que mantiene AWE fuera del alcance de malware con pocos privilegios.

Uso común por malware

Tres abusos destacados. Primero, **escondrijo de código no-paginable**: las páginas asignadas vía AWE nunca se swapean al archivo de paginación, así que un payload mapeado vía NtMapUserPhysicalPages permanece fuera de pagefile.sys para siempre — frustrando la forense de disco muerto que recupera shellcode RWX desde un volcado de swap. Segundo, **amplificación de primitiva R/W de kernel**: combinado con un driver firmado vulnerable que exponga lectura/escritura arbitraria de memoria física, los PFN AWE permiten a una cadena de exploit aliasar el contenido de una página de kernel en una ventana user-mode, convirtiendo una lectura puntual en un mapeo persistente. Tercero, **evasión AV vía tipos VAD inusuales**: las asignaciones AWE aparecen como un subtipo VAD `VadAwe` que algunos escáneres ignoran. SeLockMemoryPrivilege es el cuello de botella; las muestras que necesitan AWE suelen pivotar por un servicio SYSTEM primero o encadenar una primitiva de suplantación de token que sobreviva al privilegio.

Oportunidades de detección

El uso de AWE fuera de SQL Server, Exchange, Oracle y un puñado de frameworks HPC es extremadamente raro. Detección por registro de eventos: vigile la adición de `SeLockMemoryPrivilege` a una cuenta no-servicio en la Local Security Policy, y los eventos de ajuste de token (Sysmon Event ID 4673 si la auditoría de subcategoría está habilitada) sobre `SeLockMemoryPrivilege`. Del lado kernel, el recorrido VAD aflorará entradas `VadAwe` en procesos inesperados (notepad.exe con una región AWE es enormemente anómalo). Los EDR con integración de escáner de memoria deberían tratar las reservas VirtualAlloc MEM_PHYSICAL en procesos no-base-de-datos como de alta severidad.

Ejemplos de syscalls directos

cAWE allocation gated on SeLockMemoryPrivilege

// Enable SeLockMemoryPrivilege, then allocate physical pages and reserve a
// virtual address window for mapping.
#include <windows.h>

BOOL EnableLockMemoryPrivilege(void) {
    HANDLE hTok;
    TOKEN_PRIVILEGES tp;
    if (!OpenProcessToken(GetCurrentProcess(),
                          TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hTok)) return FALSE;
    LookupPrivilegeValueA(NULL, "SeLockMemoryPrivilege", &tp.Privileges[0].Luid);
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    BOOL ok = AdjustTokenPrivileges(hTok, FALSE, &tp, 0, NULL, NULL) && GetLastError() == ERROR_SUCCESS;
    CloseHandle(hTok);
    return ok;
}

void awe_alloc(SIZE_T pages) {
    EnableLockMemoryPrivilege();

    ULONG_PTR  request = pages;
    ULONG_PTR *pfn     = (ULONG_PTR*)HeapAlloc(GetProcessHeap(), 0, pages * sizeof(ULONG_PTR));

    if (AllocateUserPhysicalPages(GetCurrentProcess(), &request, pfn)) {
        SIZE_T window = pages * 4096;
        PVOID  view   = VirtualAlloc(NULL, window,
                                     MEM_RESERVE | MEM_PHYSICAL, PAGE_READWRITE);
        MapUserPhysicalPages(view, request, pfn);
        // 'view' now aliases the physical pages; remap on demand.
    }
}

asmx64 direct stub (Win11 24H2, SSN 0x75)

NtAllocateUserPhysicalPages PROC
    mov  r10, rcx
    mov  eax, 75h
    syscall
    ret
NtAllocateUserPhysicalPages ENDP

Mapeos MITRE ATT&CK

Last verified: 2026-05-20