Konfigurieren des EXDI-Debuggertransports

In diesem Thema wird beschrieben, wie Sie Kernel-Mode Debuggen mithilfe von EXDI einrichten. Die Extended Debugging Interface (EXDI) ist eine Anpassungsebene zwischen einem Softwaredebugger und einem Debugziel. Die Debugtools für Windows unterstützen das Kerneldebuggen mit EXDI ab Windows Version 22000.

EXDI kann verwendet werden, um eine Verbindung mit der virtuellen QEMU-Umgebung herzustellen. Weitere Informationen finden Sie unter Einrichten von QEMU Kernel-Mode Debuggen mit EXDI.

Hinweis

EXDI ist eine erweiterte, spezialisierte Form des Debuggens für bestimmte Umgebungen. Die Verwendung einer KDNET-Standardverbindung ist einfacher zu konfigurieren und wird empfohlen. Informationen zum automatischen Einrichten des Netzwerkdebuggings finden Sie unter Einrichten des automatischen Debuggens von KDNET-Netzwerkkernkernen.

Übersicht über den EXDI COM-Server

EXDI ist eine Schnittstelle, die das Erweitern von WinDbg durch Hinzufügen von Unterstützung für Hardwaredebugger (z. B. JTAG-basiert oder GdbServer-basiert) ermöglicht. Das folgende Diagramm veranschaulicht die Rolle von EXDI-GdbServer.

Stapeldiagramm: Rolle von EXDI-GdbServer mit WinDbg-DbgEng oben, einer EXDI-Schnittstelle und einem EXDI COM-Server, der mit einem GDB-Server kommuniziert.

Da die EXDI-Verbindung keine Abhängigkeit von Windows oder dem KDNET-Protokoll aufweist, das auf dem Ziel-PC geladen wird. Da diese Softwaredebuggerkomponenten nicht erforderlich sind, kann EXDI beim frühen Gerätestart und beim Debuggen von Betriebssystemstartproblemen nützlich sein.

Wichtig

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

EXDI Kernel-Mode Geräteanforderungen

Der Computer, auf dem der Debugger ausgeführt wird, heißt Hostcomputer, und der zu debuggende Computer wird als Zielcomputer bezeichnet.

Folgendes ist erforderlich:

  • Auf dem Ziel- und Hostcomputer Karte ein unterstütztes Netzwerk von der gewünschten Umgebung wie QEMU unterstützt.

  • Eine Netzwerkverbindung zwischen dem Ziel und dem Host mithilfe von TCP/IP.

  • Windows 10 oder Windows 11 Version 22000 oder höher.

Einschränkungen

  • DAS EXDI-Hardwaredebuggen muss manuell mithilfe von XML-Dateien konfiguriert werden, und es gibt keine zugehörige Benutzeroberfläche in den Windows-Debuggern.

  • Wie oben beschrieben, verfügt EXDI nicht über das KDNET-Protokoll, der verbundene Debugger verfügt über weniger Informationen über das Zielsystem und die Verwendung des Debuggers ist unterschiedlich. Ohne Zugriff auf private Symbole für den Zielcode funktionieren viele Befehle, die Symbole verwenden, um den Zustand des Zielsystems zu verstehen. In diesem Fall ist es möglich, Arbeitsspeicher anzuzeigen und Inhalte zu registrieren und Code zu disassemblieren. Die Ermittlung des Speicherorts des ausgeführten Codes oder das Ausführen anderer gängiger Debuggeraufgaben kann mit nicht privaten Symbolen sehr schwierig und zeitaufwändig sein.

COM GDB Server-Client

In diesem Thema wird die Verwendung des EXDI COM GDB Server-Clients (ExdiGdbSrv.dll) behandelt, der die EXDI COM-Debuggerschnittstelle implementiert. Es ist möglich, dieselbe COM-Schnittstelle zu verwenden, um andere Schnittstellen zu implementieren, z. B. einen EXDI COM-Server für JTAG-DCI.

Gleichzeitiges EXDI- und KDNET-Debuggen

In einigen komplexen Szenarien, z. B. bei der frühen Geräteerzielung, kann es nützlich sein, zwei Verbindungen mit dem Zielgerät zu haben. Ein EXDI und ein KDNET. Wenn es sich bei dem Ziel um ein Windows-Betriebssystem handelt, wird das KDNET-Softwaredebugging wie gewohnt konfiguriert, z. B. um eine Verbindung mit einem virtuellen Computer herzustellen. In diesem Setup kann einer der beiden gleichzeitigen Debugger zum Debuggen von Code auf dem Zielcomputer einbrechen.

Zusammenfassung des Prozesses zum Konfigurieren einer EXDI-Verbindung

In diesem Thema wird der Prozess zum Konfigurieren einer EXDI-Verbindung beschrieben. Ein BEISPIEL für ein EXDI-Nutzungsszenario finden Sie unter Einrichten von QEMU Kernel-Mode Debuggen mit EXDI.

  1. Laden Sie die Windows-Debugtools herunter, und installieren Sie sie auf dem Hostsystem.
  2. Laden Sie die EXDI-Server-DLL herunter, erstellen Sie sie und registrieren Sie sie.
  3. Konfigurieren Sie die Verbindung, indem Sie die XML-Dateien der EXDI-Konfiguration bearbeiten.
  4. Starten Sie WinDbg mit der Option -kx, um eine Verbindung mit dem EXDI-Server herzustellen.
  5. Verwenden Sie WinDbg, um das Zielsystem zu debuggen.

Herunterladen und Installieren der Windows-Debugtools

Installieren Sie die Windows-Debugtools auf dem Hostsystem. Informationen zum Herunterladen und Installieren der Debuggertools finden Sie unter Debuggen von Tools für Windows.

Herunterladen, Erstellen und Registrieren der EXDI-Server-DLL

Laden Sie den entsprechenden ExdiGdbSrv.dll Binärcode (EXDI COM-Serverclient) aus dem Microsoft/WinDbg-Samples, GitHub https://github.com/microsoft/WinDbg-Samples) herunter.

git clone https://github.com/microsoft/WinDbg-Samples

Erstellen Sie die VS-Lösung (ExdiGdbSrv.sln) gemäß der Architektur Ihrer Hostdebuggerinstallation in Exdi/exdigdbsrv.

Suchen Sie die vom Build erzeugte ExdiGdbSrv.dll.

Kopieren Sie den EXDI com-Server (ExdiGdbSrv.dll) auf den Hostcomputer in das Verzeichnis, das Ihren Debugger (.g) enthält. C:\Program Files (x86)\Windows Kits\10\Debuggers\x64 oder C:\Debuggers)

Verwenden Sie regsvr32, um die DLL an einer Administratoreingabeaufforderung zu registrieren.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>regsvr32 ExdiGdbSrv.dll

RegSvr32 sollte eine Meldung zurückgeben, die angibt, dass .DLLRegisterServer in ExdiGdbSrv.dll succeeded

Dieser Schritt muss nur einmal ausgeführt werden, aber wenn Sie den Speicherort des ExdiGdbSrv.dll ändern, müssen Sie den COM-Server erneut registrieren.

Eine weitere Option besteht darin, das PowerShell-Beispielskript zu verwenden, um die EXDI-DLL zu installieren und den Debugger beim ersten Mal zu starten. Weitere Informationen finden Sie unter Beispiel-EXDI-PowerShell-Skript.

Konfigurieren von WinDbg mithilfe der EXDI-Konfigurations-XML-Dateien

Suchen Sie die beiden erforderlichen Konfigurationsdateien in, WinDbg-Samples/Exdi/exdigdbsrv/ und kopieren Sie sie in einen lokalen Auf dem Hostdebuggercomputer, auf dem der Debugger installiert ist.

  • exdiConfigData.xml
  • systemregisters.xml

