Herramientas de verificación estática y dinámica
Hay dos tipos básicos de herramientas de comprobación:
Las herramientas de comprobación estática examinan el código del controlador sin ejecutar el controlador. Dado que estas herramientas no se basan en pruebas que ejercen el código, pueden ser extremadamente exhaustivas. En teoría, las herramientas de comprobación estática pueden examinar todo el código del controlador, incluidas las rutas de acceso de código que rara vez se ejecutan en la práctica. Sin embargo, dado que el controlador no se está ejecutando realmente, podrían generar resultados falsos positivos. Es decir, podrían notificar un error en una ruta de acceso de código que podría no producirse en la práctica.
Las herramientas de comprobación dinámica examinan el código del controlador mientras se ejecuta el controlador, normalmente interceptando las llamadas a rutinas de soporte técnico de controladores que se usan habitualmente y sustituyendo las llamadas a sus propias versiones de comprobación de errores de las mismas rutinas. Dado que el controlador se está ejecutando realmente mientras las herramientas dinámicas realizan la comprobación, los resultados falsos positivos son poco frecuentes. Sin embargo, dado que las herramientas dinámicas detectan solo las acciones que se producen mientras supervisan el controlador, las herramientas pueden perder ciertos defectos del controlador si la cobertura de pruebas del controlador no es adecuada. Al mismo tiempo, mediante el uso de información disponible en tiempo de ejecución, por ejemplo, información más difícil de extraer estáticamente del código fuente, las herramientas de verificación dinámica pueden detectar determinadas clases de errores de controlador que son más difíciles de detectar con herramientas de análisis estáticos.
El procedimiento recomendado es usar una combinación de herramientas de comprobación estáticas y dinámicas. Las herramientas estáticas permiten comprobar las rutas de acceso de código difíciles de ejercer en la práctica, mientras que las herramientas dinámicas encuentran errores graves que se producen en el controlador.
Importante
El Programa de compatibilidad de hardware de Windows necesita CodeQL para pruebas de logotipo de herramientas estáticas (STL) en nuestros sistemas operativos de cliente y servidor. Seguiremos manteniendo el servicio de SDV y CA en productos anteriores. Se recomienda a los partners a comprobar los requisitos de CodeQL para las pruebas de logotipo de herramientas estáticas. Para obtener más información sobre el uso de CodeQL, consulte CodeQL y la prueba de logotipo de herramientas estáticas.
Encuesta de herramientas de verificación
Las siguientes herramientas de comprobación se describen en WDK y se recomiendan para su uso por parte de desarrolladores y evaluadores de controladores. Se muestran en el orden en que se usan normalmente.
Tan pronto como se compila el código
- CodeQL, de GitHub, es un potente motor de análisis de código semántico, y la combinación de un amplio conjunto de consultas de seguridad de alto valor junto con una plataforma robusta lo convierten en una herramienta muy valiosa para proteger el código del controlador. Para obtener más información, consulte CodeQL y la prueba del logotipo de herramientas estáticas.
Herramientas estáticas adicionales
En función de la versión de Windows desde la que cree un controlador, es posible que se necesiten otras herramientas estáticas.
Análisis de código para controladores es una herramienta de comprobación estática que se ejecuta en tiempo de compilación. El análisis de código para controladores puede comprobar los controladores escritos en C/C++ y el código administrado. Examina el código de cada función de un controlador de forma independiente, por lo que puede ejecutarlo tan pronto como pueda compilar el controlador. Se ejecuta relativamente rápidamente y usa pocos recursos.
Las características básicas de la herramienta Análisis de código de Visual Studio detectan errores generales de codificación, como no comprobar los valores devueltos. Las características específicas del controlador detectan errores de codificación de controladores más sutiles, como dejar campos sin inicializar en un IRP copiado y no restaurar un IRQL modificado al final de una rutina.
El comprobador de controladores estáticos (SDV) es una herramienta de comprobación estática que se ejecuta en tiempo de compilación y comprueba el código del controlador en modo kernel escrito en C/C++. Se incluye en WDK y se puede iniciar desde Visual Studio Ultimate 2012 o desde una ventana del símbolo del sistema de Visual Studio mediante MSBuild.
En función de un conjunto de reglas de interfaz y un modelo del sistema operativo, el comprobador de controladores estáticos determina si el controlador interactúa correctamente con el kernel del sistema operativo Windows. El comprobador de controladores estáticos es extremadamente exhaustivo: explora todas las rutas de acceso accesibles en el código fuente del controlador y las ejecuta simbólicamente. Por lo tanto, encuentra errores que no se detectan mediante ningún otro método convencional de pruebas de controladores.
Importante
SDV ya no es compatible y SDV no está disponible en las versiones de WDK o EWDK de Windows 24H2. No está disponible en WDK más reciente que la compilación 26017 y no se incluye en windows 24H2 RTM WDK.
SDV todavía se puede usar descargando windows 11, versión 22H2 EWDK (publicada el 24 de octubre de 2023) con las herramientas de compilación de Visual Studio 17.1.5 desde Descargar el Kit de controladores de Windows (WDK). Solo se recomienda el uso de Enterprise WDK para ejecutar SDV. No se recomienda usar versiones anteriores del WDK estándar junto con las versiones recientes de Visual Studio, ya que esto probablemente provocará errores de análisis.
En el futuro, CodeQL será la herramienta de análisis estático principal para los controladores. CodeQL proporciona un lenguaje de consulta eficaz que trata el código como una base de datos que se va a consultar, lo que facilita la escritura de consultas para comportamientos, patrones y mucho más específicos.
Para obtener más información sobre el uso de CodeQL, consulte CodeQL y la prueba de logotipo de herramientas estáticas.
Cuando se ejecuta el controlador
Use las siguientes herramientas de comprobación dinámica en cuanto se compila el controlador y se ejecuta sin errores obvios.
El Comprobador de controladores es una herramienta de verificación dinámica escrita especialmente para controladores de Windows. Incluye varias pruebas que se pueden ejecutar en varios controladores simultáneamente. El comprobador de controladores es tan eficaz al encontrar errores graves en los controladores que han experimentado desarrolladores y evaluadores de controladores configuran el Comprobador de controladores para que se ejecute cada vez que su controlador se ejecute en un entorno de desarrollo o prueba. El comprobador de controladores está incluido en Windows. Al habilitar el Comprobador de controladores para un controlador, también debe ejecutar varias pruebas en el controlador. El comprobador de controladores puede detectar determinados errores de controlador que son difíciles de detectar mediante herramientas de comprobación estáticas por sí solas. Entre los ejemplos de estos tipos de errores se incluyen los siguientes:
Saturaciones del búfer del grupo de kernels. Cuando el controlador comprobado asigna búferes de memoria del grupo, el Comprobador de controladores los protege con una página de memoria no accesible. Si el controlador intenta usar la memoria más allá del final del búfer, el Comprobador de controladores emitirá una comprobación de errores.
Usar memoria después de liberarla. Los bloques de memoria de grupo especiales usan su propia página de memoria y no comparten páginas de memoria con otras asignaciones. Cuando el controlador libera el bloque de memoria del grupo, la página de memoria correspondiente deja de ser accesible. Si el controlador intenta usar esa memoria después de liberarla, el controlador se bloqueará al instante.
Uso de la memoria paginable mientras se ejecuta en IRQL con privilegios elevados. Cuando un controlador comprobado genera irQL en DISPATCH_LEVEL o superior, el comprobador de controladores recorta toda la memoria paginable del conjunto de trabajo del sistema, simulando un sistema bajo presión de memoria. El controlador se bloquea si intenta usar una de estas direcciones virtuales paginables.
Simulación de recursos bajos. Para simular un sistema en condiciones de recursos bajos, el comprobador de controladores puede producir un error en varias API de kernel del sistema operativo llamadas por los controladores.
Fugas de memoria. El comprobador de controladores realiza un seguimiento de las asignaciones de memoria realizadas por un controlador y se asegura de que la memoria se libere antes de que se descargue el controlador.
Operaciones de E/S que tardan demasiado tiempo en completarse o cancelarse. El comprobador de controladores puede probar la lógica del controlador para responder a STATUS_PENDING valores devueltos de IoCallDriver.
Comprobación de cumplimiento de DDI. (Disponible a partir de Windows 8) El comprobador de controladores aplica un conjunto de reglas de interfaz de controlador de dispositivo (DDI) que comprueban la interacción adecuada entre un controlador y la interfaz de kernel del sistema operativo. Estas reglas corresponden a reglas que usa el comprobador de controladores estáticos para analizar el código fuente del controlador. Si el comprobador de controladores encuentra un error cuando la comprobación de cumplimiento de DDI está habilitada, ejecute El comprobador de controladores estáticos y seleccione la misma regla que provocó el error. El comprobador de controladores estáticos puede ayudarle a localizar la causa del defecto en el código fuente del controlador.
Kernel Address Sanitizer (KASAN) es una tecnología de detección de errores compatible con controladores de Windows que le permite detectar varias clases de accesos de memoria ilegales, como desbordamientos de búfer y eventos de uso después de liberar.
El Comprobador de aplicaciones es una herramienta de verificación dinámica para aplicaciones y controladores en modo de usuario escritos en C/C++. No comprueba el código administrado.