> Windows Syscalls
ntoskrnl.exeT1562.001T1027.007T1106

NtQuerySection

Retrieves basic or image-specific metadata about a section object.

Prototype

NTSTATUS NtQuerySection(
  HANDLE                    SectionHandle,
  SECTION_INFORMATION_CLASS SectionInformationClass,
  PVOID                     SectionInformation,
  SIZE_T                    SectionInformationLength,
  PSIZE_T                   ResultLength
);

Arguments

NameTypeDirDescription
SectionHandleHANDLEinHandle to the section object, requiring SECTION_QUERY access.
SectionInformationClassSECTION_INFORMATION_CLASSinInfo class enum: SectionBasicInformation = 0 (BaseAddress, AllocationAttributes, MaximumSize), SectionImageInformation = 1 (full IMAGE_INFORMATION: EntryPoint, StackReserve/Commit, ImageType, Machine, CheckSum, ...), SectionRelocationInformation = 2, SectionOriginalBaseInformation = 3.
SectionInformationPVOIDoutCaller-supplied buffer receiving the SECTION_BASIC_INFORMATION or SECTION_IMAGE_INFORMATION structure.
SectionInformationLengthSIZE_TinSize in bytes of the SectionInformation buffer.
ResultLengthPSIZE_ToutOptional; receives the size actually written or required.

Syscall IDs by Windows version

Windows versionSyscall IDBuild
Win10 15070x51win10-1507
Win10 16070x51win10-1607
Win10 17030x51win10-1703
Win10 17090x51win10-1709
Win10 18030x51win10-1803
Win10 18090x51win10-1809
Win10 19030x51win10-1903
Win10 19090x51win10-1909
Win10 20040x51win10-2004
Win10 20H20x51win10-20h2
Win10 21H10x51win10-21h1
Win10 21H20x51win10-21h2
Win10 22H20x51win10-22h2
Win11 21H20x51win11-21h2
Win11 22H20x51win11-22h2
Win11 23H20x51win11-23h2
Win11 24H20x51win11-24h2
Server 20160x51winserver-2016
Server 20190x51winserver-2019
Server 20220x51winserver-2022
Server 20250x51winserver-2025

Kernel module

ntoskrnl.exeNtQuerySection

Related APIs

NtCreateSectionNtOpenSectionNtMapViewOfSectionNtUnmapViewOfSectionLdrQueryImageFileExecutionOptions

Syscall stub

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

SSN `0x51` on every Windows 10 / 11 / Server build — perfectly stable, making it a safe hardcoded-SSN target. There is no public Win32 wrapper; consumers go through the Nt name or the undocumented `ZwQuerySection`. `SectionBasicInformation` returns a `SECTION_BASIC_INFORMATION { PVOID BaseAddress; ULONG AllocationAttributes; LARGE_INTEGER MaximumSize; }` — the AllocationAttributes carries SEC_IMAGE / SEC_COMMIT / SEC_RESERVE / SEC_NOCACHE / SEC_LARGE_PAGES flags. `SectionImageInformation` returns a much larger `SECTION_IMAGE_INFORMATION` mirroring the PE OPTIONAL_HEADER (entry point, stack/heap reserve/commit, subsystem, machine, checksum, image characteristics) — equivalent to what `LdrQueryImageFileExecutionOptions` learns from disk plus the loader's resolution decisions.

Common malware usage

The fingerprint primitive in **unhooking** loaders. A typical flow: open the on-disk `ntdll.dll` (`NtCreateFile`), wrap it as an SEC_IMAGE section (`NtCreateSection`), call `NtQuerySection(SectionImageInformation)` to learn the clean `BaseOfCode` / `SizeOfCode` / `EntryPoint` for the disk image, map the section read-only (`NtMapViewOfSection`), then byte-compare the clean `.text` against the in-memory hooked ntdll's `.text` to identify EDR-installed inline hooks, finally overwriting the hooked bytes from the clean copy. Variants do the same against `kernel32.dll`, `kernelbase.dll`, and `win32u.dll`. Tools that use this pattern include Perun's Fart, RefleXXion, Hell's Hall, the Adwind/jRAT unhooker plugin, several Cobalt Strike UDRLs, and the public PoCs that ship with most red-team courses. A secondary use is forensic-evasion: zero out the SECTION_IMAGE_INFORMATION.GpValue / CheckSum fields of an injected PE before further mapping to defeat naive PE-anomaly detection.

