Configuración de la depuración de QEMU Kernel-Mode mediante EXDI

En este tema se describe cómo configurar QEMU Kernel-Mode Depuración mediante EXDI. El depurador de Windows admite la depuración del kernel de un entorno de QEMU mediante EXDI. En este documento se describen los pasos necesarios para establecer una sesión de RSP de GdbServer entre la ExdiGdbSrv.dll (cliente del servidor GDB) y el servidor GDB de QEMU.

El escenario descrito usa una máquina virtual Windows x64 y un servidor GDB de QEMU, que también se ejecuta en Windows.

Es posible conectarse a otros sistemas operativos que actúan como host, como Linux. QEMU, el software de virtualización y emulación de máquina, se puede ejecutar en numerosas arquitecturas, como x64 y Arm64. El servidor de depuración exdiGdb también admite otros procesadores, por ejemplo, es posible usar WinDbg para depurar QEMU que se ejecuta en Arm64. Esto proporciona varias opciones para depurar máquinas virtuales Windows, por lo que la máquina virtual Windows se puede depurar mediante el servidor de GDB de QEMU disponible conectado al cliente de servidor GDB del host del depurador EXDI GDB.

Para obtener información general sobre cómo configurar y solucionar problemas de conexiones EXDI, vea Configuring the EXDI Debugger Transport.

Nota

EXDI es una forma avanzada y especializada de depuración para entornos específicos. El uso de una conexión KDNET estándar es más fácil de configurar y se recomienda. Para configurar la depuración de red automáticamente, consulte Configuración de la depuración automática del kernel de red KDNET.

Servidor COM de EXDI

EXDI es una interfaz que permite extender WinDbg agregando compatibilidad con depuradores de hardware (por ejemplo, basados en JTAG o basados en GdbServer). En el diagrama siguiente se muestra el rol de EXDI-GdbServer.

Diagrama de pila que muestra el rol de EXDI-GdbServer con WinDbg-DbgEng en la parte superior, una interfaz EXDI y un servidor COM EXDI que se comunica con un servidor GDB.

Importante

Dado que EXDI no usa el protocolo KDNET, el depurador conectado tiene significativamente menos información sobre lo que se ejecuta en el equipo y muchos comandos funcionarán de forma diferente o pueden no funcionar en absoluto. El acceso a símbolos privados para el código que se está depurando puede ayudar al depurador a comprender mejor la ejecución del código de los sistemas de destino. Para obtener más información, vea Símbolos públicos y privados.

Configuración de una conexión del depurador a una imagen de Windows en QEMU

En este tema, describiremos el proceso para asociar a una imagen de Windows virtual de QEMU que se ejecuta en Windows.

  1. Descargue e instale QEMU en Windows.
  2. Configure una imagen de Windows virtual QEMU de destino para que se inicie con la red necesaria y la configuración de BIOS/UEFI para la depuración.
  3. Inicie el entorno de QEMU mediante el script de inicio configurado.
  4. Inicie gdbserver en QEMU.
  5. Compruebe la conectividad de red y busque y registre la dirección IP de la imagen de destino. (Dirección IP de HOST predeterminada de 1.2.3.4).
  6. Descargue e instale las herramientas de depuración de Windows en el sistema host.
  7. Descargue, compile, registre y configure el servidor EXDI para QEMU ubicado en GitHub.
  8. Configure el host del depurador (WinDbg) editando los archivos XML de configuración exDI.
  9. Inicie WinDbg mediante la línea de comandos para conectarse al servidor EXDI.
  10. Use WinDbg para depurar la imagen de Windows QEMU de destino.

Descargar e instalar QEMU en Windows

QEMU es un emulador de máquina genérico y código abierto y virtualizador que provoca la traducción dinámica. Cuando QEMU se usa como emulador de máquina, puede ejecutar los programas y del sistema operativo realizados para un procesador (como arm64) en otra máquina (un equipo x64). También puede ejecutar o hospedar imágenes de máquinas virtuales para diferentes sistemas operativos (Windows/Linux/Mac).

QEMU puede usar otros hipervisores como KVM para usar extensiones de CPU (HVM) para la virtualización. Cuando QEMU se usa como virtualizador, QEMU logra rendimientos casi nativos mediante la ejecución del código invitado directamente en la CPU del host. QEMU puede aprovechar las características del hipervisor del sistema operativo para descargar la emulación de CPU y MMU en hardware real.