EXDI_GDBSRV_XML_CONFIG_FILE: Beschreibt den vollständigen Pfad zur Exdi xml-Konfigurationsdatei.

EXDI_SYSTEM_REGISTERS_MAP_XML_FILE: Beschreibt den vollständigen Pfad zur Systemregisterzuordnungsdatei des Exdi-XML-Systems.

Weitere Informationen zu den exdiConfigData.xml Tags und Attributen finden Sie weiter unten unter EXDI XML-Konfigurationsdateien .

In unserem Szenario legen wir den folgenden Wert auf 0 fest, um zu deaktivieren, dass der Debugger versucht, den nt!kdVersionBlock zu suchen.

heuristicScanSize = "0"

Legen Sie die EXDI-Pfadwerte so fest, dass sie auf den Speicherort der XML-Konfigurationsdateien verweisen.

Legen Sie die Umgebungsvariable EXDI_GDBSRV_XML_CONFIG_FILE und EXDI_SYSTEM_REGISTERS_MAP_XML_FILE fest, um den vollständigen Pfad zur exdi xml-Konfigurationsdatei zu beschreiben. Stellen Sie sicher, dass der angegebene Pfadumgebungswert am Speicherort des ExdiGdbSrv.dll verfügbar ist.

Eingabeaufforderung

Öffnen Sie eine Eingabeaufforderung, und legen Sie die folgenden Umgebungsvariablen fest.

set EXDI_GDBSRV_XML_CONFIG_FILE="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\exdiConfigData.xml"

set EXDI_SYSTEM_REGISTERS_MAP_XML_FILE="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\systemregisters.xml"

Geben Sie ein SET , um zu bestätigen, dass der angegebene Pfad am Speicherort des ExdiGdbSrvSample.dll

PowerShell

Öffnen Sie eine PowerShell-Eingabeaufforderung, und legen Sie die folgenden Umgebungsvariablen fest:

$env:EXDI_GDBSRV_XML_CONFIG_FILE = 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\exdiConfigData.xml'

$env:EXDI_SYSTEM_REGISTERS_MAP_XML_FILE = 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\systemregisters.xml'

Geben Sie ein dir env: , um zu bestätigen, dass der angegebene Pfad am Speicherort des ExdiGdbSrvSample.dll

Starten Sie WinDbg, und stellen Sie eine Verbindung mit dem EXDI-Server her.

Starten Sie die windbg-Sitzung über die exdi-Schnittstelle an derselben Eingabeaufforderung, an der Sie die Umgebungsvariablen (EXDI_GDBSRV_XML_CONFIG_FILE und EXDI_SYSTEM_REGISTERS_MAP_XML_FILE) festlegen.

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

Um zusätzliche Ausgabe anzuzeigen, die für Diagnosezwecke nützlich ist, kann die ausführliche Sitzung -v: verwendet werden. Allgemeine Informationen zu den WinDbg-Optionen finden Sie unter WinDbg Command-Line Optionen. Weitere Informationen finden Sie unter EXDI WinDbg Load Parameters unten.

Der Debugger zeigt die erfolgreiche EXDI-Transportinitialisierung an.

EXDI: DbgCoInitialize returned 0x00000001
EXDI: CoCreateInstance() returned 0x00000000
EXDI: QueryInterface(IExdiServer3) returned 0x00000000
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
Kernel Debugger connection established

WinDbg-Hauptsitzung, die EXDI CLSID im Fenstertitel anzeigt.

Das EXDIGdbServer-Konsolenfenster kann auch Informationen über die status der EXDI-Verbindung anzeigen. Weitere Informationen zur Konsole finden Sie unter Problembehandlung.

EXDI WinDbg-Ladeparameter

Die folgenden Parameter werden mit WinDbg verwendet, um eine EXDI-Kernelsitzung zu starten.

-kx: EXDI:Optionen

Die folgenden EXDI-Optionen sind mit der Option -kx verfügbar.

Parameter BESCHREIBUNG
CLSID Klassen-ID, die dem LiveExdiGdbSrvServer zugewiesen ist (wie in der DateiExdiGdbSrv.idl definiert).
Kd=NtBaseAddr Das Debuggermodul sucht nach der NT-Basisadresse.
ForceX86 Erzwingt die Debugger-Engine, die IeXdiX86Context3-Schnittstelle zum Abrufen/Festlegen des CPU-Kontexts zu verwenden.
DataBreaks=Exdi Zulassen der Verwendung von Daten breakpoints.
Inproc Erlauben Sie die Verwendung eines inproc Exdi-Servers.

Verwenden von WinDbg zum Debuggen des Zielsystems

Die dbgeng.dll verwendet einen heuristischen Algorithmus, um den Speicherort der NT-Basisladeadresse zu dem Zeitpunkt zu ermitteln, an dem der Umbruchbefehl aufgetreten ist. Wenn keine privaten Symbole verfügbar sind, schlägt dieser Prozess fehl.

Dies bedeutet, dass der Umbruch unter vielen Verbindungssequenzen nicht wie erwartet funktioniert. wenn Sie manuell in den Code einbrechen, handelt es sich um einen zufälligen Ort, den Windows in diesem Moment ausgeführt hat. Da Symbole für den Zielcode möglicherweise nicht verfügbar sind, kann es schwierig sein, Haltepunkte mithilfe von Symbolen festzulegen.

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

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

r (Register)

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

u (Unassemble)

Und Sie können Code mit p (Schritt) schrittweise durchlaufen.

Es gibt auch Befehle, mit denen versucht werden kann, code zu suchen, den Sie debuggen möchten.

s (Speicher durchsuchen)

.imgscan (Bildheader suchen)

Imgscan kann beim EDXI-Debuggen hilfreich sein, da im Gegensatz zum herkömmlichen KDNET-basierten Kerneldebuggen das Festlegen von Haltepunkten basierend auf Symbolen möglicherweise nicht verfügbar ist. Das Suchen eines gewünschten Zielimages kann die Verwendung des Speicherorts erleichtern, um einen Speicherzugriffs-Breakpoint festzulegen.

.exdicmd (EXDI-Befehl)

.exdicmd sendet einen EXDI-Befehl an das Zielsystem unter Verwendung der aktiven EXDI-Debugverbindung. Weitere Informationen finden Sie unter EXDICMD (EXDI-Befehl).

Problembehandlung

Verwenden Sie die Ausgabe aus dem ExdiGdbServer-Fenster, um die Verbindungssequenz zu überwachen.

ExdiGdbServer-Textfenster mit langen Hexadezimalzahlen.

Problem: Fehler: Es konnte keine Verbindung mit dem GbDServer hergestellt werden. Überprüfen Sie die Verbindungszeichenfolge <hostname/ip>:portnumber

Dieses Problem kann durch folgende Ursachen verursacht werden:

  • Die ExdiGdbSrv.dll kann keine Verbindung mit dem GDB-Zielserver herstellen.
  • Der GDB-Server wird noch nicht am Ziel ausgeführt.
  • Stellen Sie sicher, dass beide IP-Adressen erreichbar sind, indem Sie ping, tracert oder ein anderes Tool verwenden, um zu überprüfen, ob der GDB-Datenverkehr die Firewall durchlaufen kann.

Problem: Das Kerneldebugging mit EXDI konnte nicht gestartet werden.

