Controlli vari

L'opzione Vari controlli di Driver Verifier monitora il driver per individuare errori comuni che causano l'arresto anomalo del driver o del sistema, ad esempio liberando memoria che contiene ancora oggetti kernel attivi.

In particolare, l'opzione Controlli vari cerca il comportamento non corretto del driver seguente:

  • Elementi di lavoro attivi nella memoria liberata. Il driver chiama ExFreePool per liberare un blocco di pool che contiene elementi di lavoro accodati tramite IoQueueWorkItem.

  • Risorse attive nella memoria liberata. Il driver chiama ExFreePool per liberare un blocco di pool che contiene strutture ERESOURCE attive. Il driver deve chiamare ExDeleteResource per eliminare gli oggetti ERESOURCE prima di chiamare ExFreePool.

  • Elenchi lookaside attivi nella memoria liberata. Il driver chiama ExFreePool per liberare un blocco di pool che contiene ancora elenchi lookaside attivi (NPAGED_LOOKASIDE_LIST o strutture PAGED_LOOKASIDE_LIST . Il driver deve chiamare ExDeleteNPagedLookasideList o ExDeletePagedLookasideList per eliminare gli elenchi lookaside prima di chiamare ExFreePool.

  • Problemi di registrazione di Strumentazione gestione Windows (WMI) e Event Tracing for Windows (ETW). Tali problemi rilevati da Driver Verifier includono:

    • Driver che tenta di scaricare senza annullare la registrazione del callback WMI.

    • Driver che tenta di eliminare un oggetto dispositivo che non è stato registrato da WMI.

    • Driver che tenta di scaricare senza registrare i provider in modalità kernel ETW.

    • Driver che tenta di annullare la registrazione di un provider già non registrato.

  • Gestire gli errori del kernel. (Windows Vista e versioni successive) L'abilitazione dell'opzione Controlli vari consentirà anche di gestire la traccia per il processo di sistema per facilitare l'analisi della gestione delle perdite del kernel e del controllo dei bug 0x93: INVALID_KERNEL_HANDLE. Con la traccia handle abilitata, il kernel raccoglierà le analisi dello stack per le operazioni di apertura e chiusura recenti dell'handle. Le tracce dello stack possono essere visualizzate nel debugger del kernel usando l'estensione del debugger !htrace . Per altre informazioni su !htrace, vedere la documentazione degli strumenti di debug per Windows.

  • Handle in modalità utente con accesso in modalità kernel A partire da Windows 7, quando si seleziona l'opzione Controlli vari, Driver Verifier controlla anche le chiamate a ObReferenceObjectByHandle. Non è possibile passare un handle in modalità utente con accesso in modalità kernel. Se si verifica un'operazione di questo tipo, Driver Verifier genera 0xC4 controllo bug, con un valore di parametro 1 di 0xF6.

  • UserMode Attendere gli oggetti di sincronizzazione allocati nello stack del kernel

    A partire da Windows 7, Driver Verifier può rilevare altri modi in cui i driver possono usare erroneamente i meccanismi di sincronizzazione multithreading forniti dal sistema operativo.

    L'allocazione di oggetti di sincronizzazione, ad esempio strutture KEVENT, come le variabili locali nello stack del kernel è una pratica comune. Mentre un processo viene caricato in memoria, gli stack del kernel dei thread non vengono mai tagliati dal working set o impaginati sul disco. L'allocazione di oggetti di sincronizzazione in tale memoria non modificabile è corretta.

    Tuttavia, quando i driver chiamano API come KeWaitForSingleObject o KeWaitForMultipleObjects per attendere un oggetto allocato nello stack, devono specificare il valore KernelMode per il parametro WaitMode dell'API. Quando tutti i thread di un processo sono in attesa in modalità UserMode , tale processo diventa idoneo per essere scambiato sul disco. Pertanto, se un driver specificato UserMode come parametro WaitMode , il sistema operativo può scambiare il processo corrente purché anche ogni altro thread nello stesso processo sia in attesa di UserMode. Lo scambio di un intero processo nel disco include il paging degli stack del kernel. In attesa di un oggetto di sincronizzazione in cui è stato eseguito lo scambio del sistema operativo non è corretto. A un certo punto un thread deve venire insieme e segnalare l'oggetto di sincronizzazione. La segnalazione di un oggetto di sincronizzazione comporta la modifica dell'oggetto in IRQL = DISPATCH_LEVEL o versione successiva. Se si tocca o si scambia la memoria in DISPATCH_LEVEL o superiore, si è verificato un arresto anomalo del sistema.

    A partire da Windows 7, quando si seleziona l'opzione Controlli vari, Driver Verifier verifica che gli oggetti di sincronizzazione usati dal driver verificato per l'attesa in UserMode non siano allocati nello stack del kernel del thread corrente. Quando Driver Verifier rileva un'attesa non corretta, genera un 0xC4 controllo bug: DRIVER_VERIFIER_DETECTED_VIOLATION, con un valore del parametro 1 pari a 0x123.

  • Riferimenti all'handle del kernel non corretto

    Ogni processo di Windows ha una tabella handle. È possibile visualizzare la tabella handle come matrice di voci di handle. Ogni valore handle valido fa riferimento a una voce valida in questa matrice.

    Handle del kernel come handle valido per la tabella handle del processo di sistema. Handle utente come handle valido per qualsiasi processo, ad eccezione del processo di sistema.

    In Windows 7, Driver Verifier rileva che tenta di fare riferimento ai valori dell'handle del kernel non corretti. Questi difetti del driver vengono segnalati come controllo bug 0x93: INVALID_KERNEL_HANDLE se l'opzione Verifica vari driver è abilitata. In genere questo tipo di riferimento di handle non corretto significa che il driver ha chiuso l'handle già, ma sta tentando di continuare a usarlo. Questo tipo di difetto può causare problemi imprevedibili per il sistema perché il valore di handle a cui si fa riferimento potrebbe essere stato riutilizzato già da un altro driver non correlato.

    Se un driver del kernel ha chiuso di recente un handle del kernel e in seguito fa riferimento all'handle chiuso, Driver Verifier forza il controllo dei bug come descritto in precedenza. In questo caso l'output dell'estensione del debugger !htrace fornisce l'analisi dello stack per il percorso del codice che ha chiuso questo handle. Usare l'indirizzo del processo di sistema come parametro per !htrace. Per trovare l'indirizzo del processo di sistema, usare il comando !process 4 0 .

    A partire da Windows 7, Driver Verifier aggiunge un controllo a ObReferenceObjectByHandle. È ora vietato passare un handle di spazio utente con accesso KernelMode. Se viene rilevata una combinazione di questo tipo, Driver Verifier genera 0xC4 controllo bug: DRIVER_VERIFIER_DETECTED_VIOLATION, con un valore di parametro 1 pari a 0xF6.

Attivazione di questa opzione

È possibile attivare l'opzione Controlli vari per uno o più driver usando Gestione verifica driver o la riga di comando Verifier.exe. Per informazioni dettagliate, vedere Selezione delle opzioni di verifica driver.

  • Nella riga di comando

    Nella riga di comando l'opzione Controlli vari è rappresentata da Bit 11 (0x800). Per attivare controlli vari, usare un valore flag di 0x800 o aggiungere 0x800 al valore del flag. Ad esempio:

    verifier /flags 0x800 /driver MyDriver.sys
    

    L'opzione sarà attiva dopo l'avvio successivo.

    In Windows Vista e versioni successive di Windows è anche possibile attivare e disattivare Controlli vari senza riavviare il computer aggiungendo il parametro /volatile al comando . Ad esempio:

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

    Questa impostazione è effettiva immediatamente, ma viene persa quando si arresta o si riavvia il computer. Per informazioni dettagliate, vedere Uso delle impostazioni volatili.

    L'opzione Controlli vari è inclusa anche nelle impostazioni standard. Ad esempio:

    verifier  /standard /driver MyDriver.sys
    
  • Uso di Gestione verifica driver

    1. Avviare Gestione verifica driver. Digitare Verifier in una finestra del prompt dei comandi.

    2. Selezionare Crea impostazioni personalizzate (per sviluppatori di codice) e quindi fare clic su Avanti.

    3. Selezionare Seleziona singole impostazioni da un elenco completo.

    4. Selezionare Controlli vari.

    La funzionalità Controlli vari è inclusa anche nelle impostazioni standard. Per usare questa funzionalità, in Gestione verifica driver fare clic su Crea impostazioni standard.

Visualizzare i risultati

Per visualizzare i risultati dell'opzione Controlli vari, usare l'estensione !verifier nel debugger del kernel. Per informazioni su !verifier, vedere la documentazione relativa agli strumenti di debug per Windows .

Nell'esempio seguente l'opzione Controlli vari ha rilevato una struttura ERESOURCE attiva in memoria che il driver stava tentando di liberare, causando il controllo dei bug 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION. La visualizzazione del controllo bug 0xC4 include l'indirizzo di ERESOURCE e la memoria interessata.

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.

Per esaminare l'allocazione del pool, usare l'estensione del debugger !pool con l'indirizzo iniziale dell'allocazione del pool, 9655D468. Il flag 2 visualizza le informazioni di intestazione solo per il pool che contiene l'indirizzo specificato. Le informazioni di intestazione per altri pool vengono eliminate.

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

Per trovare informazioni sull'ERESOURCE, usare l'estensione del debugger !locks (!sessionxt*.locks) con l'indirizzo della struttura.

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

Resource @ 0x9655d4a8    Available
1 total locks

È anche possibile usare il comando debugger kb per visualizzare un'analisi dello stack delle chiamate che hanno causato l'errore. Nell'esempio seguente viene illustrato lo stack, inclusa la chiamata a ExFreePoolWithTag intercettata da 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