NtLoadKey2
Charge une ruche de registre dans l'arbre de configuration via un wrapper à 2 drapeaux autour de NtLoadKey.
Prototype
NTSTATUS NtLoadKey2( POBJECT_ATTRIBUTES TargetKey, POBJECT_ATTRIBUTES SourceFile, ULONG Flags );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| TargetKey | POBJECT_ATTRIBUTES | in | Attributs d'objet décrivant la clé de point de montage (ex. \Registry\User\TempHive). |
| SourceFile | POBJECT_ATTRIBUTES | in | Attributs d'objet pointant vers le fichier de ruche sur disque (chemin NT, ex. \??\C:\Windows\System32\config\SAM). |
| Flags | ULONG | in | REG_NO_LAZY_FLUSH (0x4) est la valeur canonique ; les autres bits sont largement ignorés par le wrapper à 2 arguments. |
IDs de syscalls par version de Windows
| Version de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0xF7 | win10-1507 |
| Win10 1607 | 0xFC | win10-1607 |
| Win10 1703 | 0x100 | win10-1703 |
| Win10 1709 | 0x101 | win10-1709 |
| Win10 1803 | 0x102 | win10-1803 |
| Win10 1809 | 0x102 | win10-1809 |
| Win10 1903 | 0x103 | win10-1903 |
| Win10 1909 | 0x103 | win10-1909 |
| Win10 2004 | 0x108 | win10-2004 |
| Win10 20H2 | 0x108 | win10-20h2 |
| Win10 21H1 | 0x108 | win10-21h1 |
| Win10 21H2 | 0x109 | win10-21h2 |
| Win10 22H2 | 0x109 | win10-22h2 |
| Win11 21H2 | 0x10E | win11-21h2 |
| Win11 22H2 | 0x10F | win11-22h2 |
| Win11 23H2 | 0x10F | win11-23h2 |
| Win11 24H2 | 0x111 | win11-24h2 |
| Server 2016 | 0xFC | winserver-2016 |
| Server 2019 | 0x102 | winserver-2019 |
| Server 2022 | 0x10D | winserver-2022 |
| Server 2025 | 0x111 | winserver-2025 |
Module noyau
APIs liées
Stub du syscall
4C 8B D1 mov r10, rcx B8 11 01 00 00 mov eax, 0x111 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
`NtLoadKey2` est un wrapper fin et déprécié introduit avec Windows 2000 / XP qui redirige vers le même chemin noyau que `NtLoadKey`/`NtLoadKeyEx` (`CmLoadKey` dans `ntoskrnl.exe`). Il n'accepte que l'argument `Flags` historique et n'a pas les paramètres modernes `TrustClassKey`, `Event`, `TokenHandle` et `IoPriority` de `NtLoadKeyEx`. Microsoft le considère supplanté, mais l'export reste présent dans chaque ntdll livré jusqu'à 24H2 inclus, et le SSN pointe toujours sur un handler réel — exactement le genre de coin déprécié-mais-appelable que les attaquants apprécient car les hooks et règles EDR l'oublient souvent.
Usage courant par les malwares
Tradecraft de dump de credentials hors-ligne : les attaquants façon `secretsdump` copient une ruche victime (SAM, SYSTEM, SECURITY) via VSS / NTFS brut, puis la montent sous une clé arbitraire avec `NtLoadKey`/`NtLoadKey2` pour l'énumérer via les APIs classiques `RegOpenKeyEx` / `NtOpenKey` sans parser eux-mêmes le format binaire. `NtLoadKey2` est utilisé quand un opérateur substitue volontairement le `RegLoadKeyW` évident (qui passe par `NtLoadKeyEx`) par la variante plus ancienne pour esquiver les listes de hooks naïves. Nécessite `SeRestorePrivilege` et `SeBackupPrivilege` — autrement dit administrateur local.
Opportunités de détection
Tout appel à `NtLoadKey*` depuis un binaire non Microsoft est un signal fort, car les consommateurs légitimes se résument à `regedit.exe`, `reg.exe`, `appidcertstorecheck.exe`, le loader de profil utilisateur et quelques outils d'imagerie. Sysmon Event ID 12/13/14 (Registry) ne se déclenche **pas** pour les chargements de ruche — le noyau émet uniquement via le provider ETW `Microsoft-Windows-Kernel-Registry` (event ID 9 = HiveLoaded). Les EDR qui tracent l'activation de `SeRestorePrivilege` suivie d'ouvertures de `\??\...\config\SAM` repèrent le pattern canonique de dump SAM ; l'ouverture du fichier reste un déclencheur plus fiable que le syscall lui-même.
Exemples de syscalls directs
asmx64 direct stub (Win11 24H2)
; Direct syscall stub for NtLoadKey2 (SSN 0x111 on Win11 24H2)
NtLoadKey2 PROC
mov r10, rcx ; TargetKey
mov eax, 111h ; SSN — drifts per build
syscall
ret
NtLoadKey2 ENDPcMount an offline SAM hive grabbed via VSS
// Requires SeRestorePrivilege + SeBackupPrivilege enabled on the caller.
#include <windows.h>
#include <winternl.h>
typedef NTSTATUS (NTAPI *pNtLoadKey2)(POBJECT_ATTRIBUTES, POBJECT_ATTRIBUTES, ULONG);
NTSTATUS MountHive(LPCWSTR ntMountPath, LPCWSTR ntHiveFile) {
UNICODE_STRING uMount, uFile;
OBJECT_ATTRIBUTES oaMount, oaFile;
RtlInitUnicodeString(&uMount, ntMountPath); // e.g. L"\\REGISTRY\\USER\\OfflineSAM"
RtlInitUnicodeString(&uFile, ntHiveFile); // e.g. L"\\??\\C:\\temp\\SAM_copy"
InitializeObjectAttributes(&oaMount, &uMount, OBJ_CASE_INSENSITIVE, NULL, NULL);
InitializeObjectAttributes(&oaFile, &uFile, OBJ_CASE_INSENSITIVE, NULL, NULL);
pNtLoadKey2 fn = (pNtLoadKey2)GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtLoadKey2");
return fn(&oaMount, &oaFile, 0x4 /* REG_NO_LAZY_FLUSH */);
}Mappings MITRE ATT&CK
Last verified: 2026-05-20