Condividi tramite


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.

Diagramma dello stack che mostra il ruolo di EXDI-GdbServer con WinDbg-DbgEng sopra, un'interfaccia EXDI e un server COM EXDI che comunica con un server GDB.

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.

  1. Scaricare e installare QEMU in Windows.
  2. Configurare un'immagine di Windows virtuale QEMU di destinazione per l'avvio con le impostazioni di rete e BIOS/UEFI necessarie per il debug.
  3. Avviare l'ambiente QEMU usando uno script di avvio.
  4. Avviare GdbServer in QEMU.
  5. 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).
  6. Scaricare e installare gli strumenti di debug di Windows nel sistema host.
  7. Avviare WinDbg usando la riga di comando o l'interfaccia utente per connettersi al server EXDI.
  8. 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:

  1. Estrarre i driver VirtIo in una cartella, ad esempio C:\VirtIo_Drivers.
  2. 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:"
  3. 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.
  4. 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.

Finestra di dialogo di Windows Defender Firewall con tutte e tre le opzioni selezionate.

Dopo l'avvio della macchina virtuale Windows nell'ambiente QEMU, verrà visualizzata l'interfaccia utente QEMU.

Screenshot di QEMU che mostra le opzioni del menu di visualizzazione.

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 -

Interfaccia utente della connessione kernel EXDI windbg, con opzioni di connessione visualizzate, tra cui INDIRIZZO IP e porta.

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.

Sessione WinDbg principale che visualizza CLSID EXDI nel titolo della finestra.

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)

r (registri)

d, da, db, dc, dd, dD, df, dp, dq, du, dw (Display Memory)

u (unassemble)

Ed è possibile eseguire il codice.

p (passaggio)

Sono inoltre disponibili comandi che possono essere usati per tentare di individuare il codice di cui si vuole eseguire il debug.

s (memoria di ricerca)

.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

.exdicmd (comando EXDI)

Configurazione automatica del debug del kernel di rete KDNET

Configurazione manuale del debug del kernel di rete KDNET