Compartir a través de


Comprobador de aplicaciones: preguntas más frecuentes (P+F)

Preguntas generales

A continuación se muestra una lista de preguntas recibidas en torno al uso general del Comprobador de aplicaciones.

¿Qué es Application Verifier?

Application Verifier es una herramienta de comprobación en tiempo de ejecución que se usa para encontrar errores en aplicaciones de Microsoft Windows. Puesto que es una herramienta en tiempo de ejecución, se debe ejercer el código de la aplicación para comprobarlo. Por lo tanto, una buena cobertura de pruebas es esencial.

El escenario de uso típico de Application Verifier es habilitarlo para las aplicaciones de interés (consulte las preguntas siguientes sobre cómo hacerlo) y, a continuación, ejecutar todas las pruebas que ha escrito para la aplicación. Recibirá una notificación de cualquier error que se encuentre en forma de interrupción del depurador o una entrada de registro del comprobador.

Cómo desinstalar Application Verifier?

Para desinstalar application Verifier, acceda al panel de control haciendo clic en Inicio, seleccione Agregar o quitar programas, después Quitar un programa, haga clic en Comprobador de aplicaciones y, a continuación, haga clic en Quitar.

Cómo iniciar application Verifier?

Después de instalar Application Verifier, puede iniciarlo accediendo a él en la lista de programas O escribiendo Appverif.exe en una línea de comandos. Para ello, vaya a un símbolo del sistema o al cuadro Ejecutar del menú Inicio. Escriba appverif.exe y presione Entrar. Se iniciará Application Verifier.

El Appverifer.exe binario se instala en el directorio del sistema y se usa para realizar la configuración de la herramienta.

¿Dónde se almacenan los registros?

Los registros se almacenan en %USERPROFILE%\AppVerifierLogs.

¿Qué debo hacer si tengo problemas al usar el Comprobador de aplicaciones?

Asegúrese de que está ejecutando la versión más reciente. Considere la posibilidad de probar la misma aplicación en un equipo diferente o incluso en una versión de Windows.

¿Comprueba application Verifier el código administrado?

AppVerifier se preocupa por las interfaces entre el sistema operativo y la aplicación. Como resultado, a menos que el código administrado realice la interoperabilidad con las API nativas que tienen que ver con montones, identificadores, sección crítica, etc. Los casos de prueba no le proporcionarán ninguna interacción con las interfaces que se comprueban.

Se recomienda aprovechar los asistentes de depuración administrada para comprobar el código administrado. Obtenga más información sobre ellos en Depuración de código administrado mediante el depurador de Windows.

Preguntas sobre el depurador

A continuación se muestra la lista de preguntas recibidas con respecto al depurador.

¿Por qué he recibido un error que me indica que necesito un depurador?

La capa de comprobación Aspectos básicos de Application Verifier requiere que ejecute la aplicación en un depurador. Si no tiene un depurador asociado a la aplicación antes de seleccionar la prueba, recibirá un cuadro de diálogo que le recordará que deberá ejecutar la aplicación en un depurador para obtener la información registrada.

Cómo ejecutar mi aplicación en un depurador?

Consulte los temas de instalación y configuración del depurador: Introducción con la depuración de Windows

Cómo expansión de pila de prueba sin ninguna otra instrumentación?

En general, la expansión de la pila debe probarse realmente de forma aislada de otras capas de comprobación, incluido el montón. El motivo es el siguiente: cada capa de verificación "thunks" una API o un punto exportado con alguna rutina.

Por ejemplo, una llamada a CreateFileA será una llamada a appvocre. NS_SecurityChecks::CreateFileA, que podría llamar a appvcore! NS_FillePaths::CreateFileA que podría llamar al kernel32. CreateFileA, que podría llamar al comprobador. AVrfpNtCreateFile, que llamará a ntdll! NtCreateFile. Puede ver que la instrumentación ha agregado tres llamadas de función "apiladas", cada una de ellas puede consumir más pila.

