Partager via


Configuration du débogage en mode noyau de QEMU avec EXDI

Cette rubrique explique comment configurer le débogage en mode noyau QEMU à l’aide d’EXDI avec le débogueur Windows.

Pour des informations générales sur la configuration et la résolution des problèmes liés aux connexions EXDI, consultez Configuration du transport du débogueur EXDI.

À l’aide de QEMU, le logiciel d’émulation de machine et de virtualisation permet de se connecter à d’autres systèmes d’exploitation servant d’hôte, tels que Linux. QEMU lui-même peut s’exécuter sur de nombreuses architectures, telles que x64 et Arm64. Le serveur de débogage ExdiGdb prend également en charge d’autres processeurs, par exemple, il est possible d’utiliser WinDbg pour déboguer QEMU s’exécutant sur x64, en émulant Arm64. L’utilisation d’EXDI permet également à la machine virtuelle d’être déboguée tôt dans le processus de démarrage, même avant le chargement du système d’exploitation.

Remarque

EXDI est une forme avancée et spécialisée de débogage pour des environnements spécifiques. Nous recommandons l’utilisation d’une connexion KDNET standard, plus facile à configurer. Pour une configuration automatique du débogage réseau, consultez la configuration automatique du débogage réseau du noyau KDNET.

Serveur EXDI COM

EXDI est une interface qui permet d’étendre WinDbg en ajoutant la prise en charge des débogueurs matériels (par exemple, basé sur JTAG ou GdbServer). Le diagramme ci-dessous illustre le rôle d’EXDI-GdbServer.

Diagramme de pile illustrant le rôle d’EXDI-GdbServer avec WinDbg-DbgEng en haut, une interface EXDI et un serveur COM EXDI communiquant avec un serveur GDB.

Important

EXDI n’utilisant pas le protocole KDNET, le débogueur connecté dispose de beaucoup moins d’informations sur ce qui se passe sur le PC et de nombreuses commandes fonctionneront différemment ou ne fonctionneront pas du tout. L’accès aux symboles privés pour le code en cours de débogage peut permettre au débogueur de mieux comprendre l’exécution du code des systèmes cibles. Pour en savoir plus, consultez Symboles publics et privés.

Configurer une connexion de débogueur à une image Windows sur QEMU

Ces étapes décrivent comment attacher une machine virtuelle Windows x64 exposant un serveur GDB à un client Windbg (qui utilise le serveur COM EXDI), également en cours d’exécution sur Windows. Une session GdbServer RSP entre le serveur WinDbg ExdiGdbSrv.dll (client de serveur GDB) et le serveur GDB QEMU est utilisée.

  1. Téléchargez et installez QEMU sur Windows.
  2. Configurez une image Windows virtuelle QEMU cible à lancer avec les paramètres BIOS/UEFI requis pour le débogage.
  3. Démarrez l’environnement QEMU à l’aide d’un script de lancement.
  4. Démarrez GdbServer sur QEMU.
  5. Vérifiez la connectivité réseau et recherchez et enregistrez l’adresse IP de l’image cible. (Adresse IP hôte par défaut de LocalHost et port 1234).
  6. Télécharger et installer les outils de débogage Windows sur le système hôte.
  7. Lancez WinDbg à l’aide de la ligne de commande ou de l’interface utilisateur pour vous connecter au serveur EXDI.
  8. Utilisez WinDbg pour déboguer l’image Windows QEMU cible.

Émulateur d’ordinateur open source QEMU

QEMU est un émulateur de machine générique et open source et un virtualiseur qui provoque une traduction dynamique. Lorsque QEMU est utilisé en tant qu’émulateur de machine, il peut exécuter les programmes et les systèmes d’exploitation créés pour un processeur (comme Arm64) sur un autre ordinateur (un PC x64). Il peut également exécuter/héberger des images de machines virtuelles pour différents systèmes d’exploitation (Windows/Linux/Mac).

QEMU peut fonctionner avec d’autres hyperviseurs comme KVM pour utiliser des extensions d’UC (HVM) pour la virtualisation. Lorsque QEMU est utilisé comme virtualiseur, il permet d’obtenir des performances quasi natives en exécutant le code invité directement sur le processeur hôte. QEMU peut tirer parti des fonctions de l’hyperviseur du système d’exploitation pour décharger l’émulation du processeur et de MMU sur le matériel réel.

Télécharger et installer QEMU

Dans cette procédure pas à pas, QEMU pour Windows x64 sera installé sur un PC x64 sur lequel s’exécutera également le débogueur Windows.

Téléchargez QEMU à partir de la page de téléchargement QEMU : https://www.qemu.org/download/

Pour en savoir plus sur l’installation de QEMU, consultez la documentation QEMU : https://www.qemu.org/documentation/

Configurer un disque virtuel cible

Localisez ou créez une image de disque virtuel contenant le logiciel que vous souhaitez déboguer.

