EXDI XML 組態檔
本主題描述如何使用 EXDI XML 組態檔設定進階選項。 如需使用 WinDbg 使用者介面設定 EXDI 的一般資訊,請參閱 設定 EXDI 調試程式傳輸。 最常見的設定可在使用者介面中使用,這是一種更簡單的方法,然後手動編輯 EXDI XML 組態檔,如下所述。
擴充偵錯介面 (EXDI) 是軟體調試程式與偵錯目標之間的適應層。 從 Windows 版本 22000 開始,Windows 偵錯工具支援使用 EXDI 進行核心偵錯。
注意
EXDI 是特定環境的進階特製化偵錯形式。 使用標準 KDNET 連線更容易設定,而且建議使用。 若要自動設定網路偵錯,請參閱 自動設定 KDNET 網路核心偵錯。
使用 EXDI 組態 XML 檔案設定進階選項
EXDI GDB COM 伺服器會取用兩個必要的 xml 檔案(ExdiGdbSrv.dll)。
exdiConfigData.xml - 此檔案包含 GDB 伺服器用戶端使用 HW 調試程式 GDB 伺服器目標建立成功 GDB 工作階段所需的主要組態數據,因此如果檔案位置不是由EXDI_GDBSRV_XML_CONFIG_FILE環境變數設定,GDB 伺服器用戶端將不會執行。 每個 xml 標記都允許設定 GDB 伺服器功能的特定集合。 如需您可以在 XML 中修改的屬性清單,以及範例 XML,請參閱下方。
Systemregister.xml - 此檔案包含系統快取快取緩存器的程式代碼之間的對應。 這是必要的,因為 XML 檔案中的 GDB 伺服器未提供存取碼,而調試程式會透過存取碼存取每個系統快取器。 如果檔案未透過環境變數
EXDI_SYSTEM_REGISTERS_MAP_XML_FILE
設定,則ExdiGdbSrv.dll會繼續運作,但調試程式將無法透過 rdmsr 或 wrmsr 命令存取任何系統緩存器。 GDB 伺服器硬體除錯程式應該支援這些快取器的清單(特定系統快取器名稱應該出現在系統 xml 檔案中傳送的快取器清單中)。
EXDI UI 和 XML 組態檔
WinDbg 中的 EXDI UI 會使用 XML 檔案參數,並在 UI 必要參數中合併,例如 IP:Port 值。 如果需要修改預設 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 伺服器存根傳送。
Windbg-ExdiGdbSrv 仍然可以設定正確的目標OS架構,即使使用者在EXDI UI 中設定了不正確的目標架構字段輸入值也一樣。 目標 OS 架構將會從 GDB 伺服器所提供的target.xml描述檔中取得和設定,這些檔案包含 GDB 伺服器交握中的target.xml檔案。 若要檢查目標架構,請使用有效的計算機 .effmach 調試程序命令。
GDBServer 標記和屬性
下表描述檔案中 exdiConfigData.xml
定義的 GDBServer 標記和屬性。
參數 | 描述 |
---|---|
ExdiTargets | 指定ExdiGgbSrv.dll將使用哪些特定 GDB 伺服器目標組態來建立與 GDB 伺服器目標的 GDB 連線,因為exdiConfigData.xml檔案包含ExdiGdbSrv.dll目前支援的所有 GDB 伺服器(此檔案必須先填入,才能搭配特定 GDB 伺服器使用ExdiGdbSrv.dll)。 |
CurrentTarget | 指定 GDB 伺服器目標的名稱(例如,這個屬性值應該與exdiConfigData.xml檔案所包含的其中一個 <ExdiTarget Name= 標籤名稱值相符。 |
ExdiTarget | 這是每個 GDB 伺服器目標元件所包含之所有組態數據的開始標記。 |
名稱 | 指定 GDB 伺服器的名稱(例如 QEMU、BMC-OpenOCD、Trace32、VMWare)。 |
agentNamePacket | 這是 GDB 伺服器 HW 調試程式所辨識的 GDB 用戶端名稱。 GDB 伺服器 HW 調試程式可以使用此程式來設定特定 GDB 用戶端的本身(例如 Trace32 GDB 伺服器需要ExdiGdbSrv.dll傳送 “QMS.windbg” 名稱來識別 windbg-GDB 用戶端,然後啟用僅支援 MS GDB 伺服器用戶端的自定義 GDB 記憶體封包(exdiGdbSrv.dll)。 |
ExdiGdbServerConfigData | 指定ExdiGdbSrv.dll元件相關的組態參數。 |
uuid | 指定ExdiGdbSrv.dll元件的 UUI。 |
displayCommPackets | 如果為 『yes』,則我們會在命令記錄視窗中顯示 RSP 通訊協定通訊字元。 如果為 『no』,則只會顯示要求-回應組文字。 |
enableThrowExceptionOnMemoryErrors | 當 GDB 錯誤回應封包 (E0x) 時,GDB 伺服器用戶端會檢查此屬性,以判斷用戶端是否應該擲回例外狀況並停止讀取記憶體。 |
qSupportedPacket | 這可讓設定 GDB 用戶端要求在 XML 目標描述檔之後,GDB 伺服器 HW 調試程式應該傳送哪些 xml 快取器架構檔案(基本上,用戶端會通知 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 GB 伺服器)。 |
GdbServerConnectionParameters | 指定 GdbServer 工作階段參數。 這些參數可用來控制ExdiGdbSrv.dll元件與 GdbServer 之間的 RSP GdbServer 會話。 |
MultiCoreGdbServerSessions | 旗標 如果為 'yes',則我們將有多核心 GdbServer 會話(T32-GdbServer 後端所使用的會話)。 如果為 『no』,則我們只會與 GdbServer 的一個實例通訊。 |
MaximumGdbServerPacketLength | 這是一個封包所支援的最大 GdbServer 長度。 |
MaximumConnectAttempts | 這是連線嘗試次數上限。 ExdiGdbSrv.dll嘗試建立與 GdbServer 的 RSP 連線時,會使用它。 |
SendPacketTimeout | 這是 RSP 傳送逾時。 |
ReceivePacketTimeout | 這是 RSP 接收逾時。 |
HostNameAndPort | 這是格式<hostname/ip address:Port number> 的 連接字串。 可以有多個 GdbServer 連接字串 (例如 T32 多核心 GdbServer 會話)。 連接字串 數目應該與核心數目相符。 |
ExdiGdbServerMemoryCommands | 指定各種發出 GDB 記憶體命令的方式,以便取得不同例外狀況 CPU 層級的系統緩存器值或讀取/寫入存取記憶體(例如 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 | 指定特定的架構快取器核心集。 |
架構 | 已定義快取器集的CPU架構。 |
FeatureNameSupported | 這是 xml 系統快取器描述檔所提供的系統快取器群組名稱。 需要識別系統註冊 xml 群組,該群組是 GDB 伺服器所傳送之 xml 檔案的一部分。 |
SystemRegistersStart | 這是要識別作為核心緩存器集一部分回報的第一個系統緩存器(例如,在 X64 上,QEMU 不會將 x64 系統快取器集合報告為分隔的 xml 目標描述檔,因此系統 regs 是核心緩存器的一部分)。 |
SystemRegistersEnd | 這是識別在核心緩存器集中回報的最後一個系統緩存器(高緩存器編號/順序)。 |
名稱 | 緩存器的名稱。 |
訂單 | 這是識別快取器陣列中索引的數位。 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 伺服器正在接聽的埠。 |
架構 | 硬體偵錯目標的架構(此參數也表示 xml 設定檔中的 ArchitectureFamily 參數) |
ExdiDropPath | ExdiGdbSrv.dll、exdiConfigData.xml和systemregisters.xml檔案的位置。 只有在未安裝ExdiGdbSrv.dll或安裝不正確時,才會複製這些複本。 |
ExtraDebuggerArgs | 在調試程式命令行上傳遞的額外自變數 |
PreNTAppDebugging | 將啟發學習型ScanSize 的值從 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