> Windows Syscalls
ntoskrnl.exeT1055T1620T1106

NtCreateSectionEx

Creates a section object with extended parameters (NUMA node, address-requirements, user-physical pages).

Prototype

NTSTATUS NtCreateSectionEx(
  PHANDLE                 SectionHandle,
  ACCESS_MASK             DesiredAccess,
  POBJECT_ATTRIBUTES      ObjectAttributes,
  PLARGE_INTEGER          MaximumSize,
  ULONG                   SectionPageProtection,
  ULONG                   AllocationAttributes,
  HANDLE                  FileHandle,
  PMEM_EXTENDED_PARAMETER ExtendedParameters,
  ULONG                   ExtendedParameterCount
);

Arguments

NameTypeDirDescription
SectionHandlePHANDLEoutReceives a handle to the new section object.
DesiredAccessACCESS_MASKinAccess mask: SECTION_MAP_READ / SECTION_MAP_WRITE / SECTION_MAP_EXECUTE / SECTION_ALL_ACCESS.
ObjectAttributesPOBJECT_ATTRIBUTESinOptional name + security descriptor. NULL for an unnamed section (typical for in-process use).
MaximumSizePLARGE_INTEGERinRequired for pagefile-backed sections; optional (file size used) for file-backed sections.
SectionPageProtectionULONGinPage-level protection applied to mapped views: PAGE_READONLY / PAGE_READWRITE / PAGE_EXECUTE_READ / PAGE_EXECUTE_READWRITE / PAGE_WRITECOPY.
AllocationAttributesULONGinSEC_COMMIT / SEC_RESERVE / SEC_IMAGE / SEC_IMAGE_NO_EXECUTE / SEC_LARGE_PAGES / SEC_FILE / SEC_NOCACHE / SEC_WRITECOMBINE.
FileHandleHANDLEinOptional file handle for file-backed sections; NULL for pagefile-backed sections.
ExtendedParametersPMEM_EXTENDED_PARAMETERinArray of MEM_EXTENDED_PARAMETER entries: MemExtendedParameterNumaNode, MemExtendedParameterUserPhysicalHandle, MemExtendedParameterAddressRequirements (for ASLR-resistant layouts), MemExtendedParameterImageMachine (Win11 ARM64EC).
ExtendedParameterCountULONGinNumber of entries in ExtendedParameters; 0 makes this behave like classic NtCreateSection.

Syscall IDs by Windows version

Windows versionSyscall IDBuild
Win10 18090xB9win10-1809
Win10 19030xBAwin10-1903
Win10 19090xBAwin10-1909
Win10 20040xBEwin10-2004
Win10 20H20xBEwin10-20h2
Win10 21H10xBEwin10-21h1
Win10 21H20xBFwin10-21h2
Win10 22H20xBFwin10-22h2
Win11 21H20xC3win11-21h2
Win11 22H20xC4win11-22h2
Win11 23H20xC4win11-23h2
Win11 24H20xC6win11-24h2
Server 20190xB9winserver-2019
Server 20220xC2winserver-2022
Server 20250xC6winserver-2025

Kernel module

ntoskrnl.exeNtCreateSectionEx

Related APIs

CreateFileMappingWMapViewOfFile3NtCreateSectionNtMapViewOfSectionExNtAllocateVirtualMemoryExVirtualAlloc2

Syscall stub

4C 8B D1            mov r10, rcx
B8 C6 00 00 00      mov eax, 0xC6
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

Undocumented notes

Introduced in Windows 10 RS5 (1809) — note the absence of pre-1809 SSNs. `NtCreateSectionEx` extends the classic `NtCreateSection` with a `PMEM_EXTENDED_PARAMETER` array that exposes the same family of attributes used by `VirtualAlloc2` / `MapViewOfFile3` / `NtAllocateVirtualMemoryEx`: NUMA node placement, AWE (user-physical) backing, address-requirements (alignment + low/high bounds, used by CFG-aware allocators and by the Win11 ARM64EC loader), and image-machine override. The kernel handler is `MmCreateSection` (or `MmCreateSpecialImageSection` for `SEC_IMAGE` paths), reached through `MiCreateSectionCommon`. Modern allocators in `ntdll.dll` / `RtlpHpHeapManager` increasingly use the Ex variant to take advantage of address-requirements.

Common malware usage

