, Программирование ядра Windows, 2е изд.

Программирование ядра Windows, 2е изд.

Павел Йосифович

 Состав исполнителей

Автор
Павел Йосифович

 Об авторе

Павел Йосифович

 Введение

Многие рассматривают программирование ядра Windows тёмным искусством, доступным лишь тем немногим, которым удаётся каким- то образом раскрыть тайны самого ядра Windows. Однако разработка ядра Windows ничем не отличается от разработки режима пользователя, по крайней мере в общих чертах. В обоих случаях для создания высококачественного кода требуется хорошее понимание самой платформы.

Данная книга представляет собой руководство по программированию в рамках самого ядра Windows с применением известной интегрированной среды разработки (IDE, integrated development environment) Visual Studio. Данная среда знакома многим разработчикам в пространстве Microsoft, поэтому наша кривая обучения ограничивается знакомством с ядром, кодированием и отладкой, причём с меньшей относящейся к инструментам разработки силой сцепления.

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

 Для кого эта книга

Данная книга предназначена для разработчиков программного обеспечения, ориентированных на само ядро Windows, и нуждающихся в своих целях в написании драйверов ядра. Распространённые ситуации, в которых применяются драйверы ядра, относятся к области кибербезопасности, когда драйверы ядра выступают основным механизмом для получения уведомлений о важных событиях с возможностью перехвата определённых операций. В качестве примеров кода в книге применяются C и C++, тогда как API ядра это целиком C. C++ применяется там, где это имеет смысл, когда его преимущества очевидны с точки зрения сопровождения, ясности, управления ресурсами или любого их сочетания. В книге не применяются сложные конструкции C++, такие как метапрограммирование шаблонов. Данная книга не о C++, а о драйверах ядра Windows.

 Что вы должны знать, чтобы пользоваться этой книгой

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

 Содержимое книги

Вот краткое изложение глав книги:

  • Глава 1 (Обзор внутреннего устройства Windows) предоставляет основополагающие знания внутренней работы самой ОС Windows на неком верхнем уровне, достаточные для фундамента без погружения во множество подробностей.

  • Глава 2 (Приступаем к разработке ядра) описывает те инструменты и процедуры, которые требуются для настройки среды разработки для создания драйверов ядра. Чтобы убедиться что все инструменты и процедуры работают должным образом, создаётся очень простой драйвер.

  • Глава 3 (Основы программирования ядра) рассматривает основы написания драйверов, включая основы API ядра, обработку общих задач программирования, включающих строки, связанные списки, динамическое выделение памяти и многое другое.

  • Глава 4 (Драйвер от начала до конца) показывает как собрать полноценный драйвер, который выполняет некую полезную функциональность, а также клиентское приложение для управления им.

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

 Примеры кода

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

Все примеры кода были скомпилированы с применением Visual Studio 2019. Если есть такое желание, имеется возможность компиляции большинства примеров кода и более ранними версиями Visual Studio. В самых последних версиях стандартов C++ могут иметься несколько функциональных возможностей, которые могут не поддерживаться в более ранних версиях, однако их должно быть не сложно подправить.

Приятного чтения!

Павел Йосифович

Июнь 2022

 Содержание

