Compartir a través de


Configuración de la depuración en modo kernel de QEMU mediante EXDI

En este tema se describe cómo configurar la depuración en modo kernel de QEMU mediante EXDI con el depurador de Windows.

Para obtener información general sobre cómo configurar y solucionar problemas de conexiones de EXDI, consulte Configuración del transporte del depurador de EXDI.

Con QEMU, el software de emulación de máquina y virtualización, es posible conectarse a otros sistemas operativos que actúan como host, como Linux. QEMU puede ejecutarse en numerosas arquitecturas, como x64 y Arm64. El servidor de depuración de ExdiGdb también admite otros procesadores, por ejemplo, es posible usar WinDbg para depurar QEMU que se ejecuta en x64 emulando Arm64. El uso de EXDI también permite depurar la máquina virtual al principio del proceso de arranque, incluso antes de que se haya cargado el sistema operativo.

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 automática de la depuración del kernel de red KDNET.

Servidor EXDI COM

EXDI es una interfaz que permite extender WinDbg agregando compatibilidad con depuradores de hardware (por ejemplo, basados en JTAG o 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 mucha menos información sobre lo que se ejecuta en el equipo y muchos comandos funcionarán de forma diferente o no funcionarán en absoluto. El acceso a símbolos privados para el código que se depura puede ayudar al depurador a comprender mejor la ejecución del código de los sistemas de destino. Para obtener más información, consulte Símbolos públicos y privados.

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

En estos pasos se describe cómo adjuntar a una máquina virtual Windows x64 que expone un servidor GDB a un cliente Windbg (que usa el servidor COM EXDI), que también se ejecuta en Windows. Se usa una sesión de RSP de GdbServer entre la ExdiGdbSrv.dll WinDbg (cliente del servidor GDB) y el servidor GDB de QEMU.

  1. Descargue e instale QEMU en Windows.
  2. Configure una imagen de Windows virtual QEMU de destino para iniciarse con la red necesaria y la configuración de BIOS/UEFI para la depuración.
  3. Inicie el entorno de QEMU mediante un script de inicio.
  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 predeterminada de HOST de LocalHost y puerto de 1234).
  6. Descargue e instale las herramientas de depuración de Windows en el sistema host.
  7. Inicie WinDbg mediante la línea de comandos o la interfaz de usuario para conectarse al servidor EXDI.
  8. Use WinDbg para depurar la imagen de Windows de QEMU de destino.

Emulador de máquina de código abierto de QEMU

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

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

Descargar e instalar QEMU

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

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 obtener 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 el 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.

Para insertar el controlador VirtIO en la imagen de Windows, siga estos pasos:

  1. Extraiga los controladores De VirtIo en una carpeta, por ejemplo C:\VirtIo_Drivers.
  2. Monte el VHDX que contiene la máquina virtual Windows x64 haciendo doble clic en el VHDX en Explorador de archivos (también puede usar diskpart). Windows montará el VHDX con una letra específica, por ejemplo, "L:"
  3. Inserte el controlador en la imagen montada mediante Dism: dism /image:L: /Add-Driver /driver:C:\VirtIo_Drivers para obtener más información sobre DISM, vea Información general sobre DISM.
  4. Cuando se complete el proceso, puede desmontar la imagen y continuar con la conversión del VHDX a QEMU.

Convertir VHDX a QEMU

Este paso no es necesario, pero se recomienda, ya que se logra un mejor rendimiento cuando se usa 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 

Descarga del firmware de UEFI

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

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

El archivo OVMF.fd de UEFI de ejemplo está disponible aquí: https://github.com/clearlinux/common/tree/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. Consulte el ejemplo de archivo siguiente.

Uso del 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 mensaje 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.

Cuadro de diálogo Firewall de Windows Defender 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 de menú de visualización.

Use CTRL+ALT+ una combinación de teclas numéricas para ir a la consola del monitor QEMU. También se puede acceder a este monitor con View->compatmonitor.

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

QEMU debería mostrar 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 system_reset comando para reiniciar rápidamente la emulación. Escriba help una lista de comandos de consola de GDB.

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

Este es un script de configuración de QEMU de ejemplo que se puede usar para máquinas virtuales AMD64. Reemplace los vínculos que apuntan a los archivos DISK y CDROM con 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 "C:\Program Files\qemu\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="C:\Program Files\qemu\MyQEMUFile.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
    REM Create a mapping for the RDP service from port 3389 to 3589.
    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 DAEMON=-daemonize"
    %EXECUTABLE% %MACHINE% %CPU% %BIOS% %GFX% %USB_CTRL% %DRIVE0% %DISK0% %NETHOST% %NETGUEST%

Conectividad de red

Host local

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 par del depurador IP:Port de host.

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 en el par IP:Port. En este ejemplo, se usará el servidor y el depurador host en el mismo equipo LocalHost:1234 .

Host remoto

Si trabaja en un equipo remoto, busque la dirección IP de Windows (si la sesión del host del depurador no se ubicará en la misma máquina Windows que la máquina virtual QEMU).

La dirección IP <address>de QEMU de destino:<port number> se configurará en la interfaz de usuario de EXDI.

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

info network
info usernet

Para obtener más información sobre la conexión en red de QEMU, consulte https://wiki.qemu.org/Documentation/Networking

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, consulte Herramientas de depuración para Windows.

Inicio de WinDbg en el sistema host

En el escenario descrito aquí, establezca las siguientes opciones en la interfaz de usuario de EXDI para conectarse.

Tipo de destino: QEMU

Arquitectura de destino: x64

Sistema operativo de destino: Windows

Tamaño heurístico de escaneo de imágenes - 0xFFE - NT

Servidor y puerto de Gdb: LocalHost:1234

Interrupción en las conexiones:

Interfaz de usuario de conexión del kernel exDI de Windbg, con las opciones de conexión mostradas, incluida la dirección IP y el puerto.

Aunque se recomienda usar la interfaz de usuario exDI, también es posible iniciar WinDbg mediante la opción de línea de comandos similar a la que se muestra aquí.

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

Al usar la línea de comandos, la dirección IP y el puerto se configuran mediante el archivo exdiConfigData.xml. Para obtener más información, vea Archivos de configuración XML de EXDI.

Para mostrar una salida adicional, se puede usar la sesión -v: detallada. Para obtener información general sobre las opciones de WinDbg, consulte Opciones de línea de comandos de WinDbg.

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 *"Mostrar registro de paquetes de comunicación en Opciones avanzadas está establecido en activado. Para obtener más información, consulte la información de solución de problemas en Configuración del transporte del depurador EXDI.

Uso de WinDbg para depurar la imagen de Windows de 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 va a irrumpir manualmente en el código, será una ubicación aleatoria que Windows estaba ejecutando 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.

Comandos de acceso a memoria del depurador disponibles

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

k, kb, kc, kd, kp, kP, kv (Mostrar seguimiento de la pila)

r (Registros)

d, da, db, dc, dd, dD, df, dp, dq, du, dw (Mostrar memoria)

u (Desensamblaje)

Y puede recorrer el código.

p (paso)

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

s (Memoria de búsqueda)

.imgscan (Buscar encabezados de imagen)

Imgscan puede ser útil con la depuración de EDXI, ya que a diferencia de la depuración de kernel basada en KDNET tradicional, es posible que el establecimiento de puntos de interrupción basados en símbolos no esté disponible. La ubicación de una imagen de destino deseada puede facilitar el uso de su ubicación para establecer un punto de interrupción de acceso a 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, consulte .exdicmd (comando EXDI).

Solución de problemas

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

Consulte también

Configuración del transporte del depurador EXDI

Archivos de configuración XML de 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