Отладка драйверов Windows — пошаговая лаборатория (режим ядра echo)

В этой лаборатории представлен отладчик ядра WinDbg. WinDbg используется для отладки примера кода драйвера в режиме эхо.

Цели лаборатории

Эта лаборатория включает упражнения, включиющие средства отладки, обучающие общие команды отладки, иллюстрирующие использование точек останова и демонстрирующие использование расширений отладки.

В этой лаборатории для изучения следующих задач используется динамическое подключение отладки ядра:

  • Использование команд отладчика Windows
  • Используйте стандартные команды (стеки вызовов, переменные, потоки, IRQL)
  • Использование команд расширенной отладки драйверов (!commands)
  • Использование символов
  • Настройка точек останова в динамической отладке
  • Просмотр стеков вызовов
  • Отображение дерева устройств Plug and Play
  • Работа с потоком и контекстом процесса

Примечание При работе с отладчиком Windows есть два типа отладки, которые можно выполнить — отладку в пользовательском или режиме ядра.

Пользовательский режим — приложения и подсистемы выполняются на компьютере в пользовательском режиме. Процессы, которые выполняются в пользовательском режиме, делают это в пределах собственных виртуальных адресных пространств. Они ограничены получением прямого доступа ко многим частям системы, включая системное оборудование, память, которая не была выделена для их использования, и другие части системы, которые могут нарушить целостность системы. Поскольку процессы, выполняемые в пользовательском режиме, эффективно изолированы от системных и других процессов пользовательского режима, они не могут препятствовать этим ресурсам.

Режим ядра — режим ядра — это режим доступа к процессору, в котором работают операционная система и привилегированные программы. Код режима ядра имеет разрешение на доступ к любой части системы и не ограничивается кодом пользовательского режима. Он может получить доступ к любой части любого другого процесса, выполняемого в пользовательском режиме или в режиме ядра. Большая часть основных функций ОС и многих драйверов устройств оборудования выполняются в режиме ядра.

В этой лаборатории основное внимание уделяется отладке режима ядра, так как это метод, используемый для отладки многих драйверов устройств.

В этом упражнении рассматриваются команды отладки, которые часто используются как в пользовательском режиме, так и в режиме ядра. В этом упражнении также рассматриваются расширения отладки (иногда называемые "!команды"), которые используются для отладки в режиме ядра.

Настройка лаборатории

Чтобы завершить лабораторию, вам потребуется следующее оборудование.

  • Ноутбук или настольный компьютер (узел) под управлением Windows 10
  • Ноутбук или настольный компьютер (целевой) под управлением Windows 10
  • Сетевой концентратор или маршрутизатор и сетевые кабели для подключения двух компьютеров
  • Доступ к Интернету для скачивания файлов символов

Чтобы завершить лабораторию, вам потребуется следующее программное обеспечение.

  • Visual Studio
  • Пакет средств разработки программного обеспечения (SDK) для Windows 10
  • пакет драйверов Windows (WDK) для Windows 10
  • Пример эхо-драйвера для Windows 10

В лаборатории содержатся следующие одиннадцать разделов.

Раздел 1. Подключение сеанс WinDbg в режиме ядра

В разделе 1 вы настроите отладку сети на узле и целевой системе.

Компьютеры в этой лаборатории необходимо настроить для использования сетевого подключения Ethernet для отладки ядра.

В этой лаборатории используются два компьютера. Windows отладчик выполняется в хост-системе, а драйвер KMDF Echo работает в целевой системе.

Используйте сетевой концентратор или маршрутизатор и сетевые кабели для подключения двух компьютеров.

two pcs connected with a double arrow.

Чтобы работать с приложениями в режиме ядра и использовать WinDbg, рекомендуется использовать KDNET через транспорт Ethernet. Сведения об использовании транспортного протокола Ethernet см. в статье начало работы с WinDbg (режим ядра). Дополнительные сведения о настройке целевого компьютера см. в статье "Подготовка компьютера для развертывания драйвера вручную " и автоматической отладки сетевого ядра KDNET.

Настройка отладки в режиме ядра с помощью Ethernet

Чтобы включить отладку в режиме ядра в целевой системе, выполните следующие действия.

<— в хост-системе.

  1. Откройте командную строку в системе узла и введите ipconfig , чтобы определить его IP-адрес.
C:\>ipconfig
Windows IP Configuration
Ethernet adapter Ethernet:
   Connection-specific DNS Suffix  . :
   Link-local IPv6 Address . . . . . : fe80::c8b6:db13:d1e8:b13b%3
   Autoconfiguration IPv4 Address. . : 169.182.1.1
   Subnet Mask . . . . . . . . . . . : 255.255.0.0
   Default Gateway . . . . . . . . . :
  1. Запишите IP-адрес системы узла: ____

— в целевой системе;>

  1. Откройте командную строку в целевой системе и используйте команду проверки связи для подтверждения сетевого подключения между двумя системами. Используйте фактический IP-адрес размещенной системы, записанной вместо 169.182.1.1, показанной в примере выходных данных.
C:\> ping 169.182.1.1

Pinging 169.182.1.1 with 32 bytes of data:
Reply from 169.182.1.1: bytes=32 time=1ms TTL=255
Reply from 169.182.1.1: bytes=32 time<1ms TTL=255
Reply from 169.182.1.1: bytes=32 time<1ms TTL=255
Reply from 169.182.1.1: bytes=32 time<1ms TTL=255

Ping statistics for 169.182.1.1:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum = 1ms, Average = 0ms

Включите отладку в режиме ядра в целевой системе, выполнив следующие действия.

Важно!

Перед использованием BCDEdit для изменения сведений о загрузке может потребоваться временно приостановить Windows функции безопасности, такие как BitLocker и безопасная загрузка на тестовом компьютере. Повторно включите эти функции безопасности при завершении тестирования и соответствующим образом управляйте тестируемым компьютером при отключении функций безопасности.

  1. На целевом компьютере откройте окно командной строки от имени администратора. Введите эту команду, чтобы включить отладку.

    C:\> bcdedit /set {default} DEBUG YES
    
  2. Введите эту команду, чтобы включить тестовую подпись.

    C:\> bcdedit /set TESTSIGNING ON 
    
  3. Введите эту команду, чтобы задать IP-адрес хост-системы. Используйте IP-адрес хост-системы, записанной ранее, а не отображаемую.

    C:\> bcdedit /dbgsettings net hostip:192.168.1.1 port:50000 key:2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    

Предупреждение Чтобы повысить безопасность подключения и снизить риск запросов на случайное подключение отладчика клиента, рассмотрите возможность использования автоматического случайного ключа. Дополнительные сведения см. в разделе "Настройка автоматической отладки сетевого ядра KDNET".

  1. Введите эту команду, чтобы убедиться, что dbgsettings заданы правильно.

    C:\> bcdedit /dbgsettings
    key                     2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    debugtype               NET
    hostip                  169.168.1.1
    port                    50000
    dhcp                    Yes
    The operation completed successfully.
    

Примечание
Брандмауэры и отладчики

Если появится всплывающее сообщение от брандмауэра и вы хотите использовать отладчик, установите все три флажка.

windows security alert - windows firewall has blocked some features of this app .

<— в хост-системе.

  1. На хост-компьютере откройте окно командной строки от имени администратора. Мы будем использовать версию WinDbg.exe x64 из комплекта драйверов Windows (WDK), которая была установлена в рамках установки пакета Windows. По умолчанию он находится здесь.

    C:\> Cd C:\Program Files(x86)\Windows Kits\10\Debuggers\x64 
    

Примечание

В этих лабораториях предполагается, что обе компьютеры работают под управлением 64-разрядной версии Windows как на целевом компьютере, так и на узле. Если это не так, лучший подход заключается в том, чтобы запустить ту же "разрядность" инструментов на узле, где выполняется целевой объект. Например, если целевой объект выполняет 32-разрядную Windows, запустите 32-разрядную версию отладчика на узле. Дополнительные сведения см. в разделе "Выбор 32-разрядных или 64-разрядных средств отладки".

  1. Запустите WinDbg с отладкой удаленного пользователя с помощью следующей команды. Значение ключа и порта совпадает с заданным ранее значением BCDEdit в целевом объекте.

    WinDbg –k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    

->В целевой системе

Перезагрузите целевую систему.

<-В хост-системе

Через минуту или две выходные данные отладки должны отображаться в хост-системе.

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

