Настройка транспорта отладчика EXDI
В этом разделе описывается настройка отладки в режиме ядра с помощью EXDI. Интерфейс расширенной отладки (EXDI) — это уровень адаптации между отладчиком программного обеспечения и целевым объектом отладки. Средства отладки для Windows поддерживают отладку ядра с помощью EXDI, начиная с Windows версии 22000.
EXDI можно использовать для установления подключения к виртуальной среде QEMU. Дополнительные сведения см. в разделе "Настройка отладки в режиме ядра QEMU с помощью EXDI".
Примечание.
EXDI — это расширенная специализированная форма отладки для определенных сред. Использование стандартного подключения KDNET проще настроить и рекомендуется. Чтобы настроить автоматическую отладку сети, см. раздел "Настройка автоматической отладки сетевого ядра KDNET".
Общие сведения о сервере EXDI COM
EXDI — это интерфейс, который позволяет расширить WinDbg, добавив поддержку аппаратных отладчиков (например, на основе JTAG или GdbServer). На приведенной ниже схеме показана роль EXDI-GdbServer.
Так как подключение EXDI не зависит от Windows или протокола KDNET, загружаемого на целевом компьютере. Так как эти компоненты отладчика программного обеспечения не требуются, EXDI может оказаться полезным в начале запуска устройства и при отладке проблем с запуском ОС.
Внимание
Так как EXDI не использует протокол KDNET, подключенный отладчик имеет значительно меньше сведений о том, что выполняется на компьютере, и многие команды будут работать по-разному или не работать вообще. Доступ к частным символам для отлаживаемого кода может помочь отладчику лучше понять выполнение кода целевых систем. Дополнительные сведения см. в разделе "Открытые и частные символы".
Требования к устройству в режиме ядра EXDI
Компьютер, на котором выполняется отладчик, называется главным компьютером, а отлаживаемый компьютер называется целевым компьютером.
Требуется следующее:
На целевом и хост-компьютере поддерживаемая сеть карта, поддерживаемая требуемой средой, например QEMU.
Сетевое подключение между целевым объектом и узлом с помощью TCP/IP.
Windows 10 или Windows 11 версии 22000 или более поздней.
Ограничения
Отладка оборудования EXDI должна быть настроена вручную с помощью XML-файлов, и в отладчиках Windows нет связанного пользовательского интерфейса.
Как описано выше, так как EXDI не использует протокол KDNET, подключенный отладчик имеет меньше сведений о целевой системе, а использование отладчика отличается. Без доступа к частным символам для целевого кода многие команды, использующие символы для понимания состояния целевой системы, не будут работать. В этом случае можно просматривать память и регистрировать содержимое и дизассемблировать код. Определение расположения запуска кода или выполнение других распространенных задач отладчика может быть очень сложным и трудоемким без закрытых символов.
Клиент СЕРВЕРА COM GDB
В этом разделе рассматривается использование клиента СЕРВЕРА COM GDB EXDI (ExdiGdbSrv.dll), реализующего интерфейс отладчика EXDI COM. Можно использовать тот же com-интерфейс для реализации других интерфейсов, таких как COM-сервер EXDI для JTAG-DCI.
Одновременная отладка EXDI и KDNET
В некоторых сложных сценариях, например в начале запуска устройства, может быть полезно иметь два подключения к целевому устройству. Один EXDI и один KDNET. Если целевой объект является ОС Windows, отладка программного обеспечения KDNET настраивается как обычно, например для подключения к виртуальной машине. В этой настройке любой из двух параллельных отладчиков может прервать отладку кода на целевом компьютере.
Сводка процесса настройки подключения EXDI
В этом разделе описан процесс настройки подключения EXDI. Пример сценария использования EXDI см. в статье Настройка отладки режима ядра QEMU с помощью EXDI.
- Скачайте и установите средства отладки Windows в хост-системе.
- Скачивание, сборка и регистрация библиотеки DLL сервера EXDI.
- Настройте подключение, изменив XML-файлы конфигурации EXDI.
- Запустите WinDbg с помощью параметра -kx для подключения к серверу EXDI.
- Используйте WinDbg для отладки целевой системы.
Скачивание и установка средств отладки Windows
Установите средства отладки Windows в хост-системе. Сведения о скачивании и установке средств отладчика см. в разделе "Средства отладки" для Windows.
Скачивание, сборка и регистрация библиотеки DLL сервера EXDI
Скачайте соответствующий исходный код ExdiGdbSrv.dll (клиент сервера EXDI COM) из microsoft/WinDbg-Samples, GitHub https://github.com/microsoft/WinDbg-Samples)
git clone https://github.com/microsoft/WinDbg-Samples
Создайте решение VS (ExdiGdbSrv.sln) в соответствии с архитектурой установки отладчика узла, расположенной в Exdi/exdigdbsrv.
Найдите ExdiGdbSrv.dll, созданные сборкой.
Скопируйте com-сервер EXDI (ExdiGdbSrv.dll) на главный компьютер, в каталог, содержащий отладчик, .g. C:\Program Files (x86)\Windows Kits\10\Debuggers\x64
или C:\Debuggers
)
Используйте regsvr32, чтобы зарегистрировать библиотеку DLL в командной строке Администратор istrator.
C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>regsvr32 ExdiGdbSrv.dll
RegSvr32 должен возвращать сообщение, указывающее, что DLLRegisterServer in ExdiGdbSrv.dll succeeded
.
Этот шаг необходимо выполнить только один раз, но если изменить расположение ExdiGdbSrv.dll, необходимо снова зарегистрировать COM-сервер.
Еще одним вариантом является использование примера скрипта PowerShell для установки библиотеки DLL EXDI и запуска отладчика при первом запуске. Дополнительные сведения см. в примере скрипта PowerShell EXDI.
Настройка WinDbg с помощью XML-файлов конфигурации EXDI
Найдите два необходимых файла WinDbg-Samples/Exdi/exdigdbsrv/
конфигурации и скопируйте их на локальный компьютер отладчика узла, где установлен отладчик.
exdiConfigData.xml
systemregisters.xml
EXDI_GDBSRV_XML_CONFIG_FILE— описывает полный путь к файлу конфигурации Exdi XML.
EXDI_SYSTEM_REGISTERS_MAP_XML_FILE — описывает полный путь к файлу карты регистрации системы Exdi xml.
Дополнительные сведения о тегах и атрибутах exdiConfigData.xml см . в файлах конфигурации EXDI XML ниже.
В нашем сценарии мы зададим следующее значение нулю, чтобы отключить отладчик от попытки найти nt!kdVersionBlock.
heuristicScanSize = "0"
Задайте значения пути EXDI для ссылки на расположение XML-файлов конфигурации
Задайте переменную среды EXDI_GDBSRV_XML_CONFIG_FILE и EXDI_SYSTEM_REGISTERS_MAP_XML_FILE, чтобы описать полный путь к файлу конфигурации exdi XML. Убедитесь, что указанное значение среды пути доступно из расположения ExdiGdbSrv.dll.
Командная строка
Откройте командную строку и задайте следующие переменные среды.
set EXDI_GDBSRV_XML_CONFIG_FILE="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\exdiConfigData.xml"
set EXDI_SYSTEM_REGISTERS_MAP_XML_FILE="C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\systemregisters.xml"
Введите, SET
чтобы убедиться, что указанный путь доступен из расположения ExdiGdbSrvSample.dll
PowerShell
Откройте запрос PowerShell и задайте следующие переменные среды:
$env:EXDI_GDBSRV_XML_CONFIG_FILE = 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\exdiConfigData.xml'
$env:EXDI_SYSTEM_REGISTERS_MAP_XML_FILE = 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\systemregisters.xml'
Введите, dir env:
чтобы убедиться, что указанный путь доступен из расположения ExdiGdbSrvSample.dll
Запустите WinDbg и подключитесь к серверу EXDI
Запустите сеанс windbg через интерфейс exdi в той же командной строке, где заданы переменные среды (EXDI_GDBSRV_XML_CONFIG_FILE и EXDI_SYSTEM_REGISTERS_MAP_XML_FILE).
c:\Debuggers> windbg.exe -v -kx exdi:CLSID={29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014},Kd=NtBaseAddr,DataBreaks=Exdi
Чтобы отобразить дополнительные выходные данные, полезные для диагностики, можно использовать подробный сеанс -v. Общие сведения о параметрах WinDbg см. в разделе "Параметры командной строки WinDbg". Дополнительные сведения см. в разделе параметров загрузки WinDbg EXDI ниже.
Отладчик отобразит успешную инициализацию транспорта EXDI.
EXDI: DbgCoInitialize returned 0x00000001
EXDI: CoCreateInstance() returned 0x00000000
EXDI: QueryInterface(IExdiServer3) returned 0x00000000
EXDI: Server::GetTargetInfo() returned 0x00000000
EXDI: Server::SetKeepaliveInterface() returned 0x00000000
EXDI: Server::GetNbCodeBpAvail() returned 0x00000000
EXDI: ExdiNotifyRunChange::Initialize() returned 0x00000000
EXDI: LiveKernelTargetInfo::Initialize() returned 0x00000000
EXDI: Target initialization succeeded
Kernel Debugger connection established
Окно консоли EXDIGdbServer также может отображать сведения о состоянии подключения EXDI. Дополнительные сведения о консоли см. в разделе "Устранение неполадок".
Параметры загрузки ExDI WinDbg
Для запуска сеанса ядра EXDI используются следующие параметры с WinDbg.
-kx: EXDI:Options
Следующие параметры EXDI доступны с параметром -kx.
Параметр | Описание |
---|---|
CLSID | Идентификатор класса, назначенный LiveExdiGdbSrvServer (как определено в файлеExdiGdbSrv.idl). |
Kd=NtBaseAddr | Обработчик отладчика будет искать базовый адрес NT. |
ForceX86 | Принудительно заставляет обработчик отладчика использовать интерфейс IeXdiX86Context3 для получения и настройки контекста ЦП. |
DataBreaks=Exdi | Разрешить использование точек останова данных. |
Inproc | Разрешить использование inproc Exdi-Server. |
Отладка целевой системы с помощью WinDbg
Dbgeng.dll использует эвристические алгоритмы для поиска расположения базового адреса загрузки NT во время выполнения команды останова. Если закрытые символы недоступны, этот процесс завершится ошибкой.
Это означает, что при множестве последовательностей подключений разрыв не будет функционировать должным образом. Если вы вручную войдете в код, это будет случайное расположение, которое Windows выполнялось в данный момент. Так как символы целевого кода могут быть недоступны, может быть трудно задать точки останова с помощью символов.
Команды, такие как указанные ниже, напрямую будут работать для доступа к памяти.
k, kb, kc, kd, kp, kP, kv (Display Stack Backtrace)
d, da, db, dc, dd, dD, df, dp, dq, du, dw (display Memory)
И вы можете выполнить пошаговое выполнение кода с помощью P (Step).
Существуют также команды, которые можно использовать для поиска кода, который требуется выполнить отладку.
.imgscan (поиск заголовков изображений)
Imgscan может быть полезным при отладке EDXI, так как в отличие от традиционной отладки ядра на основе KDNET, установка точек останова на основе символов может быть недоступна. Поиск требуемого целевого образа может упростить использование его расположения для задания точки останова доступа к памяти.
.exdicmd (команда EXDI)
Exdicmd отправляет команду EXDI в целевую систему с помощью активного подключения отладки EXDI. Дополнительные сведения см. в разделе .exdicmd (команда EXDI).
Устранение неполадок
Используйте выходные данные из окна ExdiGdbServer для мониторинга последовательности подключений.
Проблема: ошибка: не удается установить соединение с GbDServer. Проверьте строка подключения <hostname/ip>:portnumber
Эта проблема может быть вызвана следующими причинами:
- ExdiGdbSrv.dll не удается подключиться к целевому серверу GDB.
- Сервер GDB еще не запущен в целевом объекте.
- Проблемы с брандмауэром, убедитесь, что оба IP-адреса доступны с помощью ping, tracert или другого средства, чтобы убедиться, что трафик GDB может проходить через брандмауэр.
Проблема. Не удалось запустить отладку ядра с помощью EXDI.
Эта проблема может быть вызвана следующими причинами:
- Существует еще один экземпляр ExdiGdbSrv.dll (размещенного dllhost.exe) на компьютере отладчика узла.
- Завершите дополнительный экземпляр службы COM, на котором размещена ExdiGdbSrv.dll.
- Сначала перечислить процессы с помощью служебной программы, например TList на хост-компьютере. DLLHost, на котором размещена ExdiGdbSrv.dll, будет отображаться ExdiGdbServer.
tlist 261928 dllhost.exe ExdiGdbServer
- Используйте
kill -f XXXXX
в командной строке отладчика, чтобы завершить процесс с помощью номера процесса.
- Сначала перечислить процессы с помощью служебной программы, например TList на хост-компьютере. DLLHost, на котором размещена ExdiGdbSrv.dll, будет отображаться ExdiGdbServer.
Проблема: ошибка: не удается настроить сеанс GdbServer.
Эта проблема может быть вызвана следующими причинами:
- Произошла ошибка при поиске сведений о сеансе, таких как путь к XML-файлам конфигурации.
Проблема. Ошибка: переменная среды EXDI_GDBSRV_XML_CONFIG_FILE не определена.
Эта проблема может быть вызвана следующими причинами:
- ExdiGdbSrv.dll переменные среды не заданы или в противном случае недоступны в среде.
Проблема. Ошибка: переменная среды EXDI_GDBSRV_XML_CONFIG_FILE не определена. Пример Exdi-GdbServer не будет продолжаться на этом этапе. Укажите полный путь к файлу конфигурации Exdi XML.
Эта проблема может быть вызвана следующими причинами:
- Переменная среды EXDI_GDBSRV_XML_CONFIG_FILE не задана. В некоторых ситуациях ExdiGDbSrv.dll продолжить работу, если нажать кнопку "ОК", но windbg.exe завершится сбоем запросов к системным регистрам (например, через функции rdmsr/wrmsr).
Проблема. Сценарий ошибки с целевой системой недоступен — DbgCoInitialize возвращается 0x00000001
Следующие выходные данные могут быть возвращены, если целевая система не загружена или недоступна.
Microsoft (R) Windows Debugger Version 10.0.20317.1 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
EXDI: DbgCoInitialize returned 0x00000001
Это распространенная ошибка, когда ExdiGdbSrv.dll COM-сервер не удалось подключиться к GDServer QEMU, поэтому это может привести к сбою из-за:
Сбой при запуске COM-сервера EXDI (ExdiGDbSrv.dll) через процесс dllhost.exe (связанный COM). Чтобы устранить эту проблему, перезапустите компьютер отладчика узла или снова войдите в Систему и выполните вход. Если это не работает, повторно зарегистрируйте COM-сервер EXDI после перезапуска или входа снова.
regsvr32.exe <full path to the ExdiGdbSrv.dll)
Предыдущий сеанс ExdiGdbSrv.dll по-прежнему размещен процессом dllhost.exe, поэтому необходимо убить процесс dllhost.exe. Контрольный список для dllhost.exe, на котором размещается ExdiGdbSrv.dll, и убить связанный пид.
Сервер gdbserver QEMU еще не запущен или файл exdiconfigdata.xml содержит недопустимые значения IP:Port. Если сеанс WinDbg запускается на том же компьютере узла, что и виртуальная машина Windows QEMU, то IP=LocalHost.
Проблема. Не удалось запустить сеанс отладки: FAILURE HR=0x80004005:Failed to AttachKernel.
Эта проблема может быть вызвана следующими причинами:
- Как описано выше, возможно, что предыдущий сеанс ExdiGdbSrv.dll по-прежнему активен. Найдите и завершите связанный узел DLL, как описано выше.
Файлы конфигурации EXDI XML
Существует два необходимых XML-файла, которые используются COM-сервером EXDI GDB (ExdiGdbSrv.dll).
exdiConfigData.xml . Этот файл содержит основные данные конфигурации, необходимые клиенту сервера GDB для успешного создания сеанса GDB с целевым объектом сервера GDB HW, поэтому клиент сервера GDB-сервера GDB не будет запускаться, если расположение файла не задано переменной среды EXDI_GDBSRV_XML_CONFIG_FILE. Каждый тег XML позволяет настроить определенный набор функций сервера GDB. Ниже приведен список атрибутов, которые можно изменить в XML и примере XML.
Systemregister.xml . Этот файл содержит сопоставление между системными регистрами и кодом доступа. Это необходимо, так как код доступа не предоставляется сервером GDB в XML-файле, а отладчик обращается к каждой системной регистрации через код доступа. Если файл не задан с помощью переменной
EXDI_SYSTEM_REGISTERS_MAP_XML_FILE
среды, ExdiGdbSrv.dll продолжит работать, но отладчик не сможет получить доступ к системной регистрации через команды rdmsr или wrmsr. Список этих регистров должен поддерживаться отладчиком оборудования сервера GDB (определенное имя системного регистра должно присутствовать в списке регистров, отправляемых в системном XML-файле).
Теги и атрибуты GDBServer
В следующей таблице описываются теги и атрибуты GDBServer, определенные в exdiConfigData.xml
файле.
Параметр | Описание |
---|---|
ExdiTargets | Указывает, какую конкретную конфигурацию целевого сервера GDB будет использоваться ExdiGgbSrv.dll для установления подключения GDB к целевому объекту сервера GDB, так как файл exdiConfigData.xml включает все серверы GDB, поддерживаемые в настоящее время ExdiGdbSrv.dll (этот файл должен быть заполнен перед использованием ExdiGdbSrv.dll с определенным сервером GDB). |
CurrentTarget | Указывает имя целевого объекта сервера GDB (например, это значение атрибута должно совпадать со значением имени одного из <ExdiTarget Name= тегов, включенных в файл exdiConfigData.xml. |
ExdiTarget | это тег запуска для всех данных конфигурации, включенных каждым целевым компонентом сервера GDB. |
Имя. | Указывает имя сервера GDB (например, QEMU, BMC-OpenOCD, Trace32, VMWare). |
agentNamePacket | Это имя клиента GDB, который распознается отладчиком HW сервера GDB. Это можно использовать отладчиком GDB-сервера HW для настройки для определенных клиентов GDB (например, для сервера Trace32 GDB требуется ExdiGdbSrv.dll отправить имя QMS.windbg для идентификации клиента windbg-GDB, а затем включить настраиваемые пакеты памяти GDB, поддерживаемые только для клиента сервера MS GDB (exdiGdbSrv.dll). |
ExdiGdbServerConfigData | Указывает параметры конфигурации ExdiGdbSrv.dll компонента. |
uuid | указывает UUI компонента ExdiGdbSrv.dll. |
displayCommPackets | Помечайте, если да, то в окне журнала команд будут отображаться символы связи протокола RSP. Если "нет", то мы отображаем только текст пары "запрос-ответ". |
enableThrowExceptionOnMemoryErrors | Этот атрибут будет проверка клиентом сервера GDB, если существует пакет ответа об ошибке GDB (E0x), чтобы определить, должен ли клиент вызывать исключение и перестать читать память. |
qSupportedPacket | Это позволяет клиенту GDB запрашивать, какой файл архитектуры xml-регистра должен отправляться отладчиком HW сервера GDB после xml-файла описания целевого объекта (в основном клиент будет информировать сервер GDB, какие архитектуры поддерживаются клиентом, в настоящее время клиент поддерживает архитектуру x64). |
ExdiGdbServerTargetData | Указывает параметры, связанные с целевым объектом оборудования, отлаживаемым сеансом GdbServer. |
targetArchitecture | Строка, содержащая целевую архитектуру оборудования. Возможные значения: X86, X64, ARM, ARM64. В настоящее время exdiGdbSrv.dll поддерживает только X86 и ARM. |
targetFamily | Строка, содержащая целевое семейство оборудования. Возможные значения: ProcessorFamilyX86, ProcessorFamilyX64, ProcessorFamilyARM, ProcessorFamilyARM64. |
numberOfCores | Количество ядер процессора, которые поддерживают целевую поддержку. Этот параметр будет проверен при использовании сеанса multi-Gdbserver (сеанс T32-GdbServer). Для атрибута MultiCoreGdbServerSessions должно быть задано значение "да". |
EnableSseContext | Пометьте значение "да", то пакет RSP контекста G будет содержать значения регистров с плавающей запятой. Этот параметр имеет смысл только для целевых объектов семейства Intel. |
эвристикаScanSize | Это настраивает алгоритм быстрого эвристического алгоритма отладчика для уменьшения сканированной проверки памяти на указанный размер, если значение атрибута не указано (или "0"), то подсистема отладчика не будет использовать быструю эвристика и вернуться к устаревшей эвристики, которая сканирует всю память, ищущую подпись PE DOS. |
targetDescriptionFile | Указывает, отправляет ли сервер GDB целевой файл заголовка описания перед отправкой каждого отдельного XML-файла. Это поле пусто, тогда клиент сервера GDB не запрашивает регистр системы архитектуры XML (например, сервер Trace32 GDBs, который не поддерживает отправку регистров архитектуры в отдельном XML-файле). |
GdbServer Подключение ionParameters | Задает параметры сеанса GdbServer. Эти параметры используются для управления сеансом RSP GdbServer между компонентом ExdiGdbSrv.dll и GdbServer. |
MultiCoreGdbServerSessions | Пометьте значение "Да", то у нас будет сеанс GdbServer с несколькими ядрами (используемый серверной частью T32-GdbServer). Если значение "нет", мы будем взаимодействовать только с одним экземпляром GdbServer. |
MaximumGdbServerPacketLength | Это максимальная поддерживаемая длина GdbServer для одного пакета. |
Максимальное Подключение Attempts | Это максимальные попытки подключения. Он используется ExdiGdbSrv.dll при попытке установить подключение RSP к GdbServer. |
SendPacketTimeout | Это время ожидания отправки RSP. |
ReceivePacketTimeout | Это время ожидания получения RSP. |
HostNameAndPort | Это строка подключения в формате<hostname/ip address:Port number> . Может быть несколько строка подключения GdbServer (например, сеанс GdbServer с несколькими ядрами T32). Число строка подключения должно соответствовать числу ядер. |
ExdiGdbServerMemoryCommands | Задает различные способы выдачи команд памяти GDB для получения значений системных регистров или памяти доступа для чтения и записи на разных уровнях ЦП исключений (например, BMC-OpenOCD предоставляет доступ к регистру CP15 через настраиваемую команду aarch64 mrs nsec/sec <access code> ). |
GdbSpecialMemoryCommand | Если значение "да", сервер GDB поддерживает настраиваемые команды памяти (например, системный регистр, он должен быть установлен для сервера Trace32 GDB). |
PhysicalMemory | Если значение "да", сервер GDB поддерживает настраиваемые команды для чтения физической памяти (он установлен для сервера Trace32 GDB). |
РуководительMemory | Значение "да", то сервер GDB поддерживает настраиваемые команды для чтения памяти руководителя (он установлен для сервера Trace32 GDB). |
SpecialMemoryRegister | Значение "да", то сервер GDB поддерживает настраиваемые команды для чтения системных регистров (он установлен для сервера Trace32 GDB) |
SystemRegistersGdbMonitor | Если "да", сервер GDB поддерживает настраиваемые команды с помощью команды монитора GDB (он установлен для BMC Open-OCD). |
SystemRegisterDecoding | Значение "да", то клиент GDB принимает декодирование кода доступа перед отправкой команды монитора GDB. |
ExdiGdbServerRegisters | Указывает набор ядер регистра конкретной архитектуры. |
Архитектура | Архитектура ЦП определенного набора регистров. |
FeatureNameSupported | Это имя группы системных регистров, так как она предоставляется файлом описания реестра системы XML. Необходимо определить группу XML системного регистра, которая является частью XML-файла по мере отправки сервером GDB. |
SystemRegistersStart | Это позволяет определить первый системный регистр (низкий номер или порядок), который сообщается как часть основного набора регистров (например, в X64, QEMU не сообщает системный регистр x64 в виде файла описания отдельного целевого объекта XML, поэтому системные регистры являются частью основных регистров). |
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>
Пример скрипта PowerShell EXDI
Этот пример скрипта PowerShell устанавливает EXDI, а затем запускает отладчик. Скрипт Start-ExdiDebugger.ps1 установит ExdiGdbSrv.dll при необходимости, настройте файлы параметров XML, проверка для выполнения процессов dllhost.exe и запустите отладчик для подключения к уже работающему целевому объекту отладки оборудования сервера gdb.
Это пример вызова скрипта запуска.
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 | IP-адрес или имя узла компьютера, на котором размещен сеанс сервера gdb (по умолчанию — LocalHost) |
GdbPort | Порт, на который прослушивается сервер gdb. |
Архитектура | Архитектура целевого объекта отладки оборудования (этот параметр также подразумевает параметр ArchitectureFamily в файле параметров XML) |
ExdiDropPath | Расположение ExdiGdbSrv.dll, exdiConfigData.xml и systemregisters.xml файлов. Они будут скопированы только в том случае, если ExdiGdbSrv.dll не установлен или установлен неправильно. |
ExtraDebuggerArgs | Дополнительные аргументы для передачи командной строки отладчика |
PreNTAppDebugging | Изменяет значение эвристическогоscanSize из 0xfffe (лучше всего для NT) на 0xffe (для приложений до NT) |
DontTryDllHostCleanup | Для проверки существующих запущенных экземпляров ExdiGdbSrv.dll в dllhost.exe требуется повышение прав. Предоставление этого параметра позволит скрипту работать без повышения прав (хотя отладчик может работать неправильно). |
Чтобы включить отображение пакетов, задайте для параметра displayCommPackets значение "Да".
[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
См. также
Настройка отладки режима ядра QEMU с помощью EXDI
Автоматическая настройка отладки сетевого ядра KDNET