Стук по клавишам в три часа ночи. Сервер начал подтормаживать, пользователи звонят, но остановить его нельзя. Знакомая ситуация? В таких случаях обычная отладка с остановкой системы не вариант. Здесь на сцену выходит LiveKD, инструмент от Sysinternals, который позволяет мне заглянуть в самое ядро живой Windows, не прерывая её работу. За годы практики я научился использовать его так, что теперь могу диагностировать проблемы буквально на лету.

Философия неинтрузивности: смотреть, но не трогать

LiveKD работает по принципу "моментального снимка". Утилита загружает специальный драйвер LiveKdD.sys, который создаёт зеркало памяти ядра через технологию Copy-on-Write. Система продолжает работать, а я получаю застывшую картину для анализа. Это как сфотографировать бегущего спортсмена с очень короткой выдержкой: движение продолжается, но у меня есть кадр для детального изучения.

Важно понимать ограничения. LiveKD не останавливает выполнение ядра, поэтому команды типа breakpoint (bp, bu) или управления выполнением (g, p, t) здесь не работают. Я не могу модифицировать память напрямую. Зато доступны все команды просмотра: стеки вызовов, структуры данных, состояние процессов и потоков. Это именно то, что нужно для диагностики в продакшене.

Согласно официальной документации Microsoft, LiveKD создаёт "pseudo-live local kernel debugging" без необходимости включать режим отладки через bcdedit. При этом снимок может быть не идеально консистентным: пока драйвер собирает данные, система живёт своей жизнью. Страницы могут быть выгружены, процессы завершены, новые запущены. Но для большинства задач диагностики этого более чем достаточно.

Символы: без них вы слепы

Перед любой работой с LiveKD критически важно настроить символы (PDB-файлы). Без них отладчик показывает только шестнадцатеричные адреса вместо понятных имён функций. Адрес fffff801'8d283000 бесполезен, а вот nt!RtlpExecuteHandlerForException уже говорит о многом.

Настройка начинается с переменной среды. Открываю командную строку с правами администратора:

setx _NT_SYMBOL_PATH "srv*C:\Symbols*https://msdl.microsoft.com/download/symbols"

Здесь srv* указывает на использование символьного сервера Microsoft, C:\Symbols это локальный кэш (папка создастся автоматически), а дальше идёт адрес официального сервера. При первом запуске LiveKD предложит настроить символы автоматически, но я предпочитаю сделать это явно и один раз.

После запуска отладчика первым делом проверяю загрузку:

lm v m nt

Эта команда показывает информацию о модуле nt (ntoskrnl.exe, ядро системы). Если вижу статус "pdb symbols", значит всё настроено правильно. Надпись "export symbols only" сигнализирует о проблеме: символы неполные, многие команды будут работать некорректно.

Иногда символы загружаются медленно или возникают сетевые ошибки. Включаю подробный режим:

!sym noisy
.reload /f nt

Вывод покажет, какие файлы скачиваются, где возникают проблемы и почему определённые символы недоступны. Этот навык сэкономил мне десятки часов в критических ситуациях. Кстати, LiveKD всегда будет жаловаться на отсутствие символов для собственного драйвера LIVEKDD.SYS, это нормально и не влияет на работу.

Установка и первый запуск

Начинаю с установки Debugging Tools for Windows (входит в Windows SDK). Скачиваю его с официального сайта Microsoft и при установке выбираю только компонент "Debugging Tools for Windows". Полный SDK весит гигабайты, а мне нужны только отладчики.

Затем скачиваю LiveKD с сайта Sysinternals. Распаковываю архив и копирую livekd64.exe (для 64-битных систем) в удобное место: либо в папку с отладчиком, либо просто в System32. Главное, чтобы путь был доступен из командной строки.

Запуск требует прав администратора:

livekd -w

Флаг -w запускает графический WinDbg вместо консольного kd. При первом запуске появится окно лицензионного соглашения (нажимаю Agree), затем LiveKD спросит о настройке пути к символам. Если я уже настроил переменную среды, просто нажимаю Enter.

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

!process 0 0