Using NET for debugging
Opened WinSock 2.0
Waiting to reconnect...
Connected to target 169.182.1.1 on port 50005 on local IP 169.182.1.2
You can get the target MAC address by running .kdtargetmac command.
Connected to Windows 10 16299 x64 target at (Wed Feb 28 17:16:23.051 2018 (UTC - 8:00)), ptr64 TRUE
Kernel Debugger connection established.  (Initial Breakpoint requested)
Symbol search path is: srv*
Executable search path is: 
Windows 10 Kernel Version 16299 MP (4 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 16299.15.amd64fre.rs3_release.170928-1534
Machine Name:
Kernel base = 0xfffff800`9540d000 PsLoadedModuleList = 0xfffff800`95774110
Debug session time: Wed Feb 28 17:16:23.816 2018 (UTC - 8:00)
System Uptime: 0 days 0:00:20.534

Командное окно отладчика — это основное окно сведений об отладке в WinDbg. Вы можете ввести команды отладчика и просмотреть выходные данные команды в этом окне.

Командное окно отладчика разделено на две области. Вы вводите команды в меньшей области (область входа команд) в нижней части окна и просматриваете выходные данные команды в более крупной области в верхней части окна.

В области ввода команд используйте клавиши со стрелками вверх и вниз, чтобы прокрутить журнал команд. Когда появится команда, ее можно изменить или нажать клавишу ВВОД , чтобы выполнить команду.

Раздел 2. Команды и методы отладки в режиме ядра

В разделе 2 вы будете использовать команды отладки для отображения сведений о целевой системе.

<— в хост-системе.

Включение языка разметки отладчика (DML) с помощью .prefer_dml

Некоторые команды отладки отображают текст с помощью языка разметки отладчика, который можно выбрать для быстрого сбора дополнительных сведений.

  1. Используйте клавиши CTRL+Break (Scroll Lock) в WinDBg, чтобы разбить код, выполняемый в целевой системе. Для реагирования целевой системы может потребоваться некоторое время.

windows debugger showing command window output from a live kernel connection.

  1. Введите следующую команду, чтобы включить DML в окне командной строки отладчика.
0: kd> .prefer_dml 1
DML versions of commands on by default

Использование HH для получения справки

С помощью команды HH можно получить доступ к справочной команде.

  1. Введите следующую команду, чтобы просмотреть справку по ссылке на команду для .prefer_dml.
0: kd> .hh .prefer_dml

Файл справки отладчика отобразит справку для команды .prefer_dml .

debugger help application showing help for the .prefer-dml command.

Отображение версии Windows в целевой системе

  1. Отображение подробных сведений о версии целевой системы, введя команду vertarget (Показать версию целевого компьютера) в окне WinDbg.
0: kd> vertarget
Windows 10 Kernel Version 9926 MP (4 procs) Free x64
Product: WinNt, suite: TerminalServer SingleUserTS
Built by: 9926.0.amd64fre.fbl_awesome1501.150119-1648
Machine Name: ""
Kernel base = 0xfffff801`8d283000 PsLoadedModuleList = 0xfffff801`8d58aef0
Debug session time: Fri Feb 20 10:15:17.807 2015 (UTC - 8:00)
System Uptime: 0 days 01:31:58.931

Вывод списка загруженных модулей

  1. Чтобы убедиться, что вы работаете с правильным процессом режима ядра, отобразив загруженные модули, введя команду lm (список загруженных модулей) в окне WinDbg.
0: Kd> lm
start             end                 module name
fffff801`09200000 fffff801`0925f000   volmgrx    (no symbols)           
fffff801`09261000 fffff801`092de000   mcupdate_GenuineIntel   (no symbols)           
fffff801`092de000 fffff801`092ec000   werkernel   (export symbols)       werkernel.sys
fffff801`092ec000 fffff801`0934d000   CLFS       (export symbols)       CLFS.SYS
fffff801`0934d000 fffff801`0936f000   tm         (export symbols)       tm.sys
fffff801`0936f000 fffff801`09384000   PSHED      (export symbols)       PSHED.dll
fffff801`09384000 fffff801`0938e000   BOOTVID    (export symbols)       BOOTVID.dll
fffff801`0938e000 fffff801`093f7000   spaceport   (no symbols)           
fffff801`09400000 fffff801`094cf000   Wdf01000   (no symbols)           
fffff801`094d9000 fffff801`09561000   CI         (export symbols)       CI.dll
...

Примечание Выходные данные, которые были пропущены, обозначены словом "... " в этой лаборатории.

  1. Чтобы запросить подробные сведения о конкретном модуле, используйте параметр v (verbose), как показано ниже.
0: Kd> lm v m tcpip
Browse full module list
start             end                 module name
fffff801`09eeb000 fffff801`0a157000   tcpip      (no symbols)           
    Loaded symbol image file: tcpip.sys
    Image path: \SystemRoot\System32\drivers\tcpip.sys
    Image name: tcpip.sys
    Browse all global symbols  functions  data
    Timestamp:        Sun Nov 09 18:59:03 2014 (546029F7)
    CheckSum:         00263DB1
    ImageSize:        0026C000
    Translations:     0000.04b0 0000.04e4 0409.04b0 0409.04e4

Unable to enumerate user-mode unloaded modules, Win32 error 0n30
  1. Так как мы еще не задали путь к символам и загруженным символам, в отладчике доступны ограниченные сведения.

Раздел 3. Скачивание и сборка драйвера эхо KMDF

В разделе 3 вы скачайте и создадите драйвер echo KMDF.

Как правило, при использовании WinDbg вы будете работать с собственным кодом драйвера. Чтобы ознакомиться с операцией WinDbg, используется пример драйвера шаблона KMDF Echo. При наличии исходного кода также будет проще понять сведения, отображаемые в WinDbg. Кроме того, этот пример используется для демонстрации того, как можно выполнить один шаг с помощью кода в собственном режиме ядра. Этот метод может быть очень ценным для отладки сложных проблем с кодом в режиме ядра.

Чтобы скачать и создать пример звукового драйвера Echo, выполните следующие действия.

  1. Скачивание и извлечение примера echo KMDF из GitHub

    Вы можете использовать браузер для просмотра примера эхо в GitHub здесь:

    https://github.com/Microsoft/Windows-driver-samples/tree/master/general/echo/kmdf

    Пример можно прочитать здесь:

    https://github.com/microsoft/Windows-driver-samples/blob/master/general/echo/kmdf/README.md

    Вы можете просмотреть все примеры драйверов Windows здесь:

    https://github.com/Microsoft/Windows-driver-samples

    Пример kmDF Echo находится в общей папке.

    github windows-driver-samples highlighting the general folder and the download zip button.

    а. В этой лаборатории показано, как скачать примеры драйверов в один ZIP-файл.

    https://github.com/Microsoft/Windows-driver-samples/archive/master.zip

    b. Скачайте файл master.zip на локальный жесткий диск.

    c. Выберите и удерживайте (или щелкните правой кнопкой мыши) Windows-driver-samples-master.zipи выберите команду "Извлечь все". Укажите новую папку или перейдите к существующей, в которую будут храниться извлеченные файлы. Например, можно указать C:\DriverSamples\ в качестве новой папки, в которую извлекаются файлы.

    d. После извлечения файлов перейдите к следующей вложенной папке.

    C:\DriverSamples\general\echo\kmdf

  2. Откройте решение драйвера в Visual Studio

    В Microsoft Visual Studio выберите FileOpen>>Project/Solution... и перейдите к папке, содержащей извлеченные файлы (например, C:\DriverSamples\general\echo\kmdf). Дважды щелкните файл решения kmdfecho , чтобы открыть его.

    В Visual Studio найдите Обозреватель решений. (Если это еще не открыто, выберите Обозреватель решений в меню "Вид".) В Обозреватель решений можно увидеть одно решение с тремя проектами.

    visual studio with the device.c file loaded from the kmdfecho project.

  3. Настройка конфигурации и платформы примера

    В Обозреватель решений выберите и удерживайте (или щелкните правой кнопкой мыши) решение kmdfecho (3 проекта) и выберите Configuration Manager. Убедитесь, что параметры конфигурации и платформы одинаковы для трех проектов. По умолчанию для конфигурации задано значение "Отладка Win10", а платформа имеет значение "Win64" для всех проектов. При внесении изменений конфигурации и (или) платформы для одного проекта необходимо внести те же изменения для оставшихся трех проектов.

  4. Настройка библиотеки среды выполнения

    Задайте библиотеку среды выполнения. Откройте страницу свойств драйвера echo и найдите создание кодаC/C++>. Измените библиотеку среды выполнения с версии DLL на версию, не относячную к библиотеке DLL. Без этого параметра необходимо установить среду выполнения MSVC на целевой компьютер отдельно.

    echo property page highlighting the runtime library setting.

  5. Проверка подписи драйвера

    Кроме того, в свойствах драйвера убедитесь, что для режимаподписывания> драйвера задано значение "Test Sign". Это необходимо, так как Windows требует подписи драйверов.

    echo property page highlighting the sign mode setting.

  6. Создание примера с помощью Visual Studio

    В Visual Studio выберите "BuildBuild>Solution".

    Если все работает хорошо, окна сборки должны отобразить сообщение о том, что сборка для всех трех проектов выполнена успешно.

  7. Поиск встроенных файлов драйверов

    В проводник перейдите в папку, содержащую извлеченные файлы для примера. Например, вы перейдете в папку C:\DriverSamples\general\echo\kmdf, если это указанная ранее папка. В этой папке расположение скомпилированных файлов драйверов зависит от параметров конфигурации и платформы, выбранных в Configuration Manager. Например, если вы оставили параметры по умолчанию без изменений, то скомпилированные файлы драйверов будут сохранены в папке с именем \x64\Debug для 64-разрядной сборки отладки.

    Перейдите к папке, содержащей созданные файлы для драйвера автосинхронной синхронизации:

    C:\DriverSamples\general\echo\kmdf\driver\AutoSync\x64\Debug.

    Папка должна содержать следующие файлы:

    Файл Описание
    Echo.sys Файл драйвера.
    Echo.inf Файл сведений (INF), содержащий сведения, необходимые для установки драйвера.

    Кроме того, был создан файл echoapp.exe и он должен находиться здесь: C:\DriverSamples\general\echo\kmdf\exe\x64\Debug

    Файл Описание
    EchoApp.exe Исполняемый файл теста командной строки, взаимодействующий с драйвером echo.sys.
  8. Найдите usb-накопитель или настройте сетевую папку для копирования встроенных файлов драйверов и тестового EchoApp с узла в целевую систему.

В следующем разделе вы скопируйте код в целевую систему, а затем установите и протестируете драйвер.

Раздел 4. Установка примера драйвера echo KMDF в целевой системе

В разделе 4 вы будете использовать devcon для установки примера драйвера echo.

Компьютер, на котором устанавливается драйвер, называется целевым компьютером или тест-компьютером. Как правило, это отдельный компьютер от компьютера, на котором вы разрабатываете и создаете пакет драйверов. Компьютер, на котором вы разрабатываете и создаете драйвер, называется главным компьютером.

Процесс перемещения пакета драйверов на целевой компьютер и установка драйвера называется развертыванием драйвера.

Перед развертыванием тестового подписанного драйвера необходимо подготовить целевой компьютер, включив подписывание тестов. Кроме того, необходимо найти средство DevCon в установке WDK и скопировать его в целевую систему.

Чтобы установить драйвер в целевой системе, выполните следующие действия.

— в целевой системе;>

Включение тестовых драйверов, подписанных

Включите возможность запуска тестовых подписанных драйверов:

а. Откройте Windows Параметры.

b. В разделе "Обновление и безопасность" выберите "Восстановление".

c. В разделе "Расширенный запуск" выберите "Перезапустить сейчас".

d. Когда компьютер перезагружается, выберите параметры запуска. В Windows 10 выберите "TroubleshootAdvanced>optionsStartup> Параметры", а затем нажмите кнопку "Перезапустить".

д) Выберите "Отключить принудительное применение подписи драйвера", нажав клавишу F7 .

