03.04.2014 Views

Май - Xakep Online

Май - Xakep Online

Май - Xakep Online

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

coding<br />

Официальный отладчик режима ядра от MS Внутреннее устройство Windows<br />

се, наверное, знают замечательную<br />

В утилиту от Марка Руссиновича<br />

под названием RegMon. Эта тузла<br />

показывает, какой процесс к какому<br />

ключу реестра хочет обратиться. В ОС семейства<br />

NT это было реализовано с помощью драйвера,<br />

который перехватывал соответствующие<br />

системные сервисы. Подобной технологией<br />

пользовались практически все антивирусы и<br />

персональные файрволы, но с выходом Windows<br />

Vista эту «дыру» (по мнению Майкрософт)<br />

прикрыли. Официальная причина — чтобы<br />

противостоять действию руткитов, однако еще<br />

до выхода релиза знаменитый PatchGuarg (так<br />

называется технология защиты ядерного кода<br />

от патча) поломали раз десять.<br />

Разработчики серьезного ПО, естественно, не<br />

станут ломать эту «защиту», а воспользуются<br />

альтернативными способами.<br />

Инструментарий<br />

Итак, мы собрались писать драйвер, а для этого<br />

нам понадобятся некоторые дополнительные<br />

инструменты. Хочу сразу предупредить, что этот<br />

материал ориентирован на людей, которые достаточно<br />

хорошо программируют на прикладном<br />

уровне, но ни разу не сталкивались с кодом для<br />

ядра. Поэтому, если ты имеешь подобный опыт,<br />

можешь просто просмотреть текст, так как что-то<br />

новое в нем ты вряд ли найдешь.<br />

Первым делом нам понадобится компилятор.<br />

Стандартом здесь является пакет от MS — DDK<br />

(Driver Development Kits). В него входит много<br />

всего полезного, но, к сожалению, нет оболочки<br />

для редактирования кода, так что об этом надо<br />

тоже позаботиться.<br />

Когда мы начнем писать более-менее серьезные<br />

драйверы, нам понадобится отладчик режима ядра.<br />

Самыми известными являются SoftICE и WinDbg.<br />

SoftICE хорош тем, что драйверы можно отлаживать<br />

прямо на своей машине, а вот для WinDbg нужен<br />

второй компьютер. Но отлаживать драйвер на<br />

своей машине — это то же самое, что самому делать<br />

операцию на собственном мозге. Так что советую<br />

использовать WinDbg в тандеме с виртуальной<br />

машиной. Еще нам пригодится DbgView — утилита<br />

от уже упомянутого здесь Руссиновича, которая<br />

позволяет просматривать отладочные сообщения<br />

от драйвера в реальном времени без отладчика.<br />

Писать драйвер мы будем под Висту, поэтому,<br />

чтобы избежать лишних проблем, нужно найти<br />

последние версии всего упомянутого выше.<br />

Основа драйвера<br />

Теперь приступим непосредственно к программированию.<br />

Написать минимальный драйвер,<br />

оказывается, очень просто. Надо всего лишь<br />

определить тело функции DriverEntry(). Чтобы<br />

наш драйвер успешно загрузился и не вызвал<br />

при этом голубого экрана смерти (BsoD), нужно<br />

написать следующие строки:<br />

Код минимального драйвера<br />

NTSTATUS DriverEntry (<br />

IN PDRIVER_OBJECT pDriverObject,<br />

IN PUNICODE_STRING pRegistryPath<br />

)<br />

{<br />

NTSTATUS status = STATUS_<br />

DEVICE_CONFIGURATION_ERROR;<br />

return status;<br />

}<br />

Если мы скомпилируем драйвер и попробуем<br />

его загрузить (о том, как это сделать, я расскажу<br />

чуть позже), он завершит свою работу и будет<br />

выгружен из памяти, поскольку мы вернули код<br />

ошибки. Если бы мы не сделали этого, драйвер<br />

висел бы в памяти бесконечно, так как пока у<br />

нас нет функции DriverUnload, ответственной за<br />

выгрузку драйвера.<br />

Теперь надо разобраться с параметрами,<br />

передаваемыми в функцию, и их типами, так как<br />

некоторые уже могли заметить, что, например,<br />

PUNICODE_STRING никогда раньше не встречался<br />

в программировании для юзер-мода.<br />

Сама функция DriverEntry — это входная точка в<br />

модуль, именно этой функции передается управление<br />

при загрузке драйвера.<br />

Первый параметр pDriverObject — это указатель<br />

на объект только что созданного драйвера.<br />

Windows является объектно-ориентированной<br />

системой; загружая драйвер, система создает<br />

объект «драйвер» (driver object), представляющий<br />

для нее образ драйвера в памяти. Через<br />

этот объект система управляет драйвером. На<br />

самом деле, это вовсе не объект в классическом<br />

понимании, а просто некая структура данных<br />

типа DRIVER_OBJECT, определение которой можно<br />

посмотреть здесь: \include\w2k\ntddk.inc. Некоторые<br />

поля этой структуры заполняет система,<br />

некоторые придется заполнять нам самим. Обращаясь<br />

к этой структуре, система и управляет<br />

драйвером.<br />

Следующий параметр — это pRegistryPath. Он<br />

является указателем на unicode-строку, которая,<br />

в свою очередь, указывает на путь к разделу<br />

реестра, содержащему параметры инициализации<br />

драйвера. Структуру этого раздела, как<br />

xàêåð 05 /101/ 07<br />

/<br />

125

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!