Введение
Для кого эта книга
Что вы должны знать, чтобы пользоваться этой книгой
Содержимое книги
Примеры кода
Глава 1. Обзор внутреннего устройства Windows
Процессы
Виртуальная память
Состояния страниц
Системная память
Потоки
Стеки потоков
Системные службы (или Системные вызовы)
Общая архитектура системы
Дескрипторы и объекты
Имена объектов
Доступ к имеющимся объектам
Глава 2. Приступаем к разработке ядра
Установка необходимых инструментов
Создаём проект драйвера
Процедуры DriverEntry и Unload
Развёртывание драйвера
Простая трассировка
Выводы
Глава 3. Основы программирования ядра
Общие руководящие правила программирования ядра
Необработанные исключительные ситуации
Прекращение
Возвращаемые значения функции
IRQL
Применение C++
Тестирование и отладка
Сопоставление отладки и выпуска
API ядра
Функции и коды ошибок
Строки
Динамическое выделение памяти
Связные списки
Объект драйвера
Атрибуты объекта
Объекты устройства
Непосредственное открытие объекта
Выводы
Глава 4. Драйвер от начала до конца
Введение
Инициализация драйвера
Передача информации в драйвер
Протокол взаимодействия клиент/ драйвер
Создание объекта устройства
Код клиента
Создание и закрытие процедур Dispatch
Написание процедуры Dispatch
Установка и тестирование
Выводы
Глава 5. Отладка и тестирование
Инструменты отладки для Windows
Введение в WinDbg
Руководство: основы отладки режима пользователя
Отладка ядра
Локальная отладка ядра
Основы локальной отладки ядра
Полная отладка ядра
Применение виртуального последовательного порта
Применение сетевой среды
Руководство отладки драйвера ядра
Предположения и трассировка
Предположения
Расширенный DbgPrint
Прочие функции отладки
Журналирование отладки
Просмотр трассировки ETW
Выводы
Глава 6. Механизмы ядра
Уровень запроса на прерывание (IRQL)
Повышение и понижение IRQL
Сопоставление приоритетов потоков и IRQL
Отложенные вызовы процедур (DPC)
Применение DPC с таймером
Асинхронные вызовы процедур
Критические области и защищённые области
Структурированная обработка исключительных ситуаций
Применение __try/__except
Применение __try/__finally
Применение C++ RAII вместо __try/__finally
Крушение системы
Сведения дампа крушения
Анализ файла дампа
Зависание системы
Синхронизация потоков
Операции взаимной блокировки
Объекты диспетчера
Взаимное исключение
Быстрое взаимное исключение
Семафор
Событие
Именованное событие
Исполняемый ресурс
Синхронизация верхних IRQL
Спин- блокировки
Очереди спин- блокировок
Зависание системы
Рабочие элементы
Выводы
Глава 7. Пакет запроса на ввод/ вывод (IRP)
Введение в IRP
Узлы устройств
Поток IRP
IRP и местоположение стека ввода/ вывода
Просмотр сведений IRP
Процедуры Dispatch
Выполнение запроса
Доступ к буферам пользователя
Буферированный ввод/ вывод
Непосредственный ввод/ вывод
Буферы пользователя для IRP_MJ_DEVICE_CONTROL
Собираем всё воедино: Драйвер Zero
Применение предварительно скомпилированного заголовка
Процедура DriverEntry
Создание и закрытие процедур Dispatch
Процедура Read Dispatch
Процедура Write Dispatch
Тестирование приложения
Статистики чтения/ записи
Выводы
Глава 8. Современные технологии программирования (Часть I)
Создаваемые драйвером потоки
Управление памятью
Выделение пула
Безопасность пулов
Перекрытие операторов new и delete
Подготовленные заранее списки
"Классический" API заблаговременной подготовки
Более новый API заблаговременной подготовки
Вызов прочих драйверов
Собираем всё воедино: драйвер Melody
Активация системных служб
Пример: нумерация процессов
Выводы
Глава 9. Извещения процесса и потока
Извещения процесса
Реализация извещения процесса
Процедура DriverEntry
Обработка уведомлений выхода из процесса
Обработка уведомлений создания процесса
Предоставление данных в режим пользователя
Извещения потока
Клиент режима пользователя
Извещения загрузки образа
Окончательный код клиента
Выявление удалённого потока
Клиент Detector
Выводы
Глава 10. Извещения объектов и реестра
Извещения объектов
Обратные вызовы перед операцией
Обратные вызовы после операции
Драйвер защиты процесса
Регистрация извещения объекта
Управление процессами защиты
Предварение обратного вызова
Приложение клиента
Извещения реестра
Обзор реестра
Применение извещений реестра
Обработка предварения извещения
Обработка действий после операции
Расширение нашего драйвера SysMon
Обработка обратного вызова реестра
Изменение кода клиента
Вопросы производительности
Различные замечания
Выводы
l>