EXDI XML 配置文件
本主题介绍如何使用 EXDI XML 配置文件配置高级选项。 有关使用 WinDbg 用户界面配置 EXDI 的一般信息,请参阅 配置 EXDI 调试器传输。 用户界面中提供了最常见的设置,这是一种更简单的方法,然后手动编辑此处所述的 EXDI XML 配置文件。
扩展调试接口 (EXDI) 是软件调试器和调试目标之间的适应层。 从 Windows 版本 22000 开始,Windows 调试工具支持使用 EXDI 进行内核调试。
注意
EXDI 是一种针对特定环境的高级专业调试方式。 使用标准 KDNET 连接更容易配置,因此建议使用。 要自动设置网络调试,请参阅设置 KDNET 网络内核自动调试。
使用 EXDI 配置 XML 文件配置高级选项
EXDI GDB COM 服务器 (ExdiGdbSrv.dll) 需要使用两个 xml 文件。
exdiConfigData.xml - 该文件包含 GDB 服务器客户端与 HW 调试器 GDB 服务器目标成功建立 GDB 会话所需的主要配置数据,因此如果 EXDI_GDBSRV_XML_CONFIG_FILE 环境变量未设置该文件位置,GDB 服务器客户端将无法运行。 每个 xml 标记都可以配置特定的 GDB 服务器功能集。 有关可以在 XML 中修改的属性列表和示例 XML,请参阅下文。
Systemregister.xml - 此文件包含系统寄存器与用于访问寄存器的代码之间的映射。 之所以需要这样做,是因为 GDB 服务器没有在 xml 文件中提供访问代码,而调试器是通过访问代码来访问每个系统寄存器的。 如果未通过环境变量
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 服务器存根之间的 GDB-RSP 协议握手期间发送。
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 服务器(在将 ExdiGdbSrv.dll 用于特定 GDB 服务器之前必须填充此文件)。 |
CurrentTarget | 指定 GDB 服务器目标的名称(例如,此属性值应与 exdiConfigData.xml 文件包含的 <ExdiTarget Name= 标记之一的名称值匹配。 |
ExdiTarget | 这是每个 GDB 服务器目标组件包含的所有配置数据的开始标记。 |
名称 | 指定 GDB 服务器的名称(例如 QEMU、BMC-OpenOCD、Trace32、VMWare)。 |
agentNamePacket | 这是 GDB 客户端的名称,因为 GDB 服务器 HW 调试器可以识别它。 GDB 服务器 HW 调试器可以使用这一点为特定 GDB 客户端(例如 Trace32 GDB 服务器)配置自身(例如 Trace32 GDB 服务器)需要 ExdiGdbSrv.dll 发送“QMS.windbg”名称来标识 windbg-GDB 客户端,然后启用仅支持 MS GDB 服务器客户端 (exdiGdbSrv.dll) 的自定义 GDB 内存数据包。 |
ExdiGdbServerConfigData | 指定与组件相关的 ExdiGdbSrv.dll 配置参数。 |
uuid | 指定 ExdiGdbSrv.dll 组件的 UUI。 |
displayCommPackets | 如果标记为“是”,则会在命令日志窗口中显示 RSP 协议通信字符。 如果为“否”,则仅显示请求-响应对文本。 |
enableThrowExceptionOnMemoryErrors | 当存在 GDB 错误响应数据包 (E0x) 时,GDB 服务器客户端将检查此属性,以确定客户端是否应引发异常并停止读取内存。 |
qSupportedPacket | 这允许将 GDB 客户端配置为请求 GDB 服务器 HW 调试器应按照 xml 目标说明文件发送哪个 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 GDB 服务器)。 |
GdbServerConnectionParameters | 指定 GdbServer 会话参数。 这些参数用于控制 ExdiGdbSrv.dll 组件和 GdbServer 之间的 RSP GdbServer 会话。 |
MultiCoreGdbServerSessions | 标志如果为“yes”,则我们将具有多核 GdbServer 会话(T32-GdbServer 后端使用的会话)。 如果为“no”,我们将仅与 GdbServer 的一个实例通信。 |
MaximumGdbServerPacketLength | 这是一个数据包支持的最大 GdbServer 长度。 |
MaximumConnectAttempts | 这是最大连接尝试次数。 尝试建立与 GdbServer 的 RSP 连接时,ExdiGdbSrv.dll 会使用它。 |
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 系统注册说明文件提供的系统注册组的名称。 在 GDB 服务器发送 xml 文件时,需要用它来识别 xml 文件中的系统注册 xml 组。 |
SystemRegistersStart | 这是为了识别作为核心寄存器集一部分报告的第一个系统寄存器(低寄存器编号/顺序)(例如,在 X64 上,QEMU 不会将 x64 系统寄存器集作为单独的 xml 目标说明文件报告,因此系统寄存器是核心寄存器的一部分)。 |
SystemRegistersEnd | 这是为了标识作为核心寄存器集的一部分报告的最后一个系统寄存器(高寄存器编号/顺序)。 |
名称 | 寄存器的名称。 |
订单 | 这是一个数字,用于标识寄存器数组中的索引。 GDB 客户端和服务器集/查询 (p<number>”/”q<number> ) 将使用此数字来注册数据包。 |
大小 | 这是寄存器大小(以字节为单位)。 |
Sample exdiConfigData.xml file
<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 | 将 heuristicScanSize 的值从 0xfffe(最适合 NT)更改为 0xffe(适用于 pre-N 应用) |
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