Freigeben über


Sonstige Überprüfungen

Die Option Verschiedene Überprüfungen der Treiberüberprüfung überwacht den Treiber auf häufige Fehler, die zum Absturz des Treibers oder Systems führen, z. B. das Freigeben von Arbeitsspeicher, der noch aktive Kernelobjekte enthält.

Insbesondere sucht die Option Verschiedene Überprüfungen nach dem folgenden fehlerhaften Treiberverhalten:

  • Aktive Arbeitselemente im freigegebenen Arbeitsspeicher. Der Treiber ruft ExFreePool auf, um einen Poolblock freizugeben, der Arbeitselemente enthält, die mithilfe von IoQueueWorkItem in die Warteschlange gestellt wurden.

  • Aktive Ressourcen im freigegebenen Arbeitsspeicher. Der Treiber ruft ExFreePool auf, um einen Poolblock freizugeben, der aktive ERESOURCE-Strukturen enthält. Der Treiber sollte ExDeleteResource aufrufen, um ERESOURCE-Objekte vor dem Aufruf von ExFreePool zu löschen.

  • Aktive Suchlisten im freigegebenen Arbeitsspeicher. Der Treiber ruft ExFreePool auf, um einen Poolblock freizugeben, der weiterhin aktive Suchlisten (NPAGED_LOOKASIDE_LIST - oder PAGED_LOOKASIDE_LIST-Strukturen enthält. Der Treiber sollte ExDeleteNPagedLookasideList oder ExDeletePagedLookasideList aufrufen, um die Suchlisten vor dem Aufruf von ExFreePool zu löschen.

  • Windows-Verwaltungsinstrumentation (WMI) und Ereignisablaufverfolgung für Windows (ETW) Registrierungsprobleme. Zu diesen problemen, die von Driver Verifier erkannt wurden, gehören:

    • Ein Treiber, der versucht, die Registrierung des WMI-Rückrufs zu entladen, ohne die Registrierung aufzuheben.

    • Ein Treiber, der versucht, ein Geräteobjekt zu löschen, das die Registrierung von WMI nicht aufgehoben hat.

    • Ein Treiber, der versucht, die Registrierung der ETW-Kernelmodusanbieter zu entladen, ohne die Registrierung aufzuheben.

    • Ein Treiber, der versucht, die Registrierung eines Anbieters aufzuheben, der bereits nicht registriert ist.

  • Kernel behandeln Fehler. (Windows Vista und höhere Versionen) Wenn Sie die Option Verschiedene Überprüfungen aktivieren, wird auch die Handle-Ablaufverfolgung für den Systemprozess aktiviert, um die Untersuchung von Kernel-Handle-Leaks und die Fehlerüberprüfung 0x93: INVALID_KERNEL_HANDLE zu unterstützen. Wenn die Handle-Ablaufverfolgung aktiviert ist, sammelt der Kernel Stapelablaufverfolgungen für aktuelle Vorgänge zum Öffnen und Schließen von Handle. Die Stapelablaufverfolgungen können mithilfe der Debuggererweiterung !htrace im Kerneldebugger angezeigt werden. Weitere Informationen zu !htrace finden Sie in der Dokumentation Debugtools für Windows.

  • Benutzermodushandle mit Kernelmoduszugriff Wenn Sie ab Windows 7 die Option Verschiedene Überprüfungen auswählen, überprüft Driver Verifier auch Aufrufe von ObReferenceObjectByHandle. Sie können ein Benutzermodushandle nicht mit Kernelmoduszugriff übergeben. Wenn ein solcher Vorgang ausgeführt wird, gibt die Treiberüberprüfung fehlerprüfer 0xC4 aus, wobei der Parameter 1-Wert 0xF6.

  • UserMode: Warten auf Synchronisierungsobjekte, die auf dem Kernelstapel zugeordnet sind

    Ab Windows 7 kann driver verifier zusätzliche Möglichkeiten erkennen, wie Treiber die vom Betriebssystem bereitgestellten Multithreadingsynchronisierungsmechanismen fälschlicherweise verwenden können.

    Das Zuweisen von Synchronisierungsobjekten, z. B. KEVENT-Strukturen, als lokale Variablen auf dem Kernelstapel ist eine gängige Vorgehensweise. Während ein Prozess im Arbeitsspeicher geladen wird, werden die Kernelstapel seiner Threads nie vom Arbeitssatz gekürzt oder auf den Datenträger ausgelagert. Das Zuweisen von Synchronisierungsobjekten in einem solchen nicht ausstellbaren Arbeitsspeicher ist richtig.

    Wenn Treiber jedoch APIs wie KeWaitForSingleObject oder KeWaitForMultipleObjects aufrufen, um auf ein Objekt zu warten, das im Stapel zugeordnet ist, müssen sie den KernelMode-Wert für den WaitMode-Parameter der API angeben. Wenn alle Threads eines Prozesses im Benutzermodus warten, kann dieser Prozess auf den Datenträger ausgetauscht werden. Wenn also ein Treiber UserMode als WaitMode-Parameter angegeben hat, kann das Betriebssystem den aktuellen Prozess austauschen, solange jeder andere Thread im gleichen Prozess ebenfalls wie UserMode wartet. Das Austauschen eines gesamten Prozesses auf den Datenträger umfasst das Auslagern der Kernelstapel. Das Warten auf ein Synchronisierungsobjekt, das vom Betriebssystem ausgetauscht wurde, ist falsch. Irgendwann muss ein Thread kommen und das Synchronisierungsobjekt signalisieren. Das Signalisieren eines Synchronisierungsobjekts beinhaltet, dass der Windows-Kernel das Objekt bei IRQL = DISPATCH_LEVEL oder höher manipuliert. Das Berühren von ausgelagertem oder ausgetauschtem Arbeitsspeicher bei DISPATCH_LEVEL oder höher führt zu einem Systemabsturz.

    Wenn Sie ab Windows 7 die Option Verschiedene Überprüfungen auswählen, überprüft die Treiberüberprüfung, ob die Synchronisierungsobjekte, die der überprüfte Treiber zum Warten in UserMode verwendet, nicht im Kernelstapel des aktuellen Threads zugeordnet sind. Wenn die Driver Verifier eine solche falsche Wartezeit erkennt, wird eine Fehlerüberprüfung 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION mit dem Parameter 1-Wert 0x123 ausgeführt.

  • Falsche Kernelhandleverweise

    Jeder Windows-Prozess verfügt über eine Handle-Tabelle. Sie können die Handle-Tabelle als Array von Handle-Einträgen anzeigen. Jeder gültige Handle-Wert bezieht sich auf einen gültigen Eintrag in diesem Array.

    Ein Kernelhandle als Handle, das für die Handle-Tabelle des Systemprozesses gültig ist. Ein Benutzerhandle als Handle, das für alle Prozesse mit Ausnahme des Systemprozesses gültig ist.

    In Windows 7 erkennt driver verifier versuche, auf Kernelhandlewerte zu verweisen, die falsch sind. Diese Treiberfehler werden als Fehlerüberprüfung 0x93 gemeldet: INVALID_KERNEL_HANDLE , wenn die Option Driver Verifier Miscellaneous Checks aktiviert ist. Normalerweise bedeutet diese Art von falscher Handle-Referenz, dass der Treiber dieses Handle bereits geschlossen hat, aber versucht, es weiterhin zu verwenden. Diese Art von Fehler kann zu unvorhersehbaren Problemen für das System führen, da der Handle-Wert, auf den verwiesen wird, möglicherweise bereits von einem anderen unabhängigen Treiber wiederverwendet wurde.

    Wenn ein Kerneltreiber kürzlich ein Kernelhandle geschlossen hat und später auf das geschlossene Handle verweist, erzwingt Driver Verifier die Fehlerüberprüfung, wie zuvor beschrieben. In diesem Fall stellt die Ausgabe der Debuggererweiterung !htrace die Stapelablaufverfolgung für den Codepfad bereit, der dieses Handle geschlossen hat. Verwenden Sie die Adresse des Systemprozesses als Parameter für !htrace. Um die Adresse des Systemprozesses zu finden, verwenden Sie den Befehl !process 4 0 .

    Ab Windows 7 fügt Driver Verifier eine Überprüfung zu ObReferenceObjectByHandle hinzu. Es ist jetzt verboten, ein Benutzerspeicherhandle mit KernelMode-Zugriff zu übergeben. Wenn eine solche Kombination erkannt wird, gibt der Treiberprüfer die Fehlerüberprüfung 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION mit dem Parameter 1-Wert 0xF6 aus.

Aktivieren dieser Option

Sie können die Option Verschiedene Überprüfungen für einen oder mehrere Treiber aktivieren, indem Sie den Treiberüberprüfungs-Manager oder die befehlszeile Verifier.exe verwenden. Ausführliche Informationen finden Sie unter Auswählen von Treiberüberprüfungsoptionen.

  • An der Befehlszeile

    In der Befehlszeile wird die Option Verschiedene Überprüfungen durch Bit 11 (0x800) dargestellt. Um Verschiedene Überprüfungen zu aktivieren, verwenden Sie den Flagwert 0x800, oder fügen Sie dem Flagwert 0x800 hinzu. Beispiel:

    verifier /flags 0x800 /driver MyDriver.sys
    

    Die Option ist nach dem nächsten Start aktiv.

    Unter Windows Vista und höheren Versionen von Windows können Sie verschiedene Überprüfungen auch aktivieren und deaktivieren, ohne den Computer neu zu starten, indem Sie dem Befehl den Parameter /volatile hinzufügen. Beispiel:

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

    Diese Einstellung ist sofort wirksam, geht aber verloren, wenn Sie den Computer herunterfahren oder neu starten. Ausführliche Informationen finden Sie unter Verwenden flüchtiger Einstellungen.

    Die Option Verschiedene Überprüfungen ist auch in den Standardeinstellungen enthalten. Beispiel:

    verifier  /standard /driver MyDriver.sys
    
  • Verwenden des Treiberüberprüfungs-Managers

    1. Starten Sie den Treiberüberprüfungs-Manager. Geben Sie Verifier in ein Eingabeaufforderungsfenster ein.

    2. Wählen Sie Benutzerdefinierte Einstellungen erstellen (für Codeentwickler) aus, und klicken Sie dann auf Weiter.

    3. Wählen Sie Einzelne Einstellungen aus einer vollständigen Liste auswählen aus.

    4. Wählen Sie Verschiedene Überprüfungen aus.

    Das Feature Verschiedene Überprüfungen ist auch in den Standardeinstellungen enthalten. Um dieses Feature zu verwenden, klicken Sie im Treiberüberprüfungs-Manager auf Standardeinstellungen erstellen.

Anzeigen der Ergebnisse

Um die Ergebnisse der Option Verschiedene Überprüfungen anzuzeigen, verwenden Sie die Erweiterung !verifier im Kerneldebugger. (Informationen zu !verifier finden Sie in der Dokumentation Debugtools für Windows .)

Im folgenden Beispiel hat die Option Verschiedene Überprüfungen eine aktive ERESOURCE-Struktur im Arbeitsspeicher erkannt, die der Treiber freizugeben versuchte, was zu einer Fehlerüberprüfung 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION führte. Die Fehlerüberprüfung 0xC4 Anzeige enthält die Adresse der ERESOURCE und den betroffenen Arbeitsspeicher.

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.

Verwenden Sie zum Untersuchen der Poolzuordnung die Debuggererweiterung !pool mit der Startadresse der Poolzuordnung 9655D468. (Das Flag 2 zeigt nur Headerinformationen für den Pool an, der die angegebene Adresse enthält. Headerinformationen für andere Pools werden unterdrückt.)

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

Um Informationen zur ERESOURCE zu finden, verwenden Sie die Debuggererweiterung !locks (!kdext*.locks) mit der Adresse der Struktur.

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

Resource @ 0x9655d4a8    Available
1 total locks

Sie können auch den Befehl kb debugger verwenden, um eine Stapelablaufverfolgung der Aufrufe anzuzeigen, die zu dem Fehler geführt haben. Das folgende Beispiel zeigt den Stapel, einschließlich des Aufrufs von ExFreePoolWithTag , den Driver Verifier abgefangen hat.

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