NtMapViewOfSectionEx
Syscall étendu de mapping de section (Windows 10 1809+) qui accepte des contraintes MEM_EXTENDED_PARAMETER.
Prototype
NTSTATUS NtMapViewOfSectionEx( HANDLE SectionHandle, HANDLE ProcessHandle, PVOID *BaseAddress, PLARGE_INTEGER SectionOffset, PSIZE_T ViewSize, ULONG AllocationType, ULONG Win32Protect, PMEM_EXTENDED_PARAMETER ExtendedParameters, ULONG ParameterCount );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| SectionHandle | HANDLE | in | Handle vers la section à mapper. Doit posséder un accès SECTION_MAP_* adéquat. |
| ProcessHandle | HANDLE | in | Processus cible. NtCurrentProcess() pour soi-même ; handle distant pour mapping inter-processus. |
| BaseAddress | PVOID* | in/out | Pointeur vers l'adresse de base demandée. NULL laisse le noyau choisir. Mis à jour au retour. |
| SectionOffset | PLARGE_INTEGER | in | Offset optionnel dans la section, doit être aligné sur 64 KiB. |
| ViewSize | PSIZE_T | in/out | Taille de vue demandée en entrée, taille réellement mappée en sortie. 0 mappe toute la section. |
| AllocationType | ULONG | in | MEM_RESERVE, MEM_COMMIT, MEM_LARGE_PAGES, MEM_TOP_DOWN, SEC_NO_CHANGE etc. |
| Win32Protect | ULONG | in | Protection initiale des pages (PAGE_READONLY, PAGE_EXECUTE_READ, PAGE_EXECUTE_WRITECOPY, …). |
| ExtendedParameters | PMEM_EXTENDED_PARAMETER | in | Tableau optionnel de paramètres étendus (contraintes d'adresses, opt-out CFG, hints NUMA). |
| ParameterCount | ULONG | in | Nombre d'entrées dans ExtendedParameters. 0 si ExtendedParameters est NULL. |
IDs de syscalls par version de Windows
| Version de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1803 | 0x10D | win10-1803 |
| Win10 1809 | 0x10E | win10-1809 |
| Win10 1903 | 0x10F | win10-1903 |
| Win10 1909 | 0x10F | win10-1909 |
| Win10 2004 | 0x114 | win10-2004 |
| Win10 20H2 | 0x114 | win10-20h2 |
| Win10 21H1 | 0x114 | win10-21h1 |
| Win10 21H2 | 0x115 | win10-21h2 |
| Win10 22H2 | 0x115 | win10-22h2 |
| Win11 21H2 | 0x11B | win11-21h2 |
| Win11 22H2 | 0x11C | win11-22h2 |
| Win11 23H2 | 0x11C | win11-23h2 |
| Win11 24H2 | 0x11E | win11-24h2 |
| Server 2019 | 0x10E | winserver-2019 |
| Server 2022 | 0x11A | winserver-2022 |
| Server 2025 | 0x11E | winserver-2025 |
Module noyau
APIs liées
Stub du syscall
4C 8B D1 mov r10, rcx B8 1E 01 00 00 mov eax, 0x11E ; Win11 24H2 SSN 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
Introduit dans Windows 10 1809 (Redstone 5) comme équivalent section-mapping de `NtAllocateVirtualMemoryEx`. L'ajout clé par rapport à `NtMapViewOfSection` est le tableau `ExtendedParameters`, qui accepte actuellement `MemExtendedParameterAddressRequirements` (LowestStartingAddress / HighestEndingAddress / Alignment), `MemExtendedParameterAttributeFlags` (`MEM_EXTENDED_PARAMETER_EC_CODE`, `MEM_EXTENDED_PARAMETER_IMAGE_NO_HOTPATCH`), et `MemExtendedParameterImageMachine` (Arm64EC). La contrainte de plage d'adresses est ce qui rend l'API intéressante pour l'outillage offensif — on peut demander que le mapping atterrisse au-dessus de la frontière 32 bits ou à l'écart d'une plage heuristique connue d'un scanner. Indisponible sur Windows 10 1507–1709.
Usage courant par les malwares
Utilisé par les loaders reflectifs modernes et de module stomping qui veulent un contrôle fin sur l'adresse du mapping. Le **Phantom DLL Hollowing** (Forrest Orr, 2020) mappe une DLL Microsoft signée propre sur disque avec `SEC_IMAGE` via `NtCreateSection` + `NtMapViewOfSectionEx`, puis écrase les pages `.text` alors que le noyau croit encore que le mapping est image-backed et signé — défaisant les vérifs de hash de module EDR. Le paramètre `MemExtendedParameterAddressRequirements` sert aussi à imiter le comportement de mapping en haute adresse de `LoadLibraryEx`, se fondant dans les bases de modules légitimes. SSN absent sur Windows 10 1507–1709, donc les loaders ciblant ces builds doivent retomber sur le `NtMapViewOfSection` simple.
Opportunités de détection
Presque toute utilisation de `NtMapViewOfSectionEx` pour des mappings exécutables est anormale hors d'un petit ensemble de loaders système (`ntdll!LdrpMapViewOfSection`, `wow64cpu`). Les EDR qui hookent cette routine dans ntdll attrapent la plupart des appelants non-système ; les utilisateurs de syscalls directs contournent ce hook mais déclenchent quand même les events ETW `Microsoft-Windows-Kernel-Process` ImageLoad quand la section mappée est une image — et l'*absence* d'un event ImageLoad pour un mapping exécutable est en soi un IOC (évasion manual-map). Chasser les mappings section-image dont le fichier de backing n'apparaît pas ensuite dans la liste des modules chargés (`PEB_LDR_DATA`).
Exemples de syscalls directs
cHigh-address mapping with MemExtendedParameterAddressRequirements
// Force the mapping to land above 0x0000_0001_0000_0000 to dodge
// scanner heuristics that focus on low VAs.
MEM_EXTENDED_PARAMETER ep[1] = {0};
MEM_ADDRESS_REQUIREMENTS req = {0};
req.LowestStartingAddress = (PVOID)0x0000000100000000ULL;
req.HighestEndingAddress = (PVOID)0x00007FFFFFFFFFFFULL;
req.Alignment = 0; // default 64 KiB
ep[0].Type = MemExtendedParameterAddressRequirements;
ep[0].Pointer = &req;
PVOID base = NULL; SIZE_T viewSize = 0;
NTSTATUS s = NtMapViewOfSectionEx(
hSection, NtCurrentProcess(),
&base, NULL, &viewSize,
0, PAGE_EXECUTE_READ,
ep, 1);asmx64 direct stub (Win11 24H2)
; NtMapViewOfSectionEx direct stub — SSN 0x11E on Win11 24H2.
; Note: ParameterCount is the 9th argument; spilled onto the stack per
; the Win64 calling convention (shadow + 5th slot).
NtMapViewOfSectionEx PROC
mov r10, rcx
mov eax, 11Eh
syscall
ret
NtMapViewOfSectionEx ENDPrustPhantom DLL Hollowing skeleton
// Phantom DLL Hollowing (Forrest Orr, 2020) — abbreviated.
// 1) Open kernelbase.dll as a SEC_IMAGE section.
// 2) Map it with NtMapViewOfSectionEx into our process.
// 3) Overwrite the .text bytes with shellcode while the kernel still
// believes the region is signed image-backed memory.
use ntapi::ntmmapi::NtMapViewOfSectionEx;
use winapi::shared::ntdef::{HANDLE, PVOID};
use std::{mem, ptr::null_mut};
unsafe fn map_image(section: HANDLE) -> PVOID {
let mut base: PVOID = null_mut();
let mut view: usize = 0;
let s = NtMapViewOfSectionEx(
section,
-1isize as HANDLE, // NtCurrentProcess()
&mut base,
null_mut(),
&mut view,
0,
0x20, // PAGE_EXECUTE_READ
null_mut(),
0,
);
assert!(s >= 0);
base
}Mappings MITRE ATT&CK
Last verified: 2026-05-20