> Windows Syscalls
ntoskrnl.exeT1112T1547.001T1106

NtRestoreKey

Overwrites a registry key's contents from a hive file — replaces subtrees in bulk.

Prototype

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

Arguments

NameTypeDirDescription
KeyHandleHANDLEinOpen handle to the registry key whose contents will be replaced (must have KEY_WRITE).
FileHandleHANDLEinOpen handle to the hive file containing the source contents (opened with GENERIC_READ).
FlagsULONGinREG_WHOLE_HIVE_VOLATILE (4), REG_REFRESH_HIVE (2), REG_NO_LAZY_FLUSH (4), REG_FORCE_RESTORE (8).

Syscall IDs by Windows version

Windows versionSyscall IDBuild
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

Kernel module

ntoskrnl.exeNtRestoreKey

Related APIs

RegRestoreKeyWRegReplaceKeyWNtSaveKeyNtLoadKeyNtUnloadKey

Syscall stub

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

Undocumented notes

NtRestoreKey is the inverse of NtSaveKey: it replaces the contents of an open key with whatever is contained in a hive file. With `REG_FORCE_RESTORE` the kernel does so even when there are open handles to the destination subtree. The caller needs **SeRestorePrivilege**. The Win32 wrapper is `RegRestoreKeyW`. The operation is atomic at the hive-block level; partial failure leaves the destination in the pre-restore state.

Common malware usage

Two patterns dominate. First, **tampering with persistence**: an attacker who staged a known-good Run-key template can overwrite `HKLM\Software\Microsoft\Windows\CurrentVersion\Run` (or a service config subtree) wholesale, replacing every entry in one syscall — useful for both planting persistence *and* erasing competing entries from rival malware. Second, **rollback after tampering**: red-team tooling sometimes takes a NtSaveKey snapshot, modifies a key, performs work, and then NtRestoreKey-rolls back to defeat host-based change auditing. Less commonly, ransomware uses it to swap out service-DLL paths in bulk before reboot.

Detection opportunities

ETW `Microsoft-Windows-Kernel-Registry` emits a load/restore event distinct from value-set events. Sysmon Event 13 fires per value modified by the restore — a single NtRestoreKey can produce a *burst* of Event 13 records with identical timestamps under the same key, which is itself an unusual pattern worth a rule. SeRestorePrivilege enablement (Sysmon 4673) immediately preceding a registry write is a strong leading indicator. Hunting tip: alert on REG_FORCE_RESTORE flag usage — it is almost never seen in benign software.

Direct syscall examples

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

MITRE ATT&CK mappings

Last verified: 2026-05-20