Она выводит список всех процессов системы с минимальной информацией: адреса блоков EPROCESS, PID, имена образов. Вижу десятки строк с названиями System, svchost.exe, explorer.exe? Отлично, я внутри ядра.

Команды расширений: где живёт магия

Расширения (extension commands) начинаются с восклицательного знака и загружаются из специальных DLL-библиотек вроде kdexts.dll. Именно они превращают отладчик из простого просмотрщика памяти в мощнейший инструмент диагностики.

!process с различными флагами даёт разную детализацию. Базовый вариант:

!process 0 0

Показывает все процессы в одну строку. Для детального анализа конкретного процесса:

!process <адрес_EPROCESS> 7

Флаг 7 означает максимальную детализацию: все потоки, их стеки, открытые дескрипторы, статистика памяти. Осторожно: на системе с сотнями процессов команда !process 0 7 может выполняться минуты. Я всегда использую её точечно.

!thread показывает детали потока:

!thread <адрес_ETHREAD>

Вывод включает состояние потока (выполняется, ожидает, приостановлен), на что он ждёт (объект синхронизации, ввод-вывод), полный стек вызовов. Для просмотра стека текущего потока просто:

k

Или с параметрами функций:

kv

Команда !locks сканирует ресурсы ERESOURCE на предмет блокировок:

!locks

Критически важна при диагностике deadlock'ов (взаимных блокировок), когда два или более потока вечно ждут друг друга. Покажет, какие потоки захватили какие блокировки и кто чего ждёт.

Для анализа памяти использую:

!vm 1

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

!poolused 2

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

!analyze -v автоматически анализирует текущее состояние:

!analyze -v

Обычно её используют при BSOD, но и в LiveKD она даёт полезную информацию, автоматически проанализировав состояние системы и выдав сводку с рекомендациями. Ключ -v означает verbose (подробный режим).

Для просмотра загруженных модулей:

lm

Команда x ищет символы по маске:

x nt!*Create*

Найдёт все функции в модуле nt, содержащие "Create" в имени.

Реальный сценарий: поиск виновника торможения

Сервер начал периодически зависать на несколько секунд. Пользователи жалуются, мониторинг не показывает ничего подозрительного. Останавливать нельзя. Идеальный случай для LiveKD.

Запускаю в момент торможения:

livekd -w

После открытия WinDbg обновляю символы:

.reload

Затем ищу потоки, потребляющие много процессорного времени:

!runaway 7

Вижу поток с аномально высоким временем в режиме ядра. Копирую его адрес и выполняю:

!thread ffffcb088f0a4480

Смотрю на стек:

kv

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

Проверяю все блокировки:

!locks

Нахожу ту, которую ожидает мой поток. Вижу, что её держит другой поток из другого процесса. Анализирую этот второй поток и обнаруживаю: он ждёт завершения дисковой операции.

Использую !process для поиска процесса-виновника:

!process 0 0

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

Создание дампов для последующего анализа

Бывают ситуации, когда проблема возникает спорадически. В такие моменты некогда вникать в детали. Я создаю дамп памяти:

livekd -m -o C:\dumps\snapshot.dmp

Флаг -m создаёт mirror dump (зеркальный дамп), -o указывает файл для сохранения. Позже открываю этот дамп в WinDbg:

windbg -z C:\dumps\snapshot.dmp

И спокойно анализирую в удобное время. Дамп содержит полное состояние памяти ядра на момент создания снимка.

Для дампа конкретного процесса использую флаг -mp:

livekd -mp <PID> -o C:\dumps\process.dmp

Это полезно, когда проблема локализована в одном приложении.

Работа с Hyper-V виртуальными машинами

LiveKD версии 5.0 и выше поддерживает отладку Hyper-V виртуальных машин. Для просмотра списка VM:

livekd -hvl

Команда выведет GUID и имена всех запущенных виртуальных машин. Для подключения к конкретной VM:

livekd -hv <имя_VM> -w

Флаг -hvd включает в анализ страницы гипервизора (работает на Windows 8.1 и новее):

livekd -hv <имя_VM> -hvd -w

Для создания дампа виртуальной машины с паузой (более консистентный снимок):

livekd -hv DFIR-PC -p -o DFIR-PC.dmp