Dieses Problem kann durch folgende Ursachen verursacht werden:

  • Auf dem Hostdebuggercomputer wird eine weitere instance der ExdiGdbSrv.dll (gehostet von dllhost.exe) ausgeführt.
  • Beenden Sie den zusätzlichen instance des COM-Diensts, der die ExdiGdbSrv.dll hostt.
    • Führen Sie zunächst die Prozesse mit dem Hilfsprogramm TList auf dem Host-PC auf. Der DLLHost, der die ExdiGdbSrv.dll hosten, zeigt ExdiGdbServer an.

      tlist 261928 dllhost.exe ExdiGdbServer

    • Verwenden Sie kill -f XXXXX an der Debugger-Eingabeaufforderung, um den Prozess mit der Prozessnummer zu beenden.

Problem: Fehler: Die GdbServer-Sitzung kann nicht konfiguriert werden.

Dieses Problem kann durch folgende Ursachen verursacht werden:

  • Fehler beim Suchen der Sitzungsinformationen, z. B. des Pfads zu den XML-Konfigurationsdateien.

Problem: Fehler: Die EXDI_GDBSRV_XML_CONFIG_FILE Umgebungsvariable ist nicht definiert.

Dieses Problem kann durch folgende Ursachen verursacht werden:

  • ExdiGdbSrv.dll Umgebungsvariablen sind in der Umgebung nicht festgelegt oder anderweitig nicht verfügbar.

Problem: Fehler: Die EXDI_GDBSRV_XML_CONFIG_FILE Umgebungsvariable ist nicht definiert. Das Exdi-GdbServer Beispiel wird an diesem Punkt nicht fortgesetzt. Legen Sie den vollständigen Pfad auf die Exdi xml-Konfigurationsdatei fest.

Dieses Problem kann durch folgende Ursachen verursacht werden:

  • Die EXDI_GDBSRV_XML_CONFIG_FILE Umgebungsvariable ist nicht festgelegt. In einigen Situationen funktioniert ExdiGDbSrv.dll weiterhin, wenn Sie die Schaltfläche "OK" drücken, aber windbg.exe fehler beim Abfragen von Systemregistern (z. B. über rdmsr/wrmsr-Funktionen).

Problem: Fehlerszenario mit dem Zielsystem ist nicht verfügbar: DbgCoInitialize gibt 0x00000001

Die folgende Ausgabe wird möglicherweise zurückgegeben, wenn das Zielsystem nicht geladen oder anderweitig nicht verfügbar ist.

Microsoft (R) Windows Debugger Version 10.0.20317.1 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

EXDI: DbgCoInitialize returned 0x00000001

Dies ist ein häufiger Fehler, wenn der ExdiGdbSrv.dll COM-Server keine Verbindung mit dem QEMU GDServer herstellen konnte, sodass ein Fehler aufgrund von:

  • Fehler beim Starten des EXDI COM-Servers (ExdiGDbSrv.dll) über den dllhost.exe-Prozess (COM-bezogen). Um dies zu beheben, starten Sie den Hostdebugger-PC neu, oder melden Sie sich erneut ab, und melden Sie sich erneut an. Wenn dies nicht funktioniert, registrieren Sie den EXDI COM-Server nach dem neustarten/anmelden erneut.

    • regsvr32.exe <full path to the ExdiGdbSrv.dll)
  • Die vorherige Sitzung des ExdiGdbSrv.dll wird weiterhin von einem dllhost.exe-Prozess gehostet, sodass Sie den dllhost.exe-Prozess beenden müssen. Überprüfen Sie tlist auf den Pid von dllhost.exe, der die ExdiGdbSrv.dll hostet, und töten Sie den zugehörigen pid.

  • Der QEMU gdbserver wurde noch nicht gestartet, oder die exdiconfigdata.xml Datei enthält ungültige IP:Port-Werte. Wenn die WinDbg-Sitzung auf demselben Host-PC wie die QEMU-Windows-VM gestartet wird, dann die IP=LocalHost.

Problem: Die Debugsitzung konnte nicht gestartet werden: FAILURE HR=0x80004005:Failed to AttachKernel.

Dieses Problem kann durch folgende Ursachen verursacht werden:

  • Wie oben beschrieben, ist es möglich, dass die vorherige Sitzung des ExdiGdbSrv.dll weiterhin aktiv ist. Suchen und beenden Sie den zugeordneten DLL-Host, wie oben beschrieben.

WinDbg-Dialogfeld, das einen Fehler mit HR-0x80004005 anzeigt.

EXDI XML-Konfigurationsdateien

Es gibt zwei erforderliche XML-Dateien, die vom EXDI GDB COM-Server (ExdiGdbSrv.dll) verwendet werden.

  1. exdiConfigData.xml : Diese Datei enthält die Standard Konfigurationsdaten, die vom GDB-Serverclient erforderlich sind, um eine erfolgreiche GDB-Sitzung mit dem GDB-Serverziel des HW-Debuggers einzurichten, sodass der GDB-Serverclient nicht ausgeführt wird, wenn der Dateispeicherort nicht von der EXDI_GDBSRV_XML_CONFIG_FILE Umgebungsvariablen festgelegt wird. Jedes XML-Tag ermöglicht das Konfigurieren eines bestimmten Satz der GDB-Serverfunktionalität. Unten finden Sie eine Liste der Attribute, die Sie im XML-Code ändern können, und beispiel-XML.

  2. Systemregister.xml : Diese Datei enthält eine Zuordnung zwischen Systemregistern und ihrem Zugriffscode. Dies ist erforderlich, da der Zugriffscode nicht vom GDB-Server in der XML-Datei bereitgestellt wird und der Debugger über den Zugriffscode auf jedes Systemregister zugreift. Wenn die Datei nicht über die Umgebungsvariable EXDI_SYSTEM_REGISTERS_MAP_XML_FILEfestgelegt wird, funktioniert die ExdiGdbSrv.dll weiterhin, aber der Debugger kann nicht über rdmsr- oder wrmsr-Befehle auf ein Systemregister zugreifen. Die Liste dieser Register sollte vom Hardwaredebugger des GDB-Servers unterstützt werden (der spezifische Systemregistername sollte in der Liste der Register enthalten sein, die in der XML-Datei des Systems gesendet werden).

GDBServer-Tags und -Attribute

In der folgenden Tabelle werden die GDBServer-Tags und -Attribute beschrieben, die in der exdiConfigData.xml Datei definiert sind.

