NtExtendSection
Grows an existing pagefile- or file-backed section to a larger maximum size.
Prototype
NTSTATUS NtExtendSection( HANDLE SectionHandle, PLARGE_INTEGER NewSectionSize );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| SectionHandle | HANDLE | in | Handle to the section to extend. Must have SECTION_EXTEND_SIZE access. |
| NewSectionSize | PLARGE_INTEGER | in/out | On input: requested new max size. On output: actual new size (rounded up to a page boundary). |
Syscall IDs by Windows version
| Windows version | Syscall ID | Build |
|---|---|---|
| Win10 1507 | 0xD3 | win10-1507 |
| Win10 1607 | 0xD6 | win10-1607 |
| Win10 1703 | 0xD9 | win10-1703 |
| Win10 1709 | 0xDA | win10-1709 |
| Win10 1803 | 0xDB | win10-1803 |
| Win10 1809 | 0xDC | win10-1809 |
| Win10 1903 | 0xDD | win10-1903 |
| Win10 1909 | 0xDD | win10-1909 |
| Win10 2004 | 0xE2 | win10-2004 |
| Win10 20H2 | 0xE2 | win10-20h2 |
| Win10 21H1 | 0xE2 | win10-21h1 |
| Win10 21H2 | 0xE3 | win10-21h2 |
| Win10 22H2 | 0xE3 | win10-22h2 |
| Win11 21H2 | 0xE8 | win11-21h2 |
| Win11 22H2 | 0xE9 | win11-22h2 |
| Win11 23H2 | 0xE9 | win11-23h2 |
| Win11 24H2 | 0xEB | win11-24h2 |
| Server 2016 | 0xD6 | winserver-2016 |
| Server 2019 | 0xDC | winserver-2019 |
| Server 2022 | 0xE7 | winserver-2022 |
| Server 2025 | 0xEB | winserver-2025 |
Kernel module
Related APIs
Syscall stub
4C 8B D1 mov r10, rcx B8 EB 00 00 00 mov eax, 0xEB ; 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
Undocumented notes
Extends the maximum committable size of a section object. Only sections created with `SEC_RESERVE` or pagefile-backed sections (`SEC_COMMIT` without a file handle) are typically extendable — image sections (`SEC_IMAGE`) are not. The new size cannot exceed the size of the backing file if the section was file-backed without `SEC_RESERVE`. The kernel rounds the requested size up to the next page boundary and writes it back through `NewSectionSize`.
Common malware usage
Used by shellcode loaders that build a payload in stages without committing the final size up front. The loader creates a small `SEC_RESERVE` pagefile-backed section, maps a view, writes the first stage, then calls `NtExtendSection` once the second stage size is known and remaps a larger view — avoiding an early RWX allocation of the entire eventual payload size. Also appears in shared-buffer IPC channels between cooperating implants that grow dynamically. Not a frequent IOC on its own, but combined with `SEC_COMMIT` pagefile sections and remote-process mapping it forms the backbone of memory-only loaders that never touch disk.
Detection opportunities
No dedicated ETW event. Detection is by combining `NtCreateSection` of a `SEC_RESERVE` pagefile-backed section followed by `NtExtendSection` followed by `NtMapViewOfSection(Ex)` with `PAGE_EXECUTE_*` protection in the same process within a short window. EDR products that hook `NtMapViewOfSection` can flag executable mappings of pagefile-backed sections — a combination almost never seen in legitimate applications outside of JIT engines and a handful of database servers.
Direct syscall examples
cGrow a SEC_RESERVE pagefile section
// Initial 4 KiB reserve.
LARGE_INTEGER initialSize; initialSize.QuadPart = 0x1000;
HANDLE hSection;
NtCreateSection(&hSection, SECTION_ALL_ACCESS, NULL, &initialSize,
PAGE_EXECUTE_READWRITE, SEC_RESERVE, NULL);
// ... map, write stage 1 ...
// Now grow to 1 MiB to fit stage 2 + relocations.
LARGE_INTEGER newSize; newSize.QuadPart = 0x100000;
NTSTATUS s = NtExtendSection(hSection, &newSize);
// newSize.QuadPart is updated to the actual rounded value.asmx64 direct stub (Win11 24H2)
; NtExtendSection direct stub — SSN 0xEB on Win11 24H2
NtExtendSection PROC
mov r10, rcx
mov eax, 0EBh
syscall
ret
NtExtendSection ENDPrustExtend via ntapi crate
use ntapi::ntmmapi::NtExtendSection;
use winapi::shared::ntdef::{HANDLE, LARGE_INTEGER};
use std::mem;
unsafe fn extend(section: HANDLE, new_bytes: i64) -> i64 {
let mut li: LARGE_INTEGER = mem::zeroed();
*li.QuadPart_mut() = new_bytes;
let s = NtExtendSection(section, &mut li);
assert!(s >= 0);
*li.QuadPart()
}MITRE ATT&CK mappings
Last verified: 2026-05-20