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

NtQueryInformationFile

Lee metadatos de un archivo abierto — timestamps, tamaño, EA, streams, puntos de reparse y más.

Prototipo

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

Argumentos

NameTypeDirDescription
FileHandleHANDLEinHandle a un archivo o directorio abierto; el acceso requerido depende de la clase de información.
IoStatusBlockPIO_STATUS_BLOCKoutRecibe el NTSTATUS y el número de bytes realmente escritos en FileInformation.
FileInformationPVOIDoutBúfer asignado por el llamante; el layout corresponde a la estructura FILE_INFORMATION_CLASS solicitada.
LengthULONGinTamaño en bytes del búfer FileInformation; STATUS_INFO_LENGTH_MISMATCH si es demasiado pequeño.
FileInformationClassFILE_INFORMATION_CLASSinEnum selector — FileBasicInformation, FileStandardInformation, FileEaInformation, FileStreamInformation, etc.

IDs de syscalls por versión de Windows

Versión 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

Módulo del kernel

ntoskrnl.exeNtQueryInformationFile

APIs relacionadas

GetFileInformationByHandleExNtSetInformationFileNtQueryDirectoryFileGetFileTimeFindFirstStreamW

Stub del 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

Notas no documentadas

NtQueryInformationFile es el lector genérico de metadatos para un archivo o directorio abierto. La firma (handle, IOSB, buf, len, *clase de información*) la espeja `NtSetInformationFile` en el lado escritura y `NtQueryDirectoryFile` para la enumeración. El SSN `0x11` está estable desde Windows 10 1507. Clases de información a conocer: `FileBasicInformation` (4 × LARGE_INTEGER timestamps + FileAttributes), `FileStandardInformation` (tamaño, conteo de enlaces, delete-pending, flag de directorio), `FileEaInformation` (tamaño de atributos extendidos), `FileStreamInformation` (enumeración de ADS / alternate data streams), `FileAttributeTagInformation` (consulta de tag de reparse — enlace simbólico, junction, IO_REPARSE_TAG_*) y `FileAlignmentInformation` (alineamiento de sector / dispositivo).

Uso común por malware

En el lado lectura, NtQueryInformationFile es el syscall principal en **timestomping read-back** (T1070.006): un atacante lee `FileBasicInformation` de un archivo vecino benigno (p. ej. `kernel32.dll`), luego usa `NtSetInformationFile` con la misma estructura para copiar CreationTime / LastWriteTime / ChangeTime sobre un payload malicioso — haciendo que se mezcle visualmente en los listados y sobreviva a búsquedas superficiales de anomalías de timestamps. `FileStreamInformation` es usado por infostealers y frameworks de persistencia para descubrir Alternate Data Streams (`file.txt:hidden.exe`) usados para esconder payloads en NTFS. `FileAttributeTagInformation` permite a código de comprobación distinguir un directorio real de una junction/symlink antes de depositar persistencia — importante cuando los objetivos están en rutas user-writable junction-ables.

Oportunidades de detección

Como NtOpenFile, NtQueryInformationFile es extremadamente común en software legítimo (explorer.exe solo lo llama miles de veces por segundo en sistemas cargados) y no es señal útil por sí solo. Los puntos de inspección útiles son (1) la *clase de información* y (2) el *objetivo*: un proceso no sistema que llama a NtQueryInformationFile + NtSetInformationFile ambos con `FileBasicInformation` sobre el mismo handle en sucesión rápida es el patrón canónico del timestomp. ETW `Microsoft-Windows-Kernel-File` expone eventos de acceso a metadatos por clase de información. Los drivers mini-filter de EDR ven el `IRP_MJ_QUERY_INFORMATION` subyacente.

Ejemplos de syscalls directos

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);
    }
}

Mapeos MITRE ATT&CK

Last verified: 2026-05-20