Freigeben über


Festlegen von QEMU-Kernel-Mode Debugging mit EXDI

In diesem Thema wird beschrieben, wie Sie das QEMU-Kernelmodusdebugging mit EXDI mit dem Windows-Debugger einrichten.

Allgemeine Informationen zum Festlegen, Konfigurieren und zur Fehlerbehebung von EXDI-Verbindungen finden Sie unter Konfigurieren des EXDI-Debugger-Transports.

Mit QEMU, der Virtualisierungs- und Computeremulationssoftware, ist es möglich, eine Verbindung mit anderen Betriebssystemen herzustellen, die als Host dienen, z. B. Linux. QEMU selbst kann auf zahlreichen Architekturen wie x64 und Arm64 laufen. Der ExdiGdb-Debugserver unterstützt auch andere Prozessoren, beispielsweise ist es möglich, WinDbg zum Debuggen von QEMU unter x64 zu verwenden und Arm64 zu emulieren. Mit EXDI kann der virtuelle Computer auch frühzeitig im Startprozess gedebuggt werden, auch bevor das Betriebssystem geladen wurde.

Hinweis

EXDI ist eine fortschrittliche, spezielle Form des Debuggings für bestimmte Umgebungen. Die Verwendung einer Standard-KDNET-Verbindung ist einfacher zu konfigurieren und wird empfohlen. Um das Networking-Debugging automatisch einzurichten, siehe KDNET-Network-Kernel-Debugging automatisch einrichten.

EXDI COM Server

EXDI ist eine Schnittstelle, die die Möglichkeit bietet, WinDbg um den Support für Hardware-Debugger (z. B. JTAG-basiert oder GdbServer-basiert) zu erweitern. Das folgende Diagramm veranschaulicht die Rolle von EXDI-GdbServer.

Stack-Diagramm, das die Rolle von EXDI-GdbServer zeigt, mit WinDbg-DbgEng darüber, einer EXDI-Schnittstelle und einem EXDI-COM-Server, der mit einem GDB-Server kommuniziert.

Wichtig

Da EXDI nicht das KDNET-Protokoll verwendet, verfügt der angeschlossene Debugger über deutlich weniger Informationen über das, was auf dem PC ausgeführt wird, und viele Befehle funktionieren anders oder möglicherweise gar nicht. Der Zugriff auf private Symbole für den zu debuggenden Code kann dem Debugger helfen, die Code-Ausführung des Zielsystems besser zu verstehen. Weitere Informationen finden Sie unter Öffentliche und private Symbole.

Einrichtung einer Debugger-Verbindung zu einem Windows-Image unter QEMU

In diesen Schritten wird beschrieben, wie Sie an einen virtuellen Windows x64-Computer anfügen, der einen GDB-Server an einen Windbg-Client (der den EXDI COM-Server verwendet) verfügbar machen, auch unter Windows ausgeführt wird. Es wird eine GdbServer-RSP-Sitzung zwischen dem WinDbg-ExdiGdbSrv.dll (GDB-Serverclient) und dem QEMU GDB-Server verwendet.

  1. Laden Sie QEMU herunter, und installieren Sie es auf Windows.
  2. Konfigurieren Sie ein virtuelles Windows-Zielimage für QEMU für den Start mit den erforderlichen Netzwerk- und BIOS-/UEFI-Einstellungen für das Debuggen.
  3. Starten Sie die QEMU-Umgebung mit einem Startskript.
  4. Starten Sie den GdbServer auf QEMU.
  5. Überprüfen Sie die Netzwerkkonnektivität, und lokalisieren und notieren Sie die IP-Adresse des Ziel-Images. (HOST IP-Standardadresse von LocalHost und Port von 1234).
  6. Laden Sie die Windows-Debugging-Tools herunter und installieren Sie sie auf dem Hostsystem.
  7. Starten Sie WinDbg mithilfe der Befehlszeile oder Benutzeroberfläche, um eine Verbindung mit dem EXDI-Server herzustellen.
  8. Verwenden Sie WinDbg, um das Ziel-QEMU-Windows-Image zu debuggen.

QEMU-Open-Source-Computer-Emulator