е) Перезагрузите целевой компьютер.

<— На хост-системе;

Перейдите в папку Tools в установке WDK и найдите средство DevCon. Например, просмотрите следующую папку:

C:\Program Files (x86)\Windows Kits\10\Tools\x64\devcon.exe

Создайте папку в целевом объекте для встроенного пакета драйверов (например, C:\EchoDriver). Скопируйте devcon.exe в целевую систему. Найдите CER-сертификат в системе узла, он находится в той же папке на хост-компьютере в папке, содержащей встроенные файлы драйверов. Скопируйте все файлы из встроенного драйвера, описанного ранее на хост-компьютере, и сохраните их в той же папке, что и на целевом компьютере.

— в целевой системе;>

На целевом компьютере выберите и удерживайте (или щелкните правой кнопкой мыши) файл сертификата и выберите " Установить", а затем следуйте инструкциям по установке тестового сертификата.

Если вам нужны более подробные инструкции по настройке целевого компьютера, см. статью "Подготовка компьютера для развертывания драйверов вручную".

— в целевой системе;>

Установка драйвера

В следующих инструкциях показано, как установить и проверить пример драйвера. Ниже приведен общий синтаксис средства разработки, который будет использоваться для установки драйвера:

Devcon install <INF filehardware>< ID>

Inf-файл, необходимый для установки этого драйвера, — echo.inf. Inf-файл содержит идентификатор оборудования для установки echo.sys. Для примера echo идентификатор оборудования — root\ECHO.

На целевом компьютере откройте окно командной строки от имени администратора. Перейдите в папку пакета драйверов и введите следующую команду:

devcon install echo.inf root\ECHO Если появляется сообщение об ошибке о том, что devcon не распознается, попробуйте добавить путь к средству devcon . Например, если вы скопировали его в папку C:\Tools, попробуйте использовать следующую команду:

c:\tools\devcon install echo.inf root\ECHO Появится диалоговое окно, указывающее, что драйвер тестирования является драйвером без знака. Чтобы продолжить , выберите "Установить этот драйвер ".

windows security warning - windows can't verify the publisher of this driver software.

Совет

 Если у вас возникли проблемы с установкой, дополнительные сведения см. в следующем файле. %windir%\inf\setupapi.dev.log

После успешной установки примера драйвера вы можете протестировать его.

Изучение драйвера в диспетчер устройств

На целевом компьютере в окне командной строки введите devmgmt, откройте диспетчер устройств. В диспетчер устройств в меню "Вид" выберите "Устройства по типу". В дереве устройства найдите пример драйвера echo WDF в узле "Образец устройства".

device manager tree with the sample wdf echo driver highlighted.

Тестирование драйвера

Введите echoapp , чтобы запустить тестовое приложение echo, чтобы убедиться, что драйвер работает.

C:\Samples\KMDF_Echo_Sample> echoapp
DevicePath: \\?\root#sample#0005#{cdc35b6e-0be4-4936-bf5f-5537380a7c1a}
Opened device successfully
512 Pattern Bytes Written successfully
512 Pattern Bytes Read successfully
Pattern Verified successfully
30720 Pattern Bytes Written successfully
30720 Pattern Bytes Read successfully
Pattern Verified successfully

Раздел 5. Использование WinDbg для отображения сведений о драйвере

В разделе 5 вы настроите путь к символам и используйте команды отладчика ядра для отображения сведений о примере драйвера echo KMDF.

Просмотрите сведения о драйвере, выполнив следующие действия.

<-В хост-системе

  1. Если вы закрыли отладчик, снова откройте его с помощью следующей команды в окне командной строки администратора.

    WinDbg -k net:port=50000,key=2steg4fzbj2sz.23418vzkd4ko3.1g34ou07z4pev.1sp3yo9yz874p
    
  2. Нажмите клавиши CTRL+Break (Scroll Lock), чтобы разбить код, выполняемый в целевой системе.

Задание пути к символам

  1. Чтобы задать путь к символам на сервер символов Майкрософт в среде WinDbg, используйте команду Symfix .

    0: kd> .symfix
    
  2. Чтобы добавить локальное расположение символов для использования локальных символов, добавьте путь с помощью .sympath+ и .reload /f.

    0: kd> .sympath+ C:\DriverSamples\general\echo\kmdf
    0: kd> .reload /f
    

    Примечание Команда RELOAD с параметром /f force удаляет все сведения о символах для указанного модуля и перезагружает символы. В некоторых случаях эта команда также перезагружает или выгружает сам модуль.

Примечание Для использования расширенных функциональных возможностей, которые предоставляет WinDbg, необходимо загрузить соответствующие символы. Если символы не настроены должным образом, вы получите сообщения о том, что символы недоступны при попытке использовать функции, зависящие от символов.

0:000> dv
Unable to enumerate locals, HRESULT 0x80004005
Private symbols (symbols.pri) are required for locals.
Type “.hh dbgerr005” for details.

Примечание
Серверы символов

