NtQueryInformationByName
Queries file information by path without an open handle, introduced in Windows 10 RS5.
Prototype
NTSTATUS NtQueryInformationByName( POBJECT_ATTRIBUTES ObjectAttributes, PIO_STATUS_BLOCK IoStatusBlock, PVOID FileInformation, ULONG Length, FILE_INFORMATION_CLASS FileInformationClass );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| ObjectAttributes | POBJECT_ATTRIBUTES | in | Object attributes describing the target file path. ObjectName is the NT path. |
| IoStatusBlock | PIO_STATUS_BLOCK | out | Receives the final status and the number of bytes written to FileInformation. |
| FileInformation | PVOID | out | Caller buffer that receives the requested information class. |
| Length | ULONG | in | Size of FileInformation in bytes. |
| FileInformationClass | FILE_INFORMATION_CLASS | in | Class identifying which information to return (e.g. FileStatInformation, FileStatBasicInformation). |
Syscall IDs by Windows version
| Windows version | Syscall ID | Build |
|---|---|---|
| Win10 1703 | 0x13B | win10-1703 |
| Win10 1709 | 0x13E | win10-1709 |
| Win10 1803 | 0x140 | win10-1803 |
| Win10 1809 | 0x141 | win10-1809 |
| Win10 1903 | 0x142 | win10-1903 |
| Win10 1909 | 0x142 | win10-1909 |
| Win10 2004 | 0x148 | win10-2004 |
| Win10 20H2 | 0x148 | win10-20h2 |
| Win10 21H1 | 0x148 | win10-21h1 |
| Win10 21H2 | 0x149 | win10-21h2 |
| Win10 22H2 | 0x149 | win10-22h2 |
| Win11 21H2 | 0x14F | win11-21h2 |
| Win11 22H2 | 0x151 | win11-22h2 |
| Win11 23H2 | 0x151 | win11-23h2 |
| Win11 24H2 | 0x153 | win11-24h2 |
| Server 2019 | 0x141 | winserver-2019 |
| Server 2022 | 0x14E | winserver-2022 |
| Server 2025 | 0x153 | winserver-2025 |
Kernel module
Related APIs
Syscall stub
4C 8B D1 mov r10, rcx B8 53 01 00 00 mov eax, 0x153 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
Introduced in Windows 10 1709 (officially documented usage starting at RS5/1803), NtQueryInformationByName collapses the legacy `NtCreateFile → NtQueryInformationFile → NtClose` triplet into a single syscall when the caller only needs metadata. Internally the kernel still has to traverse the parent directory's filesystem stack and acquire a transient FILE_OBJECT, but never installs a handle in the caller's handle table — meaning fewer Sysmon Event ID 11/15 noise events and zero handle-table churn. Only a handful of `FILE_INFORMATION_CLASS` values are accepted (FileStatInformation, FileStatBasicInformation, FileStatLxInformation, FileCaseSensitiveInformation, FileStorageReserveIdInformation).
Common malware usage
Used by scanners, environment-keying loaders, and EDR-aware staged-payload droppers to test for the existence of marker files (e.g. proof of a specific build of an EDR on disk, or a victim-fingerprint file) without leaving an open-handle telemetry trail. Because no handle is created, file-system minifilters that key off `IRP_MJ_CREATE` see the open as transient and ephemeral; user-mode hooks on `NtCreateFile`/`NtOpenFile` are bypassed entirely — the syscall path is `NtQueryInformationByName` directly. The signal is weaker than NtCreateFile-based reconnaissance, which is precisely the point. Some commodity scanners (CCleaner-style profilers, but also more recent infostealers) have migrated to this API to reduce open-file noise.
Detection opportunities
Filesystem minifilters still see the transient IRP_MJ_CREATE — Sysmon File events configured with `IncludeTransientHandles=true` (a relatively new option) will surface these. ETW Microsoft-Windows-Kernel-File `Create` events fire with a `TransitionTrace` flag set distinguishing the by-name query from a held-handle open. Hunting on `NtQueryInformationByName` calls targeting `*.exe`, `*.dll`, or specific EDR install paths from a non-system process is a stronger anomaly signal than the syscall itself. Sysmon Event ID 11 (FileCreate) and Event ID 15 (FileCreateStreamHash) will *not* fire — that absence, paired with file-existence-conditioned behaviour, is the detection.
Direct syscall examples
cCheck for EDR install marker without opening a handle
// Probe for the presence of an EDR DLL on disk using the new RS5+ syscall.
#include <windows.h>
#include <winternl.h>
typedef struct _FILE_STAT_BASIC_INFORMATION {
LARGE_INTEGER FileId;
LARGE_INTEGER CreationTime;
LARGE_INTEGER LastAccessTime;
LARGE_INTEGER LastWriteTime;
LARGE_INTEGER ChangeTime;
LARGE_INTEGER AllocationSize;
LARGE_INTEGER EndOfFile;
ULONG FileAttributes;
ULONG ReparseTag;
ULONG NumberOfLinks;
ULONG DeviceType;
ULONG DeviceCharacteristics;
ULONG Reserved;
LARGE_INTEGER VolumeSerialNumber;
FILE_ID_128 FileId128;
} FILE_STAT_BASIC_INFORMATION;
typedef NTSTATUS (NTAPI *PNTQUERYINFORMATIONBYNAME)(
POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK, PVOID, ULONG, ULONG);
BOOL FileExistsQuietly(LPCWSTR ntPath) {
UNICODE_STRING us;
RtlInitUnicodeString(&us, ntPath);
OBJECT_ATTRIBUTES oa;
InitializeObjectAttributes(&oa, &us, OBJ_CASE_INSENSITIVE, NULL, NULL);
FILE_STAT_BASIC_INFORMATION info;
IO_STATUS_BLOCK iosb;
PNTQUERYINFORMATIONBYNAME f = (PNTQUERYINFORMATIONBYNAME)GetProcAddress(
GetModuleHandleA("ntdll.dll"), "NtQueryInformationByName");
return f && f(&oa, &iosb, &info, sizeof(info), 75 /* FileStatBasicInformation */) == 0;
}asmx64 direct stub (Win11 24H2, SSN 0x153)
NtQueryInformationByName PROC
mov r10, rcx
mov eax, 153h
syscall
ret
NtQueryInformationByName ENDPMITRE ATT&CK mappings
Last verified: 2026-05-20