Partilhar via


Verificações automáticas

O Verificador de Driver executa as seguintes verificações sempre que estiver verificando um ou mais drivers. Não é possível ativar ou desativar essas verificações. A partir do Windows 10, versão 1709, essas verificações automáticas foram movidas para sinalizadores padrão relevantes. Como resultado, os usuários que habilitam o Verificador de Driver com os sinalizadores padrão não devem ver nenhuma redução nas verificações aplicadas.

Monitoramento de IRQL e rotinas de memória

Driver Verifier monitora o driver selecionado para as seguintes ações proibidas:

  • Aumentando o IRQL chamando KeLowerIrql

  • Baixando IRQL chamando KeRaiseIrql

  • Solicitando uma alocação de memória de tamanho zero

  • Alocando ou liberando pool paginado com IRQL > APC_LEVEL

  • Alocando ou liberando pool não paginado com IRQL > DISPATCH_LEVEL

  • Tentando liberar um endereço que não foi retornado de uma alocação anterior

  • Tentando liberar um endereço que já estava liberado

  • Adquirir ou liberar um mutex rápido com IRQL > APC_LEVEL

  • Adquirir ou liberar um bloqueio de rotação com IRQL não igual a DISPATCH_LEVEL

  • Liberação dupla de um bloqueio de rotação.

  • Marcar um pedido de atribuição MUST_SUCCEED. Tais pedidos nunca são permitidos.

Se o Verificador de Driver não estiver ativo, essas violações podem não causar uma falha imediata do sistema em todos os casos. O Verificador de Controladores monitora o comportamento do controlador e emite a verificação de erro 0xC4 se alguma dessas violações ocorrer. Consulte Bug Check 0xC4 (DRIVER_VERIFIER_DETECTED_VIOLATION) para obter uma lista dos parâmetros de verificação de erro.

Monitoramento de comutação de pilha

O Verificador de Driver monitora o uso da pilha pelo driver que está sendo verificado. Se o driver alternar sua pilha e a nova pilha não for nem uma pilha de threads nem uma pilha DPC, uma verificação de bug será emitida. (Esta será a verificação de bugs 0xC4 com o primeiro parâmetro igual a 0x90.) A pilha exibida pelo comando KB geralmente revelará o driver que executou essa operação.

Verificando a descarga do driver

Depois que um driver que está sendo verificado é descarregado, o Verificador de Driver executa várias verificações para certificar-se de que o driver foi limpo.

Em particular, o Driver Verifier procura:

  • Temporizadores não apagados

  • Chamadas de procedimento diferido pendentes (DPCs)

  • Listas lookaside que não foram excluídas

  • Threads de trabalho não excluídos

  • Filas não deletadas

  • Outros recursos semelhantes

Problemas como estes podem potencialmente fazer com que verificações de erros do sistema sejam emitidas algum tempo depois de o driver ser descarregado, e a causa desses erros pode ser difícil de determinar. Quando o Verificador de Driver está ativo, tais violações resultarão em uma verificação de erros 0xC7 sendo emitida imediatamente após o driver ser desativado. Consulte Bug Check 0xC7 (TIMER_OR_DPC_INVALID) para obter uma lista dos parâmetros de verificação de bugs.

Monitorando o uso da lista de descritores de memória (MDL)

No Windows Vista, o Verificador de Driver também monitora o driver selecionado para as seguintes ações proibidas:

  • Chamando MmProbeAndLockPages ou MmProbeAndLockProcessPages em um MDL que não tem os flags apropriados. Por exemplo, é incorreto chamar MmProbeAndLockPages para um MDL que foi criado usando MmBuildMdlForNonPagedPool.

  • Chamando MmMapLockedPages em um MDL que não tem os sinalizadores apropriados. Por exemplo, é incorreto chamar MmMapLockedPages para um MDL que já está mapeado para um endereço do sistema ou um MDL que não está trancado.

  • Chamando MmUnlockPages ou MmUnmapLockedPages em um MDL parcial, ou seja, um MDL criado usando IoBuildPartialMdl.

  • Chamando MmUnmapLockedPages num MDL que não está mapeado para um endereço de sistema.

