NtCreateSectionEx
Erzeugt ein Section-Objekt mit erweiterten Parametern (NUMA-Knoten, Adress-Anforderungen, User-Physical-Pages).
Prototyp
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 );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| SectionHandle | PHANDLE | out | Empfängt ein Handle auf das neue Section-Objekt. |
| DesiredAccess | ACCESS_MASK | in | Zugriffsmaske: SECTION_MAP_READ / SECTION_MAP_WRITE / SECTION_MAP_EXECUTE / SECTION_ALL_ACCESS. |
| ObjectAttributes | POBJECT_ATTRIBUTES | in | Optionaler Name + Security-Descriptor. NULL für eine anonyme Section (typisch in-process). |
| MaximumSize | PLARGE_INTEGER | in | Erforderlich für pagefile-gestützte Sections; optional (Dateigröße wird verwendet) für datei-gestützte Sections. |
| SectionPageProtection | ULONG | in | Page-Level-Protection für gemappte Views: PAGE_READONLY / PAGE_READWRITE / PAGE_EXECUTE_READ / PAGE_EXECUTE_READWRITE / PAGE_WRITECOPY. |
| AllocationAttributes | ULONG | in | SEC_COMMIT / SEC_RESERVE / SEC_IMAGE / SEC_IMAGE_NO_EXECUTE / SEC_LARGE_PAGES / SEC_FILE / SEC_NOCACHE / SEC_WRITECOMBINE. |
| FileHandle | HANDLE | in | Optionales File-Handle für datei-gestützte Sections; NULL für pagefile-gestützt. |
| ExtendedParameters | PMEM_EXTENDED_PARAMETER | in | Array von MEM_EXTENDED_PARAMETER-Einträgen: MemExtendedParameterNumaNode, MemExtendedParameterUserPhysicalHandle, MemExtendedParameterAddressRequirements (ASLR-resistente Layouts), MemExtendedParameterImageMachine (Win11 ARM64EC). |
| ExtendedParameterCount | ULONG | in | Anzahl der Einträge in ExtendedParameters; 0 verhält sich wie klassisches NtCreateSection. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1809 | 0xB9 | win10-1809 |
| Win10 1903 | 0xBA | win10-1903 |
| Win10 1909 | 0xBA | win10-1909 |
| Win10 2004 | 0xBE | win10-2004 |
| Win10 20H2 | 0xBE | win10-20h2 |
| Win10 21H1 | 0xBE | win10-21h1 |
| Win10 21H2 | 0xBF | win10-21h2 |
| Win10 22H2 | 0xBF | win10-22h2 |
| Win11 21H2 | 0xC3 | win11-21h2 |
| Win11 22H2 | 0xC4 | win11-22h2 |
| Win11 23H2 | 0xC4 | win11-23h2 |
| Win11 24H2 | 0xC6 | win11-24h2 |
| Server 2019 | 0xB9 | winserver-2019 |
| Server 2022 | 0xC2 | winserver-2022 |
| Server 2025 | 0xC6 | winserver-2025 |
Kernel-Modul
Verwandte APIs
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
Undokumentierte Hinweise
Eingeführt in Windows 10 RS5 (1809) — daher fehlen Pre-1809-SSNs. `NtCreateSectionEx` erweitert das klassische `NtCreateSection` um ein `PMEM_EXTENDED_PARAMETER`-Array, das dieselbe Attributfamilie freilegt wie `VirtualAlloc2` / `MapViewOfFile3` / `NtAllocateVirtualMemoryEx`: NUMA-Node-Platzierung, AWE-Backing (User-Physical-Pages), Address-Requirements (Alignment + Low/High-Grenzen, von CFG-bewussten Allokatoren und vom Win11-ARM64EC-Loader genutzt) und Image-Machine-Override. Kernel-Handler ist `MmCreateSection` (oder `MmCreateSpecialImageSection` für `SEC_IMAGE`-Pfade), erreicht über `MiCreateSectionCommon`. Moderne Allokatoren in `ntdll.dll` / `RtlpHpHeapManager` nutzen die Ex-Variante zunehmend, um die Address-Requirements auszunutzen.
Häufige Malware-Nutzung
Zwei reale Use Cases. (1) **Phantom-DLL-Hollowing-/Process-Doppelgänging-Varianten**, die eine Section auf einer transaktionierten, gelöschten oder `SEC_IMAGE_NO_EXECUTE`-Datei brauchen, bevorzugen gelegentlich die Ex-Form, um eine Address-Requirement zu setzen, die mit dem legitimen Image kollidiert, das ausgehöhlt wird — das Schad-Image landet exakt auf der vom Loader erwarteten Basisadresse. (2) **CFG-/XFG-umgehende Shellcode-Loader** nutzen `MemExtendedParameterAddressRequirements` mit hoher `LowestStartingAddress`, um weit weg von kanonischen `KnownDlls`-Mappings zu landen — naive Scanner, die nur die untere Adresshälfte ablaufen, verpassen die Payload. Beides ist nicht besonders verbreitet — die meisten Loader zielen weiter auf das klassische `NtCreateSection`, das auf jedem unterstützten Build verfügbar ist, während `NtCreateSectionEx` auf Server 2016 / Win10 1703-1803 nicht existiert.
Erkennungsmöglichkeiten
Gleiche Haltung wie `NtCreateSection`: Der Syscall selbst ist sehr aufkommensstark (jedes `LoadLibrary` einer noch unbekannten DLL erreicht ihn auf modernen Builds irgendwann), also auf die *Kombination* alerten. Sysmon Event ID 7 (ImageLoad) mit einem geladenen Image, dessen Backing-File in `%TEMP%`, `%PROGRAMDATA%` oder im transaktionierten / Pending-Delete-Zustand liegt, ist das starke Signal. EDRs, die gezielt `NtCreateSectionEx` hooken, können den seltenen `MemExtendedParameterImageMachine`-Override auf x64-Hosts als anomal markieren — legitime ARM64EC-Binaries auf x64 sind faktisch nicht vorhanden.
Direkte Syscall-Beispiele
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 ENDPcPagefile-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