NtQuerySection
Liefert Basis- oder Image-spezifische Metadaten eines Section-Objekts.
Prototyp
NTSTATUS NtQuerySection( HANDLE SectionHandle, SECTION_INFORMATION_CLASS SectionInformationClass, PVOID SectionInformation, SIZE_T SectionInformationLength, PSIZE_T ResultLength );
Argumente
| Name | Type | Dir | Description |
|---|---|---|---|
| SectionHandle | HANDLE | in | Handle auf das Section-Objekt mit SECTION_QUERY-Zugriff. |
| SectionInformationClass | SECTION_INFORMATION_CLASS | in | Info-Klassen-Enum: SectionBasicInformation = 0 (BaseAddress, AllocationAttributes, MaximumSize), SectionImageInformation = 1 (vollständige IMAGE_INFORMATION: EntryPoint, StackReserve/Commit, ImageType, Machine, CheckSum, ...), SectionRelocationInformation = 2, SectionOriginalBaseInformation = 3. |
| SectionInformation | PVOID | out | Vom Aufrufer bereitgestellter Puffer für die SECTION_BASIC_INFORMATION- oder SECTION_IMAGE_INFORMATION-Struktur. |
| SectionInformationLength | SIZE_T | in | Größe des Puffers SectionInformation in Bytes. |
| ResultLength | PSIZE_T | out | Optional; empfängt die tatsächlich geschriebene oder benötigte Größe. |
Syscall-IDs pro Windows-Version
| Windows-Version | Syscall-ID | Build |
|---|---|---|
| Win10 1507 | 0x51 | win10-1507 |
| Win10 1607 | 0x51 | win10-1607 |
| Win10 1703 | 0x51 | win10-1703 |
| Win10 1709 | 0x51 | win10-1709 |
| Win10 1803 | 0x51 | win10-1803 |
| Win10 1809 | 0x51 | win10-1809 |
| Win10 1903 | 0x51 | win10-1903 |
| Win10 1909 | 0x51 | win10-1909 |
| Win10 2004 | 0x51 | win10-2004 |
| Win10 20H2 | 0x51 | win10-20h2 |
| Win10 21H1 | 0x51 | win10-21h1 |
| Win10 21H2 | 0x51 | win10-21h2 |
| Win10 22H2 | 0x51 | win10-22h2 |
| Win11 21H2 | 0x51 | win11-21h2 |
| Win11 22H2 | 0x51 | win11-22h2 |
| Win11 23H2 | 0x51 | win11-23h2 |
| Win11 24H2 | 0x51 | win11-24h2 |
| Server 2016 | 0x51 | winserver-2016 |
| Server 2019 | 0x51 | winserver-2019 |
| Server 2022 | 0x51 | winserver-2022 |
| Server 2025 | 0x51 | winserver-2025 |
Kernel-Modul
Verwandte APIs
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
Undokumentierte Hinweise
SSN `0x51` auf jedem Windows-10-/11-/Server-Build — perfekt stabil, was sie zu einem sicheren Hartkodier-SSN-Ziel macht. Es gibt keinen öffentlichen Win32-Wrapper; Konsumenten gehen über den Nt-Namen oder das undokumentierte `ZwQuerySection`. `SectionBasicInformation` gibt ein `SECTION_BASIC_INFORMATION { PVOID BaseAddress; ULONG AllocationAttributes; LARGE_INTEGER MaximumSize; }` zurück — die AllocationAttributes tragen die Flags SEC_IMAGE / SEC_COMMIT / SEC_RESERVE / SEC_NOCACHE / SEC_LARGE_PAGES. `SectionImageInformation` liefert ein deutlich größeres `SECTION_IMAGE_INFORMATION`, das den PE-OPTIONAL_HEADER spiegelt (Entry Point, Stack-/Heap-Reserve/Commit, Subsystem, Machine, Checksum, Image-Eigenschaften) — äquivalent zu dem, was `LdrQueryImageFileExecutionOptions` von der Platte plus den Auflösungsentscheidungen des Loaders erfährt.
Häufige Malware-Nutzung
Die Fingerprint-Primitive in **Unhooking**-Loadern. Typischer Ablauf: das On-Disk-`ntdll.dll` öffnen (`NtCreateFile`), als SEC_IMAGE-Section wrappen (`NtCreateSection`), `NtQuerySection(SectionImageInformation)` aufrufen, um die sauberen `BaseOfCode` / `SizeOfCode` / `EntryPoint` des Disk-Images zu lernen, die Section read-only mappen (`NtMapViewOfSection`), dann byteweise das saubere `.text` gegen das `.text` des in-memory gehookten ntdll vergleichen, um vom EDR installierte Inline-Hooks zu identifizieren, und schließlich die gehookten Bytes aus der sauberen Kopie überschreiben. Varianten tun dasselbe gegen `kernel32.dll`, `kernelbase.dll` und `win32u.dll`. Tools mit diesem Muster: Perun's Fart, RefleXXion, Hell's Hall, das Adwind/jRAT-Unhooker-Plugin, mehrere Cobalt-Strike-UDRLs sowie die öffentlichen PoCs, die mit den meisten Red-Team-Kursen ausgeliefert werden. Sekundärnutzung: Forensik-Evasion — die Felder SECTION_IMAGE_INFORMATION.GpValue / CheckSum eines injizierten PE vor weiterem Mapping nullen, um naive PE-Anomalie-Erkennung zu schlagen.
Erkennungsmöglichkeiten
Für sich allein ist NtQuerySection unauffällig — der Windows-Loader und die CLR-Runtime rufen ihn beim DLL-Laden ständig auf. Die Detektion muss kontextuell sein. Die Unhooker-Signatur: ein Prozess, der gerade `\Device\HarddiskVolumeN\Windows\System32\ntdll.dll` geöffnet, als SEC_IMAGE gemappt und SectionImageInformation abgefragt hat und dann `NtProtectVirtualMemory` gefolgt von `NtWriteVirtualMemory` gegen das `.text` seines eigenen geladenen ntdll absetzt — das ist die unverwechselbare Unhook-Kette. Kernel-Mode-EDRs (Defenders WdFilter, CrowdStrikes CSAgent, MDEs MsSense-Kernel-Sensor) erkennen den *NtProtect/NtWrite-auf-System-DLL*-Schritt statt NtQuerySection selbst, weshalb die meisten Unhooker-Autoren voll erwarten, dass der Aufruf unsichtbar ist, und sich darauf verlassen, dass der Rest der Kette unter dem Radar bleibt. ETW Threat Intelligence bringt den `.text`-Write auf PG-geschützten Systemen ans Licht.
Direkte Syscall-Beispiele
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 ENDPcUnhooker: 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