Dans cet exemple, nous utilisons une image de disque de machine virtuelle VHDX Windows x64. Pour en savoir plus sur les images de machine virtuelle Windows, consultez Créer une machine virtuelle avec Hyper-V sur Windows 10.

Injecter les pilotes VirtIO dans l’image Windows

Pour assurer la fonctionnalité du réseau et des performances raisonnables des périphériques de stockage, il convient d’injecter ou d’installer les pilotes VirtIO dans l’image disque de la machine virtuelle Windows. Les pilotes VirtIO sont disponibles ici : https://github.com/virtio-win/kvm-guest-drivers-windows

VirtIO est une interface normalisée qui permet aux machines virtuelles d’accéder à du matériel abstrait, tel que des périphériques de bloc, des adaptateurs de réseau et des consoles. VirtIO sert de couche d’abstraction aux périphériques matériels dans un environnement virtualisé comme QEMU.

Pour injecter le pilote VirtIO dans l’image Windows, procédez comme suit :

  1. Extrayez les pilotes VirtIo dans un dossier, par exemple C:\VirtIo_Drivers.
  2. Montez le VHDX contenant la machine virtuelle Windows x64 en double-cliquant sur le VHDX dans Explorateur de fichiers (vous pouvez également utiliser le composant disque). Windows monte le VHDX à l’aide d’une lettre spécifique, par exemple « L : »
  3. Injectez le pilote dans l’image montée à l’aide de Dism : dism /image:L: /Add-Driver /driver:C:\VirtIo_Drivers Pour plus d’informations sur DISM, consultez vue d’ensemble de DISM.
  4. Une fois le processus terminé, vous pouvez démonter l’image et continuer à convertir le VHDX en QEMU.

Convert VHDX to QEMU

Cette étape n’est pas obligatoire, mais elle est recommandée, car ont obtient de meilleures performances en utilisant une image QEMU QCOW native au lieu d’un VHDX.

Utilisez la commande qemu-img.exe suivante pour convertir le vhdx. Cet utilitaire se trouve à l’emplacement où vous avez installé QEMU, par exemple C:\Program Files\qemu.

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

Télécharger le microprogramme UEFI

Pour obtenir des résultats optimaux, téléchargez ou compilez le fichier de microprogramme UEFI (OVMF.fd). Le microprogramme est nécessaire, car QEMU émule par défaut les anciens systèmes BIOS.

Le projet Open Clear Linux est l’une des sources permettant d’obtenir le microprogramme UEFI : https://clearlinux.org/

Le fichier UEFI OVMF.fd d’exemple est disponible ici : https://github.com/clearlinux/common/tree/master/OVMF.fd

Extrayez le contenu du fichier téléchargé dans C:\Program Files\qemu\Firmware.

Pour les plateformes autres qu’Intel AMD64, vous devez compiler le microprogramme à partir de l’EDK2. Pour plus d’informations, consultez https://github.com/tianocore/tianocore.github.io/wiki/How-to-build-OVMF.

Configurer le script de lancement QEMU

Créez votre fichier de configuration dans QEMU. Par exemple, créez un StartQEMUx64Windows.bat fichier sous le répertoire racine QEMU. Consultez le fichier d’exemple ci-dessous.

Utilisez le script de lancement QEMU pour lancer QEMU

Exécutez le script de lancement QEMU pour démarrer QEMU.

c:\Program Files\qemu\StartQEMUx64Windows.bat

Si une invite du pare-feu de Windows Defender s’affiche, accordez à l’application tous les droits sur tous les types de réseaux afin d’activer Windbg à travers le pare-feu Windows pour la machine de débogage hôte.

Boîte de dialogue du pare-feu Windows Defender avec les trois options cochées.

Une fois la machine virtuelle Windows lancée dans l’environnement QEMU, l’interface utilisateur QEMU s’affiche.

Capture d’écran des options de menu affichage QEMU.

Utilisez Ctrl+Alt+ une combinaison de touches numériques pour accéder à la console de surveillance QEMU. Cette surveillance est également possible avec View>-compatmonitor.

Saisissez gdbserver pour lancer le serveur GDB frontal sur QEMU.

QEMU doit afficher Waiting for gdb connection on device ‘tcp::1234’

Revenez à la fenêtre principale à l’aide de la combinaison de touches Ctrl+Alt+1.

Conseil : la fenêtre de console GDB prend en charge la system_reset commande pour redémarrer rapidement l’émulation. Tapez help la liste des commandes de console GDB.

Exemple de script de lancement de machine virtuelle Windows QEMU x64

Voici un exemple de script de configuration QEMU qui peut être utilisé pour les machines virtuelles AMD64. Remplacez les liens qui pointent vers les fichiers DISK et CDROM vers les emplacements de votre PC.

    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%

Connectivité réseau

Hôte local

Si le serveur GDB a démarré correctement, vous verrez le numéro de port où le serveur GDB sera à l’écoute et vous devez utiliser ce port pour configurer la paire de débogueur IP:Port de l’hôte.

