Bagikan melalui


Mengonfigurasi Exdi Debugger Transport

Topik ini menjelaskan cara menyiapkan Debugging Mode Kernel menggunakan EXDI. Extended Debugging Interface (EXDI) adalah lapisan adaptasi antara debugger perangkat lunak dan target penelusuran kesalahan. Alat Penelusuran Kesalahan untuk Windows mendukung penelusuran kesalahan kernel menggunakan EXDI yang dimulai dengan Windows versi 22000.

EXDI dapat digunakan untuk membuat koneksi dengan lingkungan virtual QEMU. Untuk informasi selengkapnya, lihat Menyiapkan Debugging Mode Kernel QEMU menggunakan EXDI.

Catatan

EXDI adalah bentuk debugging khusus yang canggih untuk lingkungan tertentu. Menggunakan koneksi KDNET standar lebih mudah dikonfigurasi, dan disarankan. Untuk menyiapkan penelusuran kesalahan jaringan secara otomatis, lihat Menyiapkan Penelusuran Kesalahan Kernel Jaringan KDNET Secara Otomatis.

Gambaran umum server EXDI COM

EXDI adalah antarmuka yang memungkinkan perluasan WinDbg dengan menambahkan dukungan untuk debugger perangkat keras (misalnya berbasis JTAG, atau berbasis GdbServer). Diagram di bawah ini mengilustrasikan peran EXDI-GdbServer.

Diagram tumpukan memperlihatkan peran EXDI-GdbServer dengan WinDbg-DbgEng di atasnya, antarmuka EXDI, dan server EXDI COM berkomunikasi dengan server GDB.

Karena koneksi EXDI tidak memiliki dependensi pada Windows atau protokol KDNET yang dimuat pada PC target. Karena komponen debugger perangkat lunak ini tidak diperlukan, EXDI dapat berguna di perangkat awal memunculkan dan dalam men-debug masalah startup OS.

Penting

Karena EXDI tidak menggunakan protokol KDNET, debugger yang terhubung memiliki informasi yang jauh lebih sedikit tentang apa yang berjalan pada PC dan banyak perintah akan bekerja secara berbeda atau mungkin tidak berfungsi sama sekali. Akses ke simbol privat untuk kode yang di-debug dapat membantu debugger lebih memahami eksekusi kode sistem target. Untuk informasi selengkapnya, lihat Simbol Publik dan Privat.

Persyaratan perangkat EXDI Kernel-Mode

Komputer yang menjalankan debugger disebut komputer host, dan komputer yang sedang di-debug disebut komputer target.

Hal-hal berikut diperlukan:

  • Pada komputer target dan host, kartu jaringan yang didukung didukung oleh lingkungan yang diinginkan seperti QEMU.

  • Koneksi jaringan antara target dan host menggunakan TCP/IP.

  • Windows 10 atau Windows 11 versi 22000 atau yang lebih baru.

Batasan

  • Debugging Perangkat Keras EXDI harus dikonfigurasi secara manual menggunakan file XML dan tidak ada UI terkait di debugger Windows.

  • Seperti yang dijelaskan di atas, karena EXDI tidak menggunakan protokol KDNET, debugger yang terhubung memiliki lebih sedikit informasi tentang sistem target dan penggunaan debugger berbeda. Tanpa akses ke simbol privat untuk kode target, banyak perintah yang menggunakan simbol untuk memahami status sistem target tidak akan berfungsi. Dalam hal ini, dimungkinkan untuk melihat memori dan mendaftarkan konten dan membongkar kode. Menentukan lokasi kode yang berjalan, atau melakukan tugas debugger umum lainnya, bisa sangat sulit dan memakan waktu tanpa simbol privat.

Klien COM GDB Server

Topik ini mencakup penggunaan klien EXDI COM GDB Server (ExdiGdbSrv.dll), yang mengimplementasikan antarmuka debugger EXDI COM. Dimungkinkan untuk menggunakan antarmuka COM yang sama untuk mengimplementasikan antarmuka lain, seperti EXDI COM Server untuk JTAG-DCI.

Penelusuran kesalahan EXDI dan KDNET Bersamaan