QEMU ist ein generischer und Open-Source-Computeremulator und Virtualizer, der eine dynamische Übersetzung verursacht. Wenn QEMU als Computer-Emulator verwendet wird, kann es Betriebssysteme und Programme, die für einen Prozessor (z. B. Arm64) entwickelt wurden, auf einem anderen Computer (einem x64-PC) ausführen. Er kann auch Images virtueller Maschinen für verschiedene Betriebssysteme (Windows/Linux/Mac) ausführen/hosten.

QEMU kann mit anderen Hypervisoren wie HYPERVISOREN arbeiten, um CPU-Erweiterungen (HVM) für die Virtualisierung zu verwenden. Wenn QEMU als Virtualisierer verwendet wird, erzielt QEMU nahezu native Leistungen, indem es den Code des Gastes direkt auf der Host-CPU ausführt. QEMU kann die Funktionen des Betriebssystem-Hypervisors nutzen, um die CPU- und MMU-Emulation auf echte Hardware auszulagern.

QEMU herunterladen und installieren

In dieser Anleitung wird QEMU für Windows x64 auf einem x64-PC installiert, auf dem auch der Windows-Debugger ausgeführt wird.

Laden Sie QEMU von der QEMU-Download-Seite herunter: https://www.qemu.org/download/

In der QEMU-Dokumentation finden Sie Informationen zur Installation von QEMU: https://www.qemu.org/documentation/

Konfigurieren eines virtuellen Datenträgers als Ziel

Suchen oder erstellen Sie ein Image eines virtuellen Datenträgers, der die Software enthält, die Sie debuggen möchten.

In diesem Beispiel wird ein Image eines virtuellen Computers unter Windows x64 VHDX verwendet. Um mehr über die Images virtueller Maschinen unter Windows zu erfahren, lesen Sie Virtuelle Maschine mit Hyper-V unter Windows 10 erstellen.

VirtIO-Treiber in das Windows-Image einfügen

Um Netzwerkfunktionen und eine angemessene Leistung der Datenträger zuzulassen, injizieren oder installieren Sie die VirtIO-Treiber in das Image der virtuellen Maschine unter Windows. Die VirtIO-Treiber sind hier verfügbar: https://github.com/virtio-win/kvm-guest-drivers-windows

VirtIO ist eine standardisierte Schnittstelle, die virtuellen Maschinen die Möglichkeit bietet, auf abstrahierte Hardware zuzugreifen, wie z. B. Blockgeräte, Netzwerkadapter und Konsolen. VirtIO dient als Abstraktionsebene für Hardwaregeräte in einer virtualisierten Umgebung wie QEMU.

Führen Sie die folgenden Schritte aus, um den VirtIO-Treiber in das Windows-Image einzufügen:

  1. Extrahieren Sie die VirtIo-Treiber in einem Ordner, z. B C:\VirtIo_Drivers. .
  2. Mount the VHDX containing the Windows x64 Virtual machine by double clicking on the VHDX in Explorer (you can use also diskpart). Windows stellt die VHDX-Datei mit einem bestimmten Buchstaben wie "L:" ein.
  3. Fügen Sie den Treiber mithilfe von Dism in das bereitgestellte Image ein: dism /image:L: /Add-Driver /driver:C:\VirtIo_Drivers Weitere Informationen zu DISM finden Sie unter DISM Overview.
  4. Nach Abschluss des Vorgangs können Sie die Bereitstellung des Images aufheben und mit der Konvertierung des VHDX in QEMU fortfahren.

Konvertieren von VHDX in QEMU

Dieser Schritt ist nicht erforderlich, wird aber empfohlen, da eine bessere Leistung erzielt wird, wenn Sie ein natives QEMU-QCOW-Image anstelle einer VHDX verwenden.

Verwenden Sie den Befehl qemu-img.exe, um die VHDX zu konvertieren. Dieses Dienstprogramm finden Sie dort, wo Sie QEMU installiert haben, z. B. C:\Program Files\qemu.

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

UEFI-Firmware herunterladen

Die besten Ergebnisse erzielen Sie, wenn Sie die UEFI-Firmware-Datei (OVMF.fd) herunterladen oder kompilieren. Die Firmware wird benötigt, da QEMU sonst standardmäßig ältere BIOS-Systeme emuliert.

Eine Quelle für UEFI-Firmware ist das Open-Source-Linux-Projekt: https://clearlinux.org/