Descarga e instalación de QEMU

En este tutorial, QEMU para Windows x64 se instalará en un equipo x64 en el que también se ejecutará el depurador de Windows.

Descargue QEMU desde la página de descarga de QEMU: https://www.qemu.org/download/

Consulte la documentación de QEMU para obtener información sobre cómo instalar QEMU: https://www.qemu.org/documentation/

Configuración de un disco virtual de destino

Busque o cree una imagen de disco virtual que tenga el software que desea depurar.

En este ejemplo, se usará una imagen de disco de máquina virtual windows x64 VHDX. Para más información sobre las imágenes de máquina virtual Windows, consulte Creación de una máquina virtual con Hyper-V en Windows 10.

Inserción de los controladores virtIO en la imagen de Windows

Para permitir la funcionalidad de red y un rendimiento razonable del dispositivo de almacenamiento, inserte o instale los controladores VirtIO en la imagen de disco de la máquina virtual Windows. Los controladores virtIo están disponibles aquí: https://github.com/virtio-win/kvm-guest-drivers-windows

VirtIO es una interfaz estandarizada que permite a las máquinas virtuales acceder al hardware abstracto, como dispositivos de bloque, adaptadores de red y consolas. Virtio actúa como una capa de abstracción para dispositivos de hardware en un entorno virtualizado como QEMU.

Conversión de VHDX a QEMU

Este paso no es necesario, pero se recomienda, ya que se logra un mejor rendimiento al usar una imagen QCOW de QEMU nativa en lugar de un VHDX.

Use el siguiente comando qemu-img.exe para convertir el vhdx. Esta utilidad se encuentra donde instaló QEMU, por ejemplo C:\Program Files\qemu.

C:\Program Files\qemu> qemu-img convert -c -p -O qcow2 MyVHDXFile.vhdx MyQEMUFile.qcow2 

Descargar firmware de UEFI

Para obtener los mejores resultados, descargue o compile el archivo de firmware UEFI (OVMF.fd). El firmware es necesario porque, de lo contrario, QEMU emula sistemas BIOS antiguos.

Un origen para el firmware de UEFI es el proyecto Open Clear Linux: https://clearlinux.org/

El archivo UEFI OVMF.fd de ejemplo está disponible aquí: https://github.com/clearlinux/common/blob/master/OVMF.fd

Extraiga el contenido del archivo descargado en C:\Program Files\qemu\Firmware.

En el caso de las plataformas que no sean Intel AMD64, debe compilar el firmware desde EDK2. Para obtener más información, vea https://github.com/tianocore/tianocore.github.io/wiki/How-to-build-OVMF.

Configuración del script de inicio de QEMU

Cree el archivo de configuración en QEMU. Por ejemplo, cree un StartQEMUx64Windows.bat archivo en el directorio raíz de QEMU. Vea el archivo de ejemplo siguiente.

Usar el script de inicio de QEMU para iniciar QEMU

Ejecute el script de inicio de QEMU para iniciar QEMU.

c:\Program Files\qemu\StartQEMUx64Windows.bat

Si aparece un símbolo del sistema de Firewall Defender, conceda a la aplicación todos los derechos a todos los tipos de redes para habilitar Windbg a través del firewall de Windows para la máquina del depurador host.

Windows Defender cuadro de diálogo Firewall con las tres opciones activadas.

Una vez iniciada la máquina virtual Windows en el entorno de QEMU, aparecerá la interfaz de usuario de QEMU.

Captura de pantalla de QEMU en la que se muestran las opciones del menú ver.

Use CTRL+ALT+ una combinación de teclas numéricas para ir a la consola del monitor QEMU. Este monitor también está disponible mediante View-compatmonitor>.

Escriba gdbserver para iniciar el servidor GDB de front-end en QEMU.

QEMU debe mostrarse Waiting for gdb connection on device ‘tcp::1234’

Vuelva a la ventana principal mediante la combinación de teclas CTRL+ALT+1.

Sugerencia: La ventana de la consola de GDB admite el comando "system_reset" para reiniciar rápidamente la emulación. Escriba ayuda para obtener una lista de comandos de consola de GDB.

Ejemplo de script de inicio de máquina virtual Windows de QEMU x64