Dalam beberapa skenario kompleks, misalnya di perangkat awal muncul, dapat berguna untuk memiliki dua koneksi ke perangkat target. Satu EXDI dan satu KDNET. Jika target adalah OS Windows, penelusuran kesalahan perangkat lunak KDNET dikonfigurasi seperti biasanya, misalnya untuk terhubung ke komputer virtual. Dalam penyiapan ini, salah satu dari dua debugger bersamaan dapat masuk ke kode debug pada komputer target.

Ringkasan proses untuk mengonfigurasi koneksi EXDI

Dalam topik ini, kami akan menjelaskan proses untuk mengonfigurasi koneksi EXDI. Untuk contoh skenario penggunaan EXDI, lihat Menyiapkan Penelusuran Kesalahan Mode Kernel QEMU menggunakan EXDI.

  1. Unduh dan instal alat penelusuran kesalahan Windows pada sistem host.
  2. Unduh, bangun, dan daftarkan DLL server EXDI.
  3. Konfigurasikan koneksi dengan mengedit file XML konfigurasi EXDI.
  4. Luncurkan WinDbg menggunakan opsi -kx untuk menyambungkan ke server EXDI.
  5. Gunakan WinDbg untuk men-debug sistem target.

Mengunduh dan menginstal alat penelusuran kesalahan Windows

Instal Windows Debugging Tools pada sistem host. Untuk informasi tentang mengunduh dan menginstal alat debugger, lihat Alat Debugging untuk Windows.

Mengunduh, membangun, dan mendaftarkan DLL server EXDI

Unduh kode sumber biner ExdiGdbSrv.dll (klien server EXDI COM) yang sesuai dari microsoft/WinDbg-Samples, GitHub https://github.com/microsoft/WinDbg-Samples)

git clone https://github.com/microsoft/WinDbg-Samples

Bangun solusi VS (ExdiGdbSrv.sln) sesuai dengan arsitektur penginstalan Host Debugger Anda yang terletak di Exdi/exdigdbsrv.

Temukan ExdiGdbSrv.dll yang dihasilkan oleh build.

Salin server com EXDI (ExdiGdbSrv.dll) ke komputer Host, ke direktori yang berisi debugger Anda, .g. C:\Program Files (x86)\Windows Kits\10\Debuggers\x64 atau C:\Debuggers)

Gunakan regsvr32 untuk mendaftarkan DLL di prompt perintah Administrator.

C:\Program Files (x86)\Windows Kits\10\Debuggers\x64>regsvr32 ExdiGdbSrv.dll

RegSvr32 harus mengembalikan pesan yang menunjukkan bahwa DLLRegisterServer in ExdiGdbSrv.dll succeeded.

Langkah ini hanya perlu dilakukan sekali, tetapi jika Anda mengubah lokasi ExdiGdbSrv.dll, maka Anda harus mendaftarkan server COM lagi.

Opsi lain adalah menggunakan contoh skrip PowerShell adalah menginstal EXDI DLL, dan meluncurkan debugger untuk pertama kalinya. Untuk informasi selengkapnya, lihat Contoh skrip EXDI PowerShell.

Mengonfigurasi WinDbg menggunakan file XML konfigurasi EXDI

Temukan dua file konfigurasi yang diperlukan dan WinDbg-Samples/Exdi/exdigdbsrv/ salin ke lokal ke komputer debugger Host Anda ke tempat debugger diinstal.

  • exdiConfigData.xml
  • systemregisters.xml

EXDI_GDBSRV_XML_CONFIG_FILE – Menjelaskan jalur lengkap ke file konfigurasi xml Exdi.

EXDI_SYSTEM_REGISTERS_MAP_XML_FILE – Menjelaskan jalur lengkap ke file peta daftar sistem xml Exdi.

Lihat File Konfigurasi XML EXDI di bawah ini untuk informasi selengkapnya tentang tag dan atribut exdiConfigData.xml.

Dalam skenario kami, kami akan mengatur nilai berikut ke nol, untuk menonaktifkan debugger dari mencoba menemukan nt!kdVersionBlock.

heuristicScanSize = "0"

Atur nilai Jalur EXDI untuk mereferensikan lokasi file konfigurasi XML

Atur variabel lingkungan EXDI_GDBSRV_XML_CONFIG_FILE dan EXDI_SYSTEM_REGISTERS_MAP_XML_FILE untuk menjelaskan jalur lengkap ke file konfigurasi xml exdi. Pastikan bahwa nilai lingkungan jalur yang ditentukan tersedia dari lokasi ExdiGdbSrv.dll.

