次の方法で共有


EXDI XML 構成ファイル

このトピックでは、EXDI XML 構成ファイルを使用して詳細オプションを構成する方法について説明します。 WinDbg ユーザー インターフェイスを使用して EXDI を構成する方法の一般的な情報については、「EXDI デバッガー トランスポートの構成を参照してください。 最も一般的な設定はユーザー インターフェイスで使用できます。これは、ここで説明する EXDI XML 構成ファイルを手動で編集する方が簡単な方法です。

拡張デバッグ インターフェイス (EXDI) は、ソフトウェア デバッガーとデバッグ ターゲットの間の適合レイヤーです。 Windows デバッグ ツールでは、Windows バージョン 22000 以降の EXDI を使用したカーネル デバッグがサポートされています。

Note

EXDI は、特定の環境向けの高度で特殊な形式のデバッグです。 標準の KDNET 接続を使用するほうが構成が容易であり、推奨されます。 ネットワーク デバッグを自動的に設定するには、「KDNET ネットワーク カーネル デバッグの自動設定」を参照してください。

EXDI 構成 XML ファイルを使用して詳細オプションを構成する

EXDI GDB COM サーバー (ExdiGdbSrv.dll) で使用される必須の XML ファイルが 2 つあります。

  1. exdiConfigData.xml - このファイルには、GDB サーバー クライアントが HW デバッガー GDB サーバー ターゲットとの GDB セッションを正常に確立するために必要なメイン構成データが含まれているため、ファイルの場所が EXDI_GDBSRV_XML_CONFIG_FILE 環境変数によって設定されて いない 場合、GDB サーバー クライアントは実行されません。 各 XML タグを使用すると、GDB サーバー機能の特定のセットを構成できます。 XML で変更できる属性の一覧およびサンプル XML については、以下を参照してください。

  2. Systemregister.xml - このファイルには、システム レジスタとレジスタへのアクセスに使用されるコード間のマッピングが含まれています。 これは、GDB サーバーはアクセス コードを XML ファイルで提供しておらず、デバッガーはアクセス コードを介して各システム レジスタにアクセスするためです。 このファイルが環境変数 EXDI_SYSTEM_REGISTERS_MAP_XML_FILE で設定されていない場合、ExdiGdbSrv.dll は引き続き動作しますが、デバッガーはどのシステム レジスタにも rdmsr コマンドまたは wrmsr コマンドでアクセスできません。 これらのレジスタの一覧は、GDB サーバー ハードウェア デバッガーでサポートされている必要があります (特定のシステム レジスタ名が、システム XML ファイルで送信されるレジスタ一覧に存在する必要があります)。

EXDI UI と XML 構成ファイル

WinDbg の EXDI UI は、XML ファイル パラメーターを使用し、IP:Port 値などの UI に必要なパラメーターをマージします。 既定の XML ファイル パラメーターを変更する必要がある場合は、コマンド ラインからパラメーター PathToSrvCfgFiles=<path to the modified exdiconfigdata.xml file>を使用して WinDbgNext アプリケーションを起動します。

ターゲット アーキテクチャ

EXDI UI ターゲット アーキテクチャ フィールドの値は、Windows OS ターゲット アーキテクチャを記述するターゲット記述 XML ファイルを実装していない GDB サーバー スタブに対してのみ、ターゲットで実行されている Windows OS と一致する必要があります。 このtarget.xmlファイル情報は、GDB クライアントと GDB サーバー スタブ間の GDB-RSP プロトコルハンドシェイク中に GDB サーバー スタブによって送信されます。

ユーザーが EXDI UI で正しくないターゲット アーキテクチャ フィールド入力値を設定した場合でも、Windbg-ExdiGdbSrv は正しいターゲット OS アーキテクチャを設定できます。 ターゲット OS アーキテクチャは、GDB サーバーのハンドシェイクにtarget.xml ファイルを含む GDB サーバーによって提供されるtarget.xml記述ファイルから取得および構成されます。 ターゲット アーキテクチャを確認するには、有効なマシン .effmach デバッガー コマンドを使用します。

GDBServer のタグと属性

次の表で、 exdiConfigData.xml ファイルで定義される GDBServer のタグと属性について説明しています。