Существует ряд подходов, которые можно использовать для работы с символами. Во многих ситуациях компьютер можно настроить для доступа к символам с сервера символов, который корпорация Майкрософт предоставляет при необходимости. В этом пошаговом руководстве предполагается, что этот подход будет использоваться. Если символы в вашей среде находятся в другом расположении, измените шаги, чтобы использовать это расположение. Дополнительные сведения см. в разделе "Путь к символам" для отладчика Windows.

Примечание
Общие сведения о требованиях к символам исходного кода

Чтобы выполнить отладку исходного кода, необходимо создать проверенную (отладочную) версию двоичных файлов. Компилятор создаст файлы символов (PDB-файлы). Эти файлы символов показывают отладчику, как двоичные инструкции соответствуют исходным строкам. Фактические исходные файлы также должны быть доступны отладчику.

Файлы символов не содержат текст исходного кода. Для отладки лучше всего, если компоновщик не оптимизирует код. Отладка исходного кода и доступ к локальным переменным сложнее, а иногда и практически невозможно, если код был оптимизирован. Если у вас возникли проблемы с просмотром локальных переменных или исходных строк, задайте следующие параметры сборки:

set COMPILE_DEBUG=1
set ENABLE_OPTIMIZER=0
  1. Введите следующую команду в области команд отладчика, чтобы отобразить сведения о драйвере echo:

    0: kd> lm m echo* v
    Browse full module list
    start             end                 module name
    fffff801`4ae80000 fffff801`4ae89000   ECHO       (private pdb symbols)  C:\Samples\KMDF_ECHO_SAMPLE\echo.pdb
        Loaded symbol image file: ECHO.sys
        Image path: \SystemRoot\system32\DRIVERS\ECHO.sys
        Image name: ECHO.sys
    ...  
    

    Дополнительные сведения см. в разделе lm.

  2. Так как мы задали prefer_dml =1 ранее, некоторые элементы выходных данных являются горячими ссылками, которые можно выбрать. Щелкните ссылку "Обзор всех глобальных символов" в выходных данных отладки , чтобы отобразить сведения о символах элементов, начинающихся с буквы "a".

    0: kd> x /D Echo!a*
    
  3. Как оказалось, образец echo не содержит символов, которые начинаются с буквы "a", поэтому введите x ECHO!Echo* для отображения сведений обо всех символах, связанных с драйвером эхо, которые начинаются с Echo.

    0: kd> x ECHO!Echo*
    fffff801`0bf95690 ECHO!EchoEvtIoQueueContextDestroy (void *)
    fffff801`0bf95000 ECHO!EchoEvtDeviceSelfManagedIoStart (struct WDFDEVICE__ *)
    fffff801`0bf95ac0 ECHO!EchoEvtTimerFunc (struct WDFTIMER__ *)
    fffff801`0bf9b120 ECHO!EchoEvtDeviceSelfManagedIoSuspend (struct WDFDEVICE__ *)
    ...
    

    Дополнительные сведения см. в разделе x (изучение символов).

  4. Расширение !lmi отображает подробные сведения о модуле. Введите !lmi echo. Выходные данные должны выглядеть примерно так, как показано ниже.

    0: kd> !lmi echo
    Loaded Module Info: [echo] 
             Module: ECHO
       Base Address: fffff8010bf94000
         Image Name: ECHO.sys
    … 
    
  5. Используйте расширение !dh для отображения сведений о заголовке, как показано ниже.

    0: kd> !dh echo
    
    File Type: EXECUTABLE IMAGE
    FILE HEADER VALUES
         14C machine (i386)
           6 number of sections
    54AD8A42 time date stamp Wed Jan 07 11:34:26 2015
    ...
    
  6. Настройка маски отладки

    Введите следующую команду, чтобы изменить маску бита отладки по умолчанию, чтобы все сообщения отладки из целевой системы отображались в отладчике.

    0: kd> ed nt!Kd_DEFAULT_MASK  0xFFFFFFFF
    

    Некоторые драйверы будут отображать дополнительные сведения при использовании маски 0xFFFFFFFF. Присвойте маске значение 0x00000000, если вы хотите уменьшить объем отображаемых сведений.

    0: kd> ed nt!Kd_DEFAULT_MASK  0x00000000
    

    Используйте команду dd, чтобы подтвердить, что маска настроена для отображения всех сообщений отладчика.

    0: kd> dd nt!kd_DEFAULT_MASK 
    fffff802`bb4057c0  ffffffff 00000000 00000000 00000000
    fffff802`bb4057d0  00000000 00000000 00000000 00000000
    fffff802`bb4057e0  00000001 00000000 00000000 00000000
    fffff802`bb4057f0  00000000 00000000 00000000 00000000
    fffff802`bb405800  00000000 00000000 00000000 00000000
    fffff802`bb405810  00000000 00000000 00000000 00000000
    fffff802`bb405820  00000000 00000000 00000000 00000000
    fffff802`bb405830  00000000 00000000 00000000 00000000
    

Раздел 6. Отображение сведений о дереве устройств Plug and Play

В разделе 6 вы увидите сведения о примере драйвера устройства echo и расположении в дереве устройств Plug and Play.

Сведения о драйвере устройства в дереве устройств Plug and Play могут быть полезны для устранения неполадок. Например, если драйвер устройства не находится в дереве устройства, может возникнуть проблема с установкой драйвера устройства.

Дополнительные сведения о расширении отладки узла устройства см. в разделе !devnode.

<-В хост-системе

  1. Чтобы просмотреть все узлы устройств в дереве устройств Plug and Play, введите команду !devnode 0 1.

    0: kd> !devnode 0 1
    Dumping IopRootDeviceNode (= 0xffffe0005a3a8d30)
    DevNode 0xffffe0005a3a8d30 for PDO 0xffffe0005a3a9e50
      InstancePath is "HTREE\ROOT\0"
      State = DeviceNodeStarted (0x308)
      Previous State = DeviceNodeEnumerateCompletion (0x30d)
      DevNode 0xffffe0005a3a3d30 for PDO 0xffffe0005a3a4e50
        InstancePath is "ROOT\volmgr\0000"
        ServiceName is "volmgr"
        State = DeviceNodeStarted (0x308)
        Previous State = DeviceNodeEnumerateCompletion (0x30d)
        DevNode 0xffffe0005a324560 for PDO 0xffffe0005bd95ca0…
    …
    
  2. Нажмите клавиши CTRL+F для поиска в выходных данных, созданных для поиска имени драйвера устройства, echo.

    find dialog box showing the term echo being searched for.

  3. Необходимо загрузить драйвер эхо-устройства. Используйте команду echo !devnode 0 1, чтобы отобразить Plug and Play сведения, связанные с драйвером устройства echo, как показано ниже.

    0: Kd> !devnode 0 1 echo
    Dumping IopRootDeviceNode (= 0xffffe0007b725d30)
    DevNode 0xffffe0007b71a630 for PDO 0xffffe0007b71a960
      InstancePath is "ROOT\SAMPLE\0000"
      ServiceName is "ECHO"
      State = DeviceNodeStarted (0x308)
      Previous State = DeviceNodeEnumerateCompletion (0x30d)
    …
    
  4. Выходные данные, отображаемые в предыдущей команде, включают PDO, связанные с запущенным экземпляром нашего драйвера, в этом примере это 0xffffe0007b71a960. Введите команду адреса> !devobjPDO<, чтобы отобразить Plug and Play сведения, связанные с драйвером эхо устройства. Используйте адрес PDO, отображаемый на компьютере !devnode , а не тот, который показан здесь.

    0: kd> !devobj 0xffffe0007b71a960
    Device object (ffffe0007b71a960) is for:
     0000000e \Driver\PnpManager DriverObject ffffe0007b727e60
    Current Irp 00000000 RefCount 0 Type 00000004 Flags 00001040
    Dacl ffffc102c9b36031 DevExt 00000000 DevObjExt ffffe0007b71aab0 DevNode ffffe0007b71a630 
    ExtensionFlags (0x00000800)  DOE_DEFAULT_SD_PRESENT
    Characteristics (0x00000180)  FILE_AUTOGENERATED_DEVICE_NAME, FILE_DEVICE_SECURE_OPEN
    AttachedDevice (Upper) ffffe000801fee20 \Driver\ECHO
    Device queue is not busy.
    
  5. Выходные данные, отображаемые в команде !devnode 0 1 , включают адрес PDO, связанный с запущенным экземпляром нашего драйвера, в этом примере это 0xffffe0007b71a960. Введите команду адреса> !devstackPDO<, чтобы отобразить Plug and Play сведения, связанные с драйвером устройства. Используйте адрес PDO, отображаемый на компьютере !devnode , а не тот, который показан ниже.

    0: kd> !devstack 0xffffe0007b71a960
      !DevObj           !DrvObj            !DevExt           ObjectName
      ffffe000801fee20  \Driver\ECHO       ffffe0007f72eff0  
    > ffffe0007b71a960  \Driver\PnpManager 00000000  0000000e
    !DevNode ffffe0007b71a630 :
      DeviceInst is "ROOT\SAMPLE\0000"
      ServiceName is "ECHO"
    

