Partager via


Vérifications diverses

L’option Vérifications diverses du vérificateur de pilotes surveille le pilote pour les erreurs courantes qui provoquent le blocage du pilote ou du système, telles que la libération de la mémoire qui contient toujours des objets de noyau actifs.

Plus précisément, l’option Vérifications diverses recherche le comportement incorrect suivant du pilote :

  • Éléments de travail actifs dans la mémoire libérée. Le pilote appelle ExFreePool pour libérer un bloc de pool qui contient des éléments de travail mis en file d’attente à l’aide d’IoQueueWorkItem.

  • Ressources actives dans la mémoire libérée. Le pilote appelle ExFreePool pour libérer un bloc de pool qui contient des structures ERESOURCE actives. Le pilote doit appeler ExDeleteResource pour supprimer des objets ERESOURCE avant d’appeler ExFreePool.

  • Listes de lookaside actives dans la mémoire libérée. Le pilote appelle ExFreePool pour libérer un bloc de pool qui contient toujours des listes de recherche actives (NPAGED_LOOKASIDE_LIST ou structures PAGED_LOOKASIDE_LIST . Le pilote doit appeler ExDeleteNPagedLookasideList ou ExDeletePagedLookasideList pour supprimer les listes de lookaside avant d’appeler ExFreePool.

  • Problèmes d’inscription de Windows Management Instrumentation (WMI) et de suivi d’événements pour Windows (ETW). Ces problèmes détectés par Driver Verifier sont les suivants :

    • Un pilote qui tente de décharger sans désinscrire son rappel WMI.

    • Pilote qui tente de supprimer un objet d’appareil qui n’a pas été désinscrit de WMI.

    • Pilote qui tente de décharger sans désinscrire ses fournisseurs en mode noyau ETW.

    • Pilote qui tente d’annuler l’inscription d’un fournisseur qui n’est déjà pas inscrit.

  • Les erreurs de gestion du noyau. (Windows Vista et versions ultérieures) L’activation de l’option Vérifications diverses permet également d’activer le suivi des handles pour le processus système afin de faciliter l’examen des fuites de gestion du noyau et de la vérification des bogues 0x93 : INVALID_KERNEL_HANDLE. Une fois le suivi de handle activé, le noyau collecte les traces de pile pour les opérations récentes d’ouverture et de fermeture de handle. Les traces de pile peuvent être affichées dans le débogueur du noyau à l’aide de l’extension !htrace débogueur. Pour plus d’informations sur !htrace, consultez la documentation Outils de débogage pour Windows.

  • Handle en mode utilisateur avec accès en mode noyau À compter de Windows 7, lorsque vous sélectionnez l’option Vérifications diverses, Driver Verifier vérifie également les appels à ObReferenceObjectByHandle. Vous ne pouvez pas passer un handle en mode utilisateur avec accès en mode noyau. Si une telle opération se produit, le vérificateur de pilotes émet la vérification des bogues 0xC4, avec la valeur de paramètre 1 de 0xF6.

  • UserMode Wait pour les objets de synchronisation alloués sur la pile du noyau

    À compter de Windows 7, Driver Verifier peut détecter d’autres façons que les pilotes peuvent utiliser incorrectement les mécanismes de synchronisation multithreading fournis par le système d’exploitation.

    L’allocation d’objets de synchronisation, tels que des structures KEVENT, en tant que variables locales sur la pile du noyau est une pratique courante. Lorsqu’un processus est chargé en mémoire, les piles de noyau de ses threads ne sont jamais supprimées du groupe de travail ou paginées sur le disque. L’allocation d’objets de synchronisation dans cette mémoire non modifiable est correcte.

    Toutefois, lorsque les pilotes appellent des API telles que KeWaitForSingleObject ou KeWaitForMultipleObjects pour attendre qu’un objet soit alloué sur la pile, ils doivent spécifier la valeur KernelMode pour le paramètre WaitMode de l’API. Lorsque tous les threads d’un processus sont en attente en mode Utilisateur , ce processus devient éligible pour être échangé sur le disque. Par conséquent, si un pilote a spécifié UserMode comme paramètre WaitMode , le système d’exploitation peut permuter le processus en cours tant que tous les autres threads du même processus sont également en attente en tant que UserMode. L’échange d’un processus entier vers le disque inclut la pagination de ses piles de noyau. L’attente d’un objet de synchronisation que le système d’exploitation a échangé est incorrecte. À un moment donné, un thread doit arriver et signaler l’objet de synchronisation. La signalisation d’un objet de synchronisation implique que le noyau Windows manipule l’objet à l’adresse IRQL = DISPATCH_LEVEL ou au-dessus. Le fait de toucher la mémoire paginée ou échangée à DISPATCH_LEVEL ou au-dessus entraîne un plantage du système.

    À compter de Windows 7, lorsque vous sélectionnez l’option Vérifications diverses, Driver Verifier vérifie que les objets de synchronisation que le pilote vérifié utilise pour attendre dans UserMode ne sont pas alloués sur la pile du noyau du thread actif. Lorsque le vérificateur de pilotes détecte une telle attente incorrecte, il émet un 0xC4 de vérification de bogue : DRIVER_VERIFIER_DETECTED_VIOLATION, avec une valeur de paramètre 1 de 0x123.

  • Références de handle de noyau incorrectes

    Chaque processus Windows a une table de handle. Vous pouvez afficher la table handle sous la forme d’un tableau d’entrées de handle. Chaque valeur de handle valide fait référence à une entrée valide dans ce tableau.

    Un handle de noyau en tant que handle valide pour la table de handle du processus système. Handle utilisateur en tant que handle valide pour n’importe quel processus, à l’exception du processus système.

    Dans Windows 7, driver verifier détecte les tentatives de référence des valeurs de handle du noyau qui sont incorrectes. Ces défauts de pilote sont signalés sous la forme d’un 0x93 de vérification des bogues : INVALID_KERNEL_HANDLE si l’option Vérifications diverses du pilote est activée. En règle générale, ce type de référence de handle incorrecte signifie que le pilote a déjà fermé ce handle, mais qu’il essaie de continuer à l’utiliser. Ce type de défaut peut entraîner des problèmes imprévisibles pour le système, car la valeur de handle référencée a peut-être déjà été réutilisée par un autre pilote non lié.

    Si un pilote de noyau a récemment fermé un handle de noyau et fait référence ultérieurement au handle fermé, Driver Verifier force le bogue case activée comme décrit précédemment. Dans ce cas, la sortie de l’extension de débogueur !htrace fournit la trace de pile pour le chemin de code qui a fermé ce handle. Utilisez l’adresse du processus système comme paramètre pour !htrace. Pour trouver l’adresse du processus système, utilisez la commande !process 4 0 .

    À compter de Windows 7, Driver Verifier ajoute un case activée à ObReferenceObjectByHandle. Il est désormais interdit de passer un handle d’espace utilisateur avec l’accès KernelMode. Si une telle combinaison est détectée, le vérificateur de pilotes émet la vérification des bogues 0xC4 : DRIVER_VERIFIER_DETECTED_VIOLATION, avec une valeur de paramètre 1 de 0xF6.

Activation de cette option

Vous pouvez activer l’option Vérifications diverses pour un ou plusieurs pilotes à l’aide du Gestionnaire du vérificateur de pilotes ou de la ligne de commande Verifier.exe. Pour plus d’informations, consultez Sélection des options du vérificateur de pilote.

  • Sur la ligne de commande

    Sur la ligne de commande, l’option Vérifications diverses est représentée par Bit 11 (0x800). Pour activer les vérifications diverses, utilisez une valeur d’indicateur de 0x800 ou ajoutez 0x800 à la valeur d’indicateur. Par exemple :

    verifier /flags 0x800 /driver MyDriver.sys
    

    L’option sera active après le prochain démarrage.

    Sur Windows Vista et les versions ultérieures de Windows, vous pouvez également activer et désactiver vérifications diverses sans redémarrer l’ordinateur en ajoutant le paramètre /volatile à la commande. Par exemple :

    verifier /volatile /flags 0x800 /adddriver MyDriver.sys
    

    Ce paramètre prend effet immédiatement, mais il est perdu lorsque vous arrêtez ou redémarrez l’ordinateur. Pour plus d’informations, consultez Utilisation de paramètres volatiles.

    L’option Vérifications diverses est également incluse dans les paramètres standard. Par exemple :

    verifier  /standard /driver MyDriver.sys
    
  • Utilisation du Gestionnaire de vérificateur de pilotes

    1. Démarrez le Gestionnaire de vérificateur de pilotes. Tapez Vérificateur dans une fenêtre d’invite de commandes.

    2. Sélectionnez Créer des paramètres personnalisés (pour les développeurs de code), puis cliquez sur Suivant.

    3. Sélectionnez Sélectionner des paramètres individuels dans une liste complète.

    4. Sélectionnez Vérifications diverses.

    La fonctionnalité Vérifications diverses est également incluse dans les paramètres standard. Pour utiliser cette fonctionnalité, dans Le Gestionnaire du vérificateur de pilotes, cliquez sur Créer des paramètres standard.

Consultation des résultats

Pour afficher les résultats de l’option Vérifications diverses, utilisez l’extension !verifier dans le débogueur du noyau. (Pour plus d’informations sur !verifier, consultez la documentation Outils de débogage pour Windows .)

Dans l’exemple suivant, l’option Vérifications diverses a détecté une structure ERESOURCE active dans la mémoire que le pilote essayait de libérer, ce qui a entraîné la vérification des bogues 0xC4 : DRIVER_VERIFIER_DETECTED_VIOLATION. La vérification des bogues 0xC4'affichage inclut l’adresse de l’ERESOURCE et la mémoire affectée.

1: kd> !verifier 1

Verify Level 800 ... enabled options are:
 Miscellaneous checks enabled

Summary of All Verifier Statistics

RaiseIrqls                             0x0
AcquireSpinLocks                       0x0
Synch Executions                       0x0
Trims                                  0x0

Pool Allocations Attempted             0x1
Pool Allocations Succeeded             0x1
Pool Allocations Succeeded SpecialPool 0x0
Pool Allocations With NO TAG           0x0
Pool Allocations Failed                0x0
Resource Allocations Failed Deliberately   0x0

Current paged pool allocations         0x0 for 00000000 bytes
Peak paged pool allocations            0x0 for 00000000 bytes
Current nonpaged pool allocations      0x0 for 00000000 bytes
Peak nonpaged pool allocations         0x0 for 00000000 bytes

Driver Verification List

Entry     State           NonPagedPool   PagedPool   Module

8459ca50 Loaded           00000000       00000000    buggy.sys



*** Fatal System Error: 0x000000c4
 (0x000000D2,0x9655D4A8,0x9655D468,0x000000B0)


        0xD2 : Freeing pool allocation that contains active ERESOURCE.
               2 -  ERESOURCE address.
               3 -  Pool allocation start address.
               4 -  Pool allocation size.

Pour examiner l’allocation de pool, utilisez l’extension !pool débogueur avec l’adresse de départ de l’allocation de pool, 9655D468. (L’indicateur 2 affiche les informations d’en-tête uniquement pour le pool qui contient l’adresse spécifiée. Les informations d’en-tête pour les autres pools sont supprimées.)

1: kd> !pool 9655d468  2
Pool page 9655d468 region is Paged pool
*9655d468 size:   b0 previous size:    8  (Allocated) *Bug_

Pour obtenir des informations sur ERESOURCE, utilisez l’extension de débogueur !locks ( !kdext*.locks) avec l’adresse de la structure.

1: kd> !locks 0x9655D4A8     <<<<<- ERESOURCE @0x9655D4A8 lives inside the pool block being freed

Resource @ 0x9655d4a8    Available
1 total locks

Vous pouvez également utiliser la commande de débogueur kb pour afficher une trace de pile des appels qui ont conduit à l’échec. L’exemple suivant montre la pile, y compris l’appel à ExFreePoolWithTag intercepté par Driver Verifier.

1: kd> kb
ChildEBP RetAddr  Args to Child
92f6374c 82c2c95a 00000003 92f68cdc 00000000 nt!RtlpBreakWithStatusInstruction
92f6379c 82c2d345 00000003 9655d468 000000c4 nt!KiBugCheckDebugBreak+0x1c
92f63b48 82c2c804 000000c4 000000d2 9655d4a8 nt!KeBugCheck2+0x5a9
92f63b6c 82e73bae 000000c4 000000d2 9655d4a8 nt!KeBugCheckEx+0x1e
92f63b88 82e78c32 9655d4a8 9655d468 000000b0 nt!VerifierBugCheckIfAppropriate+0x3c
92f63ba4 82ca7dcb 9655d468 000000b0 00000000 nt!VfCheckForResource+0x52
92f63bc8 82e7fb2d 000000b0 00000190 9655d470 nt!ExpCheckForResource+0x21
92f63be4 82e6dc6c 9655d470 92f63c18 89b6c58c nt!ExFreePoolSanityChecks+0x1fb
92f63bf0 89b6c58c 9655d470 00000000 89b74194 nt!VerifierExFreePoolWithTag+0x28
92f63c00 89b6c0f6 846550c8 846550c8 846e2200 buggy!MmTestProbeLockForEverStress+0x2e
92f63c18 82e6c5f1 846e2200 846550c8 85362e30 buggy!TdDeviceControl+0xc4
92f63c38 82c1fd81 82d4d148 846550c8 846e2200 nt!IovCallDriver+0x251
92f63c4c 82d4d148 85362e30 846550c8 84655138 nt!IofCallDriver+0x1b
92f63c6c 82d4df9e 846e2200 85362e30 00000000 nt!IopSynchronousServiceTail+0x1e6
92f63d00 82d527be 00000001 846550c8 00000000 nt!IopXxxControlFile+0x684
92f63d34 82cb9efc 0000004c 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
92f63d34 6a22b204 0000004c 00000000 00000000 nt!KiFastCallEntry+0x12c