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.
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.
- Laden Sie QEMU herunter, und installieren Sie es auf Windows.
- 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.
- Starten Sie die QEMU-Umgebung mit einem Startskript.
- Starten Sie den GdbServer auf QEMU.
- Ü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).
- Laden Sie die Windows-Debugging-Tools herunter und installieren Sie sie auf dem Hostsystem.
- Starten Sie WinDbg mithilfe der Befehlszeile oder Benutzeroberfläche, um eine Verbindung mit dem EXDI-Server herzustellen.
- 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:
- Extrahieren Sie die VirtIo-Treiber in einem Ordner, z. B
C:\VirtIo_Drivers
. . - 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.
- 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. - 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.
Sobald der virtuelle Windows-Computer in der QEMU-Umgebung gestartet ist, erscheint die QEMU-Benutzeroberfläche.
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
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.
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)
d, da, db, dc, dd, dD, df, dp, dq, du, dw (Display-Speicher)
Und Sie können Schritt für Schritt durch den Code gehen.
Es gibt auch Befehle, mit denen Sie versuchen können, den Code zu finden, den Sie debuggen möchten.
.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
Automatisches Einrichten des KDNET-Netzwerkkernel-Debuggings