Se o Verificador de Driver não estiver ativo, essas violações podem não fazer com que o sistema pare de responder imediatamente em todos os casos. O Verificador de Controladores monitora o comportamento do controlador e emite verificação de erro 0xC4 se alguma dessas violações ocorrer. Consulte Bug Check 0xC4 (DRIVER_VERIFIER_DETECTED_VIOLATION) para obter uma lista dos parâmetros de verificação de erros.

Alocação de objeto de sincronização da memória NonPagedPoolSession

A partir do Windows 7, o Verificador de Driver verifica se há objetos de sincronização na memória da sessão.

Os objetos de sincronização devem ser não pagináveis. Eles também devem residir no espaço de endereçamento virtual global do sistema.

Um driver gráfico pode alocar memória de sessão chamando APIs como EngAllocMem. Ao contrário do espaço de endereçamento global, o espaço de endereçamento da sessão é virtualizado para cada sessão do Terminal Server. Isso significa que o mesmo endereço virtual usado no contexto de duas sessões diferentes refere-se a dois objetos diferentes. O kernel do Windows deve ser capaz de acessar objetos de sincronização de qualquer sessão do Terminal Server. Tentar fazer referência a um endereço de memória de sessão de uma sessão diferente tem resultados imprevisíveis, como falhas do sistema ou corrupção silenciosa dos dados de outra sessão.

A partir do Windows 7, quando um driver verificado inicializa um objeto de sincronização chamando APIs como KeInitializeEvent ou KeInitializeMutex, o Verificador de Driver verifica se o endereço do objeto está dentro do espaço de endereçamento virtual da sessão. Se o Verificador de Driver detetar esse tipo de endereço incorreto, ele emitirá uma Verificação de Erro 0xC4: DRIVER_VERIFIER_DETECTED_VIOLATION, com o valor do parâmetro 1 de 0xDF.

O contador de referência do objeto altera-se de 0 para 1

A partir do Windows 7, o Verificador de Driver verifica se há classes adicionais de referências de objeto incorretas.

Quando o gerenciador de objetos do kernel do Windows cria um objeto, como um objeto File ou um objeto Thread, o contador de referência do novo objeto é definido como 1. O contador de referência é incrementado por chamadas para APIs como ObReferenceObjectByPointer ou ObReferenceObjectByHandle. O contador de referência é diminuído por cada chamada ObDereferenceObject para o mesmo objeto.

Depois que o contador de referência atinge o valor 0, o objeto se torna elegível para ser liberado. O gerenciador de objetos pode liberá-lo imediatamente ou liberá-lo mais tarde. Chamar ObReferenceObjectByPointer ou ObDereferenceObject e alterar o contador de referência de 0 para 1 significa incrementar o contador de referência de um objeto já liberado. Isso é sempre incorreto porque pode resultar em corromper a alocação de memória de outra pessoa.

Bloqueios ou atrasos no desligamento do sistema

A partir do Windows 7, o Verificador de Controladores gera uma interrupção no depurador do kernel se o encerramento do sistema não se concluir 20 minutos depois de iniciado. O Verificador de Driver atribui o início do desligamento do sistema como o momento em que o kernel do Windows começa a desligar seus vários subsistemas, como o Registro, Plug And Play ou os subsistemas do gerenciador de E/S.

Se um depurador do kernel não estiver conectado ao sistema, o Verificador de Driver emitirá um 0xC4 de verificação de bugs: DRIVER_VERIFIER_DETECTED_VIOLATION, com um valor de parâmetro 1 de 0x115, em vez desse ponto de interrupção.

Freqüentemente, um desligamento do sistema que não pode terminar em menos de 20 minutos indica que um dos drivers que está sendo executado nesse sistema está funcionando mal. A execução de !analyze -v a partir do depurador do kernel exibe o rastreamento de pilha do thread de trabalho do sistema responsável pelo desligamento. Você deve examinar esse rastreamento de pilha e determinar se o thread de desligamento está bloqueado por um dos drivers que estão sendo testados.

Às vezes, o sistema não pode desligar porque está sujeito a testes de esforço intensivos, mesmo que todos os drivers estejam funcionando corretamente. O usuário pode optar por continuar a execução após este ponto de interrupção do Verificador de Driver e verificar se o sistema eventualmente desliga.