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.
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.
- Téléchargez et installez QEMU sur Windows.
- Configurez une image Windows virtuelle QEMU cible à lancer avec les paramètres BIOS/UEFI requis pour le débogage.
- Démarrez l’environnement QEMU à l’aide d’un script de lancement.
- Démarrez GdbServer sur QEMU.
- 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).
- Télécharger et installer les outils de débogage Windows sur le système hôte.
- Lancez WinDbg à l’aide de la ligne de commande ou de l’interface utilisateur pour vous connecter au serveur EXDI.
- 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 :
- Extrayez les pilotes VirtIo dans un dossier, par exemple
C:\VirtIo_Drivers
. - 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 : »
- 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. - 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.
Une fois la machine virtuelle Windows lancée dans l’environnement QEMU, l’interface utilisateur QEMU s’affiche.
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
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.
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)
d, da, db, dc, dd, dD, df, dp, dq, du, dw (Afficher la mémoire)
Vous pouvez également parcourir le code.
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