Establezca el seguimiento de puntos de interrupción en Windbg para abrir el módulo del interruptor de depuración remota del programa C ++

Tabla de contenido

1. Depuración dinámica de Windbg

2. Establecer puntos de interrupción en Windbg

2.1 Establecer un punto de interrupción en la entrada de la función

2.2 Establecer un punto de interrupción en una línea dentro de la función

3. Establezca un punto de interrupción para rastrear la llamada para abrir la interfaz del interruptor de depuración remota

3.1, escribir código de demostración

3.2 Establezca un punto de interrupción llamando a la interfaz SetRemoteDebugOn en Windbg para el seguimiento

4. Finalmente


Resumen de desarrollo de funciones comunes de VC++ (lista de artículos de la columna, bienvenido a suscribirse, actualización continua...) https://blog.csdn.net/chenlycly/article/details/124272585 Tutorial de la serie de solución de problemas de excepciones de software C++ desde la entrada hasta el dominio (artículo de la columna lista, bienvenido a suscribirse, seguir actualizando...) https://blog.csdn.net/chenlycly/article/details/125529931 Colección de casos de herramientas de análisis de software C++ (actualización) https://blog.csdn.net/chenlycly/ category_12279968.html?spm=1001.2014.3001.5482Recientemente        , durante las pruebas, descubrimos que nuestro software enciende automáticamente el interruptor de depuración remota después de que se inicia, pero por razones de seguridad, el interruptor de depuración remota debe ser operado manualmente por el usuario en el configuración, y no se puede hacer automáticamente Abrir. Debido a que nuestro módulo de software tiene cientos de bibliotecas dll e involucra a varios equipos de desarrollo, es imposible determinar qué módulo se abre automáticamente Más tarde, pensé que podríamos usar la depuración dinámica de Winddbg para establecer puntos de interrupción para localizar rápidamente el problema. Este artículo describe el proceso de solución de problemas para este problema en detalle.

1. Depuración dinámica de Windbg

       En general, cuando se solucionan problemas de excepciones de software de C++, si hay un archivo de volcado que contiene el contexto de la excepción, le damos prioridad al uso de Windbg para abrir el archivo de volcado para el análisis estático. Si no se genera un archivo de volcado cuando ocurre una excepción, adjunte Windbg al proceso de destino (o use Windbg para iniciar el programa de destino) para la depuración dinámica.

       Windbg se usa principalmente para analizar las excepciones del software C++, además, también puede ayudarnos a localizar problemas durante la depuración dinámica. Podemos establecer un punto de interrupción (establecer la dirección del segmento de código) en Windbg para la depuración dinámica para rastrear la pista de ejecución del programa. En este caso, el problema se localiza estableciendo un punto de interrupción en Windbg.

        Hay dos formas de usar Windbg para la depuración dinámica:

1) Adjunte Windbg directamente al proceso de destino que ya se está ejecutando . Haga clic en Archivo->Adjuntar a un proceso... en la barra de menú.
2) Puede usar Windbg directamente para iniciar el programa de destino . Haga clic en Archivo->Abrir ejecutable... en la barra de menú. Use este método si el problema es durante el inicio del programa.

       En este problema de proyecto, la operación de encender automáticamente el interruptor de depuración remota debe realizarse cuando se inicia el programa, por lo que debemos usar Windbg para iniciar el programa.

2. Establecer puntos de interrupción en Windbg

       Puede usar el comando bp para establecer un punto de interrupción, puede establecer un punto de interrupción en la entrada de la función o puede establecer un punto de interrupción dentro de la función. Establezca un punto de interrupción en una determinada línea dentro de la función y podrá ver el valor de la variable local en la función en el momento de la interrupción. El valor de la variable puede ser una pista importante para la resolución de problemas.

2.1 Establecer un punto de interrupción en la entrada de la función

      Establezca un punto de interrupción en la entrada de la función, solo use el nombre de la función directamente, y el nombre de la función es la primera dirección de la función en el segmento de código. Tomando la función SetRemoteDebugOn en la biblioteca netdll.dll como ejemplo, el comando para establecer un punto de interrupción es:

bp netdll!SetRemoteDebugOn

Entre ellos, netdll es el nombre de la biblioteca dll (sin el sufijo .dll) y SetRemoteDebugOn es el nombre de la función.

       La función SetRemoteDebugOn aquí es una función de exportación de la biblioteca netdll.dll, y el símbolo de la función está abierto al mundo exterior, sin el archivo de biblioteca de símbolos pdb. Si la función a configurar es una función dentro de la biblioteca dll, no una función de exportación de la biblioteca dll, debe configurar el archivo pdb de la biblioteca en Windbg, porque la función interna necesita el símbolo de función en el archivo pdb, de lo contrario Windbg no puede reconocerlo.

2.2 Establecer un punto de interrupción en una línea dentro de la función

       Cierta línea dentro de la función mencionada aquí no es una determinada línea de código fuente de C++, sino una determinada línea de código ensamblador en el archivo binario. Debido a que el programa finalmente ejecuta el archivo binario, ejecuta el código binario en el archivo binario (equivalente al código ensamblador, el código ensamblador es el mnemotécnico del código binario).

       De hecho, es para agregar un valor de compensación de compensación sobre la base de la función (la función es la primera dirección de la función en el segmento de código). Pero este valor de compensación no se escribe al azar, debe usar IDA para abrir el archivo binario y verificar el código de ensamblaje para determinarlo. Debido a que las diferentes instrucciones de ensamblaje tienen diferentes longitudes, solo se puede establecer la dirección de la instrucción de ensamblaje y no se puede establecer el valor de la dirección entre las direcciones de dos instrucciones de ensamblaje; de ​​lo contrario, no será válido y no se alcanzará el punto de interrupción.

       Tomando la biblioteca de código abierto libcurl.dll como ejemplo, usamos IDA Pro para abrir el archivo de la biblioteca para ver el código ensamblado desensamblado , encontrar la función interna easy_perform de la biblioteca y establecer un punto de interrupción en la línea 10007D2D en esta función, como se muestra en la figura:

