NtMakePermanentObject
Pose l'attribut OBJ_PERMANENT sur un objet noyau nommé pour qu'il survive après la fermeture du dernier handle.
Prototype
NTSTATUS NtMakePermanentObject( HANDLE Handle );
Arguments
| Name | Type | Dir | Description |
|---|---|---|---|
| Handle | HANDLE | in | Handle vers un objet noyau nommé dont l'en-tête sera marqué OBJ_PERMANENT. |
IDs de syscalls par version de Windows
| Version de Windows | ID de syscall | Build |
|---|---|---|
| Win10 1507 | 0xFD | win10-1507 |
| Win10 1607 | 0x102 | win10-1607 |
| Win10 1703 | 0x106 | win10-1703 |
| Win10 1709 | 0x107 | win10-1709 |
| Win10 1803 | 0x108 | win10-1803 |
| Win10 1809 | 0x108 | win10-1809 |
| Win10 1903 | 0x109 | win10-1903 |
| Win10 1909 | 0x109 | win10-1909 |
| Win10 2004 | 0x10E | win10-2004 |
| Win10 20H2 | 0x10E | win10-20h2 |
| Win10 21H1 | 0x10E | win10-21h1 |
| Win10 21H2 | 0x10F | win10-21h2 |
| Win10 22H2 | 0x10F | win10-22h2 |
| Win11 21H2 | 0x115 | win11-21h2 |
| Win11 22H2 | 0x116 | win11-22h2 |
| Win11 23H2 | 0x116 | win11-23h2 |
| Win11 24H2 | 0x118 | win11-24h2 |
| Server 2016 | 0x102 | winserver-2016 |
| Server 2019 | 0x108 | winserver-2019 |
| Server 2022 | 0x114 | winserver-2022 |
| Server 2025 | 0x118 | winserver-2025 |
Module noyau
APIs liées
Stub du syscall
4C 8B D1 mov r10, rcx B8 18 01 00 00 mov eax, 0x118 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
Pose le flag `OBJ_PERMANENT` sur le `_OBJECT_HEADER` sous-jacent pour que l'objet ne soit *pas* libéré quand le dernier handle utilisateur est fermé. Côté noyau : `ObSetPermanentObject(object, TRUE)` suivi d'une référence supplémentaire conservée par Ob. Les objets permanents sont la manière dont Win32 garde sections nommées, events et sémaphores vivants après que leur créateur sort — `\BaseNamedObjects\Global\Foo` survit parce que SCM, csrss ou le desktop window manager a appelé `NtMakePermanentObject` dessus (ou créé l'objet directement avec `OBJ_PERMANENT` dans `OBJECT_ATTRIBUTES::Attributes`). Requiert `SeCreatePermanentPrivilege`, détenu uniquement par `LocalSystem` et quelques identités de service — donc un usage depuis un token user-mode normal renvoie d'ordinaire `STATUS_PRIVILEGE_NOT_HELD`. L'appel est sur la liste de dépréciation Microsoft depuis Vista (remplacé par la création directe avec `OBJ_PERMANENT` dans l'appel `NtCreate*`), mais toujours exporté et fonctionnel. Pendant : `NtMakeTemporaryObject`.
Usage courant par les malwares
Faible signal malware. Le cas d'usage légitime étroit — garder les survivants `\BaseNamedObjects` — recoupe un petit ensemble de tricks de persistance. La persistance par section nommée (ère Skywiper / Flame, et PoC modernes) crée une section nommée permanente, y écrit un payload, puis sort — un map ultérieur par un processus privilégié du même nom de section ramène le payload dans un espace d'adressage privilégié. Mettre `OBJ_PERMANENT` au moment de la création est la voie la plus courante ; appeler `NtMakePermanentObject` après coup est un pattern moins discret. Certains droppers et installeurs de rootkits l'utilisent pour garder un objet nommé IPC `Event` ou `Mutex` vivant à travers les redémarrages de processus, comme une balise de présence. L'exigence de privilège plafonne l'abus réel aux payloads déjà élevés.
Opportunités de détection
Aucun événement ETW dédié. La nature privilégiée de `SeCreatePermanentPrivilege` elle-même est le signal haute fidélité — tout processus non-système qui l'active et l'utilise avec succès mérite enquête peu importe le syscall appelé. Côté chasse, snapshotter `\BaseNamedObjects` et `\BaseNamedObjects\Global` (`WinObj`, ou parcours `NtQueryDirectoryObject`) au boot et à intervalles ; les objets avec l'attribut `Permanent` qui n'existaient pas au boot et ont été créés par un processus non-système sont le vrai IOC. ETW `Microsoft-Windows-Kernel-Object` avec les événements `Handle Create` permet de corréler l'attribut `OBJ_PERMANENT` dans `ObjectAttributes` au moment de la création.
Exemples de syscalls directs
asmx64 direct stub (Win11 24H2)
; Direct syscall stub for NtMakePermanentObject (SSN 0x118 on Win11 24H2 / Server 2025)
NtMakePermanentObject PROC
mov r10, rcx ; syscall convention
mov eax, 118h ; SSN — drifts; resolve dynamically for portability
syscall
ret
NtMakePermanentObject ENDPcPromote a named section so it outlives the creator
// Promote an existing named section to OBJ_PERMANENT so closing the last
// handle does not free it — payload-staging persistence pattern.
// Requires SeCreatePermanentPrivilege enabled in the calling token.
UNICODE_STRING name; RtlInitUnicodeString(&name, L"\\BaseNamedObjects\\Global\\__stage__");
OBJECT_ATTRIBUTES oa;
InitializeObjectAttributes(&oa, &name, OBJ_CASE_INSENSITIVE, NULL, NULL);
HANDLE hSec;
LARGE_INTEGER size = { .QuadPart = 0x10000 };
if (NT_SUCCESS(NtCreateSection(&hSec, SECTION_ALL_ACCESS, &oa,
&size, PAGE_EXECUTE_READWRITE,
SEC_COMMIT, NULL))) {
NtMakePermanentObject(hSec); // section now survives our process exit
NtClose(hSec); // a later process can NtOpenSection() it
}Mappings MITRE ATT&CK
Last verified: 2026-05-20