> Windows Syscalls
ntoskrnl.exeT1497T1486T1106

NtLockFile

Acquiert un verrou sur une plage d'octets d'un fichier ouvert, optionnellement exclusif et optionnellement asynchrone.

Prototype

NTSTATUS NtLockFile(
  HANDLE           FileHandle,
  HANDLE           Event,
  PIO_APC_ROUTINE  ApcRoutine,
  PVOID            ApcContext,
  PIO_STATUS_BLOCK IoStatusBlock,
  PLARGE_INTEGER   ByteOffset,
  PLARGE_INTEGER   Length,
  ULONG            Key,
  BOOLEAN          FailImmediately,
  BOOLEAN          ExclusiveLock
);

Arguments

NameTypeDirDescription
FileHandleHANDLEinHandle vers un fichier ouvert avec au moins FILE_READ_DATA ou FILE_WRITE_DATA.
EventHANDLEinÉvénement optionnel signalé à la complétion async. NULL si ApcRoutine ou attente synchrone.
ApcRoutinePIO_APC_ROUTINEinRoutine APC mode utilisateur optionnelle déclenchée quand le verrou est accordé en async.
ApcContextPVOIDinValeur de contexte renvoyée à ApcRoutine.
IoStatusBlockPIO_STATUS_BLOCKoutReçoit le NTSTATUS final et Information (toujours 0 pour NtLockFile).
ByteOffsetPLARGE_INTEGERinOffset de début (en octets) de la plage à verrouiller.
LengthPLARGE_INTEGERinLongueur en octets de la plage à verrouiller. 0x7FFFFFFFFFFFFFFF couvre essentiellement tout le fichier.
KeyULONGinCookie corrélant ce verrou avec un futur NtUnlockFile / NtLockFile portant la même clé.
FailImmediatelyBOOLEANinSi TRUE, renvoie STATUS_LOCK_NOT_GRANTED au lieu d'attendre si la plage est déjà verrouillée.
ExclusiveLockBOOLEANinSi TRUE, demande un verrou exclusif (écriture) ; FALSE demande un verrou partagé (lecture).

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
Win10 15070xF9win10-1507
Win10 16070xFEwin10-1607
Win10 17030x102win10-1703
Win10 17090x103win10-1709
Win10 18030x104win10-1803
Win10 18090x104win10-1809
Win10 19030x105win10-1903
Win10 19090x105win10-1909
Win10 20040x10Awin10-2004
Win10 20H20x10Awin10-20h2
Win10 21H10x10Awin10-21h1
Win10 21H20x10Bwin10-21h2
Win10 22H20x10Bwin10-22h2
Win11 21H20x111win11-21h2
Win11 22H20x112win11-22h2
Win11 23H20x112win11-23h2
Win11 24H20x114win11-24h2
Server 20160xFEwinserver-2016
Server 20190x104winserver-2019
Server 20220x110winserver-2022
Server 20250x114winserver-2025

Module noyau

ntoskrnl.exeNtLockFile

APIs liées

LockFileLockFileExNtUnlockFileNtCreateFileNtReadFile

Stub du syscall

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

Les verrous de plage d'octets sont *obligatoires* sous Windows (contrairement aux verrous consultatifs de la plupart des Unix) : un processus tiers qui tente une lecture/écriture chevauchante reçoit STATUS_FILE_LOCK_CONFLICT (ERROR_LOCK_VIOLATION 33) même s'il n'a jamais tenté de verrouiller. Les verrous sont libérés à la fermeture du handle, mais un processus tenant un handle ouvert plus un verrou exclusif 0…INT64_MAX interdit effectivement à tout autre processus de lire le contenu. Le paramètre Key permet à un même propriétaire d'empiler de nombreux verrous chevauchants et de les libérer par cookie.

Usage courant par les malwares

Deux abus distincts. (1) **Auto-verrouillage anti-analyse** : l'implant ouvre son propre fichier avec FILE_SHARE_READ retiré, puis pose un verrou exclusif sur toute la plage. Les scanners AV qui tentent de lire le fichier pour le matching de signatures statiques rencontrent ERROR_LOCK_VIOLATION ; nombre de scanners naïfs loggent et passent. Combiné à la propriété de verrouillage à l'exécution des handles FILE_EXECUTE, cela fait échouer la suppression in-place tant que le processus n'a pas quitté. (2) **Manipulation UX rançongiciel** : les chiffreurs posent un verrou exclusif sur la note de rançon pendant la phase de chiffrement pour que la victime ne puisse pas l'écarter ; une fois le chiffrement terminé, le verrou est libéré et la note devient visible/modifiable. Certains wipers verrouillent aussi le fichier de métadonnées équivalent au MFT pour retarder l'outillage de récupération.

Opportunités de détection

NtLockFile est à *gros volume* — chaque document Office, base SQLite, PST Outlook et pack Git l'utilise en permanence. Filtres utiles : des verrous tenus sur des exécutables (.exe/.dll/.scr) par le *même* processus qui a ouvert le fichier sont inhabituels hors débogueurs. ETW Microsoft-Windows-Kernel-FileIO émet FileIo/OperationEnd avec les sous-types Lock/Unlock mais est volumineux. La télémétrie la plus actionnable est le côté *échec* : un pic de réponses ERROR_LOCK_VIOLATION (33) aux scanners légitimes est un indicateur indirect qu'un binaire s'auto-verrouille. Les minifilters EDR peuvent observer IRP_MJ_LOCK_CONTROL directement et corréler avec l'image du processus verrouilleur.

Exemples de syscalls directs

cSelf-lock anti-analysis stub

// Re-open our own image without FILE_SHARE_READ, then take a whole-file
// exclusive lock. AV scanners that try to read it for static signature
// matching hit STATUS_FILE_LOCK_CONFLICT and move on.
HANDLE hSelf = CreateFileW(g_selfPath,
    GENERIC_READ, 0 /* no share */, NULL,
    OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

IO_STATUS_BLOCK iosb;
LARGE_INTEGER off = { .QuadPart = 0 };
LARGE_INTEGER len = { .QuadPart = 0x7FFFFFFFFFFFFFFFLL };

NtLockFile(hSelf, NULL, NULL, NULL, &iosb,
           &off, &len, 0,
           TRUE,    // FailImmediately
           TRUE);   // ExclusiveLock

asmx64 direct stub (Win11 24H2 SSN 0x114)

NtLockFile PROC
    mov  r10, rcx
    mov  eax, 114h
    syscall
    ret
NtLockFile ENDP

rustRansom-note lock during encryption

// Cargo: ntapi = "0.4", windows-sys = "0.59"
// Hold an exclusive lock on the note while we burn through the file tree.
unsafe {
    let off: i64 = 0;
    let len: i64 = i64::MAX;
    let mut iosb = zeroed();
    let st = NtLockFile(h_note,
        null_mut(), None, null_mut(),
        &mut iosb,
        &off as *const _ as _, &len as *const _ as _,
        0,
        1,  // FailImmediately
        1); // ExclusiveLock
    assert!(st == 0);
}
// ...encrypt files...
unsafe { NtUnlockFile(h_note, &mut iosb, &off as *const _ as _, &len as *const _ as _, 0); }

Mappings MITRE ATT&CK

Last verified: 2026-05-20