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 />

кода прекращается и управление передается<br />

обработчику прерывания. Существуют как<br />

аппаратные, так и программные прерывания.<br />

Они обслуживаются в соответствии с их приоритетом.<br />

Windows 2000 (как и Виста) использует<br />

схему приоритетов прерываний, известную под<br />

названием «уровни запросов прерываний»<br />

(interrupt request levels, IRQL). Всего существует<br />

32 уровня: с нулевого (passive), имеющего самый<br />

низкий приоритет, по 31‐ый (high) с самым<br />

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

с IRQL=0 (passive) по IRQL=2 (DPC\dispatch)<br />

являются программными, а с IRQL=3 (device 1) по<br />

IRQL=31 (high) — аппаратными. Не путай уровни<br />

приоритета прерываний с уровнями приоритетов<br />

потоков — это разные вещи. Прерывание с<br />

уровнем IRQL=0, строго говоря, прерыванием<br />

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

работу никакого кода (ведь для этого код должен<br />

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

а такого уровня нет). На этом IRQL выполняются<br />

потоки пользовательского режима.<br />

Следует заметить, что на уровне прерывания<br />

passive можно вызывать любые функции<br />

ядра, а также обращаться к страницам<br />

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

DDK в описании каждой функции обязательно<br />

указано, на каком уровне прерывания<br />

ее можно вызывать. На более высоких<br />

уровнях прерывания (DPC/dispath и выше)<br />

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

в физической памяти, приводит<br />

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

(Memory Manager) не может обработать<br />

ошибку страницы.<br />

Компиляция кода<br />

Теперь, когда мы немного разобрались с теорией,<br />

попробуем скомпилировать наш драйвер.<br />

Первым делом создадим файл main.c и напишем<br />

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

Содержание файла main.c<br />

#include <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 />

main.c сохраним файл sources со следующим<br />

содержанием:<br />

Содержание файла sources<br />

TARGETNAME=basic_driver<br />

TARGETPATH=obj<br />

TARGETTYPE=DRIVER<br />

SOURCES=main.c<br />

Этот файл определяет имя драйвера, файл с<br />

исходным кодом и т.д. И последнее, что нам надо,<br />

— это makefile. В нем будет всего одна строка:<br />

«!INCLUDE $(NTMAKEENV)\makefile.def».<br />

Теперь, если на машине уже установлено<br />

DDK, заходим в соответствующий пункт<br />

главного меню системы, выбираем пункт Build<br />

Environments, затем ОС, под которую будем<br />

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

Windows XP x86 Checked Build Environment.<br />

Помимо Checked Build Environment, есть еще и<br />

Free Build Environment. Checked предназначена<br />

для тестовых сборок Windows, а Free — для<br />

релизов. После того как мы выбрали соответствующую<br />

оболочку, в командной строке переходим<br />

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

исходный код нашего драйвера, и вбиваем<br />

команду build. Если все в порядке, должна<br />

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

драйвер с расширением sys.<br />

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

Загрузить драйвер в систему, чтобы он работал,<br />

можно двумя способами: документированным<br />

и не очень. Документированный способ на<br />

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

при помощи диспетчера служб, то есть SCM-менеджера.<br />

Работа с драйвером сходна с работой<br />

со службой — вызываются одни и те же функции.<br />

Лишь передаваемые им параметры будут немного<br />

отличаться от обычных. Заострять на этом<br />

внимание я не буду, так как статья уже подходит<br />

к концу, а еще надо рассказать, где про все это<br />

можно почитать более подробно.<br />

Дополнительная литература и ссылки<br />

Все сказанное выше настолько мало затрагивает<br />

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

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

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

слабости изложенного материала. Но цель этой<br />

статьи вовсе не научить кодить в Kernel Mode,<br />

а лишь ввести в данную тему, для того чтобы в<br />

следующем номере рассказать о более интересных<br />

вещах. А для этого надо хорошо усвоить<br />

принципы программирования в режиме ядра.<br />

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

советую почитать следующие книги. В<br />

первую очередь, это «Внутреннее устройство<br />

Microsoft Windows 2000», написанная Дэвидом<br />

Соломоном и Марком Руссиновичем. Книга постоянно<br />

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

может немного отличаться. Хотя в этой книге нет<br />

ни одной строчки исходного кода, прежде всего<br />

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

возможности Windows 2000» Свена Шрайбера<br />

— сугубо практическая книга, в которой раскрыто<br />

множество тайн Windows 2000.<br />

Из отечественных авторов могу посоветовать<br />

В.П. Солдатова с его трудом «Программирование<br />

драйверов Windows». Первая часть<br />

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

в себе много полезной информации. Для<br />

ленивых рекомендую «Программирование<br />

драйверов и систем безопасности» Сорокиной<br />

и Щербакова — чтиво представляет<br />

собой краткий «курс молодого бойца» в<br />

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

неплохо иметь под рукой «Справочник по<br />

базовым функциям API Windows NT/2000»<br />

Гари Неббета.<br />

Теперь скажу немного об онлайн-ресурсах,<br />

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

деле. Во-первых, стоит отметить цикл статей<br />

«Драйверы режима ядра», который написал<br />

небезызвестный Four-F. Найти эти статьи<br />

можно на http://wasm.ru. На мой взгляд, это<br />

один из самых лучших русскоязычных трудов<br />

на тему программирования в режиме ядра.<br />

Исходный код примеров, правда, написан на<br />

ассемблере, но это не должно стать преградой<br />

для человека, желающего научиться кодить<br />

драйверы.<br />

Еще одним хорошим ресурсом по теме является<br />

http://osronline.com. Сайт англоязычный, но<br />

люди, при разработке драйверов сталкивающиеся<br />

с проблемой, которую не удается решить с<br />

помощью отечественных программистов, идут<br />

именно сюда. Местный форум — просто сокровищница<br />

знаний по Kernel-Mode кодингу.<br />

Это все?<br />

Итак, как я уже говорил, эта статья ознакомительная.<br />

Единственная ее цель — подготовить<br />

читателя к следующему материалу, в котором я<br />

затрону непосредственно проблемы перехвата<br />

обращений к реестру в Windows Vista. Причем<br />

с помощью этого механизма можно не только<br />

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

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

но и помешать ему сделать это прямо на<br />

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

матчасть. z<br />

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

/<br />

127

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

Saved successfully!

Ooh no, something went wrong!