Two real use cases. (1) **Phantom DLL Hollowing / Process Doppelgänging variants** that need a section backed by a transacted, deleted, or `SEC_IMAGE_NO_EXECUTE` file occasionally prefer the Ex form to specify an address-requirement that collides with the legitimate image they're hollowing — placing the malicious image at the exact base address the loader expects. (2) **CFG / XFG-evading shellcode loaders** use `MemExtendedParameterAddressRequirements` with a high `LowestStartingAddress` to land far away from canonical `KnownDlls` mappings so naïve scanners that walk only the low half of the address space miss the payload. Neither use case is particularly common — most loaders still target the classic `NtCreateSection` because it works on every supported build, whereas `NtCreateSectionEx` is unavailable on Server 2016 / Win10 1703-1803.

Detection opportunities

Same posture as `NtCreateSection`: the syscall itself is high-volume (every `LoadLibrary` of a not-yet-known DLL on modern builds eventually reaches it), so detect the *combination*. Sysmon Event ID 7 (ImageLoad) showing a loaded image whose backing file is in `%TEMP%`, `%PROGRAMDATA%`, or a transacted/pending-delete state is the strong signal. EDRs that hook `NtCreateSectionEx` specifically can flag the rare `MemExtendedParameterImageMachine` override on x64 hosts as anomalous — legitimate ARM64EC binaries on x64 are essentially nonexistent.

Direct syscall examples

asmx64 direct stub (Win11 24H2)

; Direct syscall stub for NtCreateSectionEx (SSN 0xC6 on Win11 24H2)
NtCreateSectionEx PROC
    mov  r10, rcx          ; SectionHandle
    mov  eax, 0C6h         ; SSN — drifts per build
    syscall
    ret
NtCreateSectionEx ENDP

cPagefile-backed section pinned above 0x0000_7000_0000_0000

// CFG-resilient layout: force the section to map high in the address space.
#include <windows.h>
#include <winternl.h>

typedef enum {
    MemExtendedParameterAddressRequirements = 1,
} MEM_EXTENDED_PARAMETER_TYPE;

typedef struct _MEM_ADDRESS_REQUIREMENTS {
    PVOID  LowestStartingAddress;
    PVOID  HighestEndingAddress;
    SIZE_T Alignment;
} MEM_ADDRESS_REQUIREMENTS, *PMEM_ADDRESS_REQUIREMENTS;

typedef struct DECLSPEC_ALIGN(8) _MEM_EXTENDED_PARAMETER {
    struct { DWORD64 Type : 8; DWORD64 Reserved : 56; };
    union { DWORD64 ULong64; PVOID Pointer; SIZE_T Size;
            HANDLE Handle; DWORD ULong; };
} MEM_EXTENDED_PARAMETER, *PMEM_EXTENDED_PARAMETER;

typedef NTSTATUS (NTAPI *pNtCreateSectionEx)(
    PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PLARGE_INTEGER,
    ULONG, ULONG, HANDLE, PMEM_EXTENDED_PARAMETER, ULONG);

HANDLE MakeHighSection(SIZE_T bytes) {
    HANDLE h = NULL;
    LARGE_INTEGER size; size.QuadPart = (LONGLONG)bytes;
    MEM_ADDRESS_REQUIREMENTS req = {
        .LowestStartingAddress = (PVOID)0x00007F0000000000ULL,
        .HighestEndingAddress  = (PVOID)0x00007FFFFFFFFFFFULL,
        .Alignment = 0,
    };
    MEM_EXTENDED_PARAMETER ep = {0};
    ep.Type = MemExtendedParameterAddressRequirements;
    ep.Pointer = &req;
    pNtCreateSectionEx fn = (pNtCreateSectionEx)GetProcAddress(
        GetModuleHandleA("ntdll.dll"), "NtCreateSectionEx");
    if (!fn) return NULL;  // pre-1809 — fall back to NtCreateSection
    fn(&h, SECTION_ALL_ACCESS, NULL, &size,
       PAGE_EXECUTE_READWRITE, SEC_COMMIT, NULL, &ep, 1);
    return h;
}

rustwindows-sys: MapViewOfFile3 fast path (the high-level wrapper)

// MapViewOfFile3 in kernelbase.dll resolves to NtMapViewOfSectionEx, which
// pairs naturally with NtCreateSectionEx for end-to-end extended-parameter use.
use windows_sys::Win32::System::Memory::{MapViewOfFile3,
    FILE_MAP_ALL_ACCESS, MEM_EXTENDED_PARAMETER};

unsafe fn map_high(section: isize, bytes: usize) -> *mut core::ffi::c_void {
    let mut params: [MEM_EXTENDED_PARAMETER; 0] = [];
    MapViewOfFile3(section, 0,
                   core::ptr::null_mut(),
                   0, bytes, 0,
                   FILE_MAP_ALL_ACCESS,
                   params.as_mut_ptr(), 0)
}

MITRE ATT&CK mappings

Last verified: 2026-05-20