En el caso siguiente, el LH-verifier.dll es "thunking" cada DllMain y la ruta de acceso de código del montón "instrumentada" agregará más uso de pila. Dado que el subproceso insertado del depurador no usa los valores predeterminados de IMAGE_NT_HEADERS, la pila confirmada inicialmente no será suficiente para completar el estado APC de un subproceso (un subproceso en el estado de APC ejecutó el código de inicialización).

Si desea usar Stack-Ckecs, probablemente la única capa de verificación que debe usar si FirstChanceAccessViolation.

Cuando se usa la extensión !avrf, obtengo 'Comprobador de aplicaciones no está habilitado para este proceso...'

Error completo recibido: Application verifier is not enabled for this process. Use appverif.exe tool to enable it.

Es probable que solo tenga habilitadas las capas de verificación de correcciones de compatibilidad (shim) o el montón en modo "puro". Estas son algunas de las posibles causas.

Preguntas sobre escenarios de prueba

A continuación se muestra una lista de preguntas recibidas en torno a diferentes escenarios de prueba.

¿Cómo puedo habilitar Application Verifier en mi servicio, pero no en otros?

Realice una copia de svchost.exe en el directorio System32 y llame a la copia "Mysvchost.exe".

Con regedit, abra HKLM\System\CurrentControlSet\Services\MyService.

Edite el valor "ImagePath", que será similar a "%SystemRoot%\system32\svchost.exe -k myservice" y cambie svchost.exe a "Mysvchost.exe".

Agregue "Mysvchost.exe" a la lista AppVerifier y compruebe las pruebas deseadas.

Reinicie el equipo.

Cómo ejecutar Application Verifier en una aplicación de 64 bits que se inicia desde una aplicación de 32 bits que se ejecuta en WOW64?

Versión simple: la regla de oro para habilitar la configuración del comprobador en una aplicación determinada es coincidir con el bit-ness de la herramienta y el proceso de destino. Es decir, use el appverif.exe de 32 bits para una aplicación de 32 bits (que se ejecuta en WoW64) y use el AppVerif.exe de 64 bits para el destino nativo de 64 bits nativo.

Versión larga: la configuración del comprobador de la aplicación es la unión adecuada de la configuración de "núcleo" y la configuración de "correcciones de compatibilidad".

Configuración principal: la configuración principal se almacena en Opciones de ejecución de archivos de imagen.

El valor "Debugger" se lee desde la aplicación de inicio. Por lo tanto, si desea tener devenv.exe de 32 bits iniciando my.exe de 64 bits y ejecutarlo en el depurador, debe usar la clave del Registro de 32 bits en WoW6432Node. Los demás valores, para un proceso de 32 bits, se leen de ambos lugares, tanto de IFEO nativo como de WoW6432Node.

El razonamiento es el siguiente: un proceso de 32 bits que se ejecuta en WoW es un proceso de 64 bits que ejecuta el bucle de emulación Wow64. Por lo tanto, cada proceso de 32 bits es primero un proceso de 64 bits y, a continuación, un proceso de 32 bits. IfEO de 64 bits habilitará el comprobador en el código de Wow64cpu.dll, mientras que el IFEO de 32 bits habilitará el comprobador en el código de 32 bits.

Desde el punto de vista del usuario final, verifier.dll se carga dos veces (una vez en el mundo de 64 bits, una vez en el mundo de 32 bits). Dado que la mayoría de las personas no se preocupan por comprobar wow64cpu.dll, el comportamiento más aceptado para los procesos de 32 bits es comprobar solo la parte de 32 bits. Es por eso que se aplica la regla de oro de "siempre coincide con el bit".

Cómo depurar mi servicio que se ejecuta en una estación de ventanas no interactiva

Para depurar un servicio que se ejecuta en una estación de ventanas no interactiva, haga lo siguiente (solo se aplica si usa ntsd/windbg):

Agregue una clave al Registro en HKLM\Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options. El nombre de esta clave debe ser el nombre del proceso (service.exe).

