NtAllocateUserPhysicalPages
Alloue des pages de mémoire physique pour Address Windowing Extensions (AWE).
Prototype
NTSTATUS NtAllocateUserPhysicalPages( HANDLE ProcessHandle, PULONG_PTR NumberOfPages, PULONG_PTR UserPfnArray );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| ProcessHandle | HANDLE | in | Handle vers le processus qui possédera les pages physiques. Généralement NtCurrentProcess(). |
| NumberOfPages | PULONG_PTR | in/out | En entrée : nombre de pages physiques demandées. En sortie : nombre effectivement alloué. |
| UserPfnArray | PULONG_PTR | out | Tableau fourni par l'appelant qui reçoit un identifiant opaque de page-frame par page allouée. |
IDs de syscalls par version de Windows
| Version de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0x71 | win10-1507 |
| Win10 1607 | 0x71 | win10-1607 |
| Win10 1703 | 0x72 | win10-1703 |
| Win10 1709 | 0x72 | win10-1709 |
| Win10 1803 | 0x72 | win10-1803 |
| Win10 1809 | 0x72 | win10-1809 |
| Win10 1903 | 0x72 | win10-1903 |
| Win10 1909 | 0x72 | win10-1909 |
| Win10 2004 | 0x73 | win10-2004 |
| Win10 20H2 | 0x73 | win10-20h2 |
| Win10 21H1 | 0x73 | win10-21h1 |
| Win10 21H2 | 0x73 | win10-21h2 |
| Win10 22H2 | 0x73 | win10-22h2 |
| Win11 21H2 | 0x73 | win11-21h2 |
| Win11 22H2 | 0x73 | win11-22h2 |
| Win11 23H2 | 0x73 | win11-23h2 |
| Win11 24H2 | 0x75 | win11-24h2 |
| Server 2016 | 0x71 | winserver-2016 |
| Server 2019 | 0x72 | winserver-2019 |
| Server 2022 | 0x73 | winserver-2022 |
| Server 2025 | 0x75 | winserver-2025 |
Module noyau
APIs liées
Stub du 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
Notes non documentées
Fait partie de la famille d'API Address Windowing Extensions (AWE). AWE permet à un processus de réserver une fenêtre d'adresse virtuelle fixe puis de mapper et remapper à la demande des pages physiques arbitraires dedans — en contournant entièrement le working-set et le fichier d'échange Windows. Les valeurs PFN opaques retournées dans UserPfnArray ne sont *pas* des PFN bruts ; ce sont des handles côté noyau qui ne peuvent être consommés que par NtMapUserPhysicalPages et NtFreeUserPhysicalPages sur le même processus. L'appelant doit détenir **SeLockMemoryPrivilege** (habituellement accordé uniquement à LocalSystem et aux comptes de service explicitement configurés), ce qui constitue la barrière pratique tenant AWE hors de portée des malwares peu privilégiés.
Usage courant par les malwares
Trois abus notables. Premièrement, **planque de code non-paginable** : les pages allouées via AWE ne sont jamais swappées vers le fichier d'échange, donc un payload mappé via NtMapUserPhysicalPages reste hors de pagefile.sys pour toujours — déjouant la forensique disque morte qui récupère du shellcode RWX depuis un dump de swap. Deuxièmement, **amplification de primitive R/W noyau** : combiné à un driver signé vulnérable exposant une lecture/écriture arbitraire de mémoire physique, les PFN AWE permettent à une chaîne d'exploit d'aliaser le contenu d'une page noyau dans une fenêtre user-mode, transformant une lecture ponctuelle en mapping persistant. Troisièmement, **évasion AV via des types VAD inhabituels** : les allocations AWE apparaissent comme un sous-type VAD `VadAwe` que certains scanners ignorent. SeLockMemoryPrivilege est le goulot ; les échantillons qui ont besoin d'AWE pivotent généralement par un service SYSTEM d'abord ou enchaînent une primitive d'usurpation de token survivant au privilège.
Opportunités de détection
L'usage d'AWE hors SQL Server, Exchange, Oracle et une poignée de frameworks HPC est extrêmement rare. Détection via journal d'événements : surveillez l'ajout de `SeLockMemoryPrivilege` à un compte non-service dans la Local Security Policy, et les événements d'ajustement de token (Sysmon Event ID 4673 si l'audit de sous-catégorie est activé) sur `SeLockMemoryPrivilege`. Côté noyau, le parcours VAD fera surgir des entrées `VadAwe` dans des processus inattendus (notepad.exe avec une région AWE est extrêmement anormal). Les EDR à intégration scanner mémoire devraient traiter les réservations VirtualAlloc MEM_PHYSICAL dans des processus non-base-de-données comme haute sévérité.
Exemples de syscalls directs
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 ENDPMappings MITRE ATT&CK
Last verified: 2026-05-20