Condividi tramite


Controlli vari

L'opzione Vari controlli di Driver Verifier monitora il driver per individuare errori comuni che causano il crash del driver o del sistema, come ad esempio liberare memoria che contiene ancora oggetti del 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 contenente elementi di lavoro accodati tramite IoQueueWorkItem.

  • Risorse attive nella memoria liberata. Il driver chiama ExFreePool per liberare un blocco di pool contenente 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:

    • Un driver che tenta di disinstallare senza deregistrare il callback WMI.

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

    • Un driver che tenta di scaricare senza annullare la registrazione dei suoi provider in modalità kernel ETW.

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

  • Errori relativi agli handle del kernel. (Windows Vista e versioni successive) L'abilitazione dell'opzione Controlli vari consentirà anche l'abilitazione del tracciamento degli handle per il processo di sistema per facilitare l'indagine delle perdite di handle nel kernel e del Bug Check 0x93: INVALID_KERNEL_HANDLE. Con il tracciamento degli handle abilitato, il kernel raccoglierà gli stack trace per le operazioni di apertura e chiusura recenti degli 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 relativa agli strumenti di debug per Windows.

  • Handle in modalità utente con accesso in modalità kernel A partire da Windows 7, quando si seleziona l'opzione Verifiche varie, 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 il controllo bug 0xC4, con un valore del parametro 1 pari a 0xF6.

  • Modalità utente: 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 rimossi dal working set o paginati su 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, è necessario 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 specifica UserMode come parametro WaitMode, il sistema operativo può scambiare il processo corrente purché ogni altro thread nello stesso processo sia anch'esso in attesa in modalità UserMode. Lo scambio di un intero processo al disco include il paging degli stack del kernel. In attesa di un oggetto di sincronizzazione che il sistema operativo ha sostituito non è corretto. A un certo punto un thread deve intervenire e segnalare l'oggetto di sincronizzazione. La segnalazione di un oggetto di sincronizzazione comporta la modifica dell'oggetto da parte del kernel di Windows a un livello IRQL uguale o superiore a DISPATCH_LEVEL. Se si tocca o si scambia memoria esaurita 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 di questo tipo non corretta, genera un Bug Check 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION, con un parametro 1 di 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 di handle valido fa riferimento a una voce valida in questa matrice.

    Un handle del kernel è un handle valido per la tabella degli handle del processo di sistema. Un handle utente è un handle valido per qualsiasi processo, tranne il processo di Sistema.

    In Windows 7, Driver Verifier rileva tentativi di riferimento a valori di handle del kernel non corretti. Questi difetti del driver vengono segnalati come bug check 0x93: INVALID_KERNEL_HANDLE se l'opzione Verificatore driver - Controlli vari è abilitata. Di solito un riferimento di handle non corretto significa che il driver ha già chiuso l'handle e 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 recentemente chiuso un handle del kernel e in seguito fa riferimento all'handle chiuso, Driver Verifier forza la verifica del bug come descritto in precedenza. In questo caso l'output dell'estensione del debugger !htrace fornisce la traccia 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 dello spazio utente con accesso in modalità kernel. Se viene rilevata una combinazione di questo tipo, Driver Verifier genera Controllo bug 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION, con un valore del parametro 1 pari a 0xF6.

Attivazione di questa opzione

È possibile attivare l'opzione Verifiche Varie per uno o più driver utilizzando la Gestione Verifica Driver o il comando da riga di comando Verifier.exe. Per informazioni dettagliate, vedere Selezione delle Opzioni del Verificatore Driver.

  • Alla riga di comando

    Nella riga di comando, l'opzione Controlli vari è rappresentata da Bit 11 (0x800).At the command line, the Miscellaneous Checks option is represented by Bit 11 (0x800). Per attivare controlli vari, usare un valore flag di 0x800 o aggiungere 0x800 al valore del flag. Per 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. Per 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 di impostazioni volatili.

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

    verifier  /standard /driver MyDriver.sys
    
  • Uso del Driver Verifier Manager

    1. Avviare il Manager 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 Selezionare le singole impostazioni da un elenco completo.

    4. Selezionare Controlli Miscellanei.

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

Visualizzazione dei 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 schermata del controllo bug 0xC4 include l'indirizzo dell'ERESOURCE e della 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 analizzare 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 su ERESOURCE, usare l'estensione del debugger !locks (!kdext*.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