perintah

Buka perintah dan atur variabel lingkungan berikut.

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"

Ketik SET untuk mengonfirmasi bahwa jalur yang ditentukan tersedia dari lokasi ExdiGdbSrvSample.dll

Powershell

Buka perintah PowerShell dan atur variabel lingkungan berikut:

$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'

Ketik dir env: untuk mengonfirmasi bahwa jalur yang ditentukan tersedia dari lokasi ExdiGdbSrvSample.dll

Luncurkan WinDbg dan sambungkan ke server EXDI

Luncurkan sesi windbg melalui antarmuka exdi pada prompt perintah yang sama tempat Anda mengatur variabel lingkungan (EXDI_GDBSRV_XML_CONFIG_FILE dan EXDI_SYSTEM_REGISTERS_MAP_XML_FILE).

c:\Debuggers> windbg.exe -v -kx exdi:CLSID={29f9906e-9dbe-4d4b-b0fb-6acf7fb6d014},Kd=NtBaseAddr,DataBreaks=Exdi

Untuk menampilkan output tambahan yang berguna untuk tujuan diagnostik, sesi -v: verbose dapat digunakan. Untuk informasi umum tentang opsi WinDbg, lihat Opsi Baris Perintah WinDbg. Lihat EXDI WinDbg Load Parameters di bawah ini untuk informasi selengkapnya.

Debugger akan menampilkan inisialisasi transportasi EXDI yang berhasil.

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

Sesi WinDbg utama menampilkan EXDI CLSID di judul jendela.

Jendela konsol EXDIGdbServer juga dapat menampilkan informasi tentang status koneksi EXDI. Untuk informasi selengkapnya tentang konsol, lihat Pemecahan Masalah.

EXDI WinDbg Load Parameters

Parameter berikut digunakan dengan WinDbg untuk memulai sesi kernel EXDI.

-kx: EXDI:Options

Opsi EXDI berikut tersedia dengan opsi -kx.

Parameter Deskripsi
CLSID ID Kelas yang ditetapkan ke LiveExdiGdbSrvServer (seperti yang didefinisikan dalam fileExdiGdbSrv.idl).
Kd=NtBaseAddr Mesin debugger akan mencari alamat dasar NT.
ForceX86 Memaksa mesin debugger untuk menggunakan antarmuka IeXdiX86Context3 untuk mendapatkan/mengatur Konteks CPU.
DataBreaks=Exdi Izinkan menggunakan titik henti data.
Inproc Izinkan menggunakan Exdi-Server inproc.

Gunakan WinDbg untuk men-debug sistem target

dbgeng.dll menggunakan algoritma heuristik untuk menemukan lokasi alamat beban dasar NT pada saat perintah pemutusan terjadi. Jika simbol privat tidak tersedia, proses ini akan gagal.

Ini berarti bahwa di bawah banyak urutan koneksi, pemutusan tidak akan berfungsi seperti yang diharapkan. jika Anda secara manual memecah ke dalam kode, itu akan menjadi lokasi acak yang kebetulan dieksekusi Windows pada saat itu. Karena simbol untuk kode target mungkin tidak tersedia, mungkin sulit untuk mengatur titik henti menggunakan simbol.

Perintah seperti berikut ini yang mengakses memori secara langsung akan berfungsi.

k, kb, kc, kd, kp, kP, kv (Display Stack Backtrace)

r (Daftar)

d, da, db, dc, dd, dD, df, dp, dq, du, dw (Display Memory)

u (Tidak Dapat Dirakit)

Dan Anda dapat menelusuri kode menggunakan p (Langkah).

Ada juga perintah yang dapat digunakan untuk mencoba menemukan kode yang ingin Anda debug.

s (Memori Pencarian)

.imgscan (Temukan Header Gambar)

Imgscan dapat membantu dengan penelusuran kesalahan EDXI, karena tidak seperti penelusuran kesalahan kernel berbasis KDNET tradisional, mengatur titik henti berdasarkan simbol mungkin tidak tersedia. Menemukan gambar target yang diinginkan, dapat memfasilitasi penggunaan lokasinya untuk mengatur titik henti akses memori.

.exdicmd (Perintah EXDI)