Выходные данные показывают, что у нас есть довольно простой стек драйверов устройств. Драйвер echo является дочерним элементом узла PnPManager. PnPManager является корневым узлом.

\Driver\ECHO

\Driver\PnpManager

На этой схеме показано более сложное дерево узлов устройства.

device node tree with about 20 nodes.

Примечание Дополнительные сведения о более сложных стеках драйверов см. в стеках драйверов и узлах устройств и стеках устройств.

Раздел 7. Работа с точками останова и исходным кодом

В разделе 7 вы настроите точки останова и одношаговый исходный код режима ядра.

Примечание
Установка точек останова с помощью команд

Чтобы выполнить пошаговое выполнение кода и проверить значения переменных в режиме реального времени, необходимо включить точки останова и задать путь к исходному коду.

Точки останова используются для остановки выполнения кода в определенной строке кода. Затем вы можете выполнить шаг вперед в коде с этой точки, чтобы отладить этот конкретный раздел кода.

Чтобы задать точку останова с помощью команды отладки, используйте одну из следующих команд b .

bp

Задает точку останова, которая будет активной до тех пор, пока модуль не будет выгружен.

Bu

Задает точку останова, которая не разрешена при выгрузке модуля и повторно включается при перезагрузке модуля.

Bm

Задает точку останова для символа. Эта команда будет использовать bu или bp соответствующим образом и позволяет использовать подстановочные знаки * для задания точек останова для всех символов, соответствующих (как и все методы в классе).

Дополнительные сведения см. в справочной документации по отладке исходного кода в WinDbg .

