Partager via


Fichiers de configuration XML EXDI

Cette rubrique explique comment configurer des options avancées à l’aide des fichiers de configuration EXDI XML. Pour obtenir des informations générales sur l’utilisation de l’interface utilisateur WinDbg pour configurer EXDI, consultez Configuration du transport du débogueur EXDI. Les paramètres les plus courants sont disponibles dans l’interface utilisateur, qui est une approche plus simple, puis modifiez manuellement les fichiers de configuration EXDI XML, décrits ici.

L’interface de débogage étendue (EXDI) est une couche d’adaptation entre un débogueur logiciel et une cible de débogage. Les outils de débogage pour Windows prennent en charge le débogage du noyau à l’aide d’EXDI à partir de Windows version 22000.

Remarque

EXDI est une forme avancée et spécialisée de débogage pour des environnements spécifiques. Nous recommandons l’utilisation d’une connexion KDNET standard, plus facile à configurer. Pour une configuration automatique du débogage réseau, consulter la configuration automatique du débogage réseau du noyau KDNET.

Configurer des options avancées à l’aide des fichiers XML de configuration EXDI

Il existe deux fichiers xml requis qui sont consommés par le serveur COM GDB EXDI (ExdiGdbSrv.dll).

  1. exdiConfigData.xml : ce fichier contient les données de configuration principales requises par le client serveur GDB pour établir une session GDB réussie avec la cible du serveur GDB du débogueur matériel. Le client du serveur GDB ne s’exécute donc pas si l’emplacement du fichier n’est pas défini par la variable d’environnement EXDI_GDBSRV_XML_CONFIG_FILE. Chaque balise xml permet de configurer un ensemble spécifique de fonctionnalités de serveur GDB. Consulter ci-dessous la liste des attributs qu’on peut modifier dans le code XML et l’exemple de code XML.

  2. Systemregister.xml : ce fichier contient un mappage entre les registres système et le code utilisé pour accéder aux registres. Il est nécessaire, car le code d’accès n’est pas fourni par le serveur GDB dans le fichier xml, et le débogueur accède à chaque registre système via ledit code d’accès. Si le fichier n’est pas défini avec la variable d’environnement EXDI_SYSTEM_REGISTERS_MAP_XML_FILE, la ExdiGdbSrv.dll continue de fonctionner, mais le débogueur ne peut pas accéder à un registre système via des commandes rdmsr ou wrmsr. La liste de ces registres doit être prise en charge par le débogueur matériel du serveur GDB (le nom du registre système spécifique doit être présent dans la liste des registres envoyée dans le fichier xml système).

Interface utilisateur EXDI et fichiers de configuration XML

L’interface utilisateur EXDI dans WinDbg utilise les paramètres de fichier XML et fusionne les paramètres requis de l’interface utilisateur, tels que la valeur IP :Port. S’il est nécessaire de modifier les paramètres de fichier XML par défaut, lancez l’application WinDbgNext à partir de la ligne de commande avec le paramètre PathToSrvCfgFiles=<path to the modified exdiconfigdata.xml file>.

Architecture cible

La valeur du champ d’architecture cible de l’interface utilisateur EXDI doit correspondre au système d’exploitation Windows en cours d’exécution sur la cible uniquement pour les stubs de serveur GDB qui n’implémentent pas le fichier XML de description cible cible décrivant l’architecture cible du système d’exploitation Windows. Cette target.xml informations de fichier est envoyée par le stub du serveur GDB pendant la négociation du protocole GDB-RSP entre le client GDB et le stub du serveur GDB.

Windbg-ExdiGdbSrv peut toujours définir l’architecture de système d’exploitation cible correcte même si l’utilisateur définit une valeur d’entrée de champ d’architecture cible incorrecte dans l’interface utilisateur EXDI. L’architecture du système d’exploitation cible est prise et configurée à partir du fichier de description target.xml fourni par les serveurs GDB qui incluent le fichier target.xml dans la négociation du serveur GDB. Pour vérifier l’architecture cible, utilisez la commande de débogueur .effmach de machine effective.

Balises et attributs GDBServer

Le tableau suivant décrit les balises et attributs GDBServer définis dans le fichier exdiConfigData.xml.

Paramètre Description
ExdiTargets Spécifie quelle configuration cible de serveur GDB spécifique sera utilisée par la ExdiGgbSrv.dll pour établir la connexion GDB avec la cible du serveur GDB, car le fichier exdiConfigData.xml inclut tous les serveurs GDB pris en charge actuellement par la ExdiGdbSrv.dll (ce fichier DOIT être rempli avant d’utiliser la ExdiGdbSrv.dll avec un serveur GDB particulier).
CurrentTarget Spécifie le nom de la cible du serveur GDB (par exemple, cette valeur d’attribut doit correspondre à la valeur de nom de l’une des balises <ExdiTarget Name= incluses par le fichier exdiConfigData.xml.
ExdiTarget il s’agit de la balise de début de toutes les données de configuration incluses par chaque composant cible du serveur GDB.
Nom Spécifie le nom du serveur GDB (par exemple, QEMU, BMC-OpenOCD, Trace32, VMWare).
agentNamePacket Il s’agit du nom du client GDB tel qu’il est reconnu par le débogueur matériel du serveur GDB. Il peut être utilisé par le débogueur matériel du serveur GDB pour se configurer pour des clients GDB spécifiques (par exemple, le serveur Trace32 GDB nécessite que la ExdiGdbSrv.dll envoie le nom « QMS.windbg » pour identifier le client windbg-GDB, puis activer les paquets de mémoire GDB personnalisés uniquement pris en charge pour le client serveur MS GDB (exdiGdbSrv.dll).
ExdiGdbServerConfigData Spécifie les paramètres de configuration associés au composant ExdiGdbSrv.dll.
uuid spécifie l’UUI du composant ExdiGdbSrv.dll.
displayCommPackets Si « oui », nous afficherons les caractères de communication du protocole RSP dans la fenêtre du journal des commandes. Si « non », nous affichons simplement le texte de la paire demande-réponse.
enableThrowExceptionOnMemoryErrors Cet attribut sera vérifié par le client du serveur GDB en cas de paquet de réponse d’erreur GDB (E0x) afin de déterminer si le client doit lever une exception et arrêter la lecture de la mémoire.
qSupportedPacket Il est ainsi possible de configurer le client GDB pour demander quel fichier d’architecture d’inscription xml doit être envoyé par le débogueur matériel du serveur GDB en suivant le fichier de description cible xml (en gros, le client informe le serveur GDB que les architectures sont prises en charge par le client, actuellement, le client prend en charge l’architecture x64).
ExdiGdbServerTargetData Spécifie les paramètres liés à la cible matérielle déboguée par la session GdbServer.
targetArchitecture Chaîne contenant l’architecture matérielle cible. Valeurs possibles : X86, X64, ARM, ARM64. Actuellement, la exdiGdbSrv.dll prend uniquement en charge X86 et ARM.
targetFamily Chaîne contenant la famille de matériel cible. Valeurs possibles : ProcessorFamilyX86, ProcessorFamilyX64, ProcessorFamilyARM, ProcessorFamilyARM64.
numberOfCores Nombre de cœurs de processeur pris en charge par la cible. Ce paramètre est validé lorsque nous utilisons une session multi-Gdbserver (session T32-GdbServer). L’attribut « MultiCoreGdbServerSessions » ci-dessous doit être défini sur « oui ».
EnableSseContext Si « oui », le paquet RSP de contexte « g » inclut des valeurs d’enregistrement à virgule flottante. Ce paramètre est utile uniquement pour les cibles de la famille Intel.
heuristicScanSize configure l’algorithme heuristique rapide du moteur de débogage pour réduire la sonde de mémoire analysée de la taille spécifiée. Si la valeur de l’attribut n’est pas spécifiée (ou « 0 »), le moteur de débogage n’utilisera pas l’algorithme heuristique rapide et reviendra au traditionnel qui analyse la totalité de la mémoire à la recherche de la signature DOS du PE. Les valeurs courantes de taille d’analyse sont 0xfffe (optimales pour NT) ou 0xffe (pour les applications pré-NT).
targetDescriptionFile spécifie si le serveur GDB envoie un fichier d’en-tête de description cible avant d’envoyer chaque fichier xml distinct. Si ce champ est vide, le client du serveur GDB ne demande pas le registre système de l’architecture xml (par exemple, le serveur GDBs Trace32 qui ne prend pas en charge l’envoi des registres d’architecture dans un fichier xml séparé).
GdbServerConnectionParameters Spécifie les paramètres de session GdbServer. Ces paramètres sont utilisés pour contrôler la session GdbServer RSP entre le composant ExdiGdbSrv.dll et GdbServer.
MultiCoreGdbServerSessions Si « oui », il y aura une session GdbServer multicœur (celle utilisée par le serveur principal T32-GdbServer). Si « non », on communiquera avec une seule instance de GdbServer.
MaximumGdbServerPacketLength Il s’agit de la longueur maximale prise en charge par GdbServer pour un paquet.
MaximumConnectAttempts Il s’agit des tentatives de connexion maximales. La ExdiGdbSrv.dll l’utilise pour tenter d’établir la connexion RSP au GdbServer.
SendPacketTimeout Il s’agit du délai d’attente d’envoi du RSP.
ReceivePacketTimeout Il s’agit du délai d’expiration de réception RSP.
HostNameAndPort Il s’agit de la chaîne de connexion au format <hostname/ip address:Port number>. Il peut y avoir plusieurs chaîne de connexion GdbServer (comme la session GdbServer multicœur T32). Le nombre de chaînes de connexion doit correspondre au nombre de cœurs.
ExdiGdbServerMemoryCommands Spécifie les différentes manières d’émettre les commandes de mémoire GDB, afin d’obtenir les valeurs des registres système ou d’accéder à la mémoire en lecture/écriture à différents niveaux d’exception du processeur (par exemple, BMC-OpenOCD permet d’accéder au registre CP15 via la commande personnalisée « aarch64 mrs nsec/sec <access code> »).
GdbSpecialMemoryCommand si « oui », le serveur GDB prend en charge les commandes mémoire personnalisées (par exemple, le registre système. Cela doit être défini pour le serveur Trace32 GDB).
PhysicalMemory si « oui », le serveur GDB prend en charge les commandes personnalisées pour la lecture de la mémoire physique (définie pour le serveur Trace32 GDB).
SupervisorMemory si « oui », le serveur GDB prend en charge les commandes personnalisées pour la lecture de la mémoire de supervision (définie pour le serveur Trace32 GDB).
SpecialMemoryRegister si « oui », le serveur GDB prend en charge les commandes personnalisées pour la lecture des registres systèmes (définie pour le serveur Trace32 GDB)
SystemRegistersGdbMonitor si « oui », le serveur GDB prend en charge les commandes personnalisées via la commande moniteur GDB (elle est définie pour BMC Open-OCD).
SystemRegisterDecoding si « oui », le client GDB accepte le décodage du code d’accès avant d’envoyer la commande moniteur GDB.
ExdiGdbServerRegisters Spécifie le jeu central de registres d’une architecture spécifique.
Architecture Architecture du processeur du jeu de registres définis.
FeatureNameSupported Il s’agit du nom du groupe de registres système tel qu’il est fourni par le fichier xml de description du registre système. Il faut identifier le groupe xml du registre système qui fait partie du fichier xml tel qu’il est envoyé par le serveur GDB.
SystemRegistersStart Il permet d'identifier le premier registre système (numéro/ordre de registre bas) qui est signalé comme faisant partie du jeu central de registres (par exemple, sur X64, QEMU ne signale pas le jeu de registres du système x64 dans un fichier de description de cible xml séparé, de sorte que les registres système font partie des registres centraux).
SystemRegistersEnd Il permet d’identifier le dernier registre système (numéro/ordre élevé) signalé dans le cadre du jeu central de registres.
Nom Nom du registre.
Ordre Il s’agit d’un nombre qui identifie l’index dans le tableau des registres. Ce nombre sera utilisé par le client GDB et l’ensemble serveur/requête (p<number>”/”q<number>) enregistrent des paquets.
Taille Il s’agit de la taille du registre en octets.

Exemple de fichier 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>

Exemple de script PowerShell EXDI

Cet exemple de script PowerShell installe EXDI, puis lance le débogueur. Le script Start-ExdiDebugger.ps1 installe ExdiGdbSrv.dll si nécessaire, configure les fichiers de paramètres xml, vérifie l’exécution des processus dllhost.exe et lance le débogueur pour se connecter à une cible de débogage matérielle du serveur gdb en cours d’exécution.

Lorsque vous utilisez l’interface utilisateur avalible avec WinDBg, le ExdiGdbSrv.dll est déjà installé et ce script n’est pas pertinent. Pour plus d’informations sur l’utilisation de l’interface utilisateur intégrée, consultez Configuration du transport du débogueur EXDI.

Voici un exemple d’appel du script de démarrage.

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

On peut également spécifier les fichiers générés si nécessaire.

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

Le script Start-ExdiDebugger.ps1 propose les options de paramètres suivantes.

Paramètre Description
ExdiTarget Type de cible auquel se connecter. Correspond à une section spécifique dans le fichier xml des paramètres
HostName Adresse IP ou nom d’hôte de l’ordinateur hébergeant la session du serveur gdb (par défaut, « LocalHost »)
GdbPort Port sur lequel le serveur gdb écoute.
Architecture Architecture de la cible de débogage matériel (ce paramètre implique également le paramètre ArchitectureFamily dans le fichier de paramètres xml)
ExdiDropPath Emplacement des fichiers ExdiGdbSrv.dll, exdiConfigData.xml et systemregisters.xml. Ils seront uniquement copiés si ExdiGdbSrv.dll n’est pas installé ou est mal installé.
ExtraDebuggerArgs Arguments supplémentaires à transmettre sur la ligne de commande du débogueur
PreNTAppDebugging Modifie la valeur de heuristicScanSize de 0xfffe (la meilleure pour NT) en 0xffe (pour les applications pré-NT)
DontTryDllHostCleanup La vérification des instances en cours d’exécution existantes de la ExdiGdbSrv.dll dans dllhost.exe nécessite une élévation. La fourniture de ce commutateur permet au script de s’exécuter sans élévation (même si le débogueur ne fonctionne pas correctement).

Pour permettre l’affichage des paquets, définir la valeur de displayCommPackets sur oui.

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

Pour plus d’options de paramètres, consulter les commentaires de code.

<#
.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

Voir aussi

Configuration du transport du débogueur EXDI

Configuration du débogage en mode noyau QEMU à l’aide d’EXDI

.exdicmd (commande EXDI)

Configuration automatique du débogage du noyau réseau KDNET