.exdicmd mengirimkan perintah EXDI ke sistem target menggunakan koneksi debugging EXDI aktif. Untuk informasi selengkapnya, lihat .exdicmd (Perintah EXDI).

Pemecahan Masalah

Gunakan output dari jendela ExdiGdbServer untuk memantau urutan koneksi.

Jendela teks ExdiGdbServer menampilkan angka heksadesimal panjang.

Masalah: Kesalahan: Tidak dapat membuat koneksi dengan GbDServer. Harap verifikasi string koneksi <hostname/ip>:portnumber

Masalah ini dapat disebabkan oleh:

  • ExdiGdbSrv.dll tidak dapat tersambung ke server GDB target.
  • Server GDB belum berjalan pada target.
  • Masalah firewall, pastikan bahwa kedua alamat IP dapat dijangkau dengan menggunakan ping, tracert, atau beberapa alat lain untuk memverifikasi bahwa lalu lintas GDB dapat melalui firewall.

Masalah: Tidak dapat memulai penelusuran kesalahan kernel menggunakan EXDI.

Masalah ini dapat disebabkan oleh:

  • Ada instans lain dari ExdiGdbSrv.dll (dihosting oleh dllhost.exe) yang berjalan pada komputer debugger host.
  • Hentikan instans tambahan layanan COM yang menghosting ExdiGdbSrv.dll.
    • Pertama-tama cantumkan proses, menggunakan utilitas seperti TList pada PC host. DLLHost yang menghosting ExdiGdbSrv.dll akan menampilkan ExdiGdbServer.

      daftar 261928 dllhost.exe ExdiGdbServer

    • Gunakan kill -f XXXXX pada perintah debugger untuk mengakhiri proses menggunakan nomor proses.

Masalah: Kesalahan: Tidak dapat mengonfigurasi sesi GdbServer.

Masalah ini dapat disebabkan oleh:

  • Terjadi kesalahan dalam menemukan informasi sesi, seperti jalur ke file konfigurasi XML.

Masalah: Kesalahan: Variabel lingkungan EXDI_GDBSRV_XML_CONFIG_FILE tidak ditentukan.

Masalah ini dapat disebabkan oleh:

  • ExdiGdbSrv.dll variabel lingkungan tidak diatur atau tidak tersedia di lingkungan.

Masalah: Kesalahan: variabel lingkungan EXDI_GDBSRV_XML_CONFIG_FILE tidak ditentukan. Sampel Exdi-GdbServer tidak akan berlanjut pada saat ini. Atur jalur lengkap ke file konfigurasi xml Exdi.

Masalah ini dapat disebabkan oleh:

  • Variabel lingkungan EXDI_GDBSRV_XML_CONFIG_FILE tidak diatur. Dalam beberapa situasi, ExdiGDbSrv.dll akan terus berfungsi jika Anda menekan tombol "OK", tetapi windbg.exe akan gagal mendaftarkan sistem kueri (misalnya melalui fungsi rdmsr/wrmsr).

Masalah: Skenario kesalahan dengan sistem target tidak tersedia - DbgCoInitialize dikembalikan 0x00000001

Output berikut dapat dikembalikan jika sistem target tidak dimuat atau tidak tersedia.

Microsoft (R) Windows Debugger Version 10.0.20317.1 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.

EXDI: DbgCoInitialize returned 0x00000001

Ini adalah kesalahan umum ketika server COM ExdiGdbSrv.dll tidak dapat tersambung ke QEMU GDServer, sehingga dapat gagal karena:

  • Kegagalan saat meluncurkan server EXDI COM (ExdiGDbSrv.dll) melalui proses dllhost.exe (terkait COM). Untuk mengatasinya, mulai ulang PC debugger Host atau Keluar Windows dan Masuk lagi. Jika tidak berhasil, daftarkan ulang server EXDI COM setelah memulai ulang/masuk lagi.

    • regsvr32.exe <full path to the ExdiGdbSrv.dll)
  • Sesi sebelumnya dari ExdiGdbSrv.dll masih dihosting oleh proses dllhost.exe, jadi Anda harus mematikan proses dllhost.exe. Periksa tlist untuk pid dllhost.exe yang menghosting ExdiGdbSrv.dll dan membunuh pid terkait.

  • Gdbserver QEMU belum diluncurkan, atau file exdiconfigdata.xml berisi nilai IP:Port yang tidak valid. Jika sesi WinDbg diluncurkan di pc Host yang sama dengan VM Windows QEMU, maka IP=LocalHost.