Флаг -p приостанавливает VM на момент создания дампа. Если пауза невозможна по бизнес-причинам, опускаю -p и создаю дамп с живой VM.

Подводные камни и тонкости работы

За годы использования LiveKD я столкнулся с рядом нюансов. Первое: снимок не идеально консистентен. Пока драйвер собирает данные, система работает. Иногда вижу странности вроде указателей на несуществующие адреса или процессов, которые уже завершились.

Второе: LiveKD оставляет драйвер LiveKdD.sys в системе. Античит-системы в играх могут его обнаружить. После работы проверяю:

sc query livekdd

Если драйвер остался загруженным, удаляю:

sc delete livekdd

Третье: некоторые версии Windows 10 могут выдавать ошибку "THIS DUMP FILE IS PARTIALLY CORRUPT. KdDebuggerDataBlock is not present or unreadable". Обычно это решается обновлением LiveKD до последней версии (на момент написания 5.63) или копированием livekd64.exe непосредственно в папку с WinDbg.

Четвёртое: на 64-битных системах нужна 64-битная версия отладчика. Попытка использовать x86 инструменты на x64 системе приведёт к ошибке "Local kernel debugging requires Windows XP". Проверяю архитектуру и использую соответствующую версию.

Пятое: для отладки на уровне Secure Kernel (изолированные процессы VBS) LiveKD недостаточно. Здесь нужен специализированный инструмент LiveCloudKd, построенный на базе LiveKD с расширенными возможностями.

Альтернативные подходы и расширенные техники

Начиная с Windows Vista, сам WinDbg поддерживает локальную отладку ядра. Но это требует включения режима отладки:

bcdedit /debug on
bcdedit /dbgsettings local

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

Для быстрой диагности без GUI использую консольный kd:

livekd

Без флага -w запустится консольная версия. Удобно для скриптов или удалённых сессий по SSH.

Дополнительные полезные команды, которые стоит знать:

!devnode 0 1

Просмотр дерева устройств PnP (Plug and Play). Показывает иерархию всех устройств в системе.

!drivers

Информация о всех загруженных драйверах: адреса, размеры, точки входа.

!irp <адрес_IRP>

Анализ IRP (I/O Request Packet) для диагностики проблем ввода-вывода.

!stacks

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

Сравнение с другими инструментами

LiveCloudKd, разработанный энтузиастами, предлагает дополнительные возможности: возможность записи в память VM, более высокую производительность в виртуализованных средах, поддержку различных методов доступа к памяти Hyper-V (ReadInterfaceWinHv, ReadInterfaceHvmmDrvInternal). Если работаю с Hyper-V на постоянной основе, LiveCloudKd предпочтительнее.

Для создания "живых" дампов без LiveKD можно использовать PowerShell-скрипты с вызовами NtSystemDebugControl API. Это более гибкий, но и более сложный подход, требующий глубоких знаний внутреннего устройства Windows.

В Linux-мире аналогичные задачи решаются через QEMU с GDB для отладки ядра, но прямого эквивалента LiveKD нет. Unix-системы традиционно используют другие подходы: DTrace, SystemTap, eBPF для динамической трассировки без остановки.

Практические советы из траншей

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

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

Третье: комбинирую LiveKD с другими инструментами Sysinternals. Process Explorer показывает загрузку CPU, а LiveKD объясняет, почему. ProcDump создаёт дамп пользовательского процесса, LiveKD анализирует ядро. Вместе они дают полную картину.

Четвёртое: на продуктивных системах запускаю LiveKD в моменты низкой нагрузки или только при явных проблемах. Хотя инструмент неинтрузивный, создание снимка всё равно потребляет ресурсы.

Пятое: изучаю Windows Internals Марка Руссиновича (автора LiveKD). Книга даёт фундаментальное понимание устройства ядра, без которого работа с отладчиком превращается в слепое тыкание.

LiveKD это не просто утилита, это окно в самое сердце Windows. Инструмент требует терпения и понимания, но взамен даёт почти магическую способность: видеть невидимое в работающей системе. Каждый раз, когда запускаю его в критической ситуации и нахожу корень проблемы, понимаю, что время, потраченное на изучение, окупилось сторицей.