パラメーター 説明
ExdiTargets GDB サーバー ターゲットとの GDB 接続を確立するために ExdiGgbSrv.dll によって使用される特定の GDB サーバー ターゲット構成を指定します。これは、exdiConfigData.xml ファイルには、ExdiGdbSrv.dll で現在サポートされているすべての GDB サーバーが含まれているためです (特定の GDB サーバーで ExdiGdbSrv.dll を使用する前に、このファイルに値が入力されている必要があります)。
CurrentTarget GDB サーバー ターゲットの名前を指定します (たとえば、exdiConfigData.xml ファイルに含まれる <ExdiTarget Name= タグのいずれかの名前値とこの属性値が一致する必要があります)。
ExdiTarget これは、各 GDB サーバー ターゲット コンポーネントに含まれるすべての構成データの開始タグです。
Name GDB サーバーの名前を指定します (QEMU、BMC-OpenOCD、Trace32、VMWare など)。
agentNamePacket これは、GDB サーバー HW デバッガーによって認識される GDB クライアントの名前です。 これは、GDB サーバー HW デバッガーが特定の GDB クライアント向けに自身を構成するために使用できます (たとえば、Trace32 GDB サーバーでは、windbg-GDB クライアントを識別するために ExdiGdbSrv.dll が "QMS.windbg" という名前を送信した後に、MS GDB サーバー クライアント (exdiGdbSrv.dll) でのみサポートされるカスタマイズされた GDB メモリ パケットを有効にする必要があります)。
ExdiGdbServerConfigData ExdiGdbSrv.dll コンポーネント関連の構成パラメーターを指定します。
uuid ExdiGdbSrv.dll コンポーネントの UUI を指定します。
displayCommPackets "yes" の場合はフラグを設定し、コマンド ログ ウィンドウに RSP プロトコル通信文字を表示します。 "no" の場合は、要求と応答のペアのテキストだけが表示されます。
enableThrowExceptionOnMemoryErrors この属性は、GDB エラー応答パケット (E0x) がある場合に GDB サーバー クライアントによってチェックされ、クライアントが例外をスローしてメモリの読み取りを停止する必要があるかどうかを判断します。
qSupportedPacket これにより、XML ターゲット記述ファイルに続いて GDB サーバー HW デバッガーによって送信される XML レジスタ アーキテクチャ ファイルを要求するように、GDB クライアントを構成できます (クライアントは基本的に、クライアントでサポートされるアーキテクチャを GDB サーバーに通知します。現在、クライアントは現在、x64 アーキテクチャをサポートしています)。
ExdiGdbServerTargetData GdbServer セッションによってデバッグされるハードウェア ターゲットに関連するパラメーターを指定します。
targetArchitecture ターゲット ハードウェア アーキテクチャを含む文字列。 使用可能な値: X86、X64、ARM、ARM64。 現在、exdiGdbSrv.dll では X86 と ARM のみがサポートされています。
targetFamily ターゲット ハードウェア ファミリを含む文字列。 使用可能な値: ProcessorFamilyX86、ProcessorFamilyX64、ProcessorFamilyARM、ProcessorFamilyARM64。
numberOfCores ターゲットがサポートするプロセッサ コアの数。 このパラメーターは、マルチ Gdbserver セッション (T32-GdbServer セッション) を使用するときに検証されます。 後述の MultiCoreGdbServerSessions 属性を "yes" に設定する必要があります。
EnableSseContext "yes" の場合はフラグを設定し、'g' コンテキスト RSP パケットには浮動小数点レジスタ値が含まれます。 このパラメーターは、Intel ファミリのターゲットに対してのみ有効です。
heuristicScanSize 属性値が指定されて いない (または "0" である) 場合、スキャンされたメモリ プローブを指定サイズだけ減らすためにデバッガー エンジンの高速ヒューリスティック アルゴリズムが構成され、その後、デバッガー エンジンは高速ヒューリスティックを使用せずに、PE DOS 署名を探してメモリ全体をスキャンする従来のヒューリスティックにフォールバックします。 一般的なスキャン サイズの値は、0xfffe (NT に最適) または0xffe (NT より前のアプリの場合) です。
targetDescriptionFile GDB サーバーが個別の XML ファイルを送信する前にターゲット記述ヘッダー ファイルを送信するかどうかを指定します。 このフィールドが空白の場合、GDB サーバー クライアントは XML アーキテクチャ システム レジスタを要求しません (たとえば、アーキテクチャ レジスタを個別の XML ファイルとして送信することをサポートしていない Trace32 GDBs サーバー)。
GdbServerConnectionParameters GdbServer セッション パラメーターを指定します。 これらのパラメーターは、ExdiGdbSrv.dll コンポーネントと GdbServer の間の RSP GdbServer セッションを制御するために使用されます。
MultiCoreGdbServerSessions "yes" の場合はフラグを設定し、マルチコア GdbServer セッション (T32-GdbServer バックエンドで使用されるセッション) が作成されます。 "no" の場合、GdbServer の 1 つのインスタンスとのみ通信します。
MaximumGdbServerPacketLength これは、1 パケットでサポートされる GdbServer の最大長です。
MaximumConnectAttempts これは、接続の最大試行回数です。 これは、GdbServer との RSP 接続の確立を試みる際に、ExdiGdbSrv.dll によって使用されます。
SendPacketTimeout これは RSP 送信タイムアウトです。
ReceivePacketTimeout これは RSP 受信タイムアウトです。
HostNameAndPort これは、 <hostname/ip address:Port number>形式の接続文字列です。 複数の GdbServer 接続文字列 (T32 マルチコア GdbServer セッションなど) が存在する可能性があります。 接続文字列の数は、コアの数と一致する必要があります。
ExdiGdbServerMemoryCommands さまざまな例外 CPU レベルでシステム レジスタ値または読み取り/書き込みアクセス メモリを取得するために、GDB メモリ コマンドを発行するさまざまな方法を指定します (たとえば、BMC-OpenOCD は、カスタマイズされたコマンド"aarch64 mrs nsec/sec <access code>" を使用して CP15 レジスタへのアクセスを提供します)。
GdbSpecialMemoryCommand "yes" の場合、GDB サーバーは、カスタマイズされたメモリ コマンドをサポートします (たとえばシステム レジスタは Trace32 GDB サーバー用に設定する必要があります)。
PhysicalMemory "yes" の場合、GDB サーバーは、物理メモリの読み取りに関するカスタマイズされたコマンドをサポートします (Trace32 GDB サーバー用に設定されています)。
SupervisorMemory "yes" の場合、GDB サーバーは、スーパーバイザー メモリの読み取りに関するカスタマイズされたコマンドをサポートします (Trace32 GDB サーバー用に設定されています)。
SpecialMemoryRegister "yes" の場合、GDB サーバーは、システム レジスタの読み取りに関するカスタマイズされたコマンドをサポートします (Trace32 GDB サーバー用に設定されています)
SystemRegistersGdbMonitor "yes" の場合、GDB サーバーは、GDB モニター コマンドを使用するカスタマイズされたコマンドをサポートします (BMC Open-OCD 用に設定されています)。
SystemRegisterDecoding "yes" の場合、GDB クライアントは、GDB モニター コマンドを送信する前にアクセス コードのデコードを受け入れます。
ExdiGdbServerRegisters 特定のアーキテクチャ レジスタ コア セットを指定します。
Architecture 定義されたレジスタ セットの CPU アーキテクチャ。
FeatureNameSupported これは、XML システム レジスタ記述ファイルによって提供されるシステム レジスタ グループの名前です。 GDB サーバーによって送信される際に、XML ファイルの一部であるシステム レジスタ XML グループを識別するために必要です。
SystemRegistersStart これは、コア レジスタ セットの一部として報告される最初のシステム レジスタ (下位レジスタ番号/順序) を識別するためです (たとえば、X64 では、QEMU は x64 システム レジスタ セットを分離された XML ターゲット記述ファイルとして報告しないため、システム レジスタは コアレジスタの一部です)。
SystemRegistersEnd この目的は、コア レジスタ セットの一部として報告される最後のシステム レジスタ (レジスタ番号/順序が大きいもの) を識別することです。
Name レジスタの名前。
注文 これは、レジスタの配列内のインデックスを識別する数値です。 この数値は、GDB クライアントとサーバーのセット/クエリ (p<number>”/”q<number>) レジスタ パケットによって使用されます。
サイズ これはレジスタ サイズ (バイト単位) です。

