> Windows Syscalls
ntoskrnl.exeT1070.006T1564.004T1106

NtQueryInformationFile

Lit les métadonnées d'un fichier ouvert — timestamps, taille, EA, streams, points de reparse, etc.

Prototype

NTSTATUS NtQueryInformationFile(
  HANDLE                  FileHandle,
  PIO_STATUS_BLOCK        IoStatusBlock,
  PVOID                   FileInformation,
  ULONG                   Length,
  FILE_INFORMATION_CLASS  FileInformationClass
);

Arguments

NameTypeDirDescription
FileHandleHANDLEinHandle vers un fichier ou répertoire ouvert ; l'accès requis dépend de la classe d'information.
IoStatusBlockPIO_STATUS_BLOCKoutReçoit le NTSTATUS et le nombre d'octets effectivement écrits dans FileInformation.
FileInformationPVOIDoutTampon alloué par l'appelant ; la disposition correspond à la structure FILE_INFORMATION_CLASS demandée.
LengthULONGinTaille en octets du tampon FileInformation ; STATUS_INFO_LENGTH_MISMATCH si trop petit.
FileInformationClassFILE_INFORMATION_CLASSinEnum sélecteur — FileBasicInformation, FileStandardInformation, FileEaInformation, FileStreamInformation, etc.

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
Win10 15070x11win10-1507
Win10 16070x11win10-1607
Win10 17030x11win10-1703
Win10 17090x11win10-1709
Win10 18030x11win10-1803
Win10 18090x11win10-1809
Win10 19030x11win10-1903
Win10 19090x11win10-1909
Win10 20040x11win10-2004
Win10 20H20x11win10-20h2
Win10 21H10x11win10-21h1
Win10 21H20x11win10-21h2
Win10 22H20x11win10-22h2
Win11 21H20x11win11-21h2
Win11 22H20x11win11-22h2
Win11 23H20x11win11-23h2
Win11 24H20x11win11-24h2
Server 20160x11winserver-2016
Server 20190x11winserver-2019
Server 20220x11winserver-2022
Server 20250x11winserver-2025

Module noyau

ntoskrnl.exeNtQueryInformationFile

APIs liées

GetFileInformationByHandleExNtSetInformationFileNtQueryDirectoryFileGetFileTimeFindFirstStreamW

Stub du syscall

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

Notes non documentées

NtQueryInformationFile est le lecteur de métadonnées générique pour un fichier ou répertoire ouvert. La signature (handle, IOSB, buf, len, *classe d'information*) est mirroirée par `NtSetInformationFile` côté écriture et `NtQueryDirectoryFile` pour l'énumération. Le SSN `0x11` est stable depuis Windows 10 1507. Classes d'information à connaître : `FileBasicInformation` (4 × LARGE_INTEGER timestamps + FileAttributes), `FileStandardInformation` (taille, count de liens, delete-pending, flag répertoire), `FileEaInformation` (taille des attributs étendus), `FileStreamInformation` (énumération ADS / alternate data streams), `FileAttributeTagInformation` (interrogation de tag reparse — lien symbolique, jonction, IO_REPARSE_TAG_*), et `FileAlignmentInformation` (alignement secteur / device).

Usage courant par les malwares

Côté lecture, NtQueryInformationFile est le syscall principal du **timestomping read-back** (T1070.006) : un attaquant lit `FileBasicInformation` d'un fichier voisin bénin (ex. `kernel32.dll`), puis utilise `NtSetInformationFile` avec la même structure pour copier CreationTime / LastWriteTime / ChangeTime sur un payload malveillant — le faisant se fondre visuellement dans les listings et survivre aux chasses sommaires d'anomalies de timestamps. `FileStreamInformation` est utilisé par les infostealers et frameworks de persistance pour découvrir les Alternate Data Streams (`file.txt:hidden.exe`) servant à cacher des payloads sur NTFS. `FileAttributeTagInformation` permet à du code de stage-check de distinguer un vrai répertoire d'une jonction/symlink avant de déposer une persistance — important quand les cibles résident sur des chemins user-writable jonctionnables.

Opportunités de détection

Comme NtOpenFile, NtQueryInformationFile est extrêmement courant en logiciel légitime (explorer.exe seul l'appelle des milliers de fois par seconde sur les systèmes chargés) et n'est pas un signal utile seul. Les points d'inspection utiles sont (1) la *classe d'information* et (2) la *cible* : un processus non système appelant NtQueryInformationFile + NtSetInformationFile tous deux avec `FileBasicInformation` sur le même handle en succession rapide est le pattern canonique du timestomp. L'ETW `Microsoft-Windows-Kernel-File` expose des événements d'accès métadonnées par classe d'information. Les drivers mini-filter EDR voient le `IRP_MJ_QUERY_INFORMATION` sous-jacent.

Exemples de syscalls directs

asmx64 direct stub

; Direct syscall stub for NtQueryInformationFile (SSN 0x11, stable since Win10 1507)
NtQueryInformationFile PROC
    mov  r10, rcx          ; FileHandle
    mov  eax, 11h          ; SSN
    syscall
    ret
NtQueryInformationFile ENDP

cRead FileBasicInformation timestamps

// Read CreationTime/LastAccessTime/LastWriteTime/ChangeTime + Attributes
// — the read-half of a classic timestomp.
#include <windows.h>
#include <winternl.h>

typedef struct _FILE_BASIC_INFORMATION {
    LARGE_INTEGER CreationTime;
    LARGE_INTEGER LastAccessTime;
    LARGE_INTEGER LastWriteTime;
    LARGE_INTEGER ChangeTime;
    ULONG         FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;

NTSTATUS GetBasicInfo(HANDLE h, FILE_BASIC_INFORMATION *out) {
    IO_STATUS_BLOCK iosb = {0};
    return NtQueryInformationFile(h, &iosb, out, sizeof(*out),
                                   FileBasicInformation);
}

cEnumerate Alternate Data Streams

// FileStreamInformation walk — discovers hidden ADS payloads on NTFS.
#include <windows.h>
#include <winternl.h>

typedef struct _FILE_STREAM_INFORMATION {
    ULONG         NextEntryOffset;
    ULONG         StreamNameLength;
    LARGE_INTEGER StreamSize;
    LARGE_INTEGER StreamAllocationSize;
    WCHAR         StreamName[1];
} FILE_STREAM_INFORMATION, *PFILE_STREAM_INFORMATION;

void ListStreams(HANDLE h) {
    BYTE buf[4096]; IO_STATUS_BLOCK iosb = {0};
    if (NtQueryInformationFile(h, &iosb, buf, sizeof(buf),
                                FileStreamInformation) < 0) return;
    PFILE_STREAM_INFORMATION p = (PFILE_STREAM_INFORMATION)buf;
    for (;;) {
        wprintf(L"%.*s  (%lld bytes)\n",
                p->StreamNameLength / 2, p->StreamName,
                p->StreamSize.QuadPart);
        if (!p->NextEntryOffset) break;
        p = (PFILE_STREAM_INFORMATION)((BYTE*)p + p->NextEntryOffset);
    }
}

Mappings MITRE ATT&CK

Last verified: 2026-05-20