Masalah: Sesi debugging tidak dapat dimulai: FAILURE HR=0x80004005:Failed to AttachKernel.

Masalah ini dapat disebabkan oleh:

  • Seperti yang dijelaskan di atas, ada kemungkinan bahwa sesi sebelumnya dari ExdiGdbSrv.dll masih aktif. Temukan dan hentikan host DLL terkait seperti yang dijelaskan di atas.

Kotak dialog WinDbg menampilkan kegagalan dengan 0x80004005 SDM.

File Konfigurasi XML EXDI

Ada dua file xml yang diperlukan yang digunakan oleh server EXDI GDB COM (ExdiGdbSrv.dll).

  1. exdiConfigData.xml - File ini berisi data konfigurasi utama yang diperlukan oleh klien server GDB untuk membuat sesi GDB yang berhasil dengan target server GDB debugger HW, sehingga klien server GDB tidak akan berjalan jika lokasi file tidak diatur oleh variabel lingkungan EXDI_GDBSRV_XML_CONFIG_FILE. Setiap tag xml memungkinkan konfigurasi set fungsionalitas server GDB tertentu. Lihat di bawah ini untuk daftar atribut yang dapat Anda ubah di XML, dan sampel XML.

  2. Systemregister.xml - File ini berisi pemetaan antara register sistem dan kode akses mereka. Ini diperlukan karena kode akses tidak disediakan oleh server GDB dalam file xml, dan debugger mengakses setiap pendaftaran sistem melalui kode akses. Jika file tidak diatur melalui variabel EXDI_SYSTEM_REGISTERS_MAP_XML_FILElingkungan , maka ExdiGdbSrv.dll akan terus berfungsi, tetapi debugger tidak akan dapat mengakses register sistem apa pun melalui perintah rdmsr atau wrmsr. Daftar register ini harus didukung oleh debugger perangkat keras server GDB (nama register sistem tertentu harus ada dalam daftar register yang dikirim dalam file xml sistem).

Tag dan atribut GDBServer

Tabel berikut menjelaskan tag dan atribut GDBServer yang ditentukan dalam exdiConfigData.xml file.