Parameter BESCHREIBUNG
ExdiTargets Gibt an, welche bestimmte GDB-Serverzielkonfiguration vom ExdiGgbSrv.dll verwendet wird, um die GDB-Verbindung mit dem GDB-Serverziel herzustellen, da die exdiConfigData.xml-Datei alle GDB-Server enthält, die derzeit vom ExdiGdbSrv.dll unterstützt werden (diese Datei MUSS ausgefüllt werden, bevor sie den ExdiGdbSrv.dll mit einem bestimmten GDB-Server verwenden).
CurrentTarget Gibt den Namen des GDB-Serverziels an (z. B. sollte dieser Attributwert mit dem Namenswert eines der Tags übereinstimmen, die <ExdiTarget Name= in der exdiConfigData.xml-Datei enthalten sind.
ExdiTarget dies ist das Starttag für alle Konfigurationsdaten, die von jeder GDB-Serverzielkomponente enthalten sind.
Name Gibt den Namen des GDB-Servers an (z. B. QEMU, BMC-OpenOCD, Trace32, VMWare).
agentNamePacket Dies ist der Name des GDB-Clients, da er vom HW-Debugger des GDB-Servers erkannt wird. Dies kann vom HW-Debugger des GDB-Servers verwendet werden, um sich für bestimmte GDB-Clients zu konfigurieren (z. B. benötigt der Trace32-GDB-Server den ExdiGdbSrv.dll, um den Namen "QMS.windbg" zu senden, um den windbg-GDB-Client zu identifizieren und dann benutzerdefinierte GDB-Speicherpakete zu aktivieren, die nur für den MS GDB-Serverclient (exdiGdbSrv.dll) unterstützt werden.
ExdiGdbServerConfigData Gibt die ExdiGdbSrv.dll komponentenbezogenen Konfigurationsparameter an.
UUID gibt die UUI der ExdiGdbSrv.dll-Komponente an.
displayCommPackets Wenn "ja" gekennzeichnet ist, werden die Kommunikationszeichen des RSP-Protokolls im Befehlsprotokollfenster angezeigt. Wenn "nein" ist, wird nur der Text des Anforderungs-Antwort-Paares angezeigt.
enableThrowExceptionOnMemoryErrors Dieses Attribut wird vom GDB-Serverclient überprüft, wenn ein GDB-Fehlerantwortpaket (E0x) vorhanden ist, um zu bestimmen, ob der Client eine Ausnahme auslösen und den Lesespeicher beenden soll.
qSupportedPacket Dadurch kann der GDB-Client so konfiguriert werden, dass er angibt, welche XML-Registerarchitekturdatei vom GDB-Server-HW-Debugger nach der XML-Zielbeschreibungsdatei gesendet werden soll (im Grunde teilt der Client dem GDB-Server mit, welche Architekturen vom Client unterstützt werden. Derzeit unterstützt der Client die x64-Architektur).
ExdiGdbServerTargetData Gibt die Parameter im Zusammenhang mit dem Hardwareziel an, das von der GdbServer-Sitzung gedebuggt wird.
targetArchitecture Zeichenfolge mit der Zielhardwarearchitektur. Mögliche Werte: X86, X64, ARM, ARM64. Derzeit unterstützt die exdiGdbSrv.dll nur X86 und ARM.
targetFamily Zeichenfolge, die die Zielhardwarefamilie enthält. Mögliche Werte: ProcessorFamilyX86, ProcessorFamilyX64, ProcessorFamilyARM, ProcessorFamilyARM64.
numberOfCores Anzahl der Prozessorkerne, die vom Ziel unterstützt werden. Dieser Parameter wird überprüft, wenn wir eine Multi-Gdbserver-Sitzung (T32-GdbServer-Sitzung) verwenden. Das folgende Attribut "MultiCoreGdbServerSessions" sollte auf "Ja" festgelegt werden.
EnableSseContext Wenn "ja" gekennzeichnet ist, enthält das RSP-Paket des G-Kontexts Gleitkommaregisterwerte. Dieser Parameter ist nur für Intel-Familienziele sinnvoll.
heuristicScanSize Dadurch wird der schnelle heuristische Algorithmus der Debugger-Engine so konfiguriert, dass der gescannte Speichertest um die angegebene Größe verringert wird, wenn der Attributwert nicht angegeben wird (oder "0"), dann verwendet die Debugger-Engine nicht die schnelle Heuristik und fallt auf die Legacyheuristik zurück, die den gesamten Speicher auf der Suche nach der PE DOS-Signatur überprüft.
targetDescriptionFile gibt an, ob der GDB-Server vor dem Senden jeder separaten XML-Datei eine Zielbeschreibungsheaderdatei sendet. Dieses Feld ist leer, dann fordert der GDB-Serverclient das XML-Architektursystemregister nicht an (z. B. Trace32-GDBs-Server, der das Senden von Architekturregistern in einer separaten XML-Datei nicht unterstützt).
GdbServerConnectionParameters Gibt GdbServer-Sitzungsparameter an. Diese Parameter werden verwendet, um die RSP GdbServer-Sitzung zwischen der komponente ExdiGdbSrv.dll und GdbServer zu steuern.
MultiCoreGdbServerSessions Flag If 'yes', then we will have multi-core GdbServer session (the one used by T32-GdbServer Back-End). Wenn "nein" ist, kommunizieren wir nur mit einem instance des GdbServers.
MaximumGdbServerPacketLength Dies ist die maximale von GdbServer unterstützte Länge für ein Paket.
MaximumConnectAttempts Dies ist die maximale Anzahl von Verbindungsversuchen. Sie wird vom ExdiGdbSrv.dll verwendet, wenn versucht wird, die RSP-Verbindung mit dem GdbServer herzustellen.
SendPacketTimeout Dies ist das RSP-Sendetimeout.
ReceivePacketTimeout Dies ist das RSP-Empfangstimeout.
HostNameAndPort Dies ist die Verbindungszeichenfolge im Format <hostname/ip address:Port number>. Es kann mehrere GdbServer-Verbindungszeichenfolge (z. B. eine GdbServer-Sitzung mit mehreren Kernen) geben. Die Anzahl der Verbindungszeichenfolgen sollte mit der Anzahl der Kerne übereinstimmen.
ExdiGdbServerMemoryCommands Gibt verschiedene Möglichkeiten an, die GDB-Speicherbefehle auszugeben, um Systemregisterwerte oder Lese-/Schreibzugriffsspeicher auf unterschiedlichen CPU-Ausnahmeebenen abzurufen (z. B. BMC-OpenOCD den Zugriff auf das CP15-Register über den angepassten Befehl "aarch64 mrs nsec/sec <access code>" ermöglicht).
GdbSpecialMemoryCommand Wenn "ja" ist, unterstützt der GDB-Server angepasste Speicherbefehle (z. B. Systemregister, dies sollte für Trace32 GDB-Server festgelegt werden).
PhysicalMemory Wenn ja, unterstützt der GDB-Server benutzerdefinierte Befehle zum Lesen des physischen Arbeitsspeichers (er ist für trace32 GDB-Server festgelegt).
SupervisorMemory Wenn "ja" ist, unterstützt der GDB-Server angepasste Befehle zum Lesen des Supervisorspeichers (er ist für trace32 GDB-Server festgelegt).
SpecialMemoryRegister Wenn "ja" ist, unterstützt der GDB-Server benutzerdefinierte Befehle zum Lesen von Systemregistern (er ist für Trace32 GDB-Server festgelegt).
SystemRegistersGdbMonitor Wenn "ja", unterstützt der GDB-Server angepasste Befehle über den GDB-Monitorbefehl (er ist für BMC Open-OCD festgelegt).
SystemRegisterDecoding Wenn "ja", akzeptiert der GDB-Client die Decodierung des Zugriffscodes, bevor der GDB-Monitorbefehl gesendet wird.
ExdiGdbServerRegisters Gibt den spezifischen Architekturregisterkernsatz an.
Aufbau CPU-Architektur des definierten Registersatzes.
FeatureNameSupported Dies ist der Name der Systemregistergruppe, wie er von der XML-Systemregisterbeschreibungsdatei bereitgestellt wird. Es ist erforderlich, die XML-Gruppe des Systemregisters zu identifizieren, die Teil der XML-Datei ist, während sie vom GDB-Server gesendet wird.
SystemRegisterStart Dies ist, um das erste Systemregister (niedrige Registernummer/Reihenfolge) zu identifizieren, das als Teil des Kernregistersatzes gemeldet wird (z. B. meldet QEMU bei X64 den x64-Systemregistersatz nicht als separate XML-Zieldatei, sodass Systemregs Teil der Kernregister sind).
SystemRegistersEnd Dadurch wird das letzte Systemregister (hohe Registernummer/Reihenfolge) identifiziert, das als Teil des Kernregistersatzes gemeldet wird.
Name Name des Registers.
Order Dies ist eine Zahl, die den Index im Array von Registern identifiziert. Diese Nummer wird von den GDB-Client- und Serversatz-/Abfrage-Registerpaketen (p<number>”/”q<number>) verwendet.
Size Dies ist die Registergröße in Bytes.

Beispieldatei für exdiConfigData.xml

<ExdiTargets CurrentTarget = "QEMU">
<!-- QEMU SW simulator GDB server configuration -->
    <ExdiTargets CurrentTarget="QEMU">
    <!--  QEMU SW simulator GDB server configuration  -->
    <ExdiTarget Name="QEMU">
    <ExdiGdbServerConfigData agentNamePacket="" uuid="72d4aeda-9723-4972-b89a-679ac79810ef" displayCommPackets="yes" debuggerSessionByCore="no" enableThrowExceptionOnMemoryErrors="yes" qSupportedPacket="qSupported:xmlRegisters=aarch64,i386">
    <ExdiGdbServerTargetData targetArchitecture="ARM64" targetFamily="ProcessorFamilyARM64" numberOfCores="1" EnableSseContext="no" heuristicScanSize="0xfffe" targetDescriptionFile="target.xml"/>
    <GdbServerConnectionParameters MultiCoreGdbServerSessions="no" MaximumGdbServerPacketLength="1024" MaximumConnectAttempts="3" SendPacketTimeout="100" ReceivePacketTimeout="3000">
    <Value HostNameAndPort="LocalHost:1234"/>
    </GdbServerConnectionParameters>
    <ExdiGdbServerMemoryCommands GdbSpecialMemoryCommand="no" PhysicalMemory="no" SupervisorMemory="no" HypervisorMemory="no" SpecialMemoryRegister="no" SystemRegistersGdbMonitor="no" SystemRegisterDecoding="no"> </ExdiGdbServerMemoryCommands>
        <ExdiGdbServerRegisters Architecture = "ARM64" FeatureNameSupported = "sys">
            <Entry Name ="X0"  Order = "0" Size = "8" />
            <Entry Name ="X1"  Order = "1" Size = "8" />
            <Entry Name ="X2"  Order = "2" Size = "8" />
            <Entry Name ="X3"  Order = "3" Size = "8" />
            <Entry Name ="X4"  Order = "4" Size = "8" />
            <Entry Name ="X5"  Order = "5" Size = "8" />
            <Entry Name ="X6"  Order = "6" Size = "8" />
            <Entry Name ="X7"  Order = "7" Size = "8" />
            <Entry Name ="X8"  Order = "8" Size = "8" />
            <Entry Name ="X9"  Order = "9" Size = "8" />
            <Entry Name ="X10" Order = "a"  Size = "8" />
            <Entry Name ="X11" Order = "b"  Size = "8" />
            <Entry Name ="X12" Order = "c"  Size = "8" />
            <Entry Name ="X13" Order = "d"  Size = "8" />
            <Entry Name ="X14" Order = "e"  Size = "8" />
            <Entry Name ="X15" Order = "f"  Size = "8" />
            <Entry Name ="X16" Order = "10" Size = "8" />
            <Entry Name ="X17" Order = "11" Size = "8" />
            <Entry Name ="X18" Order = "12" Size = "8" />
            <Entry Name ="X19" Order = "13" Size = "8" />
            <Entry Name ="X20" Order = "14" Size = "8" />
            <Entry Name ="X21" Order = "15" Size = "8" />
            <Entry Name ="X22" Order = "16" Size = "8" />
            <Entry Name ="X23" Order = "17" Size = "8" />
            <Entry Name ="X24" Order = "18" Size = "8" />
            <Entry Name ="X25" Order = "19" Size = "8" />
            <Entry Name ="X26" Order = "1a" Size = "8" />
            <Entry Name ="X27" Order = "1b" Size = "8" />
            <Entry Name ="X28" Order = "1c" Size = "8" />
            <Entry Name ="fp"  Order = "1d" Size = "8" />
            <Entry Name ="lr"  Order = "1e" Size = "8" />
            <Entry Name ="sp"  Order = "1f" Size = "8" />
            <Entry Name ="pc"  Order = "20" Size = "8" />
            <Entry Name ="cpsr" Order = "21" Size = "8" />
            <Entry Name ="V0" Order = "22" Size = "16" />
            <Entry Name ="V1" Order = "23" Size = "16" />
            <Entry Name ="V2" Order = "24" Size = "16" />
            <Entry Name ="V3" Order = "25" Size = "16" />
            <Entry Name ="V4" Order = "26" Size = "16" />
            <Entry Name ="V5" Order = "27" Size = "16" />
            <Entry Name ="V6" Order = "28" Size = "16" />
            <Entry Name ="V7" Order = "29" Size = "16" />
            <Entry Name ="V8" Order = "2a" Size = "16" />
            <Entry Name ="V9" Order = "2b" Size = "16" />
            <Entry Name ="V10" Order = "2c" Size = "16" />
            <Entry Name ="V11" Order = "2d" Size = "16" />
            <Entry Name ="V12" Order = "2e" Size = "16" />
            <Entry Name ="V13" Order = "2f" Size = "16" />
            <Entry Name ="V14" Order = "30" Size = "16" />
            <Entry Name ="V15" Order = "31" Size = "16" />
            <Entry Name ="V16" Order = "32" Size = "16" />
            <Entry Name ="V17" Order = "33" Size = "16" />
            <Entry Name ="V18" Order = "34" Size = "16" />
            <Entry Name ="V19" Order = "35" Size = "16" />
            <Entry Name ="V20" Order = "36" Size = "16" />
            <Entry Name ="V21" Order = "37" Size = "16" />
            <Entry Name ="V22" Order = "38" Size = "16" />
            <Entry Name ="V23" Order = "39" Size = "16" />
            <Entry Name ="V24" Order = "3a" Size = "16" />
            <Entry Name ="V25" Order = "3b" Size = "16" />
            <Entry Name ="V26" Order = "3c" Size = "16" />
            <Entry Name ="V27" Order = "3d" Size = "16" />
            <Entry Name ="V28" Order = "3e" Size = "16" />
            <Entry Name ="V29" Order = "3f" Size = "16" />
            <Entry Name ="V30" Order = "3f" Size = "16" />
            <Entry Name ="V31" Order = "3f" Size = "16" />
            <Entry Name ="fpsr" Order = "40" Size = "4" />
            <Entry Name ="fpcr" Order = "41" Size = "4" />
        </ExdiGdbServerRegisters>


        <!-- x64 GDB server core resgisters -->
        <ExdiGdbServerRegisters Architecture = "X64" FeatureNameSupported = "sys" SystemRegistersStart = "18" SystemRegistersEnd = "20" >
            <Entry Name ="rax" Order = "0" Size ="8" />
            <Entry Name ="rbx" Order = "1" Size ="8" />
            <Entry Name ="rcx" Order = "2" Size ="8" />
            <Entry Name ="rdx" Order = "3" Size ="8" />
            <Entry Name ="rsi" Order = "4" Size ="8" />
            <Entry Name ="rdi" Order = "5" Size ="8" />
            <Entry Name ="rbp" Order = "6" Size ="8" />
            <Entry Name ="rsp" Order = "7" Size ="8" />
            <Entry Name ="r8"  Order = "8" Size ="8" />
            <Entry Name ="r9"  Order = "9" Size ="8" />
            <Entry Name ="r10" Order = "a" Size ="8" />
            <Entry Name ="r11" Order = "b" Size ="8" />
            <Entry Name ="r12" Order = "c" Size ="8" />
            <Entry Name ="r13" Order = "d" Size ="8" />
            <Entry Name ="r14" Order = "e" Size ="8" />
            <Entry Name ="r15" Order = "f" Size ="8" />
            <Entry Name ="rip" Order = "10" Size ="8" />
            <!-- <flags id="x64_eflags" size="4">
                <field name="" start="22" end="31"/>
                <field name="ID" start="21" end="21"/>
                <field name="VIP" start="20" end="20"/>
                <field name="VIF" start="19" end="19"/>
                <field name="AC" start="18" end="18"/>
                <field name="VM" start="17" end="17"/>
                <field name="RF" start="16" end="16"/>
                <field name="" start="15" end="15"/>
                <field name="NT" start="14" end="14"/>
                <field name="IOPL" start="12" end="13"/>
                <field name="OF" start="11" end="11"/>
                <field name="DF" start="10" end="10"/>
                <field name="IF" start="9" end="9"/>
                <field name="TF" start="8" end="8"/>
                <field name="SF" start="7" end="7"/>
                <field name="ZF" start="6" end="6"/>
                <field name="" start="5" end="5"/>
                <field name="AF" start="4" end="4"/>
                <field name="" start="3" end="3"/>
                <field name="PF" start="2" end="2"/>
                <field name="" start="1" end="1"/>
                <field name="CF" start="0" end="0"/>
            </flags> -->
            <Entry Name ="eflags" Order = "11" Size ="4" />

            <!-- Segment registers -->
            <Entry Name ="cs" Order = "12" Size ="4" />
            <Entry Name ="ss" Order = "13" Size ="4" />
            <Entry Name ="ds" Order = "14" Size ="4" />
            <Entry Name ="es" Order = "15" Size ="4" />
            <Entry Name ="fs" Order = "16" Size ="4" />
            <Entry Name ="gs" Order = "17" Size ="4" />

            <!-- Segment descriptor caches and TLS base MSRs -->
            <!--Entry Name ="cs_base" Order = "18" Size="8"/
            <Entry Name ="ss_base" Order = "18" Size ="8" />
            <Entry Name ="ds_base" Order = "19" Size ="8" />
            <Entry Name ="es_base" Order = "1a" Size ="8" /> -->
            <Entry Name ="fs_base" Order = "18" Size ="8" />
            <Entry Name ="gs_base" Order = "19" Size ="8" />
            <Entry Name ="k_gs_base" Order = "1a" Size ="8" />

            <!-- Control registers -->
            <!-- the cr0 register format fields:
            <flags id="x64_cr0" size="8">
            <field name="PG" start="31" end="31"/>
            <field name="CD" start="30" end="30"/>
            <field name="NW" start="29" end="29"/>
            <field name="AM" start="18" end="18"/>
            <field name="WP" start="16" end="16"/>
            <field name="NE" start="5" end="5"/>
            <field name="ET" start="4" end="4"/>
            <field name="TS" start="3" end="3"/>
            <field name="EM" start="2" end="2"/>
            <field name="MP" start="1" end="1"/>
            <field name="PE" start="0" end="0"/>
            </flags> -->
            <Entry Name ="cr0" Order = "1b" Size ="8" />
            <Entry Name ="cr2" Order = "1c" Size ="8" />

            <!-- the cr3 register format fields:
            <flags id="x64_cr3" size="8">
                <field name="PDBR" start="12" end="63"/>
                <field name="PCID" start="0" end="11"/>
            </flags> -->
            <Entry Name ="cr3" Order = "1d" Size ="8" />

            <!-- the cr4 register format fields:
            <flags id="x64_cr4" size="8">
                <field name="PKE" start="22" end="22"/>
                <field name="SMAP" start="21" end="21"/>
                <field name="SMEP" start="20" end="20"/>
                <field name="OSXSAVE" start="18" end="18"/>
                <field name="PCIDE" start="17" end="17"/>
                <field name="FSGSBASE" start="16" end="16"/>
                <field name="SMXE" start="14" end="14"/>
                <field name="VMXE" start="13" end="13"/>
                <field name="LA57" start="12" end="12"/>
                <field name="UMIP" start="11" end="11"/>
                <field name="OSXMMEXCPT" start="10" end="10"/>
                <field name="OSFXSR" start="9" end="9"/>
                <field name="PCE" start="8" end="8"/>
                <field name="PGE" start="7" end="7"/>
                <field name="MCE" start="6" end="6"/>
                <field name="PAE" start="5" end="5"/>
                <field name="PSE" start="4" end="4"/>
                <field name="DE" start="3" end="3"/>
                <field name="TSD" start="2" end="2"/>
                <field name="PVI" start="1" end="1"/>
                <field name="VME" start="0" end="0"/>
            </flags> -->
            <Entry Name ="cr4" Order = "1e" Size ="8" />
            <Entry Name ="cr8" Order = "1f" Size ="8" />

            <!-- the efer register format fields:
            <flags id="x64_efer" size="8">
            <field name="TCE" start="15" end="15"/>
            <field name="FFXSR" start="14" end="14"/>
            <field name="LMSLE" start="13" end="13"/>
            <field name="SVME" start="12" end="12"/>
            <field name="NXE" start="11" end="11"/>
            <field name="LMA" start="10" end="10"/>
            <field name="LME" start="8" end="8"/>
            <field name="SCE" start="0" end="0"/>
            </flags> -->
            <Entry Name ="efer" Order = "20" Size ="8"/>

            <!-- x87 FPU -->
            <Entry Name ="st0" Order = "21" Size ="10" />
            <Entry Name ="st1" Order = "22" Size ="10" />
            <Entry Name ="st2" Order = "23" Size ="10" />
            <Entry Name ="st3" Order = "24" Size ="10" />
            <Entry Name ="st4" Order = "25" Size ="10" />
            <Entry Name ="st5" Order = "26" Size ="10" />
            <Entry Name ="st6" Order = "27" Size ="10" />
            <Entry Name ="st7" Order = "28" Size ="10" />
            <Entry Name ="fctrl" Order = "29" Size ="4" />
            <Entry Name ="fstat" Order = "2a" Size ="4" />
            <Entry Name ="ftag"  Order = "2b" Size ="4" />
            <Entry Name ="fiseg" Order = "2c" Size ="4" />
            <Entry Name ="fioff" Order = "2d" Size ="4" />
            <Entry Name ="foseg" Order = "2e" Size ="4" />
            <Entry Name ="fooff" Order = "2f" Size ="4" />
            <Entry Name ="fop" Order = "30" Size ="4" />
            <Entry Name ="xmm0" Order = "31" Size ="16"  />
            <Entry Name ="xmm1" Order = "32" Size ="16"  />
            <Entry Name ="xmm2" Order = "33" Size ="16"  />
            <Entry Name ="xmm3" Order = "34" Size ="16"  />
            <Entry Name ="xmm4" Order = "35" Size ="16"  />
            <Entry Name ="xmm5" Order = "36" Size ="16"  />
            <Entry Name ="xmm6" Order = "37" Size ="16"  />
            <Entry Name ="xmm7" Order = "38" Size ="16"  />
            <Entry Name ="xmm8" Order = "39" Size ="16"  />
            <Entry Name ="xmm9" Order = "3a" Size ="16"  />
            <Entry Name ="xmm10" Order = "3b" Size ="16"  />
            <Entry Name ="xmm11" Order = "3c" Size ="16"  />
            <Entry Name ="xmm12" Order = "3d" Size ="16"  />
            <Entry Name ="xmm13" Order = "3e" Size ="16"  />
            <Entry Name ="xmm14" Order = "3f" Size ="16"  />
            <Entry Name ="xmm15" Order = "40" Size ="16"  />
            
            <!-- the mxcsr register format fields:
            <flags id="x64_mxcsr" size="4">
                <field name="IE" start="0" end="0"/>
                <field name="DE" start="1" end="1"/>
                <field name="ZE" start="2" end="2"/>
                <field name="OE" start="3" end="3"/>
                <field name="UE" start="4" end="4"/>
                <field name="PE" start="5" end="5"/>
                <field name="DAZ" start="6" end="6"/>
                <field name="IM" start="7" end="7"/>
                <field name="DM" start="8" end="8"/>
                <field name="ZM" start="9" end="9"/>
                <field name="OM" start="10" end="10"/>
                <field name="UM" start="11" end="11"/>
                <field name="PM" start="12" end="12"/>
                <field name="FZ" start="15" end="15"/>
            </flags> -->
            <Entry Name ="mxcsr" Order = "41" Size ="4" />

        </ExdiGdbServerRegisters>
    </ExdiGdbServerConfigData>
    </ExdiTarget>
    </ExdiTargets>
</ExdiTargets>

Beispiel für EIN EXDI-PowerShell-Skript

Dieses PowerShell-Beispielskript installiert EXDI und startet dann den Debugger. Das Start-ExdiDebugger.ps1 Skript installiert bei Bedarf ExdiGdbSrv.dll, konfiguriert die XML-Einstellungsdateien, überprüft, ob dllhost.exe Prozesse ausgeführt werden, und startet den Debugger, um eine Verbindung mit einem bereits ausgeführten gdb-Serverhardwaredebugziel herzustellen.

Dies ist ein Beispiel für den Aufruf des Startskripts.

PS>.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64

Sie können bei Bedarf auch die erstellten Dateien angeben.

PS>.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 -ExdiDropPath "C:\path\to\built\exdi\files"

Die Start-ExdiDebugger.ps1 verfügt über die folgenden Setttingoptionen.

Parameter BESCHREIBUNG
ExdiTarget Der Typ des Ziels, mit dem eine Verbindung hergestellt werden soll. Dies entspricht einem bestimmten Abschnitt in der XML-Datei für Einstellungen.
HostName Die IP-Adresse oder der Hostname des Computers, auf dem die gdb-Serversitzung gehostet wird (standardwert: "LocalHost")
GdbPort Der Port, an dem der gdb-Server lauscht.
Aufbau Architektur des Hardwaredebuggingziels (dieser Parameter impliziert auch den ArchitectureFamily-Parameter in der XML-Einstellungsdatei)
ExdiDropPath Speicherort der dateien ExdiGdbSrv.dll, exdiConfigData.xml und systemregisters.xml. Diese werden nur kopiert, wenn ExdiGdbSrv.dll nicht oder falsch installiert ist.
ExtraDebuggerArgs Zusätzliche Argumente, die an der Befehlszeile des Debuggers übergeben werden sollen
PreNTAppDebugging Ändert den Wert von heuristicScanSize von 0xfffe (am besten für NT) in 0xffe (für Vor-NT-Apps).
DontTryDllHostCleanup Die Überprüfung auf vorhandene ausgeführte Instanzen von ExdiGdbSrv.dll in dllhost.exe erfordert Eine Erhöhung. Wenn Sie diesen Schalter angeben, kann das Skript ohne Erhöhung ausgeführt werden (obwohl der Debugger möglicherweise nicht ordnungsgemäß funktioniert).

Um die Anzeige von Paketen zu ermöglichen, legen Sie den Wert von displayCommPackets auf ja fest.

    [pscustomobject]@{ Path = 'displayCommPackets'                                  ; value = "yes" } 
.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 -ExdiDropPath "C:\path\to\built\exdi\files"

Weitere Einstellungsoptionen finden Sie in den Codekommentaren.

<#
.Synopsis
    Installs and launches exdi debugger (automating xml file editing)

.Description
    This script will install ExdiGdbSrv.dll if required, configure the xml settings
    files, check for running dllhost.exe processes, and launch the debugger to connect to
    an already running gdb server hardware debugging target.

.Parameter ExdiTarget
    Type of target to connect to. This corresponds to a specific section in the settings xml file

.Parameter HostName
    IP address or hostname of the computer hosting the gdb server session (defaults to "LocalHost")

.Parameter GdbPort
    Port that the gdb server is listening on.

.Parameter Architecture
    Architecture of the hardware debugging target (this parameter also implies the ArchitectureFamily
    parameter in the xml settings file)

.Parameter ExdiDropPath
    Location of the ExdiGdbSrv.dll, exdiConfigData.xml, and systemregisters.xml files. These will
    only be copied if ExdiGdbSrv.dll is not installed or is installed incorrectly.

.Parameter ExtraDebuggerArgs
    Extra arguments to pass on the debugger command line

.Parameter PreNTAppDebugging
    Changes the value of the heuristicScanSize from 0xfffe (best for NT) to 0xffe (for pre-NT Apps)

.Parameter DontTryDllHostCleanup
    Checking for existing running instances of ExdiGdbSrv.dll in dllhost.exe requires elevation.
    Providing this switch will allow the script to run without elevation (although the debugger may not
    function correctly).

.Example
    >---------------- (first run) ------------<
    .\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64 -ExdiDropPath "C:\path\to\built\exdi\files"

.Example
    PS>.\Start-ExdiDebugger.ps1 -ExdiTarget "QEMU" -GdbPort 1234 -Architecture x64
#>

[CmdletBinding()]
param
(
    [ValidateSet("QEMU")]
    [string]
    $ExdiTarget = "QEMU",

    [string]
    $HostName = "LocalHost",

    [Parameter(Mandatory=$true)]
    [Int]
    $GdbPort,

    [Parameter(Mandatory=$true)]
    [string]
    [ValidateSet("x86", "x64", "arm64")]
    $Architecture,

    [string]
    $ExdiDropPath,

    [string]
    $DebuggerPath,

    [string[]]
    $ExtraDebuggerArgs = @(),

    [switch]
    $PreNTAppDebugging,

    [switch]
    $DontTryDllHostCleanup
)

$ErrorActionPreference = "Stop"

#region Functions

Function Test-Admin
{
    ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")
}

Function Find-PathToWindbgX
{
    $InternalWindbgXPath = "$env:LOCALAPPDATA\DBG\UI\WindbgX.exe"
    $ExternalWindbgXPath = "$env:LOCALAPPDATA\Microsoft\WindowsApps\WinDbgX.exe"

    if (Test-Path $InternalWindbgXPath -PathType Leaf)
    {
        return $InternalWindbgXPath
    }
    elseif (Test-Path $ExternalWindbgXPath -PathType Leaf)
    {
        return $ExternalWindbgXPath
    }
}

Function Test-ParameterValidation
{
    $CommandName = $PSCmdlet.MyInvocation.InvocationName
    $ParameterList = (Get-Command -Name $CommandName).Parameters

    foreach ($Parameter in $ParameterList) {
        Get-Variable -Name $Parameter.Values.Name -ErrorAction SilentlyContinue | Out-String | Write-Verbose
    }

    if (-not $DebuggerPath)
    {
        throw "WindbgX is not installed"
    }
    elseif (-not (Test-Path $DebuggerPath -PathType Leaf))
    {
        throw "DebuggerPath param ($DebuggerPath) does not point to a debugger."
    }

    # Searching for loaded instances of ExdiGdbSrv.dll in dllhost.exe requires elevation
    if (-not $DontTryDllHostCleanup -and
        -not $(Test-Admin))
    {
        throw "Searching for loaded instances of ExdiGdbSrv.dll in dllhost.exe requires elevation. Run with the -DontTryDllHostCleanup parameter to skip this check (debugger session init may fail)."
    }
}

Function Get-ExdiInstallPath
{
    Get-ItemPropertyValue -Path "Registry::HKEY_CLASSES_ROOT\CLSID\{29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014}\InProcServer32" -Name "(default)" -ErrorAction SilentlyContinue
}

Function Test-ExdiServerInstalled
{
    # Check registration of exdi server class
    if ($(Get-ExdiInstallPath) -ne $null -and $(Test-Path "$(Get-ExdiInstallPath)"))
    {
        Write-Verbose "Exdi server is installed. Checking installation..."
        $ExdiInstallDir = [System.IO.Path]::GetDirectoryName($(Get-ExdiInstallPath))
        if (-not (Test-Path $ExdiInstallDir))
        {
            Write-Host "Currently Registered exdi server does not exist. Reinstalling..."
            return $false
        }
        elseif (-not ((Test-Path "$ExdiInstallDir\exdiConfigData.xml") -and (Test-Path "$ExdiInstallDir\systemregisters.xml")))
        {
            Write-Host "Currently Registered exdi server does not have required xml settings files. Reinstalling..."
            return $false
        }
        else
        {
            Write-Verbose "Exdi server is insalled correctly. Skipping installation..."
            return $true
        }
    }
    else
    {
        Write-Host "Exdi server is not installed. Installing..."
        return $false
    }
}

Function Install-ExdiServer
{
    [CmdletBinding()]
    param
    (
        [string] $InstallFrom,
        [string] $InstallTo
    )
    
    if (-not $(Test-Admin))
    {
        throw "Script needs to be run as an Admin to install exdi software."
    }

    New-Item -ItemType Directory $InstallTo -ErrorAction SilentlyContinue | Write-Verbose
    Copy-Item -Path "$InstallFrom\ExdiGdbSrv.dll" -Destination $InstallTo -ErrorAction stop | Write-Verbose
    Copy-Item -Path "$InstallFrom\exdiConfigData.xml" -Destination $InstallTo -ErrorAction stop | Write-Verbose
    Copy-Item -Path "$InstallFrom\systemregisters.xml" -Destination $InstallTo -ErrorAction stop | Write-Verbose
    regsvr32 /s "$InstallTo\ExdiGdbSrv.dll"

    if ($(Get-ExdiInstallPath) -eq $null)
    {
        throw "Unable to install exdi server"
    }
}

Function Edit-ExdiConfigFile
{
    [CmdletBinding()]
    param
    (
        [string] $ExdiFilePath,
        [string] $ExdiTargetType,
        [PSCustomObject[]] $XmlSettingPathValueList
    )
    
    # Edit exdiConfigData.xml
    [xml]$exdiConfigXml = Get-Content "$ExdiFilePath"

    # Set current target
    $exdiConfigXml.ExdiTargets.CurrentTarget = $ExdiTarget

    # set HostNameAndPort
    $ExdiTargetXmlNode = $exdiConfigXml.SelectSingleNode("//ExdiTargets/ExdiTarget[@Name='$ExdiTarget']/ExdiGdbServerConfigData")

    foreach ($XmlSettingPathValue in $XmlSettingPathValueList)
    {
        Write-Verbose "Processing $XmlSettingPathValue"
        if ($XmlSettingPathValue.Value -eq $null)
        {
            continue
        }

        $PathParts = $XmlSettingPathValue.Path.Split(".")
        $curNode = $ExdiTargetXmlNode
        if ($PathParts.Count -gt 1)
        {
            foreach ($PathPart in $PathParts[0..($PathParts.Count-2)])
            {
                Write-Verbose $PathPart
                $curNode = $curNode.($PathPart)
            }
        }
        $curNode.($PathParts[-1]) = $XmlSettingPathValue.Value
    }

    $exdiConfigXml.Save("$ExdiFilePath")
}

Function Stop-ExdiContainingDllHosts
{
    $DllHostPids = Get-Process dllhost | ForEach-Object { $_.Id }
    foreach ($DllHostPid in $DllHostPids)
    {
        $DllHostExdiDlls = Get-Process -Id $DllHostPid -Module | Where-Object { $_.FileName -like "*ExdiGdbSrv.dll" }
        if ($DllHostExdiDlls.Count -ne 0)
        {
            Write-Verbose "Killing dllhost.exe with pid $DllHostPid (Contained instance of ExdiGdbSrv.dll)"
            Stop-Process -Id $DllHostPid -Force
        }
    }
}

#endregion

#region Script

# Apply defaults for $DebuggerPath before Parameter validation
if (-not $DebuggerPath)
{
    $DebuggerPath = Find-PathToWindbgX
}

Test-ParameterValidation

# look clean up dllhost.exe early since it can hold a lock on files which
# need to be overwritten
if (-not $DontTryDllHostCleanup)
{
    Stop-ExdiContainingDllHosts
}

if (-not $(Test-ExdiServerInstalled))
{
    if (-not $ExdiDropPath)
    {
        throw "ExdiServer is not installed and -ExdiDropPath is not valid"
    }

    $ExdiInstallDir = Join-Path -Path "$([System.IO.Path]::GetDirectoryName($DebuggerPath))" -ChildPath "exdi"
    Install-ExdiServer -InstallFrom "$ExdiDropPath" -InstallTo "$ExdiInstallDir"
}

$SystemRegistersFilepath = Join-Path -Path "$([System.IO.Path]::GetDirectoryName($(Get-ExdiInstallPath)))" -ChildPath "systemregisters.xml"
$ExdiConfigFilepath      = Join-Path -Path "$([System.IO.Path]::GetDirectoryName($(Get-ExdiInstallPath)))" -ChildPath "exdiConfigData.xml"

# Calculate implied parameters
$HeuristicScanSize = if ($PreNTAppDebugging) { "0xffe" } else { "0xfffe" }
$ArchitectureFamily = switch($Architecture)
{
    x64   { "ProcessorFamilyx64" }
    x86   { "ProcessorFamilyx86" }
    arm64 { "ProcessorFamilyARM64" }
}

# Path is evaluated relative to the relevant ExdiTarget's ExdiGdbServerConfigData node in the xml schema
$SettingsToChange = @(
    [pscustomobject]@{ Path = 'GdbServerConnectionParameters.Value.HostNameAndPort' ; Value = "${HostName}:$GdbPort" },
    [pscustomobject]@{ Path = 'ExdiGdbServerTargetData.targetArchitecture'          ; Value = "$Architecture" },
    [pscustomobject]@{ Path = 'ExdiGdbServerTargetData.targetFamily'                ; Value = "$ArchitectureFamily" },
    [pscustomobject]@{ Path = 'ExdiGdbServerTargetData.heuristicScanSize'           ; Value = "$HeuristicScanSize" },
    [pscustomobject]@{ Path = 'displayCommPackets'                                  ; value = "no" }
)
Edit-ExdiConfigFile -ExdiFilePath "$ExdiConfigFilepath" -ExdiTargetType "$ExdiTarget" -XmlSettingPathValueList $SettingsToChange

# Set env vars for debugger
[System.Environment]::SetEnvironmentVariable('EXDI_GDBSRV_XML_CONFIG_FILE',"$ExdiConfigFilepath")
[System.Environment]::SetEnvironmentVariable('EXDI_SYSTEM_REGISTERS_MAP_XML_FILE',"$SystemRegistersFilepath")

$DebuggerArgs = @("-v", "-kx exdi:CLSID={29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014},Kd=Guess,DataBreaks=Exdi")
Write-Verbose "DebuggerPath = $DebuggerPath"
Start-Process -FilePath "$DebuggerPath" -ArgumentList ($DebuggerArgs + $ExtraDebuggerArgs)

#endregion

Weitere Informationen

Einrichten von QEMU Kernel-Mode Debugging mithilfe von EXDI

.exdicmd (EXDI-Befehl)

Automatisches Einrichten des KDNET-Netzwerkkernelsdebuggings

Manuelles Debuggen des KDNET-Netzwerkkerns einrichten

Manuelles Einrichten Kernel-Mode Debuggen