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.
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.
- Descargue e instale QEMU en Windows.
- 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.
- Inicie el entorno de QEMU mediante un script de inicio.
- Inicie GdbServer en QEMU.
- 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).
- Descargue e instale las herramientas de depuración de Windows en el sistema host.
- Inicie WinDbg mediante la línea de comandos o la interfaz de usuario para conectarse al servidor EXDI.
- 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:
- Extraiga los controladores De VirtIo en una carpeta, por ejemplo
C:\VirtIo_Drivers
. - 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:"
- 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. - 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.
Una vez iniciada la máquina virtual Windows en el entorno de QEMU, aparecerá la interfaz de usuario de QEMU.
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: sí
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.
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)
d, da, db, dc, dd, dD, df, dp, dq, du, dw (Mostrar memoria)
Y puede recorrer el código.
También hay comandos que se pueden usar para intentar buscar código que desea depurar.
.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
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