Die UEFI OVMF.fd Beispieldatei ist hier verfügbar: https://github.com/clearlinux/common/tree/master/OVMF.fd

Extrahieren Sie den Inhalt der heruntergeladenen Datei in C:\Program Files\qemu\Firmware.

Für andere Plattformen als Intel AMD64 sollten Sie die Firmware mit dem EDK2 kompilieren. Weitere Informationen finden Sie unter https://github.com/tianocore/tianocore.github.io/wiki/How-to-build-OVMF.

Konfigurieren des QEMU-Startskripts

Erstellen Sie Ihre Konfigurationsdatei in QEMU. Erstellen Sie beispielsweise eine StartQEMUx64Windows.bat Datei unter dem QEMU-Stammverzeichnis. Siehe die Beispielsdatei unten.

QEMU mit dem QEMU-Startskript starten

Führen Sie das QEMU-Startskript aus, um QEMU zu starten.

c:\Program Files\qemu\StartQEMUx64Windows.bat

Wenn eine Defender-Firewall-Meldung erscheint, gewähren Sie der App alle Rechte für alle Arten von Netzwerken, um Windbg durch die Windows Firewall für den Host-Debugger-Computer zu aktivieren.

Das Dialogfeld

Sobald der virtuelle Windows-Computer in der QEMU-Umgebung gestartet ist, erscheint die QEMU-Benutzeroberfläche.

Screenshot von QEMU mit der Anzeige der Menüoptionen.

Verwenden Sie die Tastenkombination STRG+ALT+ eine Zifferntaste, um die QEMU-Monitor-Konsole aufzurufen. Dieser Monitor ist auch über View->Compatmonitor verfügbar.

Geben Sie gdbserver ein, um den Front-End GDB-Server auf QEMU zu starten.

QEMU sollte Waiting for gdb connection on device ‘tcp::1234’ anzeigen.

Kehren Sie mit der Tastenkombination STRG+ALT+1 zum Hauptfenster zurück.

Tipp: Das GDB-Konsolenfenster unterstützt den system_reset Befehl, um die Emulation schnell neu zu starten. Geben Sie einen Typ help für eine Liste der GDB-Konsolenbefehle ein.

Beispiel für ein Skript zum Starten einer QEMU-x64-Windows-VM

Hier finden Sie ein Beispiel für ein QEMU-Konfigurationsskript, das für virtuelle AMD64-Maschinen verwendet werden kann. Ersetzen Sie die Links, die auf die DISK- und CDROM-Dateien verweisen, durch die entsprechenden Speicherorte auf Ihrem 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%

Netzwerkkonnektivität

Lokaler Host

Wenn der GDB-Server ordnungsgemäß gestartet wurde, wird die Portnummer angezeigt, an der der GDB-Server überwacht wird, und Sie müssen diesen Port verwenden, um das Hostdebuggerpaar IP:Port einzurichten.

Wenn sich Ihr Hostdebugger auf demselben Computer befindet, auf dem der QEMU-Gast gehostet wird, wird der Localhost-Bezeichner im IP:Port-Paar verwendet. In diesem Beispiel wird mit dem Server- und Hostdebugger auf demselben PC LocalHost:1234 verwendet.

Remotehost

Wenn Sie auf einem Remote-PC arbeiten, suchen Sie die Windows-IP-Adresse (wenn sich die Debuggerhostsitzung nicht auf demselben Windows-Computer wie die QEMU-VM befindet).

Die Ziel-QEMU-IP <address>:<port number> wird in der EXDI-Benutzeroberfläche konfiguriert.

Die folgenden Befehle können in der QEMU-Konsole (compatmonitor0) genutzt werden, um Informationen über das Netzwerk und den Verbindungsstatus anzuzeigen.

info network
info usernet

Weitere Informationen zum QEMU-Networking finden Sie unter https://wiki.qemu.org/Documentation/Networking

Downloaden und Installieren der Windows-Debugging-Tools auf dem Host-System

Installieren Sie die Windows-Debugging-Tools auf dem Host-System. Informationen zum Herunterladen und Installieren der Debugging-Tools finden Sie unter Debugging-Tools für Windows.

WinDbg auf dem Host-System starten

Legen Sie in dem hier beschriebenen Szenario die folgenden Optionen in der EXDI-Benutzeroberfläche fest, um eine Verbindung herzustellen.

