Handles d’objet

Les pilotes et les composants en mode utilisateur accèdent à la plupart des objets définis par le système via des handles. Les handles sont représentés par le type de données opaque HANDLE. (Notez que les handles ne sont pas utilisés pour accéder aux objets d’appareil ou aux objets de pilote.)

Pour la plupart des types d’objets, la routine en mode noyau qui crée ou ouvre l’objet fournit un handle à l’appelant. L’appelant utilise ensuite ce handle dans les opérations suivantes sur l’objet.

Voici une liste des types d’objets que les pilotes utilisent généralement, ainsi que les routines qui fournissent des handles aux objets de ce type.

Type d’objet Routine de création/ouverture correspondante

Fichier

IoCreateFile, ZwCreateFile, ZwOpenFile

les clés de Registre

IoOpenDeviceInterfaceRegistryKey, IoOpenDeviceRegistryKey, ZwCreateKey, ZwOpenKey

Threads

PsCreateSystemThread

Événements

IoCreateSynchronizationEvent, IoCreateNotificationEvent

Liens symboliques

ZwOpenSymbolicLinkObject

Objets annuaire

ZwCreateDirectoryObject

Objets de section

ZwOpenSection

Lorsque le pilote n’a plus besoin d’accéder à l’objet, il appelle la routine ZwClose pour fermer le handle. Cela fonctionne pour tous les types d’objets répertoriés dans le tableau ci-dessus.

La plupart des routines qui fournissent des handles prennent une structure OBJECT_ATTRIBUTES en tant que paramètre. Cette structure peut être utilisée pour spécifier des attributs pour le handle.

Les pilotes peuvent spécifier les attributs de handle suivants :

  • OBJ_KERNEL_HANDLE

    Le handle est accessible uniquement à partir du mode noyau.

  • OBJ_INHERIT

    Tous les enfants du processus actuel reçoivent une copie du handle lors de leur création.

  • OBJ_FORCE_ACCESS_CHECK

    Cet attribut spécifie que le système effectue toutes les vérifications d’accès sur le handle. Par défaut, le système contourne toutes les vérifications d’accès sur les handles créés en mode noyau.

Utilisez la routine InitializeObjectAttributes pour définir ces attributs dans une structure OBJECT_ATTRIBUTES .

Pour plus d’informations sur la validation des handles d’objet, consultez Échec de la validation des handles d’objet.

Handles d’objets privés

Chaque fois qu’un pilote crée un handle d’objet pour son utilisation privée, il doit spécifier l’attribut OBJ_KERNEL_HANDLE. Cela garantit que le handle est inaccessible aux applications en mode utilisateur.

Handles d’objets partagés

Un pilote qui partage des handles d’objet entre le mode noyau et le mode utilisateur doit être écrit avec soin pour éviter de créer accidentellement des trous de sécurité. Voici quelques recommandations :

  1. Créez des handles en mode noyau et passez-les en mode utilisateur, au lieu de l’inverse. Les handles créés par un composant en mode utilisateur et transmis au pilote ne doivent pas être approuvés.

  2. Si le pilote doit manipuler des handles pour le compte d’applications en mode utilisateur, utilisez l’attribut OBJ_FORCE_ACCESS_CHECK pour vérifier que l’application dispose de l’accès nécessaire.

  3. Utilisez ObReferenceObjectByPointer pour conserver une référence en mode noyau sur un handle partagé. Sinon, si un composant en mode utilisateur ferme le handle, le nombre de références passe à zéro, et si le pilote tente ensuite d’utiliser ou de fermer le handle, le système se bloque.

Si une application en mode utilisateur crée un objet d’événement, un pilote peut attendre en toute sécurité que cet événement soit signalé, mais uniquement si l’application transmet un handle à l’objet d’événement au pilote via un IOCTL. Le pilote doit gérer le IOCTL dans le contexte du processus qui a créé l’événement et doit vérifier que le handle est un handle d’événement en appelant ObReferenceObjectByHandle.