Este es un script de configuración de QEMU de ejemplo que se puede usar para amd64 Virtual Machines. Reemplace los vínculos que apuntan a los archivos DISK y CDROM a las ubicaciones del equipo.

    REM
    REM  This script is used to run a Windows x64 VM on QEMU that is hosted by a Windows x64 host system
    REM  The Host system is a PC with Intel(R) Xeon(R) CPU.
    REM
    set EXECUTABLE=qemu-system-x86_64
    set MACHINE=-m 6G -smp 4

    REM No acceleration
    REM generic cpu emulation.
    REM to find out which CPU types are supported by the QEMU version on your system, then run:
    REM	 qemu-system-x86_64.exe -cpu help
    REM the see if your host system CPU is listed
    REM

    set CPU=-machine q35 

    REM Enables x64 UEFI-BIOS that will be used by QEMU :
    set BIOS=-bios D:\temp\firmware\OVMF.fd

    REM  Use regular GFX simulation
    set GFX=-device ramfb -device VGA 
    set USB_CTRL=-device usb-ehci,id=usbctrl
    set KEYB_MOUSE=-device usb-kbd -device usb-tablet

    REM # The following line enable the full-speed HD controller (requires separate driver)
    REM # Following line uses the AHCI controller for the Virtual Hard Disk:
    set DRIVE0=-device ahci,id=ahci -device ide-hd,drive=disk,bus=ahci.0

    REM
    REM This will set the Windows VM x64 disk image that will be launched by QEMU
    REM The disk image is in the qcow2 format accepted by QEMU.
    REM You get the .qcow2 image, once you get the VHDX Windows VM x64 image 
    REM and apply the script to inject the virtio x64 drivers and then run the 
    REM the QEMU tool to convert the .VHDX image to .qcow2 format
    REM 	i.e. 
    REM	qemu-img convert -c -p -O qcow2 Windows_VM_VHDX_with_injected_drivers_file.vhdx file.qcow2
    REM file : points to the specified qcow2 image path.
    REM
    set DISK0=-drive id=disk,file=D:\temp\x64_image_qcow2_for_windows\basex64Client.qcow2,if=none

    REM
    REM for kdnet on, then best option:
    REM   NETWORK0="-netdev user,id=net0,hostfwd=tcp::53389-:3389,hostfwd=tcp::50001-:50001 -device virtio-net,netdev=net0,disable-legacy=on"
    REM
    set NETHOST=-netdev user,id=net0,hostfwd=tcp::3589-:3389
    set NETGUEST=-device e1000,netdev=net0

    REM # The following line should enable the Daemon (instead of interactive)
    set DEAMON=-daemonize"
    %EXECUTABLE% %MACHINE% %CPU% %BIOS% %GFX% %USB_CTRL% %DRIVE0% %DISK0% %NETHOST% %NETGUEST%

Ha comprobado la conectividad de la red

Asegúrese de obtener la dirección IP de Windows (si la sesión del host del depurador no se encuentra en la misma máquina Windows que la máquina virtual QEMU).

Si el servidor GDB se inició correctamente, verá el número de puerto donde escuchará el servidor GDB y tendrá que usar este puerto para configurar el depurador de host (par IP:Port) en el exdiConfigData.xml).

Si el depurador de host se encuentra en la misma máquina que hospeda el invitado de QEMU, el identificador localhost se usará en el exdiconfigdata.xml como par IP:Port (por ejemplo, LocalHost:Port:1234). En este ejemplo, con el servidor y el depurador host en el mismo equipo, se usarán los valores predeterminados.

Establezca el valor actual del atributo de nombre de destino (CurrentTarget) en "QEMU" en el archivo ExdiConfigData.xml.

Si trabaja en un equipo remoto, establezca la dirección IP <address> de QEMU de destino: puerto <number> donde escucha el servidor GDB:

  • Busque el elemento Tag del componente QEMU en el exdiCondifgData.xml.
  • Establezca el número ip:puerto (LocalHost si el depurador se ejecuta en el mismo host que la máquina virtual de QEMU) para el servidor GDB de QEMU mediante:
  • Guarde los cambios en el archivo exdiConfigdata.xml que se encuentra en la ruta de acceso especificada por EXDI_GDBSRV_XML_CONFIG_FILE variable de entorno.

Para más información sobre las redes QEMU, consulte https://wiki.qemu.org/Documentation/Networking

Los siguientes comandos se pueden emitir en la consola QEMU (compatmonitor0) para mostrar información sobre el estado de red y conexión.

info network
info usernet

Descarga e instalación de las herramientas de depuración de Windows en el sistema host