Si votre débogueur hôte se trouve sur la même machine que celle qui héberge l’invité QEMU, l’identificateur Localhost est utilisé dans la paire IP :Port. Dans cet exemple, avec le débogueur serveur et hôte sur le même PC, LocalHost:1234 sera utilisé.

Hôte distant

Si vous travaillez sur un PC distant, recherchez l’adresse IP Windows (si la session hôte du débogueur ne se trouve pas sur le même ordinateur Windows que la machine virtuelle QEMU).

Adresse IP <address>QEMU cible :<port number> sera configurée dans l’interface utilisateur EXDI.

Les commandes suivantes peuvent être émises sur la console QEMU (compatmonitor0) pour afficher des informations sur le réseau et l’état de connexion.

info network
info usernet

Pour en savoir plus sur la mise en réseau QEMU, consultez https://wiki.qemu.org/Documentation/Networking

Téléchargez et installez les outils de débogage Windows sur le système hôte

Installez les outils de débogage Windows sur le système hôte. Pour des informations sur le téléchargement et l’installation des outils de débogage, consulter la rubrique Outils de débogage pour Windows.

Lancer WinDbg sur le système hôte

Dans le scénario décrit ici, définissez les options suivantes dans l’interface utilisateur EXDI pour vous connecter.

Type cible - QEMU

Architecture cible - x64

Système d’exploitation cible - Windows

Taille heuristique de l’analyse d’images - 0xFFE - NT

Serveur et port Gdb - LocalHost :1234

Arrêt sur les connexions - Oui

Interface utilisateur de connexion du noyau EXDI Windbg, avec les options de connexion affichées, notamment l’adresse IP et le port.

Bien que l’utilisation de l’interface utilisateur EXDI soit recommandée, il est également possible de lancer WinDbg à l’aide de l’option de ligne de commande similaire à ce qui est illustré ici.

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

Lorsque vous utilisez la ligne de commande, l’adresse IP et le port sont configurés à l’aide du fichier exdiConfigData.xml. Pour plus d’informations, consultez les fichiers de configuration EXDI XML.

Pour afficher une sortie supplémentaire, on peut utiliser la session -v: détaillée. Pour des informations générales sur les options WinDbg, consultez Options de ligne de commande WinDbg.

Le débogueur doit lancer et se connecter au GdbServer QEMU.

Session WinDbg principale affichant EXDI CLSID dans le titre de la fenêtre.

Le débogueur affiche l’initialisation de transport EXDI réussie.

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 fenêtre des paquets de console EXDIGdbServer peut également afficher des informations sur l’état de la connexion EXDI, si *« Afficher le journal des paquets de communication sous Options avancées est activé. Pour en savoir plus, consultez les informations sur la résolution des problèmes dans Configuration du transport du débogueur EXDI.

Utilisez WinDbg pour déboguer l’image Windows QEMU cible

La dbgeng.dll utilise un algorithme heuristique pour rechercher l’emplacement de l’adresse de charge de base NT au moment où la commande d’arrêt s’est produite. Si les symboles privés ne sont pas disponibles, ce processus échoue.

Cela signifie que dans de nombreuses séquences de connexion, l’arrêt ne fonctionnera pas comme prévu. si on accède manuellement au code, il s’agira d’un emplacement aléatoire que Windows est en train d’exécuter à ce moment-là. Comme les symboles du code cible peuvent ne pas être disponibles, il peut s’avérer difficile de définir des points d’arrêt à l’aide de symboles.

Commandes d’accès à la mémoire du débogueur disponibles

Les commandes comme celles ci-dessous qui accèdent directement à la mémoire fonctionnent.

k, kb, kc, kd, kp, kP, kv (Afficher l’arborescence des appels de procédure)

r (Registres)

d, da, db, dc, dd, dD, df, dp, dq, du, dw (Afficher la mémoire)

u (Désassembler)

Vous pouvez également parcourir le code.

p (Step)

Il existe également des commandes que l’on peut utiliser pour tenter de localiser le code qu’on souhaite déboguer.

s (Rechercher dans la mémoire)

.imgscan (Rechercher des en-têtes d’image)

Imgscan peut être utile pour le débogage EDXI, car contrairement au débogage traditionnel du noyau basé sur KDNET, il n’est pas toujours possible de définir des points d’arrêt basés sur des symboles. La localisation d’une image cible souhaitée peut permettre d’utiliser son emplacement pour définir un point d’arrêt d’accès à la mémoire.

.exdicmd (commande EXDI)

.exdicmd envoie une commande EXDI au système cible à l’aide de la connexion de débogage EXDI active. Pour en savoir plus, consulter .exdicmd (commande EXDI).

Dépannage

Reportez-vous aux informations de résolution des problèmes de Configuration du transport du débogueur EXDI.

Voir aussi

Configuration du transport du débogueur EXDI

Fichiers de configuration EXDI XML

.exdicmd (commande EXDI)

Configuration automatique du débogage du noyau réseau KDNET

Configuration manuelle du débogage du noyau réseau KDNET