Detection opportunities

By itself, NtQuerySection is ordinary — the Windows loader and CLR runtime call it constantly during DLL load. Detection has to be contextual. The unhooker signature: a process that has just opened `\Device\HarddiskVolumeN\Windows\System32\ntdll.dll`, mapped it as SEC_IMAGE, queried SectionImageInformation, then issued `NtProtectVirtualMemory` followed by `NtWriteVirtualMemory` against its own loaded ntdll's `.text` — that is the unmistakable unhook chain. Kernel-mode EDRs (Defender's WdFilter, CrowdStrike's CSAgent, MDE's MsSense kernel sensor) detect the *NtProtect/NtWrite-to-system-DLL* step rather than NtQuerySection itself, which is why most unhooker authors fully expect the call to be invisible and rely on the rest of the chain staying below the radar. ETW Threat Intelligence will surface the `.text` write on PG-protected systems.

Direct syscall examples

asmx64 direct stub

; Direct syscall stub for NtQuerySection (SSN 0x51, all builds)
NtQuerySection PROC
    mov  r10, rcx          ; syscall convention
    mov  eax, 51h          ; SSN
    syscall
    ret
NtQuerySection ENDP

cUnhooker: get clean ntdll .text from disk

// Open disk ntdll, map as SEC_IMAGE, query its image info, then
// memcmp against the in-memory ntdll to spot EDR inline hooks.
#include <windows.h>

typedef struct _SECTION_IMAGE_INFORMATION {
    PVOID  TransferAddress;
    ULONG  ZeroBits;
    SIZE_T MaximumStackSize;
    SIZE_T CommittedStackSize;
    ULONG  SubSystemType;
    USHORT SubSystemMinorVersion;
    USHORT SubSystemMajorVersion;
    ULONG  GpValue;
    USHORT ImageCharacteristics;
    USHORT DllCharacteristics;
    USHORT Machine;
    BOOLEAN ImageContainsCode;
    UCHAR  ImageFlags;
    ULONG  LoaderFlags;
    ULONG  ImageFileSize;
    ULONG  CheckSum;
} SECTION_IMAGE_INFORMATION;

typedef NTSTATUS (NTAPI *pNtQuerySection)(HANDLE, ULONG, PVOID, SIZE_T, PSIZE_T);

NTSTATUS GetCleanImageInfo(HANDLE h_section, SECTION_IMAGE_INFORMATION *out) {
    pNtQuerySection NtQuerySection = (pNtQuerySection)GetProcAddress(
        GetModuleHandleA("ntdll.dll"), "NtQuerySection");
    SIZE_T ret = 0;
    return NtQuerySection(h_section, /* SectionImageInformation */ 1,
                          out, sizeof *out, &ret);
}

cBasic info: section size and attributes

// Cheap sanity check on a section we don't own: how big, what flags?
#include <windows.h>

typedef struct _SECTION_BASIC_INFORMATION {
    PVOID         BaseAddress;
    ULONG         AllocationAttributes;  // SEC_IMAGE / SEC_COMMIT / ...
    LARGE_INTEGER MaximumSize;
} SECTION_BASIC_INFORMATION;

typedef NTSTATUS (NTAPI *pNtQuerySection)(HANDLE, ULONG, PVOID, SIZE_T, PSIZE_T);

LONGLONG SectionSize(HANDLE h_section) {
    pNtQuerySection NtQuerySection = (pNtQuerySection)GetProcAddress(
        GetModuleHandleA("ntdll.dll"), "NtQuerySection");
    SECTION_BASIC_INFORMATION bi = {0};
    SIZE_T ret = 0;
    if (NtQuerySection(h_section, /* SectionBasicInformation */ 0,
                       &bi, sizeof bi, &ret) != 0) return -1;
    return bi.MaximumSize.QuadPart;
}

MITRE ATT&CK mappings

Last verified: 2026-05-20