Instale las Herramientas de depuración de Windows en el sistema host. Para obtener información sobre cómo descargar e instalar las herramientas del depurador, vea Herramientas de depuración para Windows.

Descarga, compilación y registro del archivo DLL del servidor EXDI

Descargue el código fuente binario de ExdiGdbSrv.dll correspondiente (cliente de servidor COM EXDI) desde microsoft/WinDbg-Samples, GitHub https://github.com/microsoft/WinDbg-Samples)

git clone https://github.com/microsoft/WinDbg-Samples

Compile la solución vs (ExdiGdbSrv.sln) según la arquitectura de la instalación del depurador de host ubicada en Exdi/exdigdbsrv.

Busque el ExdiGdbSrv.dll generado por la compilación.

Copie el servidor COM exDI (ExdiGdbSrv.dll) en el equipo host, en el directorio que contiene el depurador, .g. C:\Program Files (x86)\Windows Kits\10\Debuggers\x64 o C:\Debuggers)

Use regsvr32 para registrar el archivo DLL en un símbolo del sistema de administrador.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>regsvr32 ExdiGdbSrv.dll

RegSvr32 debe devolver un mensaje que indica que .DLLRegisterServer in ExdiGdbSrv.dll succeeded

Este paso solo es necesario realizar una vez, pero si cambia la ubicación del ExdiGdbSrv.dll, tendrá que volver a registrar el servidor COM.

Otra opción es usar el script de PowerShell de ejemplo es instalar el archivo DLL exDI e iniciar el depurador la primera vez. Para obtener más información, vea Script de PowerShell exDI de ejemplo en Configuración del transporte del depurador exDI.

Configure el host del depurador (WinDbg) editando los archivos XML de configuración exDI.

Busque los dos archivos de configuración necesarios en y cópielos en WinDbg-Samples/Exdi/exdigdbsrv/ un local en la máquina del depurador host a donde está instalado el depurador.

  • exdiConfigData.xml
  • systemregisters.xml

EXDI_GDBSRV_XML_CONFIG_FILE: describe la ruta de acceso completa al archivo de configuración xml exDI.

EXDI_SYSTEM_REGISTERS_MAP_XML_FILE: describe la ruta de acceso completa al archivo de asignación de registro del sistema XML EXDI.

Para obtener información general sobre cómo configurar y solucionar problemas de conexiones EXDI, así como las etiquetas y atributos de exdiConfigData.xml, vea Configuring the EXDI Debugger Transport.

Establezca la variable de entorno EXDI_GDBSRV_XML_CONFIG_FILE y EXDI_SYSTEM_REGISTERS_MAP_XML_FILE para describir la ruta de acceso completa al archivo de configuración xml exdi.

Símbolo del sistema

Abra un símbolo del sistema y establezca las siguientes variables de entorno.

set EXDI_GDBSRV_XML_CONFIG_FILE="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\exdiConfigData.xml"

set EXDI_SYSTEM_REGISTERS_MAP_XML_FILE="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\systemregisters.xml"

Escriba SET para confirmar que la ruta de acceso especificada está disponible en la ubicación del ExdiGdbSrvSample.dll

PowerShell

Abra un símbolo del sistema de PowerShell y establezca las siguientes variables de entorno:

$env:EXDI_GDBSRV_XML_CONFIG_FILE = 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\exdiConfigData.xml'

$env:EXDI_SYSTEM_REGISTERS_MAP_XML_FILE = 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\systemregisters.xml'

Escriba dir env: para confirmar que la ruta de acceso especificada está disponible en la ubicación del ExdiGdbSrvSample.dll

Inicio de WinDbg en el sistema host

Inicie la sesión de windbg a través de la interfaz exdi en el mismo símbolo del sistema donde establezca las variables de entorno (EXDI_GDBSRV_XML_CONFIG_FILE y EXDI_SYSTEM_REGISTERS_MAP_XML_FILE).

c:\Debuggers> windbg.exe -v -kx exdi:CLSID={29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014},Kd=Guess,DataBreaks=Exdi

Para mostrar una salida adicional, se puede usar la sesión detallada -v: . Para obtener información general sobre las opciones de WinDbg, vea Opciones de WinDbg Command-Line.

Otra opción es usar el script de PowerShell de ejemplo es instalar el archivo DLL exDI e iniciar el depurador la primera vez. Para obtener más información, vea Script de PowerShell exDI de ejemplo, en Configuración del transporte del depurador EXDI.