<-В хост-системе

  1. Используйте пользовательский интерфейс WinDbg, чтобы убедиться, что режим DebugSource> включен в текущем сеансе WinDbg.

  2. Добавьте локальное расположение кода в исходный путь, введя следующую команду.

    .srcpath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
    
  3. Добавьте расположение локального символа в путь к символу, введя следующую команду.

    .sympath+ C:\DriverSamples\KMDF_Echo_Sample\driver\AutoSync
    
  4. Мы будем использовать команду x для проверки символов, связанных с драйвером echo, чтобы определить имя функции, используемой для точки останова. Для поиска имени функции DeviceAdd можно использовать подстановочный знак или ctrl+F.

    0: kd> x ECHO!EchoEvt*
    8b4c7490          ECHO!EchoEvtIoQueueContextDestroy (void *)
    8b4c7000          ECHO!EchoEvtDeviceSelfManagedIoStart (struct WDFDEVICE__ *)
    8b4c7820          ECHO!EchoEvtTimerFunc (struct WDFTIMER__ *)
    8b4cb0e0          ECHO!EchoEvtDeviceSelfManagedIoSuspend (struct WDFDEVICE__ *)
    8b4c75d0          ECHO!EchoEvtIoWrite (struct WDFQUEUE__ *, struct WDFREQUEST__ *, unsigned int)
    8b4cb170          ECHO!EchoEvtDeviceAdd (struct WDFDRIVER__ *, struct 
    …
    

    В выходных данных выше показано, что метод DeviceAdd для нашего эхо-драйвера — ECHO! EchoEvtDeviceAdd.

    Кроме того, можно просмотреть исходный код, чтобы найти нужное имя функции для нашей точки останова.

  5. Задайте точку останова с помощью команды bm с помощью имени драйвера, за которым следует имя функции (например , AddDevice), где нужно задать точку останова, разделенную восклицательным знаком. Мы будем использовать AddDevice для наблюдения за загрузкой драйвера.

    0: kd> bm ECHO!EchoEvtDeviceAdd
      1: fffff801`0bf9b1c0 @!"ECHO!EchoEvtDeviceAdd"
    

    Примечание
    В сочетании с параметрами переменных, таких как <модуль>, можно использовать другой синтаксис.< symbol>, <class>::<method>,'<file.cpp>:<line number>', or skip a number of times <condition><#>. Дополнительные сведения см. в статьях об условных точках останова в WinDbg и других Windows отладчиках.

  6. Выведите список текущих точек останова, чтобы убедиться, что точка останова была задана, введя команду BL .

    0: kd> bl
    1 e fffff801`0bf9b1c0     0001 (0001) ECHO!EchoEvtDeviceAdd
    

    "e" в выходных данных, показанных выше, указывает, что точка останова 1 включена для срабатывания.

  7. Перезапустите выполнение кода в целевой системе, введя команду Gog.

  8. — в целевой системе;>

    В Windows откройте диспетчер устройств с помощью значка или введите mmc devmgmt.msc. В диспетчер устройств разверните узел Samples.

  9. Выберите и удерживайте (или щелкните правой кнопкой мыши) запись драйвера ECHO KMDF и выберите команду "Отключить " в меню.

  10. Снова выберите и удерживайте (или щелкните правой кнопкой мыши) запись драйвера ECHO KMDF и выберите "Включить " в меню.

  11. <— На хост-системе;

    Если драйвер включен, точка останова отладки AddDevice должна запускаться, а выполнение кода драйвера в целевой системе должно быть остановлено. При достижении точки останова выполнение должно быть остановлено в начале процедуры AddDevice . В выходных данных команды отладки отобразится сообщение "Достигнута точка останова 1".

    windbg showing sample code locals and command windows.

  12. Пошаговую строку кода, введя команду p или нажав клавишу F10, пока не достигнете следующего конца подпрограммы AddDevice . Символ фигурной скобки "}" будет выделен, как показано ниже.

    code window showing brace character highlighted at start of adddevice routine.

  13. В следующем разделе мы рассмотрим состояние переменных после выполнения кода DeviceAdd.

Примечание
Изменение состояния точки останова

Существующие точки останова можно изменить с помощью следующих команд:

bl

Выводит список точек останова.

Bc

Очищает точку останова из списка. Используйте bc * для очистки всех точек останова.

Bd

Отключает точку останова. Используйте bd * для отключения всех точек останова.

Быть

Включает точку останова. Используйте значение *, чтобы включить все точки останова.

Кроме того, можно также изменить точки останова, выбрав пункт "Изменить>точки останова" в WinDbg. Обратите внимание, что диалоговое окно точки останова работает только с существующими точками останова. Новые точки останова должны быть заданы из командной строки.

Примечание
Настройка точек останова доступа к памяти

Также можно задать точки останова, которые запускаются при доступе к расположению памяти. Используйте команду ba (break on access) со следующим синтаксисом.

ba <access> <size> <address> {options}
Параметр Описание

й

выполнение (при получении инструкции из адреса ЦП)

r

чтение и запись (когда ЦП считывает или записывает данные в адрес)

w

запись (когда ЦП записывает данные в адрес)

Обратите внимание, что вы можете задать только четыре точки останова данных в любой момент времени, и вам нужно убедиться, что вы правильно выравниваете данные или не активируете точку останова (слова должны заканчиваться адресами, делимыми на 2, dwords должны быть делимыми на 4, а квадровые слова на 0 или 8).

Например, чтобы задать точку останова чтения и записи для определенного адреса памяти, можно использовать следующую команду.

ba r 4 0x0003f7bf0

Примечание
Пошаговое выполнение кода из командного окна отладчика

Ниже приведены команды, которые можно использовать для пошагового выполнения кода (с соответствующими короткими срезами клавиатуры, показанными в скобках).

  • Break in (CTRL+Break) — эта команда прерывает работу системы до тех пор, пока система запущена и находится в обмене данными с WinDbg (последовательность в отладчике ядра — CTRL+C).

  • Выполнение до курсора (F7 или CTRL+F10) — поместите курсор в исходное или дизассемблированное окно, где нужно разорвать выполнение, а затем нажмите клавишу F7; Выполнение кода будет выполняться до этой точки. Обратите внимание, что если поток выполнения кода не достигает точки, указанной курсором (инструкция IF не выполняется), WinDbg не будет прерываться, так как выполнение кода не достигло указанной точки.

  • Запуск (F5) — выполнение до тех пор, пока не будет обнаружена точка останова или событие, подобное проверке ошибок.

  • Шаг с обходом (F10) — эта команда приводит к тому, что выполнение кода выполняется по одной инструкции или по одной инструкции за раз. При обнаружении вызова выполнение кода передает вызов без ввода вызываемой подпрограммы. (Если язык программирования — C или C++ и WinDbg находится в исходном режиме, исходный режим можно включить или отключить с помощью отладки>. Исходный режим).

  • Шаг в (F11) — эта команда похожа на шаг с обходом, за исключением того, что выполнение вызова переходит в вызываемую подпрограмму.

  • Шаг с выходом (SHIFT+F11) — эта команда приводит к запуску и выходу из текущей подпрограммы (текущее место в стеке вызовов). Это полезно, если вы видели достаточно рутины.

Дополнительные сведения см. в справочной документации по отладке исходного кода в WinDbg .

Раздел 8. Просмотр переменных и стеков вызовов

В разделе 8 вы увидите сведения о переменных и стеках вызовов.

В этой лаборатории предполагается, что вы остановились в процедуре AddDevice с помощью описанного выше процесса. Чтобы просмотреть выходные данные, повторите описанные ранее действия, если это необходимо.

<— На хост-системе;

Отображение переменных

Используйте пункт меню viewlocal> для отображения локальных переменных.

windbg local variables window.

Глобальные переменные

Расположение адреса глобальной переменной можно найти, введя ? < имя> переменной.

Локальные переменные

Имена и значения всех локальных переменных для заданного кадра можно отобразить, введя команду DV .

0: kd> dv
         Driver = 0x00001fff`7ff9c838
     DeviceInit = 0xffffd001`51978190
         status = 0n0

Вызовы

Примечание
Стек вызовов — это цепочка вызовов функций, которые привели к текущему расположению счетчика программы. Верхняя функция в стеке вызовов является текущей функцией, а следующая — это функция, которая вызывает текущую функцию и т. д.

Чтобы отобразить стек вызовов, используйте команды k*.

kb

Отображает стек и первые три параметра.

Кп

Отображает стеки и полный список параметров.

kn

Позволяет просматривать стек со сведениями о фрейме рядом с ним.

<-В хост-системе

  1. Если вы хотите сохранить стек вызовов доступным, можно выбрать стекпредставления>, чтобы просмотреть его. Выберите столбцы в верхней части окна, чтобы переключить отображение дополнительных сведений.

windbg display call stacks window.

  1. Используйте команду kn , чтобы отобразить стек вызовов при отладке кода адаптера образца в состоянии прерывания.
3: kd> kn
# Child-SP          RetAddr           Call Site
00 ffffd001`51978110 fffff801`0942f55b ECHO!EchoEvtDeviceAdd+0x66 [c:\Samples\kmdf echo sample\c++\driver\autosync\driver.c @ 138]
01 (Inline Function) --------`-------- Wdf01000!FxDriverDeviceAdd::Invoke+0x30 [d:\wbrtm\minkernel\wdf\framework\shared\inc\private\common\fxdrivercallbacks.hpp @ 61]
02 ffffd001`51978150 fffff801`eed8097d Wdf01000!FxDriver::AddDevice+0xab [d:\wbrtm\minkernel\wdf\framework\shared\core\km\fxdriverkm.cpp @ 72]
03 ffffd001`51978570 fffff801`ef129423 nt!PpvUtilCallAddDevice+0x35 [d:\9142\minkernel\ntos\io\pnpmgr\verifier.c @ 104]
04 ffffd001`519785b0 fffff801`ef0c4112 nt!PnpCallAddDevice+0x63 [d:\9142\minkernel\ntos\io\pnpmgr\enum.c @ 7397]
05 ffffd001`51978630 fffff801`ef0c344f nt!PipCallDriverAddDevice+0x6e2 [d:\9142\minkernel\ntos\io\pnpmgr\enum.c @ 3390]
...

Стек вызовов показывает, что ядро (nt) вызывается в код Plug and Play (PnP), который называется кодом платформы драйверов (WDF), который впоследствии вызывал функцию DeviceAdd драйвера эхо.

Раздел 9. Отображение процессов и потоков

Процессов

В разделе 9 вы увидите сведения о процессе и потоках, выполняемых в режиме ядра.

Примечание
Вы можете отображать или задавать сведения о процессе с помощью расширения отладчика !process . Мы зададим точку останова для изучения процесса, используемого при воспроизведении звука.

  1. <— На хост-системе;

    Введите команду DV , чтобы изучить переменные языкового стандарта, связанные с подпрограммой EchoEvtIo , как показано ниже.

    0: kd> dv ECHO!EchoEvtIo*
    ECHO!EchoEvtIoQueueContextDestroy
    ECHO!EchoEvtIoWrite
    ECHO!EchoEvtIoRead         
    
  2. Очистите предыдущие точки останова с помощью bc *.

    0: kd> bc *  
    
    1. Установите точку останова символов в подпрограммах EchoEvtIo с помощью следующей команды.
    0: kd> bm ECHO!EchoEvtIo*
      2: aade5490          @!”ECHO!EchoEvtIoQueueContextDestroy”
      3: aade55d0          @!”ECHO!EchoEvtIoWrite”
      4: aade54c0          @!”ECHO!EchoEvtIoRead”
    
  3. Выведите список точек останова, чтобы убедиться, что точка останова задана правильно.

    0: kd> bl
    1 e aabf0490 [c:\Samples\kmdf echo sample\c++\driver\autosync\queue.c @ 197]    0001 (0001) ECHO!EchoEvtIoQueueContextDestroy
    ...
    
  4. Введите g для перезапуска выполнения кода.

    0: kd> g
    
  5. — в целевой системе;>

    Запустите тестовую программу EchoApp.exe драйвера в целевой системе.

  6. <— На хост-системе;

    При запуске тестового приложения будет вызвана подпрограмма ввода-вывода в драйвере. Это приведет к остановке точки останова, а выполнение кода драйвера в целевой системе будет остановлено.

    Breakpoint 2 hit
    ECHO!EchoEvtIoWrite:
    fffff801`0bf95810 4c89442418      mov     qword ptr [rsp+18h],r8
    
  7. Используйте команду !process , чтобы отобразить текущий процесс, участвующий в выполнении echoapp.exe.

    0: kd> !process
    PROCESS ffffe0007e6a7780
        SessionId: 1  Cid: 03c4    Peb: 7ff7cfec4000  ParentCid: 0f34
        DirBase: 1efd1b000  ObjectTable: ffffc001d77978c0  HandleCount:  34.
        Image: echoapp.exe
        VadRoot ffffe000802c79f0 Vads 30 Clone 0 Private 135. Modified 5. Locked 0.
        DeviceMap ffffc001d83c6e80
        Token                             ffffc001cf270050
        ElapsedTime                       00:00:00.052
        UserTime                          00:00:00.000
        KernelTime                        00:00:00.000
        QuotaPoolUsage[PagedPool]         33824
        QuotaPoolUsage[NonPagedPool]      4464
        Working Set Sizes (now,min,max)  (682, 50, 345) (2728KB, 200KB, 1380KB)
        PeakWorkingSetSize                652
        VirtualSize                       16 Mb
        PeakVirtualSize                   16 Mb
        PageFaultCount                    688
        MemoryPriority                    BACKGROUND
        BasePriority                      8
        CommitCharge                      138
    
            THREAD ffffe00080e32080  Cid 03c4.0ec0  Teb: 00007ff7cfece000 Win32Thread: 0000000000000000 RUNNING on processor 1
    

    Выходные данные показывают, что процесс связан с echoapp.exe, которая выполнялась при достижении точки останова на событии записи драйвера. Дополнительные сведения см. в разделе !process.

  8. Используйте !process 0 0 для отображения сводной информации для всех процессов. В выходных данных нажмите клавиши CTRL+F, чтобы найти тот же адрес процесса для процесса, связанного с изображением echoapp.exe. В приведенном ниже примере адрес процесса — ffffe0007e6a7780.

    ...
    
    PROCESS ffffe0007e6a7780
        SessionId: 1  Cid: 0f68    Peb: 7ff7cfe7a000  ParentCid: 0f34
        DirBase: 1f7fb9000  ObjectTable: ffffc001cec82780  HandleCount:  34.
        Image: echoapp.exe
    
    ...
    
  9. Запишите идентификатор процесса, связанный с echoapp.exe для последующего использования в этой лаборатории. Для копирования адреса в буфер копирования можно также использовать клавиши CTRL+C для последующего использования.

    ___(echoapp.exe адрес процесса)

  10. Введите g по мере необходимости в отладчик, чтобы запустить код вперед, пока echoapp.exe не завершит работу. Он достигнет точки останова в событии чтения и записи несколько раз. Когда echoapp.exe завершится, войдите в отладчик, нажав клавиши CTRL+ScrLk (CTRL+Break).

  11. Используйте команду !process , чтобы подтвердить, что теперь выполняется другой процесс. В выходных данных ниже процесс со значением "Изображение системы " отличается от значения echo Image.

    1: kd> !process
    PROCESS ffffe0007b65d900
        SessionId: none  Cid: 0004    Peb: 00000000  ParentCid: 0000
        DirBase: 001ab000  ObjectTable: ffffc001c9a03000  HandleCount: 786.
        Image: System
        VadRoot ffffe0007ce45930 Vads 14 Clone 0 Private 22. Modified 131605. Locked 64.
        DeviceMap ffffc001c9a0c220
        Token                             ffffc001c9a05530
        ElapsedTime                       21:31:02.516
    ...
    

    В выходных данных выше показано, что системный процесс ffffe0007b65d900 был запущен, когда мы остановили ОС.

  12. Теперь используйте команду !process , чтобы попытаться просмотреть идентификатор процесса, связанный с echoapp.exe, записанных ранее. Укажите адрес процесса echoapp.exe, записанный ранее, вместо адреса процесса, показанного ниже.

    0: kd> !process ffffe0007e6a7780
    TYPE mismatch for process object at 82a9acc0
    

    Объект процесса больше недоступен, так как процесс echoapp.exe больше не выполняется.

Потоков

Примечание
Команды для просмотра и задания потоков очень похожи на команды процессов. Используйте команду !thread для просмотра потоков. Используйте .thread для задания текущих потоков.

  1. <— На хост-системе;

    Введите g в отладчик, чтобы перезапустить выполнение кода в целевой системе.

  2. — в целевой системе;>

    Запустите тестовую программу EchoApp.exe драйвера в целевой системе.

  3. <— На хост-системе;

    Точка останова будет достигнута, и выполнение кода будет остановлено.

    Breakpoint 4 hit
    ECHO!EchoEvtIoRead:
    aade54c0 55              push    ebp
    
  4. Чтобы просмотреть выполняющиеся потоки, введите !thread. Должны отображаться следующие сведения:

    0: kd>  !thread
    THREAD ffffe000809a0880  Cid 0b28.1158  Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0
    IRP List:
        ffffe0007bc5be10: (0006,01f0) Flags: 00060a30  Mdl: 00000000
    Not impersonating
    DeviceMap                 ffffc001d83c6e80
    Owning Process            ffffe0008096c900       Image:         echoapp.exe
    ...
    

    Обратите внимание на имя образа echoapp.exe, указывающее, что мы просматриваем поток, связанный с тестируемым приложением.

    1. Используйте команду !process , чтобы определить, является ли это единственным потоком, выполняемым в процессе, связанном с echoapp.exe. Обратите внимание, что число потоков запущенного потока в процессе совпадает с тем же потоком, который отображается командой !thread.
    0: kd> !process
    PROCESS ffffe0008096c900
        SessionId: 1  Cid: 0b28    Peb: 7ff7d00df000  ParentCid: 0f34
        DirBase: 1fb746000  ObjectTable: ffffc001db6b52c0  HandleCount:  34.
        Image: echoapp.exe
        VadRoot ffffe000800cf920 Vads 30 Clone 0 Private 135. Modified 8. Locked 0.
        DeviceMap ffffc001d83c6e80
        Token                             ffffc001cf5dc050
        ElapsedTime                       00:00:00.048
        UserTime                          00:00:00.000
        KernelTime                        00:00:00.000
        QuotaPoolUsage[PagedPool]         33824
        QuotaPoolUsage[NonPagedPool]      4464
        Working Set Sizes (now,min,max)  (681, 50, 345) (2724KB, 200KB, 1380KB)
        PeakWorkingSetSize                651
        VirtualSize                       16 Mb
        PeakVirtualSize                   16 Mb
        PageFaultCount                    686
        MemoryPriority                    BACKGROUND
        BasePriority                      8
        CommitCharge                      138
    
            THREAD ffffe000809a0880  Cid 0b28.1158  Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0
    
  5. Используйте команду !process 0 0 , чтобы найти адрес процесса двух связанных процессов и записать этот адрес процесса здесь.

    Cmd.exe: ____

    EchoApp.exe: ____

    0: kd> !process 0 0 
    
    …
    
    PROCESS ffffe0007bbde900
        SessionId: 1  Cid: 0f34    Peb: 7ff72dfa7000  ParentCid: 0c64
        DirBase: 19c5fa000  ObjectTable: ffffc001d8c2f300  HandleCount:  31.
        Image: cmd.exe
    …
    PROCESS ffffe0008096c900
        SessionId: 1  Cid: 0b28    Peb: 7ff7d00df000  ParentCid: 0f34
        DirBase: 1fb746000  ObjectTable: ffffc001db6b52c0  HandleCount:  34.
        Image: echoapp.exe
    …
    

    Примечание Вы также можете использовать !process 0 17 для отображения подробных сведений о каждом процессе. Выходные данные этой команды могут быть длинными. Выходные данные можно найти с помощью клавиш CTRL+F.

  6. Используйте команду !process для перечисления сведений о процессах для обоих процессов, работающих на компьютере. Укажите адрес процесса из выходных данных !process 0 0 , а не адрес, показанный ниже.

    Этот пример выходных данных предназначен для идентификатора процесса cmd.exe, записанного ранее. Обратите внимание, что имя образа для этого идентификатора процесса cmd.exe.

    0: kd>  !process ffffe0007bbde900
    PROCESS ffffe0007bbde900
        SessionId: 1  Cid: 0f34    Peb: 7ff72dfa7000  ParentCid: 0c64
        DirBase: 19c5fa000  ObjectTable: ffffc001d8c2f300  HandleCount:  31.
        Image: cmd.exe
        VadRoot ffffe0007bb8e7b0 Vads 25 Clone 0 Private 117. Modified 20. Locked 0.
        DeviceMap ffffc001d83c6e80
        Token                             ffffc001d8c48050
        ElapsedTime                       21:33:05.840
        UserTime                          00:00:00.000
        KernelTime                        00:00:00.000
        QuotaPoolUsage[PagedPool]         24656
        QuotaPoolUsage[NonPagedPool]      3184
        Working Set Sizes (now,min,max)  (261, 50, 345) (1044KB, 200KB, 1380KB)
        PeakWorkingSetSize                616
        VirtualSize                       2097164 Mb
        PeakVirtualSize                   2097165 Mb
        PageFaultCount                    823
        MemoryPriority                    FOREGROUND
        BasePriority                      8
        CommitCharge                      381
    
            THREAD ffffe0007cf34880  Cid 0f34.0f1c  Teb: 00007ff72dfae000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable
                ffffe0008096c900  ProcessObject
            Not impersonating
    ...
    

    Этот пример выходных данных предназначен для идентификатора процесса echoapp.exe, записанного ранее.

    0: kd>  !process ffffe0008096c900
    PROCESS ffffe0008096c900
        SessionId: 1  Cid: 0b28    Peb: 7ff7d00df000  ParentCid: 0f34
        DirBase: 1fb746000  ObjectTable: ffffc001db6b52c0  HandleCount:  34.
        Image: echoapp.exe
        VadRoot ffffe000800cf920 Vads 30 Clone 0 Private 135. Modified 8. Locked 0.
        DeviceMap ffffc001d83c6e80
        Token                             ffffc001cf5dc050
        ElapsedTime                       00:00:00.048
        UserTime                          00:00:00.000
        KernelTime                        00:00:00.000
        QuotaPoolUsage[PagedPool]         33824
        QuotaPoolUsage[NonPagedPool]      4464
        Working Set Sizes (now,min,max)  (681, 50, 345) (2724KB, 200KB, 1380KB)
        PeakWorkingSetSize                651
        VirtualSize                       16 Mb
        PeakVirtualSize                   16 Mb
        PageFaultCount                    686
        MemoryPriority                    BACKGROUND
        BasePriority                      8
        CommitCharge                      138
    
            THREAD ffffe000809a0880  Cid 0b28.1158  Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0
            IRP List:
                ffffe0007bc5be10: (0006,01f0) Flags: 00060a30  Mdl: 00000000
            Not impersonating
    ...
    
  7. Запишите первый адрес потока, связанный с двумя процессами.

    Cmd.exe: ____

    EchoApp.exe: ____

  8. Используйте ! Команда потока для отображения сведений о текущем потоке.

    0: kd>  !Thread
    THREAD ffffe000809a0880  Cid 0b28.1158  Teb: 00007ff7d00dd000 Win32Thread: 0000000000000000 RUNNING on processor 0
    IRP List:
        ffffe0007bc5be10: (0006,01f0) Flags: 00060a30  Mdl: 00000000
    Not impersonating
    DeviceMap                 ffffc001d83c6e80
    Owning Process            ffffe0008096c900       Image:         echoapp.exe
    Attached Process          N/A            Image:         N/A
    ...
    

    Как и ожидалось, текущий поток является потоком, связанным с echoapp.exe, и он находится в состоянии выполнения.

  9. Используйте ! Команда потока для отображения сведений о потоке, связанном с процессом cmd.exe. Укажите адрес потока, записанный ранее.

    0: kd> !Thread ffffe0007cf34880
    THREAD ffffe0007cf34880  Cid 0f34.0f1c  Teb: 00007ff72dfae000 Win32Thread: 0000000000000000 WAIT: (UserRequest) UserMode Non-Alertable
        ffffe0008096c900  ProcessObject
    Not impersonating
    DeviceMap                 ffffc001d83c6e80
    Owning Process            ffffe0007bbde900       Image:         cmd.exe
    Attached Process          N/A            Image:         N/A
    Wait Start TickCount      4134621        Ticks: 0
    Context Switch Count      4056           IdealProcessor: 0             
    UserTime                  00:00:00.000
    KernelTime                00:00:01.421
    Win32 Start Address 0x00007ff72e9d6e20
    Stack Init ffffd0015551dc90 Current ffffd0015551d760
    Base ffffd0015551e000 Limit ffffd00155518000 Call 0
    Priority 14 BasePriority 8 UnusualBoost 3 ForegroundBoost 2 IoPriority 2 PagePriority 5
    Child-SP          RetAddr           : Args to Child                                                           : Call Site
    ffffd001`5551d7a0 fffff801`eed184fe : fffff801`eef81180 ffffe000`7cf34880 00000000`fffffffe 00000000`fffffffe : nt!KiSwapContext+0x76 [d:\9142\minkernel\ntos\ke\amd64\ctxswap.asm @ 109]
    ffffd001`5551d8e0 fffff801`eed17f79 : ffff03a5`ca56a3c8 000000de`b6a6e990 000000de`b6a6e990 00007ff7`d00df000 : nt!KiSwapThread+0x14e [d:\9142\minkernel\ntos\ke\thredsup.c @ 6347]
    ffffd001`5551d980 fffff801`eecea340 : ffffd001`5551da18 00000000`00000000 00000000`00000000 00000000`00000388 : nt!KiCommitThreadWait+0x129 [d:\9142\minkernel\ntos\ke\waitsup.c @ 619]
    ...
    

    Этот поток связан с cmd.exe и находится в состоянии ожидания.

  10. Укажите адрес потока ожидания CMD.exe потока, чтобы изменить контекст на этот поток ожидания.

    0: kd> .Thread ffffe0007cf34880
    Implicit thread is now ffffe000`7cf34880
    
  11. Используйте команду k для просмотра стека вызовов, связанного с потоком ожидания.

    0: kd> k
      *** Stack trace for last set context - .thread/.cxr resets it
    # Child-SP          RetAddr           Call Site
    00 ffffd001`5551d7a0 fffff801`eed184fe nt!KiSwapContext+0x76 [d:\9142\minkernel\ntos\ke\amd64\ctxswap.asm @ 109]
    01 ffffd001`5551d8e0 fffff801`eed17f79 nt!KiSwapThread+0x14e [d:\9142\minkernel\ntos\ke\thredsup.c @ 6347]
    02 ffffd001`5551d980 fffff801`eecea340 nt!KiCommitThreadWait+0x129 [d:\9142\minkernel\ntos\ke\waitsup.c @ 619]
    03 ffffd001`5551da00 fffff801`ef02e642 nt!KeWaitForSingleObject+0x2c0 [d:\9142\minkernel\ntos\ke\wait.c @ 683]
    ...
    

    Элементы стека вызовов, такие как KiCommitThreadWait , указывают на то, что этот поток не работает должным образом.

Примечание
Дополнительные сведения о потоках и процессах см. в следующих ссылках:

Потоки и процессы

Изменение контекстов

Раздел 10. IRQL, регистрация и завершение сеанса WinDbg

Просмотр сохраненного IRQL

В разделе 10 вы увидите IRQL и содержимое regsisters.

<— в хост-системе.

Уровень запроса прерывания (IRQL) используется для управления приоритетом обслуживания прерываний. Каждый процессор имеет параметр IRQL, который может вызывать или уменьшать потоки. Прерывания, возникающие в параметре IRQL процессора или ниже, маскируются и не препятствуют текущей операции. Прерывания, возникающие над параметром IRQL процессора, имеют приоритет над текущей операцией. Расширение !irql отображает уровень запроса прерывания (IRQL) на текущем процессоре целевого компьютера до сбоя отладчика. Когда целевой компьютер переходит в отладчик, irQL изменяется, но IRQL, действующий непосредственно перед сохранением останова отладчика и отображается с помощью !irql.

0: kd> !irql
Debugger saved IRQL for processor 0x0 -- 2 (DISPATCH_LEVEL)

Просмотр регистров

<-В хост-системе

Отображение содержимого регистров для текущего потока в текущем процессоре с помощью команды r (Registers).

0: kd> r
rax=000000000000c301 rbx=ffffe00173eed880 rcx=0000000000000001
rdx=000000d800000000 rsi=ffffe00173eed8e0 rdi=ffffe00173eed8f0
rip=fffff803bb757020 rsp=ffffd001f01f8988 rbp=ffffe00173f0b620
 r8=000000000000003e  r9=ffffe00167a4a000 r10=000000000000001e
r11=ffffd001f01f88f8 r12=0000000000000000 r13=ffffd001f01efdc0
r14=0000000000000001 r15=0000000000000000
iopl=0         nv up ei pl nz na pe nc
cs=0010  ss=0018  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
nt!DbgBreakPointWithStatus:
fffff803`bb757020 cc              int     3

Кроме того, можно отобразить содержимое регистров, выбрав параметры просмотра>. Дополнительные сведения см. в разделе r (Registers).

Просмотр содержимого регистров может оказаться полезным при пошаговом выполнении кода языка сборки и в других сценариях. Дополнительные сведения об дизассемблированном языке сборок см. в разделе Annotated x86 Disassembly и Annotated x64 Disassembly.

Сведения о содержимом регистра см. в разделе архитектуры x86 и архитектуры x64.

Завершение сеанса WinDbg

<-В хост-системе

Чтобы завершить сеанс отладки в пользовательском режиме, верните отладчик в неактивный режим и задайте целевому приложению повторное выполнение, введите команду qd (Quit and Detach).

Убедитесь, что используйте команду g , чтобы разрешить целевому компьютеру выполнять код, чтобы его можно было использовать. Кроме того, рекомендуется очистить точки останова с помощью bc *, чтобы целевой компьютер не прерывал и не пытался подключиться к отладчику главного компьютера.

0: kd> qd

Дополнительные сведения см. в разделе "Завершение сеанса отладки в WinDbg " в справочной документации по отладке.

Раздел 11. Windows ресурсов отладки

Дополнительные сведения см. в Windows отладке. Обратите внимание, что некоторые из этих книг будут использовать более старые версии Windows, такие как Windows Vista в своих примерах, но описанные концепции применимы к большинству версий Windows.

Книги

  • Расширенная Windows Отладка Марио Хевардт и Даниэль Прават

  • Внутри Windows отладки: практическое руководство по отладке и трассировке стратегий в Windows ® Tarik Soulami

  • Windows Внутренние марк Э. Руссинович, Дэвид А. Соломон и Алекс Ионеску

Видео

Средства дефрагментации показывают Эпизоды WinDbg 13-29: </show/defrag-tools/>

Поставщики обучения:

OSR https://www.osr.com/

Стандартные методы отладки

Специализированные методы отладки

начало работы с отладкой Windows