Configurazione del debug in modalità kernel QEMU con EXDI
Questo argomento descrive come configurare il debug in modalità kernel QEMU usando EXDI con il debugger di Windows.
Per informazioni generali sulla configurazione e sulla risoluzione dei problemi relativi alle connessioni EXDI, vedere Configurazione del trasporto del debugger EXDI.
Usando QEMU, il software di emulazione di macchine e virtualizzazione, è possibile connettersi ad altri sistemi operativi che fungono da host, ad esempio Linux. QEMU può essere eseguito su numerose architetture, ad esempio x64 e Arm64. Il server di debug di ExdiGdb supporta anche altri processori, ad esempio è possibile usare WinDbg per eseguire il debug di QEMU in esecuzione su x64, emulando Arm64. L'uso di EXDI consente anche il debug HW della macchina virtuale all'inizio del processo di avvio, anche prima del caricamento del sistema operativo.
Nota
EXDI è una forma avanzata e specializzata di debug per ambienti specifici. L'uso di una connessione KDNET standard è più semplice da configurare ed è consigliabile. Per configurare automaticamente il debug di rete, vedere Configurazione automatica del debug del kernel di rete KDNET.
EXDI COM Server
EXDI è un'interfaccia che consente di estendere WinDbg aggiungendo il supporto per i debugger hardware ,ad esempio basato su JTAG o basato su GdbServer. Il diagramma seguente illustra il ruolo di EXDI-GdbServer.
Importante
Poiché EXDI non usa il protocollo KDNET, il debugger connesso dispone di informazioni significativamente meno su ciò che è in esecuzione nel PC e molti comandi funzioneranno in modo diverso o potrebbero non funzionare affatto. L'accesso ai simboli privati per il codice sottoposto a debug può aiutare il debugger a comprendere meglio l'esecuzione del codice dei sistemi di destinazione. Per altre informazioni, vedere Simboli pubblici e privati.
Configurare una connessione del debugger a un'immagine Windows in QEMU
Questi passaggi descrivono come connettersi a una macchina virtuale Windows x64 che espone un server GDB a un client Windbg (che usa il server COM EXDI), in esecuzione anche in Windows. Viene usata una sessione RSP GdbServer tra il server GDBG ExdiGdbSrv.dll (client server GDB) e QEMU GDB.
- Scaricare e installare QEMU in Windows.
- Configurare un'immagine di Windows virtuale QEMU di destinazione per l'avvio con le impostazioni di rete e BIOS/UEFI necessarie per il debug.
- Avviare l'ambiente QEMU usando uno script di avvio.
- Avviare GdbServer in QEMU.
- Controllare la connettività di rete e individuare e registrare l'indirizzo IP dell'immagine di destinazione. (Indirizzo IP HOST predefinito di LocalHost e porta 1234).
- Scaricare e installare gli strumenti di debug di Windows nel sistema host.
- Avviare WinDbg usando la riga di comando o l'interfaccia utente per connettersi al server EXDI.
- Usare WinDbg per eseguire il debug dell'immagine windows QEMU di destinazione.
Emulatore di computer open source QEMU
QEMU è un emulatore di macchina generico e open source e un virtualizzatore che causa la conversione dinamica. Quando QEMU viene usato come emulatore di computer, può eseguire i programmi e del sistema operativo creati per un processore (ad esempio Arm64) in un computer diverso (un PC x64). Può anche eseguire/ospitare immagini di macchine virtuali per sistemi operativi diversi (Windows/Linux/Mac).
QEMU può funzionare con altri hypervisor, ad esempio KVM, per usare le estensioni della CPU (HVM) per la virtualizzazione. Quando QEMU viene usato come virtualizzatore, QEMU ottiene prestazioni quasi native eseguendo il codice guest direttamente nella CPU host. QEMU può sfruttare le funzionalità dell'hypervisor del sistema operativo per eseguire l'offload della CPU e dell'emulazione MMU nell'hardware reale.
Scaricare e installare QEMU
In questa procedura dettagliata, QEMU per Windows x64 verrà installato in un PC x64 in cui verrà eseguito anche il debugger di Windows.
Scaricare QEMU dalla pagina di download di QEMU: https://www.qemu.org/download/
Per informazioni sull'installazione di QEMU, vedere la documentazione di QEMU: https://www.qemu.org/documentation/
Configurare un disco virtuale di destinazione
Individuare o creare un'immagine del disco virtuale con il software di cui si vuole eseguire il debug.
In questo esempio verrà usata un'immagine del disco della macchina virtuale VHDX x64 di Windows. Per altre informazioni sulle immagini delle macchine virtuali Windows, vedere Creare una macchina virtuale con Hyper-V in Windows 10.
Inserire i driver VirtIO nell'immagine di Windows
Per consentire funzionalità di rete e prestazioni ragionevoli del dispositivo di archiviazione, inserire o installare i driver VirtIO nell'immagine del disco della macchina virtuale Windows. I driver VirtIO sono disponibili qui: https://github.com/virtio-win/kvm-guest-drivers-windows
VirtIO è un'interfaccia standardizzata che consente alle macchine virtuali di accedere a hardware astratto, ad esempio dispositivi in blocchi, schede di rete e console. VirtIO funge da livello di astrazione per i dispositivi hardware in un ambiente virtualizzato come QEMU.
Per inserire il driver VirtIO nell'immagine di Windows, seguire questa procedura:
- Estrarre i driver VirtIo in una cartella, ad esempio
C:\VirtIo_Drivers
. - Montare il VHDX contenente la macchina virtuale Windows x64 facendo doppio clic su VHDX in Esplora file (è possibile usare anche diskpart). Windows monta il VHDX usando una lettera specifica, ad esempio "L:"
- Inserire il driver nell'immagine montata usando Dism:
dism /image:L: /Add-Driver /driver:C:\VirtIo_Drivers
per altre informazioni su Gestione e manutenzione immagini distribuzione, vedere Panoramica di Gestione e manutenzione immagini distribuzione. - Al termine del processo, è possibile smontare l'immagine e procedere alla conversione di VHDX in QEMU.
Convertire VHDX in QEMU
Questo passaggio non è obbligatorio, ma è consigliabile, poiché si ottengono prestazioni migliori quando si usa un'immagine QEMU QCOW nativa anziché un VHDX.
Usare il comando qemu-img.exe seguente per convertire vhdx. Questa utilità si trova in cui è stato installato QEMU, ad esempio C:\Program Files\qemu
.
C:\Program Files\qemu> qemu-img convert -c -p -O qcow2 MyVHDXFile.vhdx MyQEMUFile.qcow2
Scaricare il firmware UEFI
Per ottenere risultati ottimali, scaricare o compilare il file del firmware UEFI (OVMF.fd). Il firmware è necessario perché per impostazione predefinita QEMU emula i sistemi BIOS meno recenti.
Un'origine per il firmware UEFI è il progetto Open Clear Linux: https://clearlinux.org/
Il file UEFI OVMF.fd
di esempio è disponibile qui: https://github.com/clearlinux/common/tree/master/OVMF.fd
Estrarre il contenuto del file scaricato in C:\Program Files\qemu\Firmware
.
Per le piattaforme diverse da Intel AMD64 è necessario compilare il firmware da EDK2. Per ulteriori informazioni, vedere https://github.com/tianocore/tianocore.github.io/wiki/How-to-build-OVMF.
Configurare lo script di avvio QEMU
Creare il file di configurazione in QEMU. Ad esempio, creare un StartQEMUx64Windows.bat
file nella directory radice QEMU. Vedere il file di esempio seguente.
Usare lo script di avvio QEMU per avviare QEMU
Eseguire lo script di avvio QEMU per avviare QEMU.
c:\Program Files\qemu\StartQEMUx64Windows.bat
Se viene visualizzata una richiesta di firewall defender, concedere all'app tutti i diritti a tutti i tipi di reti per abilitare Windbg tramite Windows Firewall per il computer del debugger host.
Dopo l'avvio della macchina virtuale Windows nell'ambiente QEMU, verrà visualizzata l'interfaccia utente QEMU.
Usare CTRL+ALT+ una combinazione di tasti numerici per passare alla console di monitoraggio QEMU. Questo monitoraggio è disponibile anche tramite View-compatmonitor>.
Digitare gdbserver
per avviare il server GDB front-end in QEMU.
QEMU dovrebbe essere visualizzato Waiting for gdb connection on device ‘tcp::1234’
Tornare alla finestra principale usando la combinazione di tasti CTRL+ALT+1.
Suggerimento: la finestra della console GDB supporta il system_reset
comando per riavviare rapidamente l'emulazione. Digitare help
per un elenco di comandi della console GDB.
Esempio di script di avvio di macchine virtuali Windows QEMU x64
Di seguito è riportato un esempio di script di configurazione QEMU che può essere usato per Macchine virtuali AMD64. Sostituire i collegamenti che puntano ai file DISK e CDROM nei percorsi del 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%
Connettività di rete
Host locale
Se il server GDB è stato avviato correttamente, verrà visualizzato il numero di porta in cui sarà in ascolto il server GDB e sarà necessario usare questa porta per configurare la coppia del debugger IP:Port
host.
Se il debugger host si trova nello stesso computer che ospita il guest QEMU, l'identificatore Localhost verrà usato nella coppia IP:Port. In questo esempio, con il server e il debugger host nello stesso PC, LocalHost:1234
verrà usato.
Host remoto
Se si usa un PC remoto, individuare l'indirizzo IP di Windows (se la sessione host del debugger non si trova nello stesso computer Windows della macchina virtuale QEMU).
L'INDIRIZZO IP <address>
<port number>
QEMU di destinazione verrà configurato nell'interfaccia utente DI EXDI.
I comandi seguenti possono essere eseguiti nella console QEMU (compatmonitor0) per visualizzare informazioni sullo stato della rete e della connessione.
info network
info usernet
Per altre informazioni sulla rete QEMU, vedere https://wiki.qemu.org/Documentation/Networking
Scaricare e installare gli strumenti di debug di Windows nel sistema host
Installare gli strumenti di debug di Windows nel sistema host. Per informazioni sul download e l'installazione degli strumenti del debugger, vedere Strumenti di debug per Windows.
Avviare WinDbg nel sistema host
Nello scenario descritto qui impostare le opzioni seguenti nell'interfaccia utente di EXDI per la connessione.
Tipo di destinazione - QEMU
Architettura di destinazione - x64
Sistema operativo di destinazione - Windows
Dimensioni euristiche dell'analisi delle immagini - 0xFFE - NT
Server e porta Gdb - LocalHost:1234
Interruzione delle connessioni - Sì
Anche se è consigliabile usare l'interfaccia utente DI EXDI, è anche possibile avviare WinDbg usando l'opzione della riga di comando simile a quella illustrata di seguito.
c:\Debuggers> windbg.exe -v -kx exdi:CLSID={29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014},Kd=Guess,Inproc=ExdiGdbSrv.dll,DataBreaks=Exdi
Quando si usa la riga di comando, l'indirizzo IP e la porta vengono configurati usando il file exdiConfigData.xml. Per altre informazioni, vedere File di configurazione XML DI EXDI.
Per visualizzare un output aggiuntivo, è possibile usare la sessione dettagliata -v: . Per informazioni generali sulle opzioni winDbg, vedere Opzioni della riga di comando di WinDbg.
Il debugger deve avviare e connettersi a QEMU GdbServer.
Il debugger mostrerà l'inizializzazione corretta del trasporto 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 finestra pacchetti della console EXDIGdbServer può anche visualizzare informazioni sullo stato della connessione EXDI, se *"Mostra log pacchetti di comunicazione in Opzioni avanzate è impostato su Attivato. Per altre informazioni, vedere le informazioni sulla risoluzione dei problemi in Configurazione del trasporto del debugger EXDI.
Usare WinDbg per eseguire il debug dell'immagine windows QEMU di destinazione
Il dbgeng.dll usa un algoritmo euristico per trovare la posizione dell'indirizzo di caricamento di base NT al momento in cui si è verificato il comando di interruzione. Se i simboli privati non sono disponibili, questo processo avrà esito negativo.
Ciò significa che in molte sequenze di connessione l'interruzione non funzionerà come previsto. se si suddivide manualmente nel codice, si tratta di una posizione casuale in cui Windows è stato eseguito in quel momento. Poiché i simboli per il codice di destinazione potrebbero non essere disponibili, può essere difficile impostare punti di interruzione usando i simboli.
Comandi di accesso alla memoria del debugger disponibili
I comandi, ad esempio i seguenti, che accedono direttamente alla memoria funzioneranno.
k, kb, kc, kd, kp, kP, kv (Display Stack Backtrace)
d, da, db, dc, dd, dD, df, dp, dq, du, dw (Display Memory)
Ed è possibile eseguire il codice.
Sono inoltre disponibili comandi che possono essere usati per tentare di individuare il codice di cui si vuole eseguire il debug.
.imgscan (Trova intestazioni immagine)
Imgscan può essere utile con il debug EDXI, come a differenza del debug del kernel basato su KDNET tradizionale, l'impostazione di punti di interruzione in base ai simboli potrebbe non essere disponibile. L'individuazione di un'immagine di destinazione desiderata può semplificare l'uso della posizione per impostare un punto di interruzione di accesso alla memoria.
.exdicmd (comando EXDI)
.exdicmd invia un comando EXDI al sistema di destinazione usando la connessione di debug EXDI attiva. Per altre informazioni, vedere .exdicmd (comando EXDI).
Risoluzione dei problemi
Fare riferimento alle informazioni sulla risoluzione dei problemi in Configurazione del trasporto del debugger EXDI.
Vedi anche
Configurazione del trasporto del debugger EXDI
File di configurazione XML DI EXDI
Configurazione automatica del debug del kernel di rete KDNET