Вторая глава, конструкторский раздел.
Делается обоснованный выбор технологии ( например, объектно-ориентированный подход ) и средств разработки ( например, выбор библиотеки NuMega Driver Studio, которая является объектно-ориентированной надстройкой над «чистым» DDK ). Определяется тип программного обеспечения, например, драйвер и приложение, взаимодействующее с драйвером, или драйвер и сервис и т.п. и описывается взаимодействие модулей разработанного ПО через подсистему ввода/вывода на основе событийной модели. Например, для драйверов болчных устройств Unix рассматриваются особенности обмена с блочным устройством и структура buf.
При разработке драйверов описывается структура выбранного драйвера: точки входа и другие функции. Для WDF описываются объекты, которые представляют абстракции компонент ов драйверов, и методы, свойства, события, посредством которых драйверы взаимодействуют с объектами WDF. Описывается реализуемая драйвером функция или функции и приводится алгоритм/алгоритмы работы в виде схем по ГОСТу.
В конструкторском разделе следует:
- обосновать какие части драйвера могут находиться в перемещаемой памяти, а какие – должны оставаться резидентными;
- описать процесс обработки пакетов запроса ввода/вывода ( I/O Request Packet или IRP ) и выбрать сценарий обработки IRP [Oni]:
- обосновать необходимость применения отложенных процедурных вызовов DPC( для Windows ):
- обосновать метод буферизации, например:
в WDM-драйверах запрос может иметь или буфер ( для буферизованного ввода/вывода ), или список MDL ( для прямого ввода/вывода ); в модели WDF можно абстрагироваться от типа запроса ( буферизованного или прямого ) [орвик]; для драйверов Unix – выбор метода буферизации: используя прерывания, с помощью функции poll(), с помощью специальных структур данных clist.
- если в драйвере создается дополнительный поток, обосновать необходимость его создания и выбор средств взаимоисключения;
- при необходимости использовать события WMI ( Windows Management Instrumentation ) для оповещения потребителей об интересных или экстренных событиях;
и т.п.
Метод II. “Сплайсинг”
“Сплайсинг” – это замена начальных байтов оригинального обработчика на переход на другой обработчик.
Описание алгоритма реализации этого метода:
- найти адрес функции, вызов которой нужно перехватить;
- сохранить несколько первых байтов этой функции в другом участке памяти;
- на их место вставить машинную команду JUMP для перехода по адресу подставной функции. - сигнатура подменяющей функции должна быть такой же, как и исходной, т. е. все параметры, возвращаемое значение и правила вызова должны совпадать;
- снять ловушку, восстановив ранее сохраненные (в п. 2) байты;
Если затем вызвать перехватываемую функцию (таковой больше не являющуюся), то она будет работать так, как работала до установки ловушки.
После того как она вернет управление, необходимо выполнить пункты 2 и 3 и тем самым вновь поставить ловушку на эту функцию.
На рис. 2.5 приведен алгоритм работы нового обработчика.
рис. 2.5. Метод II. Алгоритм работы нового обработчика
Этот метод не рекомендуется использовать в пользовательском режиме в системах с вытесняющей многозадачностью. На замену кода в начале функции уходит какое-то время, а в этот момент перехватываемая функция может понадобиться другому потоку, что приведёт к катастрофическим последствиям. Однако, в режиме ядра, вследствие наивысшего уровня привилегий можно на короткий срок запретить прерывания, тем самым избежав переключения задач. Параграф взят из курсового проекта студента Улихина.
|
Для патчей описать особенности реализации.