Zieltyp – QEMU

Zielarchitektur - x64

Zielbetriebssystem – Windows

Heuristische Größe des Bildscans - 0xFFE - NT

Gdb-Server und -Port - LocalHost:1234

Unterbrechung bei Verbindungen - ja

Windbg EXDI-Kernelverbindungs-UI mit angezeigten Verbindungsoptionen, einschließlich IP- und Portadresse.

Obwohl die Verwendung der EXDI-Benutzeroberfläche empfohlen wird, ist es auch möglich, WinDbg mit der Befehlszeilenoption zu starten, ähnlich wie hier gezeigt.

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

Bei Verwendung der Befehlszeile werden die IP-Adresse und der Port mithilfe der exdiConfigData.xml Datei konfiguriert. Weitere Informationen finden Sie unter EXDI XML-Konfigurationsdateien.

Um zusätzliche Ausgaben anzuzeigen, können Sie die -v: verbose session verwenden. Allgemeine Informationen zu den WinDbg-Optionen finden Sie unter WinDbg Kommandozeilen-Optionen.

Der Debugger sollte starten und sich mit dem QEMU-GdbServer verbinden.

Die Haupt-WinDbg-Sitzung zeigt die EXDI-CLSID im Fenstertitel an.

Der Debugger zeigt die erfolgreiche Initialisierung des EXDI-Transports an.

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

Das Fenster "EXDIGdbServer-Konsolenpakete" kann auch Informationen zum Status der EXDI-Verbindung anzeigen, wenn *"Kommunikationspaketprotokoll unter erweiterten Optionen anzeigen auf "Ein" festgelegt ist. Weitere Informationen finden Sie in der Fehlerbehebung unter Konfigurieren des EXDI-Debugger-Transports.

Verwenden von WinDbg zum Debuggen des Ziel-QEMU-Windows-Images

Die dbgeng.dll verwendet einen heuristischen Algorithmus, um die NT-Basisadresse zu dem Zeitpunkt zu finden, als der Break-Befehl erfolgte. Wenn keine privaten Symbole verfügbar sind, schlägt dieser Prozess fehl.

Das bedeutet, dass die Unterbrechung bei vielen Sequenzen von Verbindungen nicht wie erwartet funktionieren wird. Wenn Sie manuell in den Code eingreifen, wird es sich um eine zufällige Stelle handeln, die Windows zufällig in diesem Moment ausgeführt hat. Da Symbole für den Ziel-Code möglicherweise nicht verfügbar sind, kann es schwierig sein, Haltepunkte mit Hilfe von Symbolen festzulegen.

Verfügbare Debuggerspeicherzugriffsbefehle

Befehle wie die folgenden, die direkt auf den Speicher zugreifen, funktionieren.

k, kb, kc, kd, kp, kP, kv (Stack Backtrace anzeigen)

r (Register)

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

u (Unassemble)

Und Sie können Schritt für Schritt durch den Code gehen.

p (Step)

Es gibt auch Befehle, mit denen Sie versuchen können, den Code zu finden, den Sie debuggen möchten.

s (Speicher durchsuchen)

.imgscan (Bildkopfzeilen suchen)

Imgscan kann beim Debuggen von EDXI hilfreich sein, da das Festlegen von Haltepunkten auf der Basis von Symbolen im Gegensatz zum traditionellen KDNET-basierten Debuggen des Kernels nicht möglich ist. Das Auffinden eines gewünschten Ziel-Images kann das Festlegen eines Haltepunkts für den Zugriff auf den Speicher erleichtern.

.exdicmd (EXDI-Befehl)

.exdicmd sendet einen EXDI-Befehl über die aktive EXDI-Debugging-Verbindung an das Zielsystem. Weitere Informationen finden Sie unter .exdicmd (EXDI Command).

Problembehandlung

Beachten Sie die Informationen zur Fehlerbehebung in Konfiguration des EXDI-Debugger-Transports.

Siehe auch

EXDI-Debugger-Transport konfigurieren

EXDI XML-Konfigurationsdateien

.exdicmd (EXDI-Befehl)

Automatisches Einrichten des KDNET-Netzwerkkernel-Debuggings

Manuelles Debuggen des KDNET-Netzwerkkerns einrichten