Cree un valor de REG_SZ denominado Debugger y establezca este valor en la ruta de acceso donde reside el depurador. Debe contener la ruta de acceso completa, no solo el nombre del depurador. El comando debe incluir la opción –server y un puerto o intervalo de puertos específico en el que el depurador debe escuchar. Un ejemplo es c:\debuggers\ntsd.exe –server tcp:port=5500:5600 –g –G.

Conéctese al servidor del depurador mediante la ejecución del depurador con una opción –remote. Un ejemplo es: windbg.exe –remote tcp:=localhost,port=55xx donde "xx" es un número comprendido entre 00 y 99 si usó un intervalo en el servidor.

¿AppVerifier detecta fugas? En Windows 7 y versiones posteriores, hay una opción de comprobación Fugas que detectará cuándo un proceso pierde memoria. En sistemas operativos anteriores, AppVerifier no prueba la aplicación para la detección de fugas, pero busca otros problemas de memoria.

¿Qué pruebas se recomiendan para los problemas de seguridad?

  • Montones
  • Asas
  • Bloqueos
  • Pilas (solo para servicios y procesos importantes que pueden quitar la máquina)

Tenga en cuenta que ObsoleteAPICalls simplemente escupirá una advertencia para cada llamada que ve a una API que aparece como obsoleta o en desuso en MSDN. Debe decidir un caso por caso si es importante que la aplicación cambie a las nuevas API. Algunas de las API son peligrosas y algunas simplemente han sido reemplazadas por una API más reciente con más opciones. Eche un vistazo a la sección "API peligrosas" de Escritura de código seguro, segunda adición para más.

Para las aplicaciones que necesitan ser altamente confiables, como servicios y programas de servidor, también debe habilitar la comprobación Stacks. Esto comprueba si el tamaño de confirmación de la pila es adecuado al deshabilitar el crecimiento de la pila. Si la aplicación se cierra inmediatamente con un desbordamiento de pila, significa que la aplicación debe volver a compilarse con un tamaño de confirmación de pila mayor. Si es evaluador y encuentra un problema con una aplicación mientras usa la comprobación Pilas, registre un error, asígnelo al desarrollador y siga probando.

Preguntas específicas de prueba

A continuación se muestra una lista de preguntas sobre las pruebas. Haga clic en la pregunta para ver la respuesta:

¿Son importantes las fugas de secciones críticas?

Cada vez que se pierde una sección crítica, se filtra lo siguiente: un identificador de eventos, una pequeña cantidad de grupo de kernel y una pequeña asignación de montón. Se limpiarán si se cierra el proceso.

Si se supone que el proceso se mantiene vivo durante mucho tiempo, estas fugas pueden morderte. Dado que las correcciones son muy fáciles en el 99 % de los casos (el desarrollador acaba de olvidar llamar a RtlDeleteCriticalSection) debe abordarlos.

¿Podemos tratar mediante programación con desbordamientos de pila?

No se garantiza el establecimiento de un controlador de excepciones en la función de subproceso inicial para detectar los posibles desbordamientos de pila que se pueden generar. Esto se debe a que el código que envía excepciones también necesita un poco de pila para ejecutarse sobre el registro de activación actual. Dado que acabamos de producir un error en la extensión de pila, es muy probable que se supere el final de la pila confirmada y se genere una segunda excepción al intentar enviar la primera. Una excepción de error doble finalizará el proceso incondicionalmente.

La prueba loaderLock da un error al llamar a DestroyWindow. ¿Por qué no puedo llamar a DestroyWindow en DllMain? No controla qué subproceso se va a desasociar. Si no es el mismo subproceso que creó la ventana, no se puede destruir la ventana. Por lo tanto, filtra la ventana y la próxima vez que la ventana recibe un mensaje, se bloquea porque el Wndproc se ha descargado.