Parameter Deskripsi
ExdiTargets Menentukan konfigurasi target server GDB tertentu mana yang akan digunakan oleh ExdiGgbSrv.dll untuk membuat koneksi GDB dengan target server GDB, karena file exdiConfigData.xml mencakup semua server GDB yang saat ini didukung oleh ExdiGdbSrv.dll (file ini HARUS diisi sebelum menggunakan ExdiGdbSrv.dll dengan server GDB tertentu).
CurrentTarget Menentukan nama target server GDB (misalnya, nilai atribut ini harus cocok dengan nilai nama salah <ExdiTarget Name= satu tag yang disertakan oleh file exdiConfigData.xml.
ExdiTarget ini adalah tag mulai untuk semua data konfigurasi yang disertakan oleh setiap komponen target server GDB.
Nama Menentukan nama server GDB (misalnya QEMU, BMC-OpenOCD, Trace32, VMWare).
agentNamePacket Ini adalah nama klien GDB karena dikenali oleh debugger HW server GDB. Ini dapat digunakan oleh debugger HW server GDB untuk mengonfigurasi dirinya untuk klien GDB tertentu (misalnya server Trace32 GDB memerlukan ExdiGdbSrv.dll untuk mengirim nama "QMS.windbg" untuk mengidentifikasi klien windbg-GDB dan kemudian mengaktifkan paket memori GDB yang disesuaikan hanya didukung untuk klien server MS GDB (exdiGdbSrv.dll).
ExdiGdbServerConfigData Menentukan parameter konfigurasi terkait komponen ExdiGdbSrv.dll.
uuid menentukan UUI komponen ExdiGdbSrv.dll.
displayCommPackets Benderai jika 'ya', maka kita akan menampilkan karakter komunikasi protokol RSP di jendela log perintah. Jika 'tidak', maka kami hanya menampilkan teks pasangan permintaan-respons.
enableThrowExceptionOnMemoryErrors Atribut ini akan diperiksa oleh klien server GDB ketika ada paket respons kesalahan GDB (E0x) untuk menentukan apakah klien harus melempar pengecualian dan berhenti membaca memori.
qSupportedPacket Ini memungkinkan konfigurasi klien GDB untuk meminta file arsitektur xml register mana yang harus dikirim oleh debugger HW server GDB mengikuti file deskripsi target xml (pada dasarnya, klien akan menginformasikan server GDB arsitektur mana yang didukung oleh klien, saat ini, klien memang mendukung arsitektur x64).
ExdiGdbServerTargetData Menentukan parameter yang terkait dengan Target perangkat keras yang di-debug oleh sesi GdbServer.
targetArchitecture String yang berisi arsitektur perangkat keras target. Nilai yang mungkin: X86, X64, ARM, ARM64. Saat ini, exdiGdbSrv.dll hanya mendukung X86 dan ARM.
targetFamily String yang berisi keluarga perangkat keras target. Nilai yang mungkin: ProcessorFamilyX86, ProcessorFamilyX64, ProcessorFamilyARM, ProcessorFamilyARM64.
numberOfCores Jumlah inti prosesor yang didukung target. Parameter ini akan divalidasi ketika kita menggunakan sesi multi-Gdbserver (sesi T32-GdbServer). Atribut 'MultiCoreGdbServerSessions' di bawah ini harus diatur ke 'ya'.
EnableSseContext Benderai jika 'ya', maka paket RSP konteks 'g' akan menyertakan nilai floating point registers. Parameter ini masuk akal hanya untuk target keluarga Intel.
heuristicScanSize ini mengonfigurasi algoritma heuristik cepat mesin debugger untuk mengurangi pemeriksaan memori yang dipindai dengan ukuran yang ditentukan, jika nilai atribut tidak ditentukan (atau "0"), maka mesin debugger tidak akan menggunakan heuristik cepat dan kembali ke heuristik warisan yang memindai seluruh memori yang mencari tanda tangan PE DOS.
targetDescriptionFile menentukan apakah server GDB mengirim file header deskripsi target sebelum mengirim setiap file xml terpisah. Bidang ini kosong maka klien server GDB tidak akan meminta register sistem arsitektur xml (misalnya server Trace32 GDB yang tidak mendukung pengiriman register arsitektur dalam file xml terpisah).
GdbServer Koneksi ionParameters Menentukan parameter sesi GdbServer. Parameter ini digunakan untuk mengontrol sesi RSP GdbServer antara komponen ExdiGdbSrv.dll dan GdbServer.
MultiCoreGdbServerSessions Benderai Jika 'ya', maka kita akan memiliki sesi GdbServer multi-core (yang digunakan oleh T32-GdbServer Back-End). Jika 'tidak', maka kita hanya akan berkomunikasi dengan satu instans GdbServer.
MaximumGdbServerPacketLength Ini adalah panjang maksimum yang didukung GdbServer untuk satu paket.
Maksimum Koneksi Attempts Ini adalah upaya koneksi maksimum. Ini digunakan oleh ExdiGdbSrv.dll ketika mencoba membuat koneksi RSP ke GdbServer.
SendPacketTimeout Ini adalah batas waktu pengiriman RSP.
ReceivePacketTimeout Ini adalah batas waktu penerimaan RSP.
HostNameAndPort Ini adalah string koneksi dalam format <hostname/ip address:Port number>. Mungkin ada lebih dari satu string koneksi GdbServer (seperti sesi GdbServer multi-core T32). Jumlah string koneksi harus cocok dengan jumlah inti.
ExdiGdbServerMemoryCommands Menentukan berbagai cara untuk mengeluarkan perintah memori GDB, untuk mendapatkan sistem mendaftarkan nilai atau membaca/menulis memori akses pada tingkat CPU pengecualian yang berbeda (misalnya BMC-OpenOCD menyediakan akses ke register CP15 melalui "aarch64 mrs nsec/dtk <access code>" perintah disesuaikan).
GdbSpecialMemoryCommand jika "ya", maka server GDB mendukung perintah memori yang disesuaikan (misalnya register sistem, ini harus diatur untuk server Trace32 GDB).
PhysicalMemory jika "ya", maka server GDB mendukung perintah yang disesuaikan untuk membaca memori fisik (diatur untuk server Trace32 GDB).
SupervisorMemory jika "ya", maka server GDB mendukung perintah yang disesuaikan untuk membaca memori supervisor (diatur untuk server Trace32 GDB).
SpecialMemoryRegister jika "ya", maka server GDB mendukung perintah yang disesuaikan untuk membaca register sistem (diatur untuk server Trace32 GDB)
SystemRegistersGdbMonitor jika "ya", maka server GDB mendukung perintah yang disesuaikan melalui perintah monitor GDB (diatur untuk BMC Open-OCD).
SystemRegisterDecoding jika "ya", maka klien GDB menerima decoding kode akses sebelum mengirim perintah monitor GDB.
ExdiGdbServerRegisters Menentukan set inti register arsitektur tertentu.
Sistem Arsitektur CPU dari kumpulan register yang ditentukan.
FeatureNameSupported Ini adalah nama grup pendaftaran sistem karena disediakan oleh file deskripsi daftar sistem xml. Diperlukan untuk mengidentifikasi grup xml daftar sistem yang merupakan bagian dari file xml seperti yang dikirim oleh server GDB.
SystemRegistersStart Ini untuk mengidentifikasi register sistem pertama (nomor/pesanan register rendah) yang dilaporkan sebagai bagian dari set register inti (misalnya pada X64, QEMU tidak melaporkan sistem x64 register yang ditetapkan sebagai file deskripsi target xml yang dipisahkan, sehingga regs sistem adalah bagian dari register inti).
SystemRegistersEnd Ini untuk mengidentifikasi register sistem terakhir (nomor/pesanan register tinggi) yang dilaporkan sebagai bagian dari set register inti.
Nama Nama register.
Pesanan Ini adalah angka yang mengidentifikasi indeks dalam array register. Nomor ini akan digunakan oleh klien GDB dan paket register set/query server (p<number>”/”q<number>).
Ukuran Ini adalah ukuran register dalam byte.

Contoh file 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>

Contoh skrip EXDI PowerShell

Sampel skrip PowerShell ini menginstal EXDI lalu meluncurkan debugger. Skrip Start-ExdiDebugger.ps1 akan menginstal ExdiGdbSrv.dll jika diperlukan, mengonfigurasi file pengaturan xml, memeriksa proses dllhost.exe yang berjalan, dan meluncurkan debugger untuk menyambungkan ke target debugging perangkat keras server gdb yang sudah berjalan.

Ini adalah contoh memanggil skrip start up.

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

Anda juga dapat menentukan file bawaan jika perlu.

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

Start-ExdiDebugger.ps1 memiliki opsi pengaturan berikut.

Parameter Deskripsi
ExdiTarget Jenis target yang akan disambungkan. Ini sesuai dengan bagian tertentu dalam file xml pengaturan
HostName Alamat IP atau nama host komputer yang menghosting sesi server gdb (default ke "LocalHost")
GdbPort Port yang didengarkan server gdb.
Sistem Arsitektur target penelusuran kesalahan perangkat keras (parameter ini juga menyiratkan parameter ArchitectureFamily dalam file pengaturan xml)
ExdiDropPath Lokasi file ExdiGdbSrv.dll, exdiConfigData.xml, dan systemregisters.xml. Ini hanya akan disalin jika ExdiGdbSrv.dll tidak diinstal atau salah diinstal.
ExtraDebuggerArgs Argumen tambahan untuk meneruskan baris perintah debugger
PreNTAppDebugging Mengubah nilai heuristikScanSize dari 0xfffe (terbaik untuk NT) menjadi 0xffe (untuk Aplikasi pra-NT)
DontTryDllHostCleanup Memeriksa instans ExdiGdbSrv.dll yang sedang berjalan di dllhost.exe memerlukan elevasi. Menyediakan sakelar ini akan memungkinkan skrip berjalan tanpa elevasi (meskipun debugger mungkin tidak berfungsi dengan benar).

Untuk mengaktifkan paket yang akan ditampilkan, atur nilai displayCommPackets ke ya.

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

Lihat komentar kode untuk opsi pengaturan lainnya.

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

Lihat juga

Menyiapkan Debugging Mode Kernel QEMU menggunakan EXDI

.exdicmd (Perintah EXDI)

Menyiapkan penelusuran kesalahan Kernel Jaringan KDNET secara otomatis

Menyiapkan Penelusuran Kesalahan Kernel Jaringan KDNET Secara Manual

Menyiapkan Penelusuran Kesalahan Mode Kernel Secara Manual