> Windows Syscalls
ntoskrnl.exeT1112T1547.001T1106

NtRestoreKey

Écrase le contenu d'une clé de registre depuis un fichier ruche — remplace des sous-arbres en bloc.

Prototype

NTSTATUS NtRestoreKey(
  HANDLE  KeyHandle,
  HANDLE  FileHandle,
  ULONG   Flags
);

Arguments

NameTypeDirDescription
KeyHandleHANDLEinHandle ouvert vers la clé de registre dont le contenu sera remplacé (doit avoir KEY_WRITE).
FileHandleHANDLEinHandle ouvert vers le fichier ruche contenant le contenu source (ouvert en GENERIC_READ).
FlagsULONGinREG_WHOLE_HIVE_VOLATILE (4), REG_REFRESH_HIVE (2), REG_NO_LAZY_FLUSH (4), REG_FORCE_RESTORE (8).

IDs de syscalls par version de Windows

Version de WindowsID de syscallBuild
Win10 15070x160win10-1507
Win10 16070x167win10-1607
Win10 17030x16Dwin10-1703
Win10 17090x170win10-1709
Win10 18030x172win10-1803
Win10 18090x173win10-1809
Win10 19030x174win10-1903
Win10 19090x174win10-1909
Win10 20040x17Awin10-2004
Win10 20H20x17Awin10-20h2
Win10 21H10x17Awin10-21h1
Win10 21H20x17Cwin10-21h2
Win10 22H20x17Cwin10-22h2
Win11 21H20x184win11-21h2
Win11 22H20x187win11-22h2
Win11 23H20x187win11-23h2
Win11 24H20x189win11-24h2
Server 20160x167winserver-2016
Server 20190x173winserver-2019
Server 20220x182winserver-2022
Server 20250x189winserver-2025

Module noyau

ntoskrnl.exeNtRestoreKey

APIs liées

RegRestoreKeyWRegReplaceKeyWNtSaveKeyNtLoadKeyNtUnloadKey

Stub du syscall

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

NtRestoreKey est l'inverse de NtSaveKey : il remplace le contenu d'une clé ouverte par ce que contient un fichier ruche. Avec `REG_FORCE_RESTORE` le noyau le fait même s'il existe des handles ouverts sur le sous-arbre de destination. L'appelant a besoin de **SeRestorePrivilege**. Le wrapper Win32 est `RegRestoreKeyW`. L'opération est atomique au niveau du bloc de ruche ; un échec partiel laisse la destination dans son état pré-restauration.

Usage courant par les malwares

Deux usages dominent. D'abord, **altération de persistance** : un attaquant ayant préparé un template Run-key connu peut écraser `HKLM\Software\Microsoft\Windows\CurrentVersion\Run` (ou un sous-arbre de configuration service) en bloc, remplaçant toutes les entrées en un seul syscall — utile pour planter une persistance *et* effacer les entrées concurrentes de malwares rivaux. Ensuite, **rollback après altération** : du red-team prend un snapshot NtSaveKey, modifie une clé, accomplit son travail, puis fait un rollback NtRestoreKey pour contourner l'audit de changements host-based. Moins courant : du ransomware s'en sert pour permuter en masse des chemins service-DLL avant reboot.

Opportunités de détection

L'ETW `Microsoft-Windows-Kernel-Registry` émet un événement load/restore distinct des événements value-set. Sysmon Event 13 se déclenche par valeur modifiée — un seul NtRestoreKey peut produire une *rafale* d'enregistrements Event 13 aux timestamps identiques sous la même clé, motif inhabituel qui mérite une règle. L'activation de SeRestorePrivilege (Sysmon 4673) juste avant une écriture registre est un indicateur précurseur fort. Astuce de chasse : alerter sur le flag REG_FORCE_RESTORE — quasiment jamais vu en logiciel bénin.

Exemples de syscalls directs

asmx64 direct stub (Win11 24H2)

; Direct syscall stub for NtRestoreKey (SSN 0x189 on Win11 24H2 — drifts per build)
NtRestoreKey PROC
    mov  r10, rcx          ; KeyHandle
    mov  eax, 189h         ; SSN
    syscall
    ret
NtRestoreKey ENDP

cBulk-rewrite Run keys from staged template

// Overwrite HKLM\...\Run wholesale from a prepared hive file — useful for both
// persistence install and rival-eviction. Requires SeRestorePrivilege.
#include <windows.h>

LONG RestoreRunKey(LPCWSTR hivePath) {
    HKEY hRun = NULL;
    LONG s = RegOpenKeyExW(HKEY_LOCAL_MACHINE,
        L"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
        0, KEY_ALL_ACCESS, &hRun);
    if (s != ERROR_SUCCESS) return s;
    // REG_FORCE_RESTORE (8) replaces even with open handles elsewhere.
    s = RegRestoreKeyW(hRun, hivePath, 8 /* REG_FORCE_RESTORE */);
    RegCloseKey(hRun);
    return s;
}

cDirect NtRestoreKey call

// Snap a key handle and a hive file handle, then restore atomically.
#include <windows.h>
#include <winternl.h>

typedef NTSTATUS (NTAPI *pNtRestoreKey)(HANDLE, HANDLE, ULONG);

NTSTATUS DoRestore(HANDLE hKey, HANDLE hFile, ULONG flags) {
    pNtRestoreKey fn = (pNtRestoreKey)GetProcAddress(
        GetModuleHandleA("ntdll.dll"), "NtRestoreKey");
    return fn(hKey, hFile, flags);
}

Mappings MITRE ATT&CK

Last verified: 2026-05-20