Debe destruir la ventana antes de obtener la desasociación del proceso. El peligro no es que el usuario32 se descargue. El peligro es que te están descargando. Por lo tanto, el siguiente mensaje que recibe la ventana bloqueará el proceso porque user32 entregará el mensaje al Wndproc que ya no existe.

El sistema operativo Microsoft Windows tiene afinidad de subproceso. La desasociación de procesos no. El bloqueo del cargador no es realmente el gran problema; el problema es Dllmain. El proceso de desasociación es la última vez que el archivo DLL obtiene para ejecutar código. Debes deshacerte de todo antes de regresar. Pero dado que Windows tiene afinidad de subproceso, no puede limpiar la ventana si se encuentra en el subproceso incorrecto.

El bloqueo del cargador entra en la imagen si alguien tiene instalado un enlace global (por ejemplo, spy++ está en ejecución). En este caso, escriba un posible escenario de interbloqueo. De nuevo, la solución es destruir la ventana antes de obtener la desasociación del proceso.

¿Es costoso aumentar las confirmaciones de pila iniciales para evitar desbordamientos?

Al confirmar la pila, simplemente se reserva el espacio de archivos de página. No hay impacto en el rendimiento. No se usa realmente ninguna memoria física. El único costo adicional se produce si realmente toca el espacio de pila que ha confirmado. Pero esto ocurrirá de todos modos incluso si no confirma la pila por adelantado.

Veamos cuál sería el costo de hacer que todos los servicios se ejecuten en svchost.exe a prueba de balas. En una máquina de prueba, obtengo 9 svchost.exe procesos que tienen un total de 139 subprocesos. Si establecemos la pila predeterminada para cada subproceso en 32K, necesitaremos aproximadamente 32 00 x 200 ~ 6,4 Mb de espacio de archivo de página para confirmar todas las pilas por adelantado.

Se trata de un precio bastante pequeño para pagar la confiabilidad.

¿Qué ocurre con el tamaño de pila reservada?

Hay elementos interesantes, como el envío de excepciones en IA64/AMD64 que requiere una pila adicional "inesperada". Puede haber algún procesamiento que se produzca en los subprocesos de trabajo rpc cuyos requisitos de pila son intentos razonables de medirlos.

En primer lugar, debería hacerse una idea de todos los grupos de subprocesos que viven en el proceso. El grupo de subprocesos NT, con los subprocesos alertable-wait-threads a veces es especial, porque, por ejemplo, si usa un componente de base de datos de SQL, usará suspensión de alertas sobre un subproceso que es un destino de user-APC. Esto puede causar problemas con llamadas anidadas.

Una vez que conozca todos los grupos de subprocesos, obtenga una idea de cómo controlar sus requisitos de pila. Por ejemplo, RPC lee una clave del Registro para la confirmación de la pila. Los subprocesos de bomba WDM obtienen eso de la imagen. Para otros grupos de subprocesos, el kilometraje puede variar.

Cuando todos los subprocesos estén claros, puede realizar alguna acción. No tener un espacio reservado enorme ayuda a abordar la fragmentación del espacio solo si los subprocesos vienen y van muy a menudo. Si tiene un grupo de subprocesos estable que se encuentra en el control, es posible que también tenga una ventaja para reducir el espacio reservado. Realmente le ayudará a ahorrar espacio de direcciones para los montones y el espacio de direcciones para los usuarios.

¿Hay recomendaciones sobre cómo elegir el tamaño adecuado para LINKER_STACKCOMMITSIZE=?

El valor debe ser divisible por el tamaño de página (4k/8k según la CPU). Estas son algunas instrucciones para determinar el tamaño que necesita:

  1. Convierta todas las funciones recursivas con una profundidad potencial sin enlazar (o al menos la profundidad alta inducible por el usuario) en iterativa.

  2. Reduzca el uso de alloca. Use montón o safealloca.

  3. Ejecute Prefast con una comprobación de tamaño de pila reducida (por ejemplo, 8 k). Corrija esas funciones marcadas como si usaran demasiada pila.

  4. Establezca la confirmación de pila en 16 000.

  5. Ejecute en un grupo de pruebas del depurador con la comprobación "Pilas" del comprobador de aplicaciones.

  6. Cuando vea desbordamiento de pila, determine los peores infractores y corrija. (Consulte el paso 5).

  7. Cuando no se puede reducir el uso de la pila más de 8k. Si tiene un error de > 64 k, vuelva a disminuir a 64 k y vea el paso 6. De lo contrario, vaya al paso 5.

¿Cuáles son los requisitos de memoria para la prueba del montón?

Para las pruebas de montón completas, necesitará 256 MB de RAM y al menos un archivo de página de 1 GB. Para las pruebas de montón normales, necesitará al menos 128 MB de RAM. No hay requisitos específicos de procesador o disco.

¿Por qué recibo una parada de ALL_ACCESS?

Cualquier aplicación que use _ALL_ACCESS represente el objeto al que accede de forma no auditable porque el registro de auditoría no reflejará lo que realmente ha hecho con el objeto , solo lo que se le ha pedido que haga con el objeto .

Esta condición crea un camuflaje para un ataque más desviado. Un administrador que examina una actividad de ataque en curso no verá nada malo con la persona que solicita ALL_ACCESS en la clave X, ya que una aplicación determinada siempre lo hace. El administrador pensará que "es probable que la persona esté ejecutando Word". El administrador no puede decir que un hacker ha penetrado mi cuenta y ahora está sondeando el sistema para determinar qué acceso tengo, que puede explotar por sus fines nefastos. Las posibilidades son infinitas.

El problema de ACL con ALL_ACCESS es que siempre debe concederlo. Si queremos denegar algún día el acceso DELETE a una determinada clave, no sería posible. Aunque en realidad no estaba eliminando la clave, se interrumpiría la aplicación porque solicitaría la eliminación del acceso.

¿Por qué no obtengo ningún registro del montón y las pruebas de bloqueo?

Estas pruebas son capas de verificación integradas en el sistema operativo (y no en el paquete) y notifican errores en un depurador. Si ejecuta una aplicación con esas pruebas habilitadas y no tiene bloqueos, no notifica ningún problema.

Si se encuentra en bloqueos, será necesario ejecutarse en un depurador o pasar la aplicación a un desarrollador para probarla más detenidamente.

¿Por qué la inyección de errores no funciona?

La probabilidad de inyección de errores se cambió a partes por millón en compilaciones de AppVerifier publicadas después de febrero de 2007 en función de los comentarios de los clientes. Por lo tanto, una probabilidad de 0n20000 es del 2 %, 0n500000 es del 50 % y así sucesivamente.

!avrf –flt debugger extensión se puede usar para cambiar la probabilidad sobre la marcha en el depurador. Sin embargo, la comprobación de simulación de recursos bajos para que el proceso funcione.

La extensión del depurador !avrf forma parte exts.dll que se incluye con el paquete del depurador. Los cambios en !avrf que admiten el cambio de probabilidad se encuentran en el paquete del depurador más reciente. Si tiene problemas con la inyección de errores, actualice los depuradores y el paquete AppVerifier.

¿Por qué el Comprobador de fugas no notifica ciertas fugas de recursos?

El Comprobador de fugas no notifica pérdidas de recursos mientras se carga un módulo DLL o EXE. Cuando se descarga un módulo, el comprobador de fugas emite una detención si no se ha liberado alguno de los recursos asignados por el módulo.

Para inspeccionar los recursos asignados por un archivo DLL o EXE cargados, use la extensión !avrf -leak del depurador.

Consulte también

Comprobador de aplicaciones: información general

Comprobador de aplicaciones: características

Comprobador de aplicaciones: pruebas de aplicaciones

Comprobador de aplicaciones: pruebas dentro del comprobador de aplicaciones

Comprobador de aplicaciones: códigos y definiciones de detención

Comprobador de aplicaciones: se detiene la depuración del comprobador de aplicaciones