Para ver los símbolos de las funciones internas de la biblioteca en IDA, debe tomar el archivo pdb y colocarlo en el mismo directorio que libcurl.dll, e IDA lo cargará automáticamente. Para saber cómo utilizar la herramienta de desmontaje de IDA, puede consultar mi artículo anterior:

Instrucciones detalladas para usar la herramienta de desensamblaje IDA https://blog.csdn.net/chenlycly/article/details/120635120        Para establecer un punto de interrupción en la línea 10007D2D especificada, debe calcular el desplazamiento de esta línea de instrucciones de ensamblaje en relación con el función donde se encuentran

0x10007D2D - 0x10007D10 = 0x1D

Entonces, el comando WIndbg para establecer un punto de interrupción es:

bp libcurl!fácil_perform+0x1D

       También se puede ver en la figura a continuación que la longitud de la memoria del segmento de código ocupada por diferentes instrucciones de ensamblaje es diferente:

Tenga en cuenta que la dirección mencionada aquí es la dirección del segmento de código, que es la dirección ocupada por el código binario (código ensamblador) del archivo binario. La dirección del segmento de código debe distinguirse de la dirección del segmento de datos, y la memoria ocupada por la variable es la memoria del segmento de datos. Con respecto a las particiones de memoria de los programas C++, puede consultar el artículo anterior:
Los ejemplos explican las cinco principales particiones de memoria de los programas C++ https://blog.csdn.net/chenlycly/article/details/120958761         Además, queremos hablar sobre la importancia de entender el código ensamblador, desde aquí también podemos ver una pequeña pista. La familiaridad con el código ensamblador no solo puede ayudar a solucionar problemas del programa C++, sino también comprender los detalles de programación o los detalles de ejecución del código que los lenguajes de alto nivel no pueden entender. Si desea comprender los conocimientos básicos de ensamblaje necesarios para solucionar problemas de software de C++, puede consultar mi artículo anterior:
Resumen de los conocimientos de ensamblaje necesarios para analizar las excepciones de software de C++ https://blog.csdn.net/chenlycly/article/details /124758670

3. Establezca un punto de interrupción para rastrear la llamada para abrir la interfaz del interruptor de depuración remota

       Para rastrear qué módulo activa automáticamente el interruptor de depuración remota, siempre que la biblioteca subyacente se use para activar el nombre de la función de depuración remota y el nombre del módulo, puede establecer un punto de interrupción en Windbg para realizar un seguimiento de la depuración dinámica.

       No es conveniente mostrar aquí los módulos e interfaces relevantes en el proyecto, y para facilitar la explicación de los cursos de video en el futuro, escribí especialmente algunos códigos de prueba para describir el proceso de seguimiento de todo el problema.

3.1, escribir código de demostración

       Utilice Visual Studio para crear un programa principal MFC TestDlg.exe y una biblioteca dinámica netdll.dll que contenga la interfaz de depuración remota SetRemoteDebugOn. Llame a la interfaz API SetRemoteDebugOn para habilitar la depuración remota en la biblioteca netdll.dll en la función de respuesta del botón Prueba del programa principal TestDlg.exe.

       La interfaz API SetRemoteDebugOn en la biblioteca dinámica netdll.dll se define de la siguiente manera:

El código para llamar a SetRemoteDebugOn mediante la función de respuesta del botón Test en el programa principal TestDlg.exe es el siguiente:

3.2 Establezca un punto de interrupción llamando a la interfaz SetRemoteDebugOn en Windbg para el seguimiento

       Use Windbg para iniciar TestDlg.exe y use Windbg para depurar dinámicamente. Debido a que la llamada final es la interfaz SetRemoteDebugOn en el módulo netdll.dll para activar el interruptor de depuración remota, simplemente establezca un punto de interrupción en la entrada de la interfaz SetRemoteDebugOn, es decir: bp netdll!SetRemoteDebugOn, como se muestra a continuación:

Usamos el comando bl para ver la lista de puntos de interrupción actuales como se muestra arriba.

       Luego haga clic en el botón Prueba en la ventana del programa TestDlg.exe:

Llame a la interfaz SetRemoteDebugOn en la función de respuesta del botón, de modo que se alcance el punto de interrupción establecido ahora y se interrumpa Windbg. Use el comando kn para ver la pila de llamadas de función en este momento:

Sabemos qué módulo llama a la interfaz SetRemoteDebugOn para desactivar la depuración remota. Como se puede ver en la figura anterior, el módulo TestDlg.exe llama a la interfaz que habilita el interruptor de depuración remota, y también se puede ver que es llamado por la función CTestDlgDlg::OnBnClickedTest en el módulo TestDlg.exe.

4. Finalmente

       En este ejemplo, al establecer puntos de interrupción en Windbg, puede ubicar rápidamente la información del módulo y la función que habilita el interruptor de depuración remota. La función de depuración dinámica de Windbg es realmente útil. Espero que este artículo pueda brindarle algo de inspiración y referencia.

Supongo que te gusta

Origin blog.csdn.net/chenlycly/article/details/130058430
Recomendado
Clasificación