PS>.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 -ExdiDropPath "C:\path\to\built\exdi\files"

El depurador debe iniciarse y conectarse al servidor GdbServer de QEMU.

Sesión principal de WinDbg que muestra EXDI CLSID en el título de la ventana.

El depurador mostrará la inicialización correcta del transporte EXDI.

EXDI: DbgCoInitialize returned 0x00000001
EXDI: CoCreateInstance() returned 0x00000000
EXDI: QueryInterface(IExdiServer3) returned 0x00000000
Target command response: QEMU
exdiCmd: The function: 'ExdiDbgType' was completed.
EXDI: Server::GetTargetInfo() returned 0x00000000
EXDI: Server::SetKeepaliveInterface() returned 0x00000000
EXDI: Server::GetNbCodeBpAvail() returned 0x00000000
EXDI: ExdiNotifyRunChange::Initialize() returned 0x00000000
EXDI: LiveKernelTargetInfo::Initialize() returned 0x00000000
EXDI: Target initialization succeeded

La ventana de paquetes de consola EXDIGdbServer también puede mostrar información sobre el estado de la conexión EXDI, si displayCommPackets="yes" se establece en el archivo exdiConfigData.xml. Para obtener más información, consulte la información de solución de problemas de Configuración del transporte del depurador EXDI.

Usar WinDbg para depurar la imagen de Windows QEMU de destino

El dbgeng.dll usa un algoritmo heurístico para buscar la ubicación de la dirección de carga base nt en el momento en que se produjo el comando break. Si los símbolos privados no están disponibles, se producirá un error en este proceso.

Esto significa que, en muchas secuencias de conexión, la interrupción no funcionará según lo previsto. si divide manualmente en el código, será una ubicación aleatoria en la que Windows se ejecutará en ese momento. Como es posible que los símbolos del código de destino no estén disponibles, puede ser difícil establecer puntos de interrupción mediante símbolos.

Los comandos como los siguientes que acceden directamente a la memoria funcionarán.

k, kb, kc, kd, kp, kP, kv (Display Stack Backtrace)

r (registros)

d, da, db, dc, dd, dD, df, dp, dq, du, dw (memoria de visualización)

u (Unassemble)

Y puede recorrer el código.

p (paso)

También hay comandos que se pueden usar para intentar localizar el código que desea depurar.

s (memoria de búsqueda)

.imgscan (Buscar encabezados de imagen)

Imgscan puede ser útil con la depuración EDXI, como a diferencia de la depuración del kernel basada en KDNET tradicional, es posible que el establecimiento de puntos de interrupción basados en símbolos no esté disponible. La búsqueda de una imagen de destino deseada puede facilitar el uso de su ubicación para establecer un punto de interrupción de acceso a la memoria.

.exdicmd (comando EXDI)

El .exdicmd envía un comando EXDI al sistema de destino mediante la conexión de depuración de EXDI activa. Para obtener más información, vea .exdicmd (comando EXDI).

Archivos de configuración XML de EXDI

Hay dos archivos XML necesarios consumidos por el servidor COM de EXDI GDB (ExdiGdbSrv.dll).

  1. exdiConfigData.xml : este archivo contiene los datos de configuración principales que requiere el cliente del servidor GDB para establecer correctamente una sesión de GDB con el destino del servidor GDB del depurador de HW, por lo que el cliente del servidor GDB no se ejecutará si la variable de entorno EXDI_GDBSRV_XML_CONFIG_FILE no establece la ubicación del archivo. Cada etiqueta xml permite configurar un conjunto específico de la funcionalidad del servidor GDB. Vea a continuación una lista de los atributos que puede modificar en el XML y el XML de ejemplo.

  2. Systemregister.xml : este archivo contiene una asignación entre los registros del sistema y su código de acceso. Esto es necesario porque el servidor GDB no proporciona el código de acceso en el archivo xml y el depurador accede a cada registro del sistema a través del código de acceso.

Para obtener más información y una descripción de las etiquetas y atributos de GDBServer definidos en los archivos de configuración XML, vea Configuring the EXDI Debugger Transport.

Solución de problemas

Consulte la información de solución de problemas de Configuración del transporte del depurador EXDI.

Consulte también

Configuración del transporte del depurador EXDI

.exdicmd (comando EXDI)

Configuración automática de la depuración del kernel de red KDNET

Configuración manual de la depuración del kernel de red KDNET