サンプル 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>

EXDI Powershell スクリプトの例

このサンプル PowerShell スクリプトは、EXDI をインストールしてからデバッガーを起動します。 Start-ExdiDebugger.ps1 スクリプトは、必要に応じて ExdiGdbSrv.dll をインストールし、XML 設定ファイルを構成します。さらに、実行中の dllhost.exe プロセスをチェックし、デバッガーを起動して、既に実行中の GDB サーバー ハードウェア デバッグ ターゲットに接続します。

WinDBg で有効なユーザー インターフェイスを使用する場合、ExdiGdbSrv.dllは既にインストールされており、このスクリプトは関係ありません。 組み込みのユーザー インターフェイスの使用の詳細については、「 EXDI デバッガー トランスポートの構成を参照してください。

これは、スタートアップ スクリプトを呼び出す例です。

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

必要に応じて、ビルドされたファイルを指定することもできます。

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

Start-ExdiDebugger.ps1 には、以下の設定オプションがあります。

パラメーター 説明
ExdiTarget 接続先となるターゲットの種類。 これは、設定 XML ファイル内の特定のセクションに対応します。
HostName GDB サーバー セッションをホストしているコンピューターの IP アドレスまたはホスト名 (既定値は "LocalHost")
GdbPort GDB サーバがリッスンしているポート。
Architecture ハードウェア デバッグ ターゲットのアーキテクチャ (このパラメーターは、XML 設定ファイルの ArchitectureFamily パラメーターも含みます)
ExdiDropPath ExdiGdbSrv.dll、exdiConfigData.xml、および systemregisters.xml ファイルの場所。 これらは、ExdiGdbSrv.dll がインストールされていない場合または正しくインストールされていない場合にのみコピーされます。
ExtraDebuggerArgs デバッガーのコマンド ラインで渡す追加の引数
PreNTAppDebugging heuristicScanSize の値を 0xfffe (NT に最適) から 0xffe (NT 以前のアプリの場合) に変更します
DontTryDllHostCleanup dllhost.exe 内で実行中の ExdiGdbSrv.dll の既存のインスタンスを確認するには、昇格が必要です。 このスイッチを指定すると、スクリプトを昇格なしで実行できます (デバッガーが正しく機能しない可能性があります)。

パケットを表示できるようにするには、 displayCommPackets の値を "yes" に設定します。

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

その他の設定オプションについては、コードのコメントを参照してください。

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

関連項目

EXDI デバッガー トランスポートの構成

EXDI を使用した QEMU カーネル モード デバッグの設定

.exdicmd (EXDI コマンド)

KDNET ネットワーク カーネル デバッグの自動設定