API NetBIOS (Network Basic Input/Output System)
API NetBIOS (Network Basic Input/Output System)
Это прикладной программный интерфейс, позволяющий обмениваться запросами ввода/вывода с удаленным компьютером. Этот интерфейс используется для создания приложений для локальных сетей Microsoft LAN Manager, IBM LAN Server, Microsoft MS-Net или операционной среды OS/2. Этот API обеспечивает обратную совместимость для программ MS-DOS, 16-разрядной Windows и OS/2, которые передают данные по сети. Имеется также новая 32-разрядная версия. Интерфейс NetBIOS используется для посылки запросов, имеющих структуру формата SMB, на другой компьютер.
NetBIOS полагается на соглашение об именах, согласно которому компьютерам и сетевым сервисам назначаются 16-байтные имена, называемые NetBIOS-именами. Сетевой сервис WINS (Windows Internet Name service) поддерживает отображение между NetBIOS-именами и адресами протокола TCP/IP. NetBIOS-функции, как и Net-функции, экспортируются приложениям библиотекой Netapi32.dll (см. Рисунок 18). Эта библиотека открывает описатель драйвера уровня ядра, называемого эмулятором NetBIOS - NetBIOS.sys (драйвер файловой системы NetBIOS), и вызывает функцию DeviceloControl по команде приложения. Эмулятор NetBIOS транслирует NetBIOS-команды, выданные приложениями, в TDI-команды, которые посылаются драйверам протоколов. Если приложение хочет использовать NetBIOS поверх протокола TCP/IP, эмулятор NetBIOS требует присутствия драйвера NetBT.sys. Этот драйвер отвечает за поддержку семантики NetBIOS, присущей протоколу NetBEUI, а не протоколу TCP/IP. NetBIOS полагается на передачу NetBEUI-сообщений и средство разрешения имен NetBIOS, поэтому драйвер NetBT реализует их в вершине протокола TCP/IP. Подобно этому, драйвер NwLinkNB реализует семантику NetBIOS поверх протокола IPX/SPX.
API Windows Sockets
API Windows Sockets
Этот API реализует 16 и 32-разрядные сокеты - стандартный сетевой интерфейс, используемый UNIX. Winsock поддерживает надежное, ориентированное на соединение, а также ненадежное, не ориентированное на соединение взаимодействия.
Прикладной интерфейс Windows Sockets состоит из DLL Ws2_32.dll, которая обеспечивает приложениям доступ к Winsock-функциям (см. Рисунок 20). Ws2_32.dll вызывает сервисы пространства имен и провайдеров сервисов транспорта для выполнения операций по разрешению имен и передачи сообщений. Библиотека Msafd.dll действует как провайдер сервисов транспорта. Msafd.dll использует библиотеки-помощники для Winsock (которые являются специфичными для протоколов), для взаимодействия с драйверами протоколов уровня ядра. Например, Wshtcpip.dll является помощником для протокола TCP/IP, а Wshnetbs.dll - для протокола NetBEUI. Библиотека Mswsock.dll реализует расширенную функциональность Microsoft Winsock.
DCOM
DCOM
COM API фирмы Microsoft позволяет приложениям состоять из разных компонентов, где каждый компонент является заменяемым самостоятельным модулем. СОМ-объекты экспортируют ориентированный на объекты интерфейс к методам для манипулирования данными внутри объекта. Так как СОМ-объекты предоставляют хорошо определенные интерфейсы, разработчики могут реализовывать новые объекты для расширения существующих интерфейсов и для динамического добавления приложениям новой поддержки.
DCOM расширяет СОМ, позволяя компонентам приложения располагаться на разных компьютерах. Что позволяет приложениям не беспокоиться о том, что один СОМ-объект располагается на локальном компьютере, а другой в сети. DCOM, таким образом, обеспечивает прозрачность расположения, что облегчает разработку распределенных приложений. DCOM не является самостоятельным API, а полагается на RPC для выполнения своей работы.
Драйверы протоколов промежуточного уровня
Драйверы протоколов промежуточного уровня
NDIS драйверы протоколов промежуточного уровня взаимодействуют сверху с драйверами протоколов верхнего уровня (такими как драйверы транспортов), а снизу с NDIS драйверами сетевых карт локальных и глобальных сетей. Ниже NDIS драйвера промежуточного уровня может быть драйвер, не поддерживающий интерфейс NDIS. NDIS драйверы промежуточного уровня могут служить различным целям, включая фильтрацию и шифрование пакетов, реализацию специализированных протоколов и тому подобные функции.
Для драйвера протокола верхнего уровня промежуточный драйвер выглядит как драйвер виртуальной сетевой карты. Для драйвера реальной сетевой карты — как драйвер протокола. Промежуточные драйверы могут выстраиваться в цепочку, хотя такое расположение может оказывать негативное влияние на производительность системы. Типичный случай разработки и применения промежуточного драйвера - чтобы выполнять преобразование пакетов для среды передачи, неизвестной драйверу транспорта, но поддерживаемой драйвером сетевой карты. Например, может осуществляться преобразование между протоколом локальной сети и ATM протоколом.
NDIS драйвер промежуточного уровня обычно экспортирует MiniportXxx функции на своем верхнем уровне и ProtocolXxx функции на своем нижнем уровне. Реже промежуточный драйвер может экспортировать MiniportXxx функции на своем верхнем уровне, а в своей нижней части предоставлять закрытый интерфейс посредством использования пакетов IRP, нижнему драйверу, не являющемуся NDIS драйвером. Например, промежуточный драйвер может управлять сетевыми запросами ввода/вывода для устройства, соединенного с последовательным портом.
Драйверы протоколов верхнего уровня
Драйверы протоколов верхнего уровня
Драйвер протокола верхнего уровня в своей верхней части предоставляет TDI-интерфейс или, возможно, другой интерфейс, необходимый пользователям сети. Подобные драйверы выделяют ресурсы для пакетов, копируют данные приложения в пакеты и передают их драйверам более низкого уровня посредством вызова NDIS. В своей нижней части этот тип драйверов обеспечивает интерфейс для получения пакетов от нижележащего драйвера и передает полученные данные TDI-клиенту или приложению, для которого они предназначены.
К драйверам протоколов верхнего уровня относится и драйвер транспорта, реализующий стек сетевых протоколов, такой как IPX/SPX или TCP/IP. Транспортный драйвер Windows NT реализует TDI-интерфейс в своей верхней части и использует NDIS библиотеку для взаимодействия с драйверами сетевых карт в своей нижней части.
Драйверы сетевых карт
Драйверы сетевых карт
NDIS LAN Miniport NIC драйверы поддерживают сетевые карты локальных сетей. NDIS WAN Miniport NIC драйверы имеют дополнительные требования и предоставляют приложениям доступ к глобальным сетям, таким как, ISDN, Frame Relay, Switched 56.
Драйверы сетевых карт в своей нижней части взаимодействуют с оборудованием, а в верхней части предоставляют интерфейс, позволяющий верхним уровням посылать пакеты в сеть, сбрасывать и останавливать сетевую карту, а также осуществлять опрос и установку параметров драйвера сетевой карты.
Существует два типа NDIS драйверов сетевых карт:
Miniport NIC драйвер выполняет специфичные для конкретной сетевой карты операции, включая отправление и получение данных. Операции общие для всех драйверов сетевых карт, такие как синхронизация, обычно обеспечиваются NDIS. Miniport драйвер не вызывает напрямую обслуживание операционной системы, он взаимодействует с операционной системой через NDIS.
Full NIC legasy драйверы в настоящее время устарели и используются для совместимости, они выполняют одновременно специфичные для сетевой карты операции, а также всю работу по синхронизации, обслуживанию очередей, обычно выполняемые NDIS. Full NIC драйвер, например, поддерживает свою собственную информацию о привязках к вышележащим драйверам для индикации полученных данных. Miniport драйвер, напротив, не хранит информацию о привязках, он просто передает пакеты наверх интерфейсу NDIS, а тот уже гарантирует, что пакеты будут переданы соответствующим драйверам протоколов.
Поставщики ISDN, Switched 56, Х.25 и т.п. должны поставлять драйверы сетевых карт для своих адаптеров. Драйверы сетевых карт глобальных сетей взаимодействуют с драйвером ndiswan.sys посредством использования библиотеки NDIS. Драйвер ndiswan.sys обеспечивает наиболее общие сервисы, такие как сжатие данных, зашифрование, простое РРР форматирование. Драйверы сетевых карт глобальных сетей должны реализовывать только специфические черты конкретной среды передачи. Если драйвер сетевой карты глобальной сети управляет сетевой картой, которая сама реализует сжатие, РРР-форматирование и шифрование, то он может указать на это во время своей инициализации драйверу ndiswan.sys, чтобы тот не выполнял эти операции.
Ndiswan.sys привязывается к одному или нескольким драйверам сетевых карт глобальных сетей, и один или несколько драйверов протоколов привязываются к ndiswan.sys. Драйверы протоколов имеют по одной привязке к драйверу ndiswan.sys, даже если они передают данные через адаптеры разных глобальных сетей. Это экономит память и упрощает реализацию драйвера сетевой карты глобальной сети. А также упрощает драйверы протоколов, так как они должны реализовывать только одну связь с глобальной сетью. С точки зрения драйвера сетевой карты глобальной сети у каждого адаптера имеется только одна привязка к вышележащим драйверам протоколов, даже если несколько драйверов протоколов передают данные через этот адаптер.
В Windows NT есть встроенный асинхронный WAN miniport NIC драйвер, использующий драйвер последовательного порта для связи по модему.
Сетевая архитектура Windows NT
Глава 3. Сетевая архитектура Windows NT
Сетевые программные компоненты ОС Windows NT
Интерфейс TDI и транспортные протоколы
Среда NDIS и NDIS драйверы
Интерфейс DLC (Data Link Control)
Интерфейс DLC (Data Link Control)
В Windows NT приложения могут использовать интерфейс DLC, обращаясь к библиотеке dlcapi.dll. Интерфейс DLC - это немаршрутизируемый протокол, используемый для взаимодействия между компьютером с ОС Windows и мейнфреймами IBM или принтерами, присоединенными непосредственно к сети.
Интерфейс DLC представляет собой множество команд, которые сохраняются в структуре ССВ (Command Control Block) и передаются драйверу транспорта DLC. (Драйвер транспорта DLC в своей верхней части не предоставляет TDI-интерфейс.)
Интерфейс TDI
Интерфейс TDI
Windows NT предоставляет для взаимосвязи между транспортными драйверами и TDI-клиентами уровня ядра, такими как эмуляторы сетевых интерфейсов, редиректоры, серверы, единый программный интерфейс, называемый интерфейсом транспортных драйверов (Transport Driver Interface, TDI).
Изначально этот интерфейс планировалось использовать в пользовательском режиме работы ОС. В окончательном варианте интерфейс стал работать в режиме ядра, однако все еще может быть использован напрямую из пользовательского уровня. TDI предоставляется верхней частью любого транспортного стека протоколов Windows NT. TDI обеспечивает независимость TDI-клиентов от используемых ими транспортов. TDI поддерживает передачу как с установлением постоянного сеанса (виртуальная цепь), так и без него (датаграммы).
Требование, чтобы все драйверы транспорта предоставляли единый общий интерфейс TDI, облегчает задачу их разработки, а также разработки TDI-клиентов, потому что только этот интерфейс необходимо запрограммировать.
Так как TDI является относительно новым сетевым интерфейсом, и большинство приложений разработаны для использования других существующих стандартных интерфейсов, таких как NetBIOS и WinSockets, то Windows NT включает эмуляторы для этих двух популярных интерфейсов. Части уровня ядра этих эмуляторов, являющиеся драйверами файловых систем, отображают родные функции с соответствующими параметрами в одну или несколько TDI-функций, а затем вызывают соответствующие драйверы транспортов через TDI.
Интерфейс TDI включает следующее:
1. Множество стандартных диспетчерских точек входа, обеспечиваемых транспортным драйвером, к которому TDI-клиент может обратиться с запросом ввода/вывода.
2. Множество процедур обратного вызова, экспортируемых любым TDI-клиентом и регистрируемых транспортным драйвером, для получения TDI-клиентом уведомления о произошедшем сетевом событии.
3. Параметры, структуры, lOCTLs и правила, ассоциированные с процедурами транспорта и его клиента.
4. Множество функций вида TdiXxx, которые транспорт и его клиент могут вызывать для взаимодействия друг с другом.
5. Множество макросов и функций вида TdiBuildXxx, которые TDI-клиент может использовать, чтобы обеспечить принятие запросов нижележащим транспортом.
Программная модель TDI очень похожа на модель Winsocket. TDI-клиенты реализуют следующие шаги для установления соединения с удаленным сервером:
1. TDI-клиент формирует пакет TDIIRP типа address open для размещения адреса. TDI-транспорт возвращает файловый объект, известный как объект-адрес, представляющий адрес. Этот шаг эквивалентен использованию функции bind в Winsocket.
2. TDI-клиент размещает и формирует пакет TDI IRP типа connection open, и TDI-транспорт возвращает файловый объект, известный как объект-соединение, представляющий соединение. Этот шаг эквивалентен использованию функции socket в Winsocket.
3. TDI-клиент ассоциирует объект-соединение с объектом-адресом с помощью пакета TDI IRP типа associate address.
4. TDI-клиент, принимающий удаленное соединение, выпускает TDI IRP пакет типа listen, определяющий число соединений, поддерживаемых для объекта-соединения, и затем выпускает пакет TDI IRP типа accept, который завершается, когда удаленная система установит соединение. Эта операция эквивалентна использованию функций listen и accept в Winsocket.
5. TDI-клиент, который хочет установить соединение с удаленным сервером, выпускает TDI IRP пакет типа connect, определяя объект-соединение, который TDI-транспорт завершает, когда установится соединение. Выпуск TDI IRP пакета типа connect эквивалентно использованию функции connect в Winsocket.
Маршрутизатор многосетевого доступа
Маршрутизатор многосетевого доступа
Так как в систему могут быть загружены дополнительные редиректоры для доступа к сетям других типов, то существует компонент, который решает, какой редиректор вызвать для обработки запроса на удаленный ввод/вывод.
Маршрутизатор многосетевого доступа (Multiple Provider Router, MPR) - это библиотека DLL, предоставляющая приложениям интерфейс API WNet, и определяющая к какой сети следует обратиться, когда приложение использует этот интерфейс для просмотра удаленной файловой системы. Когда приложение вызывает некоторою функцию WNet, этот вызов попадает непосредственно в DLL маршрутизатора многосетевого доступа, который принимает вызов и определяет, через какой из компонентов сетевого доступа (сетевых провайдеров) можно осуществить доступ к данному ресурсу. MPR позволяет приложениям взаимодействовать стандартным образом с несколькими редиректорами, установленными в системе.
Компонент сетевого доступа (сетевой провайдер) является программным модулем (DLL), разработанным для работы в тесной кооперации с сетевым редиректором. Провайдер - это как бы надстройка над редиректором в виде DLL, которая позволяет компьютеру взаимодействовать с конкретной сетью. В состав программного обеспечения Windows NT входят: провайдер для сетей на базе Windows NT, провайдер шлюза (и клиента) для NetWare.
Компонент сетевого доступа позволяет Windows NT выступать в качестве клиента некоторого удаленного сервера. Среди операций, выполняемых, например, встроенным компонентом сетевого доступа WNet, можно назвать установление и разрыв сетевого соединения, удаленную печать и передачу данных по сети. Кроме DLL встроенного компонента сетевого доступа и встроенного редиректора в этих операциях принимает непосредственное участие сервис рабочей станции. От других изготовителей сетей требуется предоставить только DLL и редиректор.
MPR определяет два множества функций. Одно множество - независящий от сети интерфейс API WNet, предоставляемый MPR всем Win32 приложениям, желающим использовать сервисы сетевых редиректоров (посредством сетевых провайдеров). Этот интерфейс позволяет сетевым приложениям запрашивать в стандартной форме выполнения редиректором некоторой общей функциональности, без необходимости разработки специфичного кода для этого редиректора. Другое множество - интерфейс сетевого доступа, предоставляемый всеми сетевыми провайдерами маршрутизатору многосетевого доступа.
Многосетевой UNC
Многосетевой UNC
Это еще один компонент, который решает, какой редиректор вызвать для обработки запроса на удаленный ввод/вывод, если в систему загружены дополнительные редиректоры для доступа к сетям других типов.
Многосетевой UNC (Multiple UNC Provider, MUP) - драйвер, определяющий, к какой сети следует обратиться, когда приложение использует стандартный Win32 API ввода/вывода для открытия удаленных файлов. Этот сетевой компонент обрабатывает запросы к файлам или устройствам, содержащим имя UNC (это имя, начинающееся с символов \\, которые указывают, что данный ресурс находится в сети). Драйвер mup.sys, подобно MPR, определяет, какой локальный редиректор распознает удаленный ресурс.
Драйвер mup.sys активизируется, когда приложение пытается открыть удаленный файл или устройство, задавая имя UNC. Получив подобный запрос, подсистема Win32 заменяет символы \\ строкой \DosDevices\UNC и передает запрос исполнительной системе. Объект \DosDevices\UNC является символической связью на объект-устройство \Device\mup, создаваемый драйвером mup.sys. Драйвер mup.sys является довольно простым драйвером и реализует процедуры распределения create/ open. После получения запроса на открытие, драйвер mup.sys посылает особые контрольные пакеты каждому редиректору, зарегистрированному драйвером mup.sys. Этим запросом mup.sys спрашивает редиректор, может ли тот распознать оставшуюся часть имени UNC. Если да, то редиректор должен информировать драйвер mup.sys о числе символов в строке имени UNC, которые он распознает как уникальный идентификатор удаленного ресурса. Драйвер mup.sys кэширует эту часть строки имени, и в последствии посылает имена, начинающиеся с данной подстроки сразу этому редиректору.
Для того чтобы редиректор мог взаимодействовать с драйвером mup.sys, редиректор должен зарегистрировать себя для драйвера mup.sys во время инициализации, и в дальнейшем отвечать на запросы о распознавании имени, выдаваемые драйвером mup.sys. Редиректор, который первым зарегистрировал себя для драйвера mup.sys, имеет больший приоритет. Этот приоритет определяет, какой редиректор будет обрабатывать запрос, в том случае, если более одного редиректора распознает имя удаленного ресурса.
После того, как какой-нибудь редиректор распознает имя удаленного ресурса, mup.sys подставляет в начало строки имени удаленного ресурса имя объекта-устройства редиректора и помещает эту строку в файловый объект, соответствующий этому
ресурсу. С этого момента, запросы к этому удаленному ресурсу идут к редиректору напрямую, и mup.sys больше не вовлекается.
Обобщенная схема сетевой архитектуры Windows NT
Обобщенная схема сетевой архитектуры Windows NT
Промежуточные драйверы ndistapi.sys и ndiswan.sys
Промежуточные драйверы ndistapi.sys и ndiswan.sys
Часть интерфейса TAPI располагается в режиме ядра и реализуется драйвером ndistapi.sys, который взаимодействует с драйвером ndiswan.sys. Драйвер ndiswan.sys -NDIS драйвер промежуточного уровня, обеспечивающий РРР форматирование, аутентификацию, сжатие и шифрование для драйверов сетевых карт глобальных сетей. Он преобразует пакет формата NDIS_PACKET, получаемый от драйвера транспорта, в пакет формата NDIS_WAN_PACKET, и передает этот переформатированный пакет нижележащим драйверам сетевых карт глобальных сетей.
Ndiswan.sys предоставляет интерфейс стандарта 802.3 верхним драйверам протоколов и выступает в роли драйвера протокола для нижележащих драйверов сетевых карт глобальных сетей. Ndiswan.sys имеет закрытый интерфейс с драйвером ndistapi.sys для динамической установки и обрыва TAPI связей.
Ndiswan.sys преобразует формат отправляемого пакета из LAN в РРР. Большая часть разбивки фреймов, специфичной для среды передачи, должна выполняться в драйвере сетевой карты глобальной сети.
Протокол SNMP (Simple Network Management Protocol)
Протокол SNMP (Simple Network Management Protocol)
Cтандартный протокол Internet для обмена управляющей информацией между консолями управления, такими как HP Openview, Novell NMS, IBM NetView, Sun Net Manager, и набором управляемых устройств, такими как маршрутизаторы, мосты, концентраторы.
SNMP использует распределенную архитектуру, состоящую из менеджеров (консолей управления) и агентов. SNMP-агентами являются приложения, отвечающие за отслеживание и передачу информации об устройстве по запросу SNMP-диспетчера, а также за обновление локальной управляющей информации на основе сообщений, переданных от SNMP-диспетчера. Агент также оповещает зарегистрированных менеджеров о происхождении значительных событий или особых ситуаций. SNMP-диспетчер - это приложение, генерирующее запросы на получение и установку параметров к SNMP-агенту, и получающее оповещения от SNMP-агентов.
В ОС Windows NT SNMP-агент реализован в SNMP-сервисе snmp.exe. Это главный агент, получающий SNMP-запросы и передающий их соответствующей библиотеке DLL расширения агента (extension agent DLL). В Windows NT имеется множество DLLs, расширяющих возможности главного SNMP-агента, например: 1) dhcpmib.dll - DLL расширения агента, реализующая DHCP MIB и инсталлируемая только на DHCP серверах; 2) hostmib.dll - DLL расширения агента, реализующая MIB ресурсов хоста; 3) inetmibl.dll - DLL расширения агента, реализующая MIB-II; 4) Immib2.dll - DLL расширения агента, реализующая LAN Manager MIB-II; 5) winsmib.dll - DLL расширения агента, реализующая WINS MIB, инсталлируемая только на WINS серверах.
Management Information Base (MIB) описывает множество управляемых объектов, имеющих уникальные идентификаторы. SNMP-диспетчер может манипулировать объектами в требуемой базе MIB на определенном компьютере, если на этом компьютере главный SNMP-агент имеет библиотеку DLL расширения агента, поддерживающую требуемую MIB.
DLLs расширения агента для MIB-II, LAN Manager MIB-II и Host Resources MIB инсталлируются вместе с сервисом SNMP (главным агентом). DLLs расширения агента для других MIBs инсталлируются при инсталляции соответствующих им сервисов. Во время запуска некоторого сервиса, SNMP-агент загружает все соответствующие этому сервису DLLs расширения агента, перечисленные в реестре Windows NT.
SNMP-диспетчер обычно является консольным приложением третьих производителей. Windows NT включает библиотеки, поддерживающие SNMP-менеджеров. Консоль управления формирует SNMP-сообщение, используя библиотеки mgmtapi.dll (Microsoft SNMP Management API DLL), wsnmp32.dll (Microsoft WinSNMP Manager API DLL), snmpapi.dll (SNMP Utility Library). Библиотека функций SNMP - snmpapi.dll
используется как консолями управления, так и библиотеками расширения агента. Snmptrap.exe - сервис, получающий SNMP-ловушки и передающий их SNMP-диспет-черу, а snmpcfg.exe - сервис SNMP-конфигурирования. Программные компоненты, отвечающие за передачу SNMP сообщений, используют интерфейс API Windows Sockets.
Распределенная файловая система (Distributed File System, DFS)
Распределенная файловая система (Distributed File System, DFS)
В случае сетевых файловых систем, несмотря на то, что весь механизм транспо] тировки данных скрыт от пользователя файловой системы, он все равно знает, каю данные хранятся локально, а какие были получены с удаленного серверного узла. Ра пределенные файловые системы предлагают единое глобальное пространство им< файлов для пользователя и полностью скрывают действительное физическое распол жение файлов от пользователя файловой системы. DFS является сервисом, которь располагается выше сервиса рабочей станции, чтобы соединить вместе разделяем) файлы в одно пространство имен.
Распределенные файловые системы имеют сходную архитектуру с сетевыми файловыми системами. Они также имеют клиентскую часть, исполняемую на клиентском узле, и серверную часть, исполняемую на удаленном узле. Клиентская и серверная части могут одновременно исполняться на любом узле, участвующем в реализации распределенной файловой системы.
Корень пространства имен DFS должен быть разделяемым файлом, определенном на Windows 2000 Server. Серверная часть реализации DFS состоит из Win32-cepBHca и драйвера Dfs.sys. DFS-сервис отвечает за экспортирование интерфейса управления DFS-топологией и за поддержание DFS-топологии либо в реестре, либо в Active Directory. Получив запрос от клиента, DFS-драйвер выполняет просмотр топологии и направляет клиента в систему, где находится запрашиваемый им файл.
Редиректор
Редиректор
Сетевой редиректор является компонентом уровня ядра, предоставляющий ин-терфейс файловой системы локальным пользователям, для этого он принимает запросы ввода/вывода для удаленных файлов и устройств, пересылает их сетевому серверу на удаленном узле, получает данные с удаленного компьютера и предоставляет их локальному пользователю. Реализован в виде драйвера файловой системы.
Сетевой редиректор использует для взаимодействия с сервером протокол 8MB (протокол прикладного уровня, унаследованный от MS-NET), и поэтому он может работать с существующими серверами MS-NET и LAN Manager, обеспечивая Windows NT доступ к системам MS-DOS, Windows и OS/2. Но для обмена данными между системами Windows NT, базовый протокол 8MB был расширен, чтобы поддерживать распространенные операции ввода/вывода NT.
Редиректор вызывает интерфейс драйвера транспорта TDI для передачи пакета 8MB различным транспортным драйверам. Редиректор должен открыть для связи с удаленной машиной канал, называемый виртуальным контуром, и затем послать пакет 8MB через этот контур. Редиректор поддерживает по одному виртуальному контуру для каждого сетевого сервера, с которым связана операционная система
Windows NT, и мультиплексирует все запросы к данному серверу в один контур. Встроенный редиректор Windows NT может сосуществовать с редиректорами других сетей.
Встроенный редиректор и другие редиректоры создают объект-устройство в пространстве имен диспетчера объектов во время своей загрузки и инициализации. Когда WNet или другой API обращается к диспетчеру объектов для открытия ресурса, расположенного в сети, диспетчер объектов, пройдя по дереву объектов и, обнаружив объект-устройство редиректора (точку входа в удаленную файловую систему), вызывает метод разбора диспетчера ввода/вывода, который передает оставшуюся часть имени ресурса соответствующему редиректору, который и находит удаленный ресурс.
Соответствие сетевой архитектуры ОС Windows NT модели OSI
Рисунок .17. Соответствие сетевой архитектуры ОС Windows NT модели OSI
![](image/17.gif)
Задача каждого уровня состоит в том, чтобы предоставить обслуживание верхним уровням, абстрагируясь от того, как реализовано это обслуживание на нижних уровнях. Далее приводится краткое описание этих уровней:
1. Физический уровень. Физический уровень является самым нижним уровнем в модели OSI. Задачи этого уровня связаны с отправкой и получением неструктурированного потока бит по физической среде передачи. Он характеризует электрический/ оптический, механический и функциональный интерфейс к физической среде. В Windows NT физический уровень реализуется сетевой картой, ее трансивером, и средой передачи данных, к которой она присоединена. Для сетевых компонентов, которые используют последовательный порт, физический уровень может также включать низкоуровневое сетевое программное обеспечение, которое определяет, как поток последовательных бит делится на пакеты данных.
2. Канальный уровень. Пересылает низкоуровневые кадры данных, ожидает подтверждения их получения и повторяет передачу потерянных кадров.
В официальной терминологии модели OSI группа бит, посылаемая канальным уровнем, называется physical layer service data unit (единица данных, обслуживаемая физическим уровнем), на практике эту группу бит называют фреймом.
Канальный уровень делится на два подуровня: подуровень управления логической связью (Logical Link Control, LLC) и подуровень управления доступом к среде (Media Access Control, MAC). LLC управляет взаимодействием с верхним сетевым уровнем и обеспечивает безошибочную передачу фреймов от одного узла к другому. Этот уровень отвечает за установление и завершение логической связи, контроль последовательности фреймов, подтверждение приема фрейма и повтор передачи неподтвержденных фреймов. В сетевой архитектуре Windows NT функции подуровня LLC реализуются в транспортных драйверах (transport driver).
MAC подуровень управляет доступом к среде передачи, проверяет ошибки во фреймах, распознает адреса полученных фреймов. Подуровень MAC обеспечивает стандартные интерфейсы для сетей Ethernet (со случайным коллективным доступом с контролем несущей и обнаружением конфликтов, Carrier Sense Multiple Access with Collision Detection, CSMA/CD), для сетей, где используется передача маркера на общей шине (ArcNet) и в кольце (Token Ring). В сетевой архитектуре Windows NT функции подуровня MAC реализуются в сетевой карте.
3. Сетевой уровень. Сетевой уровень контролирует операции подсети. Он решает, какой физический путь должны пройти данные в зависимости от условий передачи, приоритетов сервиса и других факторов. Он отвечает за маршрутизацию, контроль интенсивности трафика, фрагментацию пакетов, распознавание адресов и межсетевой обмен. Это самый низкий из уровней, понимающих топологию сети, то есть физическую конфигурацию машин в ней, тип физических соединений между ними и ограничения пропускной способности, длины используемых кабелей и т.д. .
Сетевой уровень имеет дело с пакетами, которые могут быть меньше или больше чем фрейм. Если пакет больше, чем фрейм, то сетевой уровень разбивает его на несколько фреймов, и собирает их при получении. Если пакет меньше фрейма, то сетевой уровень объединяет несколько пакетов во фрейм, и разбивает этот фрейм на пакеты при получении.
В модели Windows NT сетевой и транспортный уровни реализуются в транспортных драйверах, иначе называемых драйверами протоколов верхнего уровня (protocol driver). Windows NT поставляется со следующими транспортными драйверами: TCP/ IP, IPX/SPX, NetBEUI, AppleTalk и DLC.
4. Транспортный уровень. Транспортный уровень имеет дело с сообщениями, которые могут быть больше или меньше, чем пакеты. Транспортный уровень гарантирует безошибочную доставку сообщений, в нужной последовательности, без потерь и повторов.
Если стек протоколов не включает подуровень LLC, и если сетевой уровень ненадежный и поддерживает передачу дейтаграмм (например, уровень IP в стеке TCP/IP или IPX в NWLink), то транспортный уровень должен включать контроль последовательности пакетов и их подтверждение, а также повторную передачу неподтвержденных пакетов. Другой пример: так как транспортный драйвер протокола NetBEUI включает функции подуровня LLC, то ему необходимо реализовать лишь минимум функций транспортного уровня.
5. Сеансовый уровень. Управляет соединением между взаимодействующими приложениями на разных компьютерах, включая синхронизацию высокого уровня, и контроль за тем, какое из приложений «говорит», а какое «слушает». Он знает имена компьютеров в сети.
Интерфейсы NetBIOS и WinSockets являются примерами типичного программно2 го обеспечения сеансового уровня.
6. Уровень представления. Предоставляет сервисы, используемые приложениями, такие как шифрование, сжатие, или преобразование символов (PC ASCII в EBCDIC). Отвечает за форматирование данных, в том числе решает, должны ли строки заканчиваться парой символов «возврат каретки/перевод строки» (CR/LF) или только символом «возврат каретки» (CR).
Примером программного модуля, реализующего уровень представления, является XDR (External Data Representation) под управлением средства удаленного вызова процедур RPC (Remote Procedure Call).
7. Прикладной уровень. Обрабатывает передачу данных между двумя сетевыми приложениями, включая проверку прав доступа, идентификацию взаимодействующих машин и инициирование передачи данных.
Прикладной уровень обрабатывает запросы от приложений, например, обращение к базе данных или доставку почты. Этот уровень доступен приложениям напрямую. RPC является примером реализации прикладного уровня. Множество известных протоколов объединяют прикладной уровень и уровень представления, например: именованные каналы и FTP (File Transfer Protocol). Клиенты используют именованные каналы, например, для взаимодействия с Microsoft SQL Server.
Интерфейс NetBIOS
Рисунок . 18. Интерфейс NetBIOS
![](image/18.gif)
Интерфейс именованных каналов и почтовых ящиков
Рисунок . 19. Интерфейс именованных каналов и почтовых ящиков
![](image/19.gif)
Позже мы обсудим, как драйвер файловой системы редиректора вовлекается, когда разрешаются имена, определяющие именованные каналы и почтовые ящики на удаленной системе. Однако, когда именованные каналы и почтовые ящики создаются сервером, или открываются клиентом, вовлекается соответствующий драйвер файловой системы на машине, где располагается именованный канал или почтовый ящик.
Обработка запроса к локальному именованному каналу или прием запроса к нему от удаленного компьютера выполняется файловой системой именованных каналов. Если же запрос к именованному каналу происходит по имени UNC, то обработка выполняется так же, как и для других запросов к удаленным файлам: запрос перехватывается драйвером mup.sys и направляется соответствующему редиректору.
Интерфейс WinSockets
Рисунок . 20. Интерфейс WinSockets
![](image/20.gif)
Провайдер сетевого транспорта Msafddll использует сервисы драйвера файловой системы AFD.sys (Ancillary Function driver, AFD) для реализации функций сокетов. AFD является TDI-клиентом и исполняет сетевые операции с сокетами, такие как посылка и получение сообщений, путем отправки запросов TDI IRP драйверам протоко-
лов. AFD не запрограммирован для использования определенных драйверов протоколов, поэтому Msafd.dll информирует AFD об имени протокола, используемого определенным сокетом, так чтобы AFD мог открыть объект-устройство, представляющее этот протокол.
Интерфейс RPC
Рисунок . 21. Интерфейс RPC
![](image/21.gif)
Для регистрации и поиска имен RPC-приложещя связываются с клиентской библиотекой сервиса имен RPC - rpcns4.dll. Эта DLL взаимодействует с подсистемой
RPCSS (RPCSS.exe для WinNT, RPCSS.dll для Win2000), стартующей автоматически при загрузке ОС, и реализованной как Win32-сервис. Сервис Rpcss сам является RFC-приложением, которое взаимодействует с такими же приложениями на других системах для выполнения поиска имен и регистрации.
Сервис Rpcss реализует некоторые RPC и OLE сервисы, включая динамическое назначение и разрешение адреса серверного процесса и разрешение DCOM-объектов (Distributed Component Object Model). Также при загрузке ОС автоматически стартует и исполняется в собственном процессе сервис locator.exe — провайдер сервиса имен для RPC. Сервис имен - сервис, отображающий имена в объекты и хранящий пары имя/объект в базе данных. Например, сервис имен RPC locator.exe отображает логические имена в описатели соединений (структуры данных, представляющие логические соединения между клиентом и сервером), чтобы клиентское приложение могло обращаться по этому логическому имени, а не использовать последовательность протоколов и сетевые адреса.
Библиотека RPC периода выполнения использует для взаимодействия с транспортным протоколом единый интерфейс доступа к транспорту RPC (RPC transport provider interface). Этот интерфейс служит прослойкой между средством RPC и транспортом и предоставляется различными библиотеками. Например:
1. rpcltcl.dll - библиотека клиентского приложения, предоставляющая транспорт именованных каналов;
2. rpcltsl.dll - библиотека серверного приложения, предоставляющая транспорт именованных каналов;
3. rpcltc3.dll - библиотека клиентского приложения, предоставляющая транспорт TCP/IP;
4. rpclts3.dll - библиотека серверного приложения, предоставляющая транспорт TCP/IP.
Существуют и другие библиотеки для серверных и клиентских приложений, предоставляющие транспорты NetBIOS, Winsock и т.д.
Средство RPC может работать поверх большого количества транспортов, однако при работе по сети LAN Manager средство RPC использует в качестве сетевого транспорта именованные каналы.
Большинство сетевых сервисов Windows NT являются RPC-приложениями, и могут вызываться как локальными процессами, так и процессами на удаленных машинах.
Приложения могут, либо использовать
Рисунок . 22
![](image/22.gif)
Приложения могут, либо использовать протокол DDE (подключая библиотеку nddeapi.dll), являющийся множеством правил передачи определенных DDE-сообщений, либо могут использовать библиотеку ddeml.dll. Ddeml.dll обеспечивает интерфейс, который облегчает задачу добавления возможностей динамического обмена данными \?1п32-приложениям. Вместо отправления, получения и обработки непосредственно DDE-сообщений по протоколу DDE-приложения используют функции, предоставляемые библиотекой ddeml.dll для управления DDE-взаимодействием между клиентским и серверным приложениями. Эта библиотека также делает возможным серверным приложениям регистрировать имена поддерживаемых ими сервисов. Приложения, использующие протокол DDE, основанный на передаче сообщений, полностью совместимы с приложениями, использующими ddeml.dll, но из-за большого числа преимуществ библиотеки ddeml.dll, новым приложениям предпочтительнее использовать эту библиотеку, чем передачу DDE-сообщений.
Во время загрузки компьютера автоматически запускается приложение nddeagntexe (Network DDE Agent), которое служит для обнаружения локальной DDE-активности, после чего, этот агент стартует приложения, необходимые для динамического обмена данными. DDE-взаимодейтствия контролируются посредством DDE-окна, ассоцииро-
ванного с одним из приложений, обеспечивающих DDE (clipsrv.exe, Windows NT DDE Server). Это приложение взаимодействует со всеми локальными и удаленными приложениями, использующими DDE.
Но Nddeagnt не может обнаружить попытку соединения удаленного клиента. Прежде чем удаленный клиент сможет успешно соединиться с серверным приложением, на серверном компьютере должен стартовать сервис netdde.exe. В качестве транспорта механизм DDE использует средство RPC с транспортом именованных каналов.
RAS
Рисунок . 23. RAS
![](image/23.gif)
В процесс rasman.exe для согласования с интерфейсом TAPI (Telephony Application Programming Interface) загружается библиотека rastapi.dll (Remote Access TAPI
Compliance Layer), которая и обращается к функциям интерфейса TAPI, предоставляемым библиотекой tapi32.dll (Microsoft Windows Telephony API Client DLL).
На удаленном серверном компьютере исполняется процесс RAS-сервера - rassrv.exe (Remote Access Server Supervisorfor). Windows NT обеспечивает поддержку администрирования RAS-сервера приложениями сторонних производителей посредством использования библиотеки rassapi.dll (Remote Access Admin APIs dll).
Сервисы удаленного доступа (Remote Access Services, RAS)
Сервисы удаленного доступа (Remote Access Services, RAS)
Сервер Windows NT поддерживает удаленный доступ (RAS) для создания временных соединений с системами, которые не находятся в локальной сети, обычно это соединения через телефонные линии. Сервер Windows NT включает встроенную поддержку для модемов, устройств Х.25 и ISDN модемов. Один сервер Windows NT может поддерживать одновременно до 255 удаленных соединений. Новый протокол РРТР (Point-to-Point Tunneling Protocol), заявленный в марте 1996, позволяет пользователям использовать «туннели» в любой сети на базе протокола TCP/IP для достижения своих защищенных сетей с удаленного компьютера.
Функции сервиса RAS позволяют приложениям устанавливать удаленные соединения. Удаленные соединения могут использовать протокол SLIP (Serial Line Internet Protocol), или, более предпочтительный протокол РРР (Point-to-Point Protocol). Сервисом RAS обеспечиваются протоколы РРР аутентификации (PAP, CHAP) и протоколы конфигурирования сети (IPCP, IPXCP, NBFCP, LCP). Когда РРР соединение уже установлено, приложения могут использовать стандартные сетевые интерфейсы, такие как Windows Sockets, NetBIOS, Named Pipes, RPC и взаимодействовать по протоколам: NetBEUI, TCP/IP или IPX/SPX, инкапсулированным в РРР. TCP/IP на основе РРР используется наиболее часто для связи мобильных пользователей с Intranet.
RAS-приложения на клиентском узле, реализующие удаленный доступ к серверному узлу, могут выполнять задачи по обеспечению RAS двумя способами. Первый способ основан на вызове функций, отображающих диалоговые окна сервиса RAS, обеспечиваемые системой для интерфейса с пользователем. Эти функции предоставляются библиотекой rasdlg.dll и позволяют приложениям легко отображать диалоговые окна, знакомые пользователю, чтобы тот мог выполнять RAS-задачи, такие как установление, завершение и наблюдение за удаленными соединениями, или работать с записной книжкой, содержащей телефонные номера.
Второй способ основан на использовании непосредственных функций дозвона, предоставляемых RAS-приложениям библиотекой rasapi32.dll (см. Рисунок 23). Клиентское приложение может использовать функцию RasDialQ для установления соединения с RAS-сервером. Функция RasDialQ начинает операцию соединения, которая затем будет выполняться программным компонентом, называемым менеджером удаленных соединений (Remote Access Connection Manager). Диспетчер удаленных соединений является сервисом пользовательского уровня, управляющим деталями установления соединения с удаленным сервером и разделяющим процесс (rasman.exe) с другим сервиcом - менеджером автодозвона (Remote Access Autodial Manager). Диспетчер удаленных соединений стартует автоматически, когда приложение загружает библиотеку rasapi32.dll.
Сетевая архитектура Windows NT
Сетевая архитектура Windows NT
Эта глава посвящена рассмотрению сетевой архитектуры ОС Windows NT. Рассматривается соответствие сетевой архитектуры модели OSI, описаны сетевые интерфейсы, сетевые компоненты, их предназначение и взаимосвязи. Обзор сетевой архитектуры позволит определить, через какие сетевые компоненты и в какой последовательности проходят данные приложений перед тем, как попасть в сеть.
Windows NT содержит механизмы динамической загрузки и выгрузки встроенной сетевой поддержки, те же самые механизмы могут использоваться для загрузки и выгрузки сетевого программного обеспечения других производителей. После инсталляции сетевое программное обеспечение становится неотъемлемой частью операционной системы, например, сетевые файловые системы, драйверы сетевых протоколов и драйверы сетевых устройств являются расширением подсистемы ввода/ вывода исполнительной системы. Таким образом, в Windows NT сетевое программное обеспечение может задействовать внутренние интерфейсы, предоставляемые компонентами исполнительной системы, ядром и HAL, тем самым, увеличивая свою производительность.
Дополнительная информация о встроенных сетевых компонентах может быть получена при непосредственном анализе реестра Windows NT, а точнее его ключа HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Services, где, помимо прочих сервисов ОС, хранится информация о сетевых компонентах: сетевых сервисах и сетевых драйверах. По значениям соответствующих подключей можно получить информацию о зависимостях между сетевыми компонентами и их привязках друг к другу. Также можно анализировались таблицы импорта и экспорта различных системных сетевых DLL и сетевых сервисов.
Сетевой сервер
Сетевой сервер
Этот компонент должен отвечать на удаленные запросы, полученные от редиректора на клиентской стороне, взаимодействуя с локальной файловой системой или принтером. Сетевой сервер реализован в виде драйвера: в одних источниках утверждается, что сервер является драйвером файловой системы (согласно реестру тип этого компонента также драйвер файловой системы), а в других - обычным драйвером.
Сетевой сервер обеспечивает совместимость с существующими протоколами 8MB MS-NET и LAN Manager, и обрабатывает запросы, приходящие не только от систем Windows NT, но также и от других систем, на которых работает программное обеспечение LAN Manager. Так как сервер находится в исполнительной системе, то он может непосредственно вызывать диспетчер кэша для оптимизации передачи данных. Если требуемых данных в кэше не оказывается, то сервер создает собственные пакеты зап роса ввода/вывода IRP и посылает их непосредственно драйверам локальных.файло вых систем NTFS, FAT и HPFS.
В 1996 году Microsoft представила на рассмотрение организации IETF специфика цию сетевого протокола Common Internet File System (CIFS) 1.0, являющимся последним расширением и улучшением протокола SMB.
Сетевые API
Сетевые API
Windows NT реализует несколько сетевых API для обеспечения поддержки сетевых приложений и совместимости с промышленными стандартами. Важно иметь в виду, что решение о том, какое API должно использовать приложение, зависит от характеристик API. Таких характеристик как, например, поддерживает ли API надежное или двунаправленное взаимодействие, над каким протоколом располагается API, переносимость API на другие Windows-платформы, на которых должно исполняться приложение. Итак, Windows NT предоставляет несколько способов получения доступа к сети, то есть несколько механизмов межпроцессных коммуникаций, часть которых описана ниже.
Сетевые API Win32 (Wnet и Net)
Сетевые API Win32 (Wnet и Net)
Windows NT обеспечивает множество независимых от сети WNet-функций, которые позволяют работать через провайдеров разных сетей.
Функции этого интерфейса полезны таким приложениям, как File Manager, которые выполняют соединение с удаленными файловыми системами и их просмотр. Функции WNet можно использовать для просмотра файловых систем Microsoft и других файловых систем по сетям LAN Manager, NetWare, VINES и т.д. Вызовы интерфейса API WNet, реализованного в виде DLL, проходят через сетевой компонент, называемый сервисом рабочей станции. Этот сервис - серверный процесс, похожий на защищенную подсистему. Сервис рабочей станции является, в сущности, надстройкой пользовательского режима для редиректора. Он поддерживает API WNet, предоставляет функции конфигурации редиректора и содержит код пользовательского режима для получения статистики редиректора. Когда приложение вызывает функции API WNet, этот вызов в начале поступает сервису рабочей станции, а затем уже к диспетчеру ввода/вывода и далее к редиректору.
Net-функции, предоставляемые сетевым интерфейсом Net, поддерживаются в «сетевой ОС» Microsoft LAN Manager, основанной на OS/2. В Windows NT большая часть сетевой функциональности является встроенной, поэтому некоторые из первоначальных Net-функций уже не поддерживаются. В Windows NT множество Net-функций, предоставляемых библиотекой netapi32.dll, дополняет встроенную сетевую функциональность, не обеспечиваемую другими сетевыми интерфейсами. Например, Net-функции позволяют приложениям взаимодействовать с сервисом рабочей станции, сервисом сервера, сервисом оповещений, сервисом передачи сообщений, репликатором и т.д.
Если существует базовая функция или WNet-функция, требуемая приложению, то лучше использовать ее, чем эквивалентную Net-функцию по двум причинам. Во-первых, WNet-функции являются независимыми от сети, в то время как Net-функции работают только в сетях Microsoft Windows. Во-вторых, некоторые из Net-функций могут быть замещены функциями базовых сетевых интерфейсов или WNet-функциями, и не поддерживаться в будущих версиях Windows NT.
Сетевые файловые системы
Сетевые файловые системы
Сетевые файловые системы позволяют пользователям разделять свои локальные диски с другими пользователями в локальной или глобальной сети. Любая сетевая файловая система состоит из двух компонентов: сетевого редиректора на клиентской стороне и сетевого сервера на узле с разделяемым диском.
Сетевые сервисы
Сетевые сервисы
Сетевые сервисы - это процессы, похожие на защищенные подсистемы. В отличие от защищенных подсистем, сетевые сервисы, имеющие собственные API, обычно используют RPC, а не LPC для обмена сообщениями со своими клиентами. Применение RPC делает сервисы доступными процессам, как на локальной, так и на удаленной машине. За загрузку и запуск сервисов отвечает компонент, называемый контроллером сервисов (service controller). Он также предоставляет средства загрузки и выгрузки драйверов. Примерами сетевых сервисов являются: 1) сервис рабочей станции (LanmanWorkstation), выполняющий администрирование встроенного редиректора; 2) сервис оповещений (alerter), выполняющий рассылку оповещений подключенным пользователям, например, при переполнении жесткого диска; 3) сервис сообщений (messager), выполняющий прием сообщений от других систем, например, уведомлений о том, что завершено выполнение задания на печать. '
Почти все сетевые сервисы, такие как сервис рабочей станции, сервис сервера (LanMan Server), сервис оповещений, сервис сообщений, обозреватель сети (Computer Browser), DHCP-клиент (DHCP client) содержатся в одном ЕХЕ-файле с именем services.exe. Остальные исполняются в собственных процессах, например, сервис WINS (Windows Internet Name Service) - это сервис динамической регистрации и разрешения имен, отображающий NetBIOS-имена компьютеров в IP-адреса. Сервис системы доменных имен DNS (Domain Name System), преобразующий DNS-имена в IP-адреса.
А также ранее упомянутые при рассмотрении сетевых API сервисы: rpcss.exe (RPC and Distribute СОМ сервисы), locator.exe (провайдер сервиса имен для RPC),
nddeagnt.exe (Network DDE агент), tapisrv.exe (сервер, обеспечивающий телефонные сервисы).
В Win2000 появился сервис репликации файлов (File Replication Service, FSR), главная задача которого состоит в репликации содержимого директории контроллера домена \SYSVOL, в которой контроллер домена хранит скрипты входа в домен и групповую политику. В дополнение FSR может быть использован для репликации разделяемых файлов распределенной файловой системы (Distributed File System) между системами. FSR реализован как Win32-cepBnc Ntfrs.exe, который использует RPC с аутентификацией и шифрованием для взаимодействия между своими же экземплярам, исполняющимися на других компьютерах.
Соответствие сетевой архитектуры Windows NT модели OSI
Соответствие сетевой архитектуры Windows NT модели OSI
Чтобы помочь производителям в стандартизации и интегрировании их сетевого программного обеспечения, Международная организация по стандартизации (ISO) определила программную модель пересылки сообщений между компьютерами - модель соединения открытых систем (Open System Interconnection reference model, OSI). В модели определены семь уровней программного обеспечения.
Сетевой запрос должен спуститься до самого нижнего уровня на клиентской машине, затем он передается по физическому носителю и вновь поднимается на серверной машине до уровня, который его поймет и обработает. Каждый уровень иерархии считает, что он общается с аналогичным уровнем на другой машине и использует некоторый стандартный протокол. Набор протоколов, в соответствии с которыми запрос проходит вниз по уровням и обратно, называется стеком протоколов.
На Рисунок 17 представлен общий вид сетевых компонентов Windows NT, а также их соответствие уровням модели OSI. Модель OSI далеко не всегда точно соответствует
коммерческим сетевым программным продуктам, реальные программные модули которых объединяют несколько уровней модели OSI или разбивают один уровень на несколько.
Среда NDIS
Среда NDIS
В 1989 г Microsoft и 3Com совместно разработали спецификацию интерфейса взаимодействия между подуровнем MAC канального уровня модели OSI и драйверами протоколов, располагающихся на вышележащих уровнях. Стандарт получил название Network Driver Interface Specification (NDIS - спецификация интерфейса сетевых драйверов). Он играет ключевую роль в сетевой архитектуре NT и служит для отделения логики работы драйвера сетевой карты от особенностей реализации различных сетевых протоколов.
С тех пор NDIS превратилась в целую семью сетевых стандартов, и сейчас эта семья включает стандарты для драйверов сетевых карт локальных и глобальных сетей (LAN NIC driver и WAN NIC driver), и стандарты для промежуточных драйверов (intermediate driver), располагающихся между драйверами протоколов и драйверами сетевых карт.
Вместо того чтобы писать несколько транспортно-зависимых драйверов, производители сетевого оборудования реализуют интерфейс NDIS на самом верхнем уровне одного драйвера сетевой карты. Это позволяет любому драйверу протокола работать с данной сетевой картой, вызывая функции этого интерфейса. Таким образом, пользователь может работать и по протоколу TCP/IP, и по протоколу NetBEUI, при помощи одной сетевой карты и одного драйвера этой сетевой карты.
Библиотека NDIS является драйвером, реализующим взаимодействие между компонентами, которые обращаются к ней, такими как: драйверы транспортов, NDIS драйверы промежуточного уровня, драйвер ndiswan.sys, драйвер ndistapi.sys, NDIS драйверы сетевых карт локальных и глобальных сетей. Интерфейс, реализуемый NDIS библиотекой, является «call and return» интерфейсом (асинхронным интерфейсом). Драйверы вызывают функции, расположенные в NDIS библиотеке, a NDIS библиотека может в свою очередь вызывать функции из других драйверов, чтобы выполнить операцию. Пакеты запроса ввода/вывода (IRP) не используются в NDIS спецификации.
Так как NDIS драйверы существуют в среде, созданной NDIS библиотекой, то структура и интерфейс, используемые этими драйверами, определяются NDIS библиотекой. Это позволяет NDIS драйверам быть переносимыми между различными операционными системами, поддерживающими данную спецификацию.
Цели NDIS библиотеки следующие:
Изолировать NDIS драйверы сетевых карт и промежуточные драйверы от операционной системы. NDIS библиотека экспортирует множество стандартных функций и макросов, которые скрывают детали операционной системы, и используются всеми NDIS драйверами. NDIS драйверы могут вызывать только те функции, которые обеспечивает NDIS библиотека. Например, создание таймера для целей синхронизации, или создание связанного списка осуществляется через NDIS. Требование к разработчикам применять вызовы NDIS функций позволяет сделать код переносимым между операционными системами фирмы Microsoft, которые поддерживают NDIS.
Выполнять как можно больше общих операций. Одной из основных целей NDIS библиотеки является исключение кодов общих функций из NDIS драйверов. Это означает, что большинству NDIS драйверов необходимо реализовать только небольшое число функций, необходимых для выполнения операций, специфических для оборудования. NDIS библиотека поддерживает информацию о статусе операции, указатели на функции интерфейсов верхнего и нижнего уровней, параметры этих функций, и многие другие системные значения для драйверов протоколов и драйверов сетевых карт.
Обеспечивать добавление заголовков к данным пользователя без необходимости их перекопирования, во время передачи данных по стеку сетевых драйверов. Во время перемещения сетевого сообщения по стеку драйверов сверху вниз, на каждом уровне к первоначальному сообщению может быть добавлен свой заголовок (реже хвост). NDIS спецификация делает возможным добавление подобных структур спереди или сзади без необходимости перекопирования первоначального сообщения. Эта возможность построения сетевого сообщения без перекопирований данных позволяет достигать высокой производительности при передаче данных.
NDIS-библиотека получает IRP-пакеты от TDI-транспортов и транслирует их в вызовы функций NDIS-драйверов. Для передачи данных между NDIS-драйверами пакеты IRP не используются. Вместо них используются, например, NDIS-пакеты, описанные в разделе «Особенности реализации NDIS-драйверов».
Среда STREAMS
Среда STREAMS
STREAMS, основанная на UNIX STREAMS, является средой для существующих STREAMS-совместимых транспортных драйверов, которая обеспечивает переносимость этим драйверам в ОС Windows NT из других ОС с незначительными модификациями или вовсе без изменений. Один или несколько драйверов, расположенных друг над другом, окружаются сверху и снизу средой Streams и формируют провайдера сетевого транспорта. Среда STREAMS обеспечивает:
Интерфейс TPI (Transport Provider Interface) - интерфейс верхней части транспортного стека. STREAMS транслирует этот интерфейс в «родной» интерфейс транспорта Windows NT - TDI.
Интерфейс DLPI (Data Link Provider Interface) - интерфейс нижней части транспортного стека. STREAMS транслирует этот интерфейс в «родной» для Windows NT интерфейс канального уровня - NDIS 3.0.
Дополнительные функции для облегчения переноса, включая функции использования таймера ОС UNIX.
Средство динамического обмена данными (Network Dynamic Data Exchange, NetDDE)
Средство динамического обмена данными (Network Dynamic Data Exchange, NetDDE)
Network DDE используется для установления и поддержания сетевых соединений, необходимых для динамического обмена данными между приложениями, выполняющимися на разных компьютерах в сети. Для реализации динамического обмена данными, приложениям необходимо использовать библиотеки nddeapi.dll (см. Рисунок 22) или ddeml.dll (DDE Management Library - библиотека управления динамическим обменом данными).
Средство удаленного вызова процедур (Remote Procedure Call, RFC)
Средство удаленного вызова процедур (Remote Procedure Call, RFC)
Средство удаленного вызова процедур позволяет создавать распределенные приложения, вызывающие функции, реализованные как локально, так и на удаленных компьютерах. RPC предоставляет модель работы с сетью, ориентированную на процедуры, а не на транспорты, что позволяет упростить разработку распределенных приложений. Библиотека RPC (rpcrt4.dll) и компилятор MIDL (Microsoft Interface Definition Language, MIDL - язык описания интерфейса фирмы Microsoft) позволяют программистам с легкостью создавать распределенные приложения.
Библиотека RPC периода выполнения включает процедуры для управления RPC по сети, а также разновидность RPC, называемою локальным RPC. Локальный RPG может быть использован для взаимодействия между двумя процессами, располагающимися на одной и той же машине, для этого библиотека RPC периода выполнения использует средство LPC в режиме ядра в качестве локального сетевого API. Когда RPC базируется на нелокальных механизмах взаимодействия, библиотека RPC использует такие интерфейсы как Winsock и именованные каналы (см. Рисунок 21).
Связь между сетевыми программными компонентами
Связь между сетевыми программными компонентами
В Windows NT различные сетевые программные компоненты связаны в определенной логической иерархии. Например, каждый драйвер транспорта может быть связан с одним или более сетевым адаптером через соответствующие драйверы сетевых карт. Сетевые компоненты более высокого уровня, такие как редиректор, могут быть связаны с одним или несколькими драйверами транспорта.
При установке сетевых компонентов информация о них записывается в реестр Windows NT, который описывает порядок, в котором сетевые компоненты должны загружаться, и как они должны быть связаны друг с другом. Приложением, которое управляет установкой и связыванием сетевых компонентов, является Network Control Panel Application (NCPA).
При установке сетевого компонента NCPA ищет специальный файл с расширением .inf в разделе, определенном пользователем. Если устанавливаемый сетевой драйвер не поставляется вместе с Windows NT, то разработчик этого драйвера должен поставлять файл oemsetup.inf, содержащий сценарий и правила установки драйвера.
После компиляции и исполнения .inf файла NCPA проводит анализ того, как данная сетевая компонента должна быть связана с другими компонентами, используя правила RawRules и NetRules. RawRules - правила по умолчанию, определяемые системой, и хранимые в реестре в ключе HKEY_LOCAL_ MACHINE \ SOFTWARE \ Microsoft \ Ncpa \ CurrentVersion \ RawRules. Правила NetRules - правила, определяемые разработчиками, и специфичные для данной компоненты, они содержатся в только что созданном при установке сетевой компоненты ключе HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ <имя сетевой компоненты> \ CurrentVersion \ NetRules.
В конце этого процесса NCPA создаст (или обновит) ключ HKEY_LOCAL_ MACHINE \ SYSTEM \ CurrentControlSet \ Services \ <имя сетевой компоненты^ \ Linkage.
NCPA включает следующие поля в этот ключ:
Bind. Список имен устройств сетевых компонент, с которыми данная сетевая компонента будет связана.
Export. Список имен объектов-устройств, которые будут добавлены в пространство имен объектов Windows NT, чтобы сделать возможным доступ к этой компоненте. Этот список содержит по одному имени объекта-устройства для каждой компоненты, с которой данная компонента будет связана внизу.
Route. Содержит список строк, где каждая строка показывает точный путь в стеке сетевых компонент.
После того как NCPA создаст все возможные связи, пользователь может, используя диалоговое окно Bindings в NCPA, Посмотреть результирующие привязки и, если
необходимо, блокировать (или разрешить) некоторые привязки. Это вызовет удаление (или восстановление) соответствующих значений в поле Bind подключа Linkage выбранной сетевой компоненты.
При загрузке ОС контроллер сервисов использует информацию в реестре для загрузки сетевых компонентов согласно иерархии связей. Во время инициализации сетевой компонент может определить, к каким компонентам более низкого уровня ему нужно привязаться, прочитав из ключа реестра Linkage значения поля Bind.
TAPI (Telephony Application Programming Interface)
TAPI (Telephony Application Programming Interface)
Интерфейс TAPI - множество функций, позволяющих запрограммировать устройства, передающие данные по телефонным линиям, не зависящим от конкретного устройства образом, предоставляя пользователям возможность взаимодействия по телефону. TAPI поддерживает передачу речи и данных, обеспечивает множество типов соединений и управление вызовами. TAPI позволяет приложениям использовать все возможности телефона, например, поддержку конференций и передачу звуковой почты.
В Windows NT подсистема обеспечения взаимодействия по телефону состоит из следующих компонентов (см. Рисунок 24):
1. TAPI-сервер tapisrv.exe (telephony service), реализующий TAPI функции;
2. библиотеки динамической загрузки tapi.dll и tapi32.dll, взаимодействующие посредством механизма RPC с TAPI-сервером;
3. один или несколько провайдеров телефонных сервисов (telephony service providers), загружаемых TAPI-сервером.
Приложения полагаются на существование провайдеров телефонных сервисов, которые предоставляют интерфейс TSPI (Telephony Service Provider Interface). Провайдеры телефонных сервисов могут быть разработаны для различных технологий, включая: 1) POTS (Plain Old Telephone Service) для передачи голоса и данных в аналоговом формате по абонентской линии, а далее везде в цифровом виде; 2) ISDN (Integrated Services Digital Network) для передачи в цифровом виде; 3) Т1/Е1 для цифровой передачи со скоростью 1.544 Mbps; 4) Switched 56 и т. д.
Провайдер сервиса является библиотекой динамической загрузки (иногда в его состав входит драйвер устройства), реализующей зависящие от устройства действия для выполнения телефонных операций на оборудовании, таком как телефон, модем, факс или ISDN карта. Таким образом, провайдер во взаимодействии с библиотеками интерфейса TAPI, предохраняет приложения от деталей, зависящих от типа сервиса и технологий коммуникаций по телефонным сетям.
Приложения вызывают функции только из библиотек tapi.dll (16-разрядные приложения) и tapi32.dll (32-разрядные приложения), они никогда не вызывают функции провайдеров напрямую. Библиотека tapi.dll является тонкой прослойкой, которая отображает 16-разрядные адреса в 32-разрядные, и передает запросы tapi32.dll. Библиотека tapi32.dll проверяет параметры функции и направляет запрос на выполнение сервису tapisrv.exe, а когда нужно загружает в процесс TAPI-приложения библиотеки, обеспечивающие интерфейс с пользователем (Telephony service provider user interface DLLs), в том случае, если провайдер реализует какие-либо элементы интерфейса с пользователем
Tapisrv.exe, исполняющийся> в собственном процессе, является ядром TAPI. Tapisrv.exe обрабатывает вызов и передает запрос соответствующему провайдеру сервиса. Получив запрос от tapisrv.exe, провайдер сервиса должен реализовать интерфейс TSPI. Все провайдеры телефонных сервисов исполняются в процессе tapisrv.exe и могут создавать необходимые для них потоки в контексте этого процесса.
DLL провайдера может использовать любые системные функции, включая CreateFileQ и DevicelOControlQ, для работы с драйверами оборудования независимых поставщиков, а также с драйверами стандартных устройств, таких как последовательные и параллельные порты. Они также могут обращаться к сетевым интерфейсам, таким как RPC, Windows Sockets, Named Pipes для клиент-серверного взаимодействия.
В Windows NT есть встроенный провайдер телефонных сервисов юнимодема -unimdm.tsp (Unimodem Service Provider), взаимодействующий с драйвером модема modem.sys, и предоставляющий сервисы TAPI с большинством типов модемов. А также встроенный провайдер сервисов компонента интерфейса TAPI уровня ядра -kmddsp.tsp (TAPI kernel-mode service provider). Kmddsp.tsp предоставляет интерфейс провайдера телефонных сервисов (TSPI) и передает преобразованные пользовательские запросы драйверу ndistapi.sys, который и является компонентом интерфейса TAPI уровня ядра.
TAPI также включает провайдеров сервиса среды (Media Service Providers, MSP), которые дают TAPI-приложению улучшенный, определяемый средой контроль над этой средой. Библиотека MSP, загруженная приложением, имеет соответствующий TSP в TAPI-сервере.
Пользователь может инсталлировать любое количество провайдеров телефонных сервисов, если только они не будут обращаться к одному и тому же устройству одновременно. Пользователь ассоциирует устройство с провайдером сервиса при инсталляции.
Некоторые провайдеры способны обращаться к нескольким устройствам. В некоторых случаях пользователю может понадобиться инсталлировать драйвер устройства вместе с провайдером.
Типы NDIS драйверов
Типы NDIS драйверов
Спецификация NDIS определяет три типа сетевых драйверов:
драйверы протоколов верхнего уровня (upper level protocol drivers);
драйверы протоколов промежуточного уровня (intermediate protocol drivers);
драйверы сетевых карт (NIC drivers), сюда входят драйверы сетевых карт локальных сетей (NDIS LAN Miniport NIC drivers) и драйверы сетевых карт глобальных сетей (NDIS WAN Miniport NIC drivers).
Транспортные протоколы
Транспортные протоколы
Microsoft предоставляет следующие транспорты:
1. NetBEUI и NetBEUI Frame (NBF) Транспортный протокол NetBEUI (Network Basic Input/Output System Extended User Interface) - является расширением канального уровня пользовательского интерфейса NetBIOS. Он является основным транспортным протоколом, используемым Windows NT для локальных сетей, и обеспечивающим взаимодействие с LAN Manager, LAN Server и MS-Net.
Протокол NetBEUI обеспечивает наивысшую скорость работы, но из-за ряда присущих ему недостатков, таких как невозможность маршрутизации и сильная зашумленность в большой сети, NetBEUI можно эффективно использовать только в небольших локальных сетях (IBM разработала протокол NetBEUI для локальных сетей, содержащих порядка 20 - 200 рабочих станций). Так как NetBEUI не маршрутизируемый, то он не позволяет создавать глобальные сети, объединяя несколько локальных сетей. Сети, основанные на протоколе NetBEUI, легко реализуются, но их трудно расширять, так как протокол NetBEUI не маршрутизируемый.
Протокол NetBEUI Frame (NBF) был создан на основе NetBEUI для преодоления некоторых его недостатков. В частности, NBF преодолевает предел количества систем - 254, существующий в NetBEUI.
2. Транспорт TCP/IP (Transmission Control Protocol/Internet Protocol, TCP/IP). Он был разработан для поддержки сети Министерства Обороны США - ARPANET (Advanced Research Projects Agency's network), предшествующей Internet, и предназначен для соединения разнородных систем через глобальные сети. Протокол TCP/IP широко распространен в сетях UNIX и позволяет Windows NT взаимодействовать с различными сервисами на UNIX - машинах.
Этот протокол быстро был адаптирован и для локальных сетей. В отличие от NetBEUI, который является запатентованным протоколом IBM и Microsoft, TCP/IP является общедоступным. Internet Engineering Task Force (IETF) координирует улучшения и расширения протокола TCP/IP через механизм, известный как Requests for Comments (RFCs). TCP/IP является надежным транспортом и очень гибким протоколом. TCP/IP можно использовать в локальных сетях небольшого масштаба, которые в дальнейшем можно легко расширить для вовлечения сотен и тысяч пользователей.
Протокол TCP/IP требует больше знаний для его использования, так как каждая машина должна иметь уникальный IP адрес и маску подсети. Такие средства как DHCP, WINS доступны в ОС Windows NT для облегчения задачи администрирования сети. Самое важное преимущество протокола ТСРЛР перед NetBEUI то, что TCP/IP - маршрутизируемый протокол. Структура IP адресов специально разработана для эффективной маршрутизации.
Транспорт ТСРЛР поддерживает множество компонент, реализующих сессионный уровень модели OSI, таких как NetBIOS, Winsock, RPC. ТСРЛР также является наиболее часто используемым протоколом при выполнении удаленного Доступа.
В Windows 2000 существуют встроенные драйверы, интегрированные с драйвером протокола ТСРЛР, которые расширяют базовые сетевые характеристики протокола ТСРЛР, используя с ним закрытый интерфейс.
Например, NAT-компонента (Network Address Translation) состоит из драйвера NAT, взаимодействующего со стеком ТСРЛР, а также редактора, используемого администратором для задания адресов. Другой пример - реализация IPSec (Internet Protocol security), включающая драйвер Ipsec.sys, интегрированный с драйвером протокола TCP/ IP. Агент политики получает информацию о конфигурации IPSec из Active Directory и передает информацию о фильтрации драйверу IPSec, а установки о безопасности модулю Internet Key Exchange. IKE-модуль ожидает запрос от драйвера IPSec и организует переговоры, возвращая результат обратно драйверу IPSec.
3. NWLink (IPX/SPX). Протокол Internetwork Packet Exchange/Sequenced Packet Exchange (IPX/SPX) используется в ОС NetWare фирмы Novell. Реализация этого протокола фирмой Microsoft называется NWLink. IPX/SPX базируется на протоколе Xerox Network System (XNS), разработанном Xerox Corp. Протокол XNS, который больше не используется, определял коммуникационные уровни от физического до прикладного. Novell использовала часть этого стека, а именно два компонента: IDP (Internet Datagram Protocol) and SPP (Sequenced Packet Protocol). IPX (nwlnkipx.sys) базируется на IDP, SPX (nwlnkspx.sys) - на SPP.
IPX/SPX - высокопроизводительный протокол для локальных сетей, и легче реализуется и администрируется, чем TCP/IP. Как и TCP/JP IPX/SPX является маршрутизируемым, и, следовательно, может использоваться для реализации глобальных сетей.
В Windows NT существует также встроенный протокол NWLink NetBIOS (nwlnknb.sys), который предоставляет возможность пересылки Novell NetBIOS-пакетов между NetWare-сервером, исполняющим Novell NetBIOS, и Windows NT компьютером, или между двумя Windows NT компьютерами.
4. AppIeTalk. Семейство сетевых протоколов AppleTalk было первоначально разработано для компьютеров Macintosh, однако уже вторая версия этого сетевого продукта позволяет взаимодействовать различным персональным компьютерам. В Windows NT он используется сервисами для Macintosh, которые позволяют пользователям Macintosh совместно использовать файлы формата Мае, хранящиеся в папках Windows NT сервера, и использовать принтеры, присоединенные к Windows NT серверу.
5. Data Link Control (DLC). DLC - протокол фирмы IBM, используется как компонент архитектуры SNA (System Network Architecture) для связи с мейнфреймами. В некоторых локальных сетях DLC используется для связи с принтерами, присоединенными непосредственно к локальной сети, а не к серверу или рабочей станции. Некоторые лазерные принтеры Hewlett-Packard предлагают по выбору интерфейс DLC. Это «сырой» протокол в том смысле, что никакие сетевые API не могут его использовать , приложения, которые захотят его использовать должны взаимодействовать напрямую с драйвером транспорта DLC.
TDI-транспорты обычно реализуют все протоколы, связанные с их основным протоколом. Например, драйвер TCP/IP (tcpip.sys) реализует TCP, UDP, IP, ARP, ICMP, IGMP. TDI-транспорты обычно создают объекты-устройства, реализующие конкретный протокол так, чтобы клиенты могли открыть объект-файл, представляющий протокол, и выдать сетевой запрос ввода/вывода этому протоколу, используя IPR-пакеты. TCP/IP-драйвер создает три объекта-устройства, которые представляют различные протоколы: \Device\Tcp, \Device\Udp, \Device\Ip.
Win32 API именованных каналов (named pipes) и почтовых ящиков (mailslots)
Win32 API именованных каналов (named pipes) и почтовых ящиков (mailslots)
Именованные каналы обеспечивают надежное двунаправленное взаимодействие между двумя процессами, независимо от того, является ли принимающая сторона локальной или удаленной. Почтовые ящики выполняют аналогичные функции, однако, вместо обеспечения канала «один к одному» между принимающей и передающей сторонами, они предоставляют ненадежную однонаправленную передачу данных типа «один ко многим» и «многие к одному». Почтовые ящики полезны для посылки широковещательных сообщений произвольному числу процессов.
Именованные каналы предоставляют абстрактный и удобный сетевой интерфейс. Вместо того чтобы иметь дело с маршрутизацией и пересылкой данных, программист, использующий именованные каналы, может просто открыть канал и поместить в него данные. Пользователь именованного канала открывает его и считывает данные. Передача данных между компьютерами выполняется автоматически и один вызов именованного канала эквивалентен нескольким операциям на уровне транспорта.
Все функции именованных каналов и почтовых ящиков реализованы в DLL клиентской части подсистемы Win32 - kernel32.dll (см. Рисунок 19). Однако имена, задаваемые приложениями, использующими именованные каналы и почтовые ящики, определяют системное пространство имен, управляемое драйвером файловой системы именованных каналов (Named Pipes File System, NPFS.sys) и драйвером файловой системы почтовых ящиков (Mail Slots File System, MSFS.sys). Драйвер файловой системы именованных каналов создает объект-устройство, называемое \Device\NamedPipe, и символическую ссылку к этому объекту, называемую \??\Pipe, а драйвер файловой системы почтовых ящиков создает объект-устройство, называемое \Device\Mailslot, и символическую ссылку \??\Mailslot, указывающую на этот объект. Имена, передаваемые функции CreateFile вида \Y\Pipe\.... и \V\Mailslot\...., имеют префикс \\.\, преобразуемый в \??\, так что имена разрешаются через символическую ссылку к объекту-устройству.
Анализ сетевой архитектуры ОС
Анализ сетевой архитектуры ОС Windows NT с точки зрения возможностей реализации средств защиты и анализа сетевого трафика
В этой главе будут проанализированы возможности реализации средств защиты сетевой информации на различных уровнях сетевой архитектуры Windows NT, начиная от уровня приложений и кончая уровнем драйверов устройств. Анализ будет проводиться со следующих позиций: существует ли возможность встраивания средства защиты на том или ином уровне сетевой архитектуры, сложность конкретной реализации с точки зрения ее недокументированности, прозрачность защиты, какие данные и в каком объеме будут контролироваться конкретным средством защиты, какое обслуживание со стороны ОС ему доступно и какие возможности предоставлены операционной системой средству защиты. В проведенном анализе не будет рассматриваться вопрос, может ли конкретный способ защиты быть подвержен воздействию со стороны злоумышленника.
Не на всех уровнях сетевой архитектуры операционная система Windows NT предоставляет возможность встраивания дополнительных программных модулей, которые могли бы контролировать вызовы сетевых программных компонент этого уровня и реализовывать функции защиты. Для реализации защиты на этих уровнях приходится использовать недокументированные методы, к которым относятся реализации защиты на уровне системных сетевых DLL, сетевых сервисов и «родного» API. Эти методы представлены в общем виде в этой главе, для их разработки использовался программный продукт фирмы NuMega - Softlce - средство отладки, работающее ниже уровня ядра операционной системы и позволяющее отлаживать такие компоненты ядра, как драйверы. С помощью Softlce удалось исследовать некоторые важные структуры данных.
Вначале будут рассмотрены основные факторы, влияющие на выбор конкретного способа реализации системы защиты.
Драйверы - фильтры
Драйверы - фильтры
Система ввода/вывода Windows NT является расширяемой. Один из методов расширения возможностей системы ввода/вывода - разработка и применение драйверов-фильтров.
Драйвер-фильтр - это промежуточный драйвер, перехватывающий запросы, предназначенные некоторым программным модулям (например, драйверу файловой системы или драйверу диска). Перехватив запрос, драйвер-фильтр имеет возможность либо расширения, либо замещения функциональности, обеспечиваемой первоначальным получателем запроса. Драйвер-фильтр может, либо использовать сервисы драйвера, которому изначально предназначался запрос, либо использовать сервисы других программных модулей уровня ядра для обеспечения дополнительной функциональности. Драйверы-фильтры могут встраиваться в любое место в стеке драйверов, их может быть несколько, в том числе расположенных подряд.
Примером использования драйвера-фильтра может послужить реализация прозрачного зашифрования/расшифрования данных, хранимых на диске или в сети. Ни одна из поставляемых с ОС Windows NT файловых систем (FASTFAT, NTFS, CDFS, LAN Manager Redirector) не обеспечивает поддержки прозрачного зашифрования данных перед записью их на диск (или отправкой в сеть) и расшифрования данных перед предоставлением их авторизированному пользователю. Но для того, чтобы выполнять шифрование, необязательно реализовать свой собственный драйвер файловой системы или специальный драйвер диска. Достаточно разработать драйвер-фильтр, располагающийся либо выше драйвера файловой системы (в этом случае драйвер-фильтр сможет обработать запрос перед тем, как драйвер файловой системы получит возможность его увидеть), либо ниже драйвера файловой системы (этот случай позволяет драйверу-фильтру выполнить любые требуемые операции после того, как драйвер файловой системы завершит свою задачу, и перед тем, как запрос будет получен драйвером диска (или сетевым драйвером)).
Драйвер-фильтр также может выполнять автоматическое обнаружение в реальном времени сигнатур вирусов в файлах (в том числе и файлах, полученных из сети). Фундаментальные шаги в разработке драйверов-фильтров:
Присоединение к нужному объекту-устройству. Диспетчер ввода/вывода включает возможность присоединения к объекту-устройству (1), созданному некоторым драйвером (1), объекта-устройства (2), созданного другим драйвером(2). В результате такого присоединения пакеты IRP, направленные драйверу (1), ассоциированному с объектом-устройством (1), будут перенаправляться драйверу (2), ассоциированному с присоединенным объектом-устройством (2). Этот «присоединенный» драйвер (2) и является драйвером-фильтром.
Каждый объект-устройство имеет поле, называемое AttachedDevice и содержащее указатель на объект-устройство, созданное драйвером-фильтром, который первым присоединил свое устройство. Если это поле содержит NULL, значит нет присоединенных устройств. В процессе присоединения нового объекта-устройства, процедура присоединения пройдет по связанному списку присоединенных устройств до конца и выполнит присоединение нового объекта-устройства к последнему объекту-устройству в этом списке. В результате, любой запрос на создание/открытие, предназначающийся некоторому объекту-устройству, будет перенаправляться последнему (в его списке присоединенных устройств) объекту-устройству. То есть последнему драйверу-фильтру, ассоциированному с последним объектом-устройством. Аналогично, при вызове функции, которая по имени объекта-устройства возвращает его указатель, будет возвращен указатель на объект-устройство, являющийся последним в списке присоединенных устройств.
Но важно заметить, что диспетчер ввода/вывода проходит до конца списка присоединенных устройств не во всех случаях. Например, никакого перенаправления не будет, если будет вызвана функция IoCallDriver(). Следовательно, чтобы обращение к драйверу назначения не миновало драйвер-фильтр, этот драйвер-фильтр должен присоединить свой объект-устройство к объекту-устройству драйвера-назначения, прежде, чем вышележащий драйвер вызовет процедуру определения указателя нижележащего объекта-устройства по его имени (это делается во время запроса на открытие), а затем будет использовать этот указатель (в частности при вызове функции IoCallDriver()).
Драйвер-фильтр может исследовать, модифицировать, завершать, или передавать дальше полученный пакет запроса драйверу назначения. Для того чтобы передать драйверу назначения полученный запрос, драйвер-фильтр должен создать собственный пакет IRP.
Драйвер-фильтр должен реализовать завершающие процедуры для завершения обработки IRP, после того, как IRP завершит драйвер назначения.
Отсоединение от объекта-устройства назначения.
Ниже рассмотрены основные принципы, которых необходимо придерживаться при разработке драйвера-фильтра, а также недостатки, из-за которых применение драйверов-фильтров становится нежелательным:
1. Разработчик драйвера-фильтра должен четко знать, как работает драйвер, создавший устройство, к которому будет присоединяться его драйвер. Драйвер-фильтр должен уметь обрабатывать все получаемые им запросы, адресованные на самом деле первоначальному драйверу, к которому он присоединился.
Несмотря на то, что все драйверы должны отвечать на стандартное множество запросов, выдаваемых менеджером ввода/вывода, в реальности, в случае разработки собственного драйвера-фильтра, нужно знать очень тонкие взаимосвязи, которые проявляются в зависимости от того, на каком уровне иерархии находится драйвер-фильтр. Возможны случаи, когда драйвер одной файловой системы запрашивает сервисы у драйвера другой файловой системы, или когда промежуточный драйвер запрашивает сервисы вышележащего драйвера файловой системы.
Например, в случае фильтрации всех запросов, предназначенных некоторому логическому тому, управляемому драйвером файловой системы (NTFS), необходимо понимать всевозможные пути вовлечения драйвера NTFS в обработку запроса, так как во всех этих случаях будут вовлекаться процедуры распределения драйвера-фильтра. Процедуры обработки запроса на чтения/запись драйвера файловой системы могут вовлекаться несколькими путями, например: из потока режима ядра, вызвавшего системные сервисы ZwReadFile(), ZwWriteFile(); из потока пользовательского режима, вызвавшего системные сервисы NtReadFile(), NtWriteFile(); из диспетчера памяти из-за обращения к отсутствующей странице спроецированного файла; из диспетчера кэша в результате асинхронного сброса буферов диспетчера кэша на диск; и так далее.
В некоторых ситуациях может быть приемлемым то, что драйвер - фильтр отправляет запрос ввода/вывода на асинхронное выполнение, но в других ситуациях (например, при обслуживании обращения к отсутствующей странице) драйвер-фильтр не должен этого делать, иначе это приведет к взаимной блокировке или зависанию.
В случае, когда драйвер-фильтр привязывается к объекту-устройству нижнего уровня (например, к устройству, представляющему физический диск), то возникают другие проблемы, с которыми сталкивается подобный драйвер-фильтр. Например, пакеты IRP, посланные драйверу диска, могут быть чаще всего ассоциированными пакетами, созданными драйвером файловой системы, и поэтому драйвер-фильтр не должен пытаться в свою очередь создавать ассоциированные пакеты. Обычно от драйверов дисков ожидают, что они будут выполнять операции асинхронно, поэтому драйвер-фильтр должен удовлетворять этим ожиданиям.
2. Драйвер-фильтр должен корректно работать с другими возможными драйверами-фильтрами, присоединенными до или после него. Никогда нельзя полагаться на то, что запрос, выпущенный драйвером-фильтром, пойдет напрямую нужному драйверу, так как он может быть перехвачен другим драйвером-фильтром.
3. Драйвер-фильтр должен знать, к чему он привязывается. Например, может получиться так, что когда драйвер-фильтр попытается привязаться к объекту-устройству, представляющему логический том файловой системы, он в действительности привяжется к объекту-устройству, представляющему физический диск, если том еще не был вмонтирован.
4. Драйвер-фильтр должен избегать поддержки ненужных ссылок. Если по небрежности драйвер-фильтр поддерживает лишнюю ссылку на объект-устройство назначения, то, возможно, что это будет препятствовать всем дальнейшим запросам на открытие и выполнение операций над этим устройством.
5. Драйвер-фильтр должен следить за контекстом потока, в котором выполняется его процедура распределения. В первую очередь это касается запросов ввода/ вывода к драйверам файловых систем, так как эти запросы должны передаваться в контексте потока, инициировавшего запрос, поэтому если драйвер-фильтр вызвал переключение контекста, например, послав запрос на исполнение рабочему потоку, то дальнейшая обработка этого запроса драйвером файловой системы приведет к непредсказуемым последствиям.
На всех уровнях, которые будут обсуждаться в дальнейшем, возможны реализация и применение драйверов-фильтров.
Анализ сетевой архитектуры
Глава 4. Анализ сетевой архитектуры ОС Windows NT с точки зрения возможностей реализации средств защиты и анализа сетевого трафика
Используемые средства построения
Используемые средства построения объединенных сетей и их влияние на уровень расположения средства защиты (согласно модели OSI)
В качестве средства наращивания и интеграции сетей может использоваться:
1. Повторитель или концентратор. Устройство, которое передает электрические сигналы из одного кабеля в другой без маршрутизации или фильтрации пакетов и служит для наращивания однотипных сетей. В терминах OSI повторитель представляет собой промежуточное устройство физического уровня.
2. Мост. Устройство, соединяющее две или несколько физических сетей. Мосты могут фильтровать пакеты, то есть передавать в другие сегменты или сети только часть трафика на основе информации канального уровня (MAC - адреса), В терминологии OSI мост является промежуточной системой на уровне канала передачи данных.
3. Маршрутизатор. Функционирует на сетевом уровне эталонной модели OSI и служит для организации связи между сетями с одинаковыми сетевыми протоколами. Маршрутизатор принимает решение о передаче пакетов на основе различных критериев, основанных на информации сетевого уровня. Для передачи пакетов их адресатам оптимальным образом маршрутизатор использует протоколы маршрутизации, например RIP.
4. Шлюз. Обеспечивает взаимодействие систем и сетей, которые используют несовместимые протоколы. Предназначен для сопряжения локальных сетей с сетями других архитектур типа SNA, DNA, X.400. Работает на самом верхнем уровне стека протоколов.
Проблем с использованием средства построения объединенных сетей не возникнет, если это средство реализует межсетевое взаимодействие, используя уровни модели OSI, расположенные ниже уровня, на котором реализован модуль защиты. Если же средство построения объединенных сетей реализует межсетевое взаимодействие, используя уровни модели OSI, расположенные как ниже, так и выше уровня реализации модуля защиты, то необходимо рассмотреть следующее условие — можно ли в это средство встроить модуль защиты:
Если можно, то после встраивания модуля защиты, средство построения объединенных сетей не повлияет на работу сети, в которой используется данный модуль защиты.
Если нельзя, тогда модуль защиты должен обладать функциональностью тех уровней, которые участвовали в переформировании пакетов в средстве межсетевого взаимодействия.
Для иллюстрации этого случая рассмотрим пример реализации модуля, осуществляющего шифрование сетевых данных. Если модуль защиты располагается ниже сетевого уровня, то надо предусмотреть случай фрагментации пакета. То есть, если средство построения объединенных сетей разобьет зашифрованный пакет, принятый от системы-отправителя, использующего этот модуль защиты, то модуль защиты в системе-получателе должен уметь собрать фрагментированный пакет (реализовать функции сетевого уровня) и выполнить его расшифрование.
Объем информации, проходящей через средство защиты
Объем информации, проходящей через средство защиты
От расположения средства защиты относительно иерархии сетевых компонентов, зависит количество проходящих через это средство данных, и, следовательно, возмож-
ность контроля и защиты этих данных. Чем выше уровень реализации средства защиты, тем меньше объем данных, проходящих через него (смотри Рисунок 25 и 26, где представлена обобщенная сетевая архитектура ОС Windows NT).
Для иллюстрации этого принципа рассмотрим следующий пример. Если разработан драйвер транспорта с функциями шифрования, то надо учитывать, что процессам зашифрования и расшифрования будут подвергаться только те данные, для которых драйверы файловых систем выбирают именно этот транспорт. В данном случае можно повлиять на объем проходящих данных через собственный драйвер транспорта, удалив из системы все другие транспорты законными методами, используя, например, NCPA (Network Control Panel Application).
Но, к сожалению, не во всех случаях возможно такое простое изменение конфигурации ОС. Например, если защита осуществляется на уровне API Windows Sockets, то удалить API NetBIOS законными методами не удастся, а простое удаление библиотеки динамической загрузки, реализующей интерфейс NetBIOS, приведет к невозможности работы приложений, использующих это API.
Поэтому наиболее естественным, и не требующим дополнительного конфигурирования способом защиты относительно этого фактора является защита на уровне драйверов сетевых карт (или на уровне промежуточного драйвера, привязанного снизу к драйверам сетевых карт). Но тогда появятся проблемы относительно реализации в этих драйверах функциональности, не свойственной уровню модели OSI, на котором они располагаются.
К сожалению, эти два фактора: объем проходящих данных и необходимость реализации дополнительной функциональности, вступают в противоречие в сетевой архитектуре операционной системе Windows NT из-за ее послойной модели.
Особенности реализации NDIS-драйвeров
Особенности реализации NDIS-драйвeров
Среда NDIS и NDIS-драйверы ранее уже описывались в разделе «Среда NDIS и NDIS драйверы». Хотя по требованиям переносимости NDIS-драйвер должен пользоваться только функциями, экспортируемыми средой NDIS, в реальных приложениях ничто не запрещает использовать функции ядра той ОС, под которую реализуется этот драйвер.
Переносимость и поддержка многопроцессорности. Драйвер должен быть написан на C/C++, причем необходимый формат результирующего файла может быть сгенерирован только компиляторами фирмы Microsoft. Драйвер должен избегать любой зависимости от типов данных, чей размер различается между платформами. Драйвер не должен вызывать никаких функций стандартных библиотек С, кроме функций обеспечиваемых NDIS. В режиме ядра не разрешены никакие операции с плавающей точкой.
В многопроцессорной среде процессоры одновременно выполняют несколько машинных инструкций. И поэтому драйвер должен синхронизировать доступ к общим структурам данных, чтобы в то время, когда одна функция драйвера обрабатывала общие данные, другая функция (или та же самая), исполняемая на другом процессоре, не попыталась изменить общие данные в тот же момент времени. Чтобы исключить эту проблему драйверы используют спин-блокировки.
Уровни IRQL исполнения функций драйвера. Любая функция драйвера, вызываемая NDIS, исполняется с уровнем приоритета, определяемым операционной системой, и варьирующимся между PASSIVEJLEVEL < DISPATCH_ LEVEL < DIRQL. Например, функция инициализации минипорта, функции останова, сброса и закрытия обычно исполняются с приоритетом PASSIVE_ LEVEL. Все другие функции NDIS-драйвера исполняются на уровне IRQL меньшем или равном DISPATCHJLEVEL. Промежуточный NDIS-драйвер или драйвер протокола никогда не исполняются на уровне DIRQL.
Уровень приоритета потока драйвера влияет на то, какие функции NDIS библиотеки он может вызывать. Некоторые функции могут вызываться только, если уровень приоритета PASSIVE_LEVEL, другие - если DISPATCH_LEVEL или ниже.
Выгружаемый и уничтожаемый код драйвера. Функции драйвера, которые всегда выполняются с уровнем приоритета PASSIVE_LEVEL, могут быть помечены как pageable (выгружаемые), используя макрос NDIS_PAGEABLE_ FUNCTION. При разработке драйверов поощряется помечать код как выгружаемый где это возможно, освобождая тем самым системную область памяти для кода, который должен быть резидентным. Функция драйвера, которая исполняется с приоритетом PASSIVEJLEVEL, может быть помечена как выгружаемая, если она сама не вызывает или ее не вызывает любая функция, которая исполняется с приоритетом большим или равным DISPATCH_LEVEL. (Например, если она не вызывает функцию, которая захватывает спин-блокировку, так как ее захват вызывает повышение уровня приоритета захватывающего потока до уровня DISPATCH_LEVEL).
Функция DriverEntry промежуточного драйвера должна быть определена как функция инициализации, используя макрос NDIS_INIT_FUNCTION. Предполагается, что код, помеченный этим макросом, исполняется только один раз во время инициализации системы, в результате чего он присутствует в оперативной памяти только в это время. После того как функция DriverEntry вернет управление, код, помеченный как NDIS_INIT_FUNCTION, уничтожается из оперативной памяти.
Сериализация вызовов функций. Среда NDIS обеспечивает сериализацию вызовов точек входа NDIS-драйверов, но при этом существует исключение. Начиная с некоторых версий ОС, появилось понятие десериализованного минипорта, где по требованиям производительности полнодуплексного обмена данными, реализация сери-ализации передачи пакетов протоколам возложена на разработчика минипорта.
реализации драйвера шифрования
Пример реализации драйвера шифрования сетевых пакетов
В качестве основы драйвера, шифрующего сетевые пакеты, может быть использован пример промежуточного драйвера ImSamp с сервера Microsoft (для NT 4.0) или промежуточный драйвер Passthru из DDK (NtDDK\src\network\ ndis\passthru, для Win2000). Этот NDIS-драйвер промежуточного уровня разработан так, чтобы располагаться между транспортным драйвером и драйвером сетевой карты (Рисунок 30). Единственное что он делает - это получает пакеты от драйвера сетевой карты и передает их драйверу транспорта, и наоборот.
Используя Network Control Panel Application (NCPA), можно привязать протокол TCP/IP к виртуальному адаптеру, создаваемому драйвером ImSamp, а все остальные привязки заблокировать. Для драйвера ТСР/IP промежуточный драйвер ImSamp выглядит как драйвер виртуальной сетевой карты. А для реальной сетевой карты Ethernet драйвер ImSamp выглядит как драйвер протокола.
Если разрабатываемый драйвер шифрования не реализует функции сетевого уровня модели OSI, то его нельзя будет использоваться в сети, где в качестве средств построения объединенных сетей используются маршрутизаторы, работающие на сетевом уровне. Так как такой драйвер не рассчитан на то, что выпущенный зашифрованный пакет может быть фрагментирован, поэтому его можно использовать только в сегменте сети до маршрутизаторов.
Реализация защиты на уровне драйвера MUP
Реализация защиты на уровне драйвера MUP
Как уже отмечалось ранее, драйвер mup.sys вовлекается при попытке достижения удаленных разделяемых ресурсов, используя UNC имена. Этот компонент во взаимодействии с сетевыми редиректорами отвечает за интеграцию пространства имен удаленных файловых систем в локальное пространство имен. Этот драйвер является простейшим драйвером файловой системы.
После запроса на создание/открытие файла по имени UNC драйвер mup.sys уже не вовлекается в обработку дальнейших запросов к этому файлу. То есть через драйвер mup.sys данные пользователя не проходят, но этот драйвер играет важную роль при открытии файлов и устройств по имени UNC. В связи с этим стоит рассмотреть возможность регистрации и аудита открытия файлов и устройств с помощью драйвера-фильтра, присоединенного к драйверу mup.sys. Так как драйвер mup.sys, является довольно простым драйвером, то реализация драйвера-фильтра в данном случае допустима.
Реализация защиты на уровне драйверов файловых систем
Реализация защиты на уровне драйверов файловых систем
Драйвер файловой системы обеспечивает пользователям механизм хранения и получения информации, реализуя возможности по созданию, модификации, удалению, разделению файлов и идентификации файлов по их символическим/логическим именам. В дополнение к этим функциям сетевые файловые системы обеспечивают в той или иной степени прозрачность местоположения файлов в сети и мобильность файлов. Файловые системы бывают разных типов, например: локальные файловые системы (FASTFAT, NTFS); сетевые и распределенные файловые системы (редиректор + сервер); псевдофайловые системы, предоставляющие пользователю интерфейс, подобный интерфейсу файловых систем, но реализующие особую функциональность, отличную от традиционных задач хранения и предоставления данных с диска, к ним относятся файловые системы, реализующие механизм межпроцессной коммуникации (NPFS-файловая система именованных каналов и MSFS-файловая система почтовых ящиков).
В принципе, ОС Windows NT предоставляет стандартный механизм для перехвата всех запросов ввода/вывода к драйверу файловой системы - это описанный выше механизм использования драйверов - фильтров. Для реализации этого механизма можно воспользоваться книгой автора Rajeev Negar «Windows NT File System Internals: A Developer's Guide», которая посвящена разработке драйверов файловых систем, и затрагивает вопрос реализации и драйверов-фильтров.
Основным недостатком, мешающим реализации защиты на уровне драйверов файловых систем, в том числе и реализации драйверов-фильтров, является закрытость и недокументированность интерфейса с этими драйверами. Microsoft неохотно поддерживает разработку драйверов файловых систем. В MSDN разработка драйверов файловых систем не документирована. И все же в 1997 году Microsoft выпустила документацию WinNT IFS Kit, необходимую для разработки драйверов файловых систем, и содержащую требуемые заголовочные файлы для успешной компиляции драйверов файловых систем с помощью компилятора Microsoft Visual C++, а также примеры простейших файловых систем. Но это средство разработки дорого стоит (1000$). Из-за этого многие запросы к драйверам файловых систем остаются загадкой, и поэтому применение драйверов-фильтров, в данном случае, скорее всего, приведет к некорректной работе стека драйверов.
В дополнение к вышеперечисленным трудностям надо учитывать и то, что многие части сетевых служб (почему-то имея тип драйверов файловых систем) на самом деле не предоставляют интерфейса, характерного драйверам файловых систем, что выясняется из анализа реализуемых ими процедур распределения.
Согласно реестру Windows NT почти все части сетевых служб, исполняющихся в режиме ядра, являются драйверами файловых систем, а именно: встроенный сетевой редиректор frdr.sys) и сервер (srv.sys), файловая система именованных каналов (npfs.sys), файловая система почтовых ящиков (msfs.sys), эмулятор интерфейса NetBIOS
(netbios.sys). Только эмулятор интерфейса WinSock (afd.sys) имеет тип стандартного драйвера. (Все эти вышеперечисленные драйверы являются TDI-клиентами и предоставляют в своей нижней части интерфейс TDI.)
Но далеко не все из этих драйверов действительно реализуют в своей верхней части интерфейс драйвера файловой системы. Например, драйвер srv.sys, который отвечает на запросы, посылаемые редиректором с удаленной машины, и взаимодействует с локальной файловой системой, не нуждается в предоставлении интерфейса файловой системы. Аналогично, драйвер netbios.sys не предоставляет интерфейс файловой системы, так как он является частью эмулятора сетевого интерфейса NetBIOS и взаимодействует с соответствующей DLL для преобразования «родных» функций этого интерфейса, вызываемых приложениями, в TDI-функции для вызова драйверов транспортов. Драйвер netbios.sys имеет только одну процедуру распределения для пакетов всего четырех типов IRP_MJ_CREATE, IRP_MJ_CLOSE, IRP_MJ_DEVICE_ CONTROL, IRP_MJ_CLEANUP, в то время как драйвер файловой системы должен обрабатывать гораздо большее число специфичных для него типов пакетов. Возможно, что это обстоятельство облегчит разработку драйвера-фильтра к нему. Чего нельзя сказать, о драйверах srv.sys и afd.sys, которые регистрируют одну процедуру распределения для всевозможных типов пакетов IRP, поэтому потребуется более детальное исследование того, какие из этих пакетов они действительно обрабатывают, а для каких просто имеют заглушки.
Архитектура Windows NT позволяет инсталлировать собственные драйверы файловых систем, это сделано специально для того, чтобы ОС Windows NT обладала способностью подключения к разнообразным сетям. Поэтому возможна разработка собственного редиректора, который сможет заменить встроенный и реализовывать функции защиты (при этом надо выгрузить встроенный редиректор и сервер).
Если разрабатывается собственный редиректор, который будет единственным в системе, то нужно также разработать и DLL сетевого провайдера (DLL компонента сетевого доступа), позволив тем самым приложениям использовать сетевой интерфейс API Win32 (WNet) для запроса сервисов от этого редиректора. Если редиректор выполняется одновременно со встроенным, то соответствующую ему библиотеку DLL провайдера можно не реализовывать, тогда запросы по интерфейсу API WNet через собственный редиректор не пойдут, а пойдут только запросы по стандартному интерфейсу API ввода/вывода через драйвер mup.sys.
Чтобы зарегистрировать DLL сетевого провайдера для MPR (предоставляющего API WNet), нужно изменить реестр. Порядок, в котором вовлекаются DLL провайдеров, зависит от порядка, в котором перечислены эти провайдеры в реестре. MPR изучает содержимое следующего ключа реестра, чтобы определить какие DLL провайдеров существуют в системе и порядок, в котором они будут вовлекаться:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\NetworkProvi-der\order.
В этом ключе содержится список имен провайдеров. Каждое имя соответствует некоторому сервису в ключе HKEY_LOCAL_MACHINE\System\CurrentControl-
Set\Services\«HMfl провайдера», который должен создаваться при инсталляции сетевого провайдера.
В книге автора Rajeev Negar «Windows NT File System Internals: A Developer's Guide» описаны функции, которые могут быть реализованы в DLL провайдера. Из них только одна функция, позволяющая пользователям узнать возможности сети, является обязательной.
DLL сетевого провайдера вовлекает сетевой редиректор в обработку запроса, используя управляющие запросы к файловой системе (FSCTL) через функцию DeviceloControl(). Эти запросы передаются менеджером ввода/вывода редиректору в пакете IRP со значением кода основной функции IRP_MJ_FILE_SYSTEM_CONTROL.
Ниже рассматриваются основные отличительные особенности драйверов файловых систем:
Первой особенностью драйверов файловых систем является то, что они находятся в вершине стека драйверов, и поэтому гарантированно вызываются в контексте потока, инициировавшего запрос. Эта особенность позволяет драйверам файловых систем манипулировать данными из адресного пространства инициатора запроса, а также осуществлять «быстрый» ввод/вывод (fast I/O), при котором диспетчер ввода/вывода вызывает драйвер файловой системы без использования пакетов запроса IRP, а с помощью определенной функции с параметрами, необходимыми для выполнения запроса драйвером файловой системы.
Учитывать эту особенность (заключающуюся в том, что запрос ввода/вывода должен передаваться драйверу файловой системы в контексте потока - инициатора запроса) необходимо также при разработке драйвера-фильтра, присоединяемого к драйверу файловой системы.
Следующая особенность драйвера файловой системы заключается в тесном взаимодействии с подсистемой виртуальной памяти, то есть с менеджером памяти и менеджером кеша. Для иллюстрации этого взаимодействия рассмотрим, упрощенно, «быстрый» запрос на чтение данных от диспетчера ввода/вывода к драйверу файловой системы. По этому запросу драйвер файловой системы вызывает диспетчер кэша, который в свою очередь копирует требуемые данные из системного кэша (если все необходимые данные там присутствуют) в пользовательский буфер. Если же не все требуемые данные присутствуют в кеше, то возникает ошибка страницы, в результате чего вовлекается диспетчер памяти для загрузки в память данных из файла на диске. Для этого он строит пакет запроса ввода/вывода IRP для получения данных с диска и передает этот IRP драйверу файловой системы. В результате данные будут прочитаны с диска в системный кэш, после чего диспетчер кеша скопирует данные из системного кэша в пользовательский буфер.
Файловые системы отвечают за обеспечение поддержки механизма кеширования данных и механизма файлов, проецируемых в память. Подсистема виртуальной памяти зависит от файловой системы, обеспечивающей поддержку страничных файлов, а
Файловая система в свою очередь зависит от подсистемы виртуальной памяти, разме-щющей память, требуемую для выполнения запросов к файловой системе.
Кроме описанных выше взаимосвязей с подсистемой виртуальной памяти драйвер файловой системы очень тесно (в отличие, например, от драйвера физического устройства) взаимодействует с менеджером ввода/вывода и менеджером объектов, так как каждая файловая система в Windows NT отвечает за реализацию своей части системного пространства имен. При открытии файла диспетчер ввода/вывода вызывает диспетчер объектов, который просматривает свое пространство имен, до тех пор, пока не попадает в объект-устройство. После чего разрешением оставшейся части имени файла занимается соответствующий драйвер файловой системы в тесной взаимосвязи с менеджером ввода/вывода.
Несмотря на желание разработчиков ОС Windows NT поддерживать четкое разграничение между файловой системой и остальной частью ОС, постепенно эта граница размывалась, и все более и более скрытая функциональность проникала в систему, есное взаимодействие драйвера файловой системы с различными компонентами исполнительной системы: менеджеров ввода/вывода, менеджером объектов, менеджером памяти и менеджером кэша, естественно, отражается на сложности разработки обственного драйвера файловой системы.
Примером реализации фильтра к драйверам файловой системы может служить рограмма FileMon, разработанная Mark Russinovich и Bruce Cogswell.
Реализация защиты на уровне драйверов сетевых устройств
Реализация защиты на уровне драйверов сетевых устройств
Сюда входят драйверы сетевых карт, драйверы устройств, которым могут направляться сетевые запросы ввода/вывода (например, драйвер последовательного порта). Реализация защиты на этом уровне зависит от того, разработан ли драйвер устройства в соответствии со стандартом NDIS (то есть это NDIS драйвер сетевой карты локальной или глобальной сети), или же это драйвер устройства, управляемый пакетами IRP. В первом случае лучше всего перейти к реализации промежуточного драйвера, а во втором к реализации драйвера-фильтра. Также на этом уровне возможна реализация
собственного драйвера устройства со встроенными функциями защиты, так как разработка подобных драйверов хорошо документирована в Windows NT DDK.
Разработка собственных драйверов сетевых карт глобальных и локальных сетей, поддерживаемых интерфейсом NDIS, хорошо документирована в DDK в главе Network drivers, в части Miniport NIC drivers и имеется ряд примеров в DDK\src\network. Если же сетевое устройство не является сетевой картой, то можно воспользоваться общими рекомендациями по разработке драйверов устройств в главе Kernel-mode drivers.
В случае разработки драйверов-фильтров, присоединенных к драйверам устройств, не являющимся сетевыми картами, необходимо знать все типы пакетов IRP и все возможные управляющие коды в пакетах IRP_MJ_DEVICE_ CONTROL, используемые для взаимодействия вышележащих драйверов с драйвером устройства.
Реализация защиты на уровне приложений и собственных DLL
Реализация защиты на уровне приложений и собственных DLL
Разработка приложений или DLL с функциями защиты - это самая тривиальная и обеспечивающая наименьшую гибкость реализация. Защита на уровне приложения не является прозрачной, в этом случае пользователь должен сам решать, нужно ли защищать его данные перед отправкой в сеть.
При запуске приложения создается новый процесс, адресное пространство которого защищено от других процессов. Поэтому приложение может защищать только свои данные.
Для того чтобы данные других приложений могли обрабатываться приложением, реализующим защиту этих данных, должны использоваться специальные механизмы межпроцессной коммуникации: копирование данных из одного адресного пространства в другое или создание области совместно используемой памяти, видимой из обоих адресных пространств. Следовательно, приложение, данные которого необходимо защитить, должно быть разработано для взаимодействия с приложением, защищающим его данные, с использованием этих механизмов. Но оно не обязано знать о существовании какой-либо системы защиты.
Реализация защиты на уровне собственной DLL также не обеспечивает прозрачной защиты. Для того чтобы защиту данных приложений выполняла некоторая библиотека DLL, необходимо, чтобы приложения были разработаны так, чтобы вызывать функции из этой DLL. После того, как исполняемый код DLL спроецируется на адресное пространство вызывающего процесса (при помощи неявной компоновки при загрузке приложения, или явной - в период выполнения), код и данные DLL просто становятся частью процесса приложения.
Уровень приложений и собственных DLL не имеет всех возможностей по реализа-циичфункций защиты сетевых ресурсов. Интерфейсы API, предоставляемые операционной системой приложениям и DLLs, не позволяют им выполнять пассивный или активный мониторинг сетевых пакетов или контролировать доступ к сетевым системным DLL и сетевым сервисам. Единственное, что они могут - это зашифровывать собственные данные перед отправкой их в сеть и расшифровывать после получения их из сети для предоставления пользователю. Только лишь во взаимодействии с собственным драйвером приложение может стать мощным средством защиты, причем в некоторых случаях приложению приходится использовать недокументированные методы.
Реализация защиты на уровне «родного» API для ОС Windows NT
Реализация защиты на уровне «родного» API для ОС Windows NT
Один из способов обеспечения прозрачной защиты связан с заменой механизма предоставления функций «родного» API. Как уже рассматривалось в главе «Общая архитектура Windows NT», системные сервисы могут быть предоставлены коду пользовательского режима посредством использования библиотеки ntdll.dll. В ntdll.dll вызов системных сервисов происходит с помощью программного прерывания int 2E. После чего обработчик прерывания для вызова соответствующего системного сервиса использует таблицу распределения системных сервисов (KeServiceDescriptorTable), экспортируемую ntoskrnl.exe (ядро и исполнительная система). Структура этой таблицы следующая:
1. указатель на массив, содержащий 4-х байтовые адреса точек входа системных сервисов в ntoskrnl.exe (4 байта);
2. 00000000 (4 байта);
3. количество системных сервисов (4 байта);
4. указатель на массив, содержащий однобайтовые значения, определяющие сколько байт надо извлечь из стека режима пользователя, содержащего параметры функции (4 байта).
Зная индексный номер функции, реализующей системный сервис, можно по таблице определить адрес ее начала и заменить его на адрес начала собственного обработчика режима ядра. После исполнения собственного обработчика необходимо передать управление по старому адресу, чтобы дать возможность стандартному обработчику выполнить запрошенные действия.
Так как эта таблица находится в системной области памяти, то такая замена может выполняться только кодом режима ядра (например, драйвером).
Примером подобного средства защиты может служить программный продукт RegMon for Windows NT, выполняющий перехват системных сервисов, реализующих обращение к реестру Windows NT.
Реализация защиты на уровне сетевого драйвера промежуточного уровня, поддерживающего интерфейс NDIS
Реализация защиты на уровне сетевого драйвера промежуточного уровня, поддерживающего интерфейс NDIS
Разработка NDIS драйверов промежуточного уровня - это один из хорошо документированных механизмов расширения возможностей системы ввода/вывода ОС Windows NT. Библиотека NDIS является очень мощным средством, используемым для разработки драйверов сетевых карт глобальных и локальных сетей и промежуточных драйверов. С использованием библиотеки NDIS можно реализовать промежуточные драйверы, служащие самым разным целям, включая фильтрацию и шифрование пакетов. Промежуточные драйверы хорошо документированы в Windows NT DDK в главе Network drivers, в части Intermediate NDIS drivers and TDI drivers. Имеется пример промежуточного драйвера packet в DDK\src\ network\packet\driver. Типичные варианты реализации промежуточного драйвера рассмотрены на Рисунок 27.
Реализация защиты на уровне сетевых сервисов
Реализация защиты на уровне сетевых сервисов
Почти все сетевые сервисы, такие как сервис рабочей станции (LanMan Workstation), сервис сервера (LanMan Server), сервис оповещений (alerter), сервис сообщений (messenger), обозреватель сети (Computer Browser), DHCP client содержатся в одном ЕХЕ-файле с именем services. Остальные исполняются в собственных процессах, например, wins.exe (WINS SERVER), dns.exe (Domain Name System (DNS) Server), rpcss.exe (RFC and Distribute COM Services), locator.exe (RFC locator), nddeagnt.exe (Network DDE Agent), tapisrv.exe (Microsoft Windows Telephony Server), rassrv.exe (Remote Access Server Supervisor).
Сетевой сервис - это серверный процесс. Некоторые сетевые сервисы выполняются в фоновом режиме, в то время как другие предоставляют API через соответствующие DLLs клиентской стороны, например: 1) tapi32.dll (Microsoft Windows Telephony API Client DLL) предоставляет приложениям взаимодействие с tapisrv.exe; 2) библиотека rassapi.dll (Remote Access Admin APIs dll) может использоваться приложениями для конфигурирования RAS сервера (rassrv.exe); 3) библиотека netapi32.dll (Net Win32 API DLL) используется приложениями для взаимодействия с browser, workstation, server, alerter, messenger, replicator; и т.д.
Сервисы, имеющие собственные API, для обмена данными со своими клиентами обычно используют механизм RPC. При этом для реализации RPC-запросов между процессами, исполняющимися на одной машине, в действительности используется механизм LPC.
Если клиентский процесс и процесс сетевого сервиса не находятся на одном компьютере, то контролировать передачу данных между этими процессами можно с помощью вмешательства в исполнение функций библиотеки rpcrt4.dll. Этот метод был подробно описан выше.
Чтобы контролировать передачу данных между клиентским процессом и процессом сетевого сервиса, исполняющимися на одной машине, нужно вмешаться в механизм LPC. В общих чертах он выглядит следующим образом: после, того как клиентский запрос к сервису перехватится заглушкой в DLL клиентского процесса, эта заглушка упакует параметры вызова, необходимые процедуре сервиса. Затем LPC обеспечит механизм передачи данных клиентского процесса процессу сетевого сервиса с помощью разделяемой памяти или с помощью посылки сообщения в очередь сообщений. Затем после того как процедура сервиса выполнит необходимую обработку, LPC возвратит результаты обработки обратно клиентскому процессу с помощью тех же механизмов.
LPC при своей работе создает и использует объекты-порты (port object), которые в качестве атрибутов имеют описатель секции (описатель совместно используемой памяти) и указатель на очередь сообщений. Объект-порт ассоциируется с серверным процессом и обеспечивает выполнение сервисов для клиентского процесса. Объект-порт как бы представляет канал для передачи сообщений между клиентским и серверным процессами. Серверный процесс определяет для связи с собой именованный объект-порт (порт соединения), а когда клиентский процесс свяжется с этим именованным портом, серверный процесс создаст два неименованных объекта-порта (порты связи) для взаимодействия.
API, необходимое для получения доступа к сервисам LPC, не документировано. Скорее всего, заглушка в клиентской DLL получает обслуживание LPC через прерывание int 2E с помощью вызова функций NtlmpersonateClientOfPort, NtAccept ConnectPort, NtCompleteConnectPort, NtCreatePort, NtReplyWaitReceive Port, NtReplyWaitReplyPort, NtRequestPort, NtConnectPort, NtReplyPort, NtRequest WaitReplyPort и т.п., предоставляемых библиотекой ntdll.dll. В результате чего обработчик прерывания 2Е (диспетчер системных сервисов) использует таблицу распределения системных сервисов (KeServiceDescriptorTable) для вызова соответствующих сервисов LPC из ntoskrnl.exe. Следовательно, для перехвата обращений к сервису LPC, можно воспользоваться методом перехвата обращений к системным сервисам, который будет рассмотрен ниже. Тем самым будет получен доступ к данным, передаваемым от клиентских процессов серверным процессам, в том числе и процессам сетевых сервисов.
Реализация защиты на уровне системных DLL, предоставляющих приложениям различные сетевые интерфейсы
Реализация защиты на уровне системных DLL, предоставляющих приложениям различные сетевые интерфейсы
К этим DLLs относятся, в первую очередь, следующие библиотеки DLLs сетевых интерфейсов:
1. Netapi32.dll (Net Win32 API DLL), предоставляющая интерфейс NetBIOS и Net-функции.
2. Ws2_32.dll (Windows Socket 2.0 32-Bit DLL), msafd.dll (Microsoft Windows Sockets 2.0 Service Provider), wsock32.dll (Windows Socket 32-Bit DLL), являющиеся DLLs интерфейса Windows Sockets.
3. Mpr.dll (Multiple Provider Router DLL), предоставляющая сетевой интерфейс Win32 (WNet), и реализующая функции маршрутизатора многосетевого доступа.
4. Kernel32.dll (Windows NT BASE API Client DLL) - DLL API ввода/вывода Win32, эта библиотека предоставляет стандартные функции, такие как функции открытия, закрытия, чтения, записи и т.п. Если файл, именованный канал, почтовый ящик, устройство, к которым обращены запросы в этих функциях, находятся на удаленной машине, то эти запросы пройдут по сети.
5. Wininet.dll (Internet Extensions for Win32), реализующая функции передачи HTTP запросов, навигации файлов по протоколу FTP, функции удаленного доступа в Internet, URL (Uniform Resource Еоса1ог)-функции и т.п.
6. Rpcrt4.dll (Remote Procedure Call Runtime), реализующая вызовы удаленных процедур.
7. Rasapi32.dll (Remote Access API), обеспечивающая приложениям удаленный доступ.
8. Nddeapi.dll (Network DDE Share Management APIs) и ddeml.dll (DDE management library), реализующие динамический обмен данными по сети.
9. Tapi32.dll (Microsoft Windows Telephony API Client DLL), предоставляющая приложениям телефонные сервисы.
10. Dlcapi.dll (DLC APIs), обеспечивающая взаимодействие по протоколу DLC.
11. Wsnmp32.dll (Microsoft WinSNMP Manager API DLL), mgmtapi.dll (Microsoft SNMP Management API DLL), snmpapi.dll (SNMP utilities DLL), используемые SNMP-приложениями.
Прежде чем перейти к рассмотрению возможностей реализации защиты на уровне этих DLL, ниже будет представлен процесс загрузки ЕХЕ-файла. При запуске ЕХЕ-файла загрузчик операционной системы выполняет следующие действия:
1. Отыскивает ЕХЕ-файл, создает новый объект-процесс, создает адресное пространство нового процесса размером 4 Гб. Резервирует регион адресного пространства - такой, чтобы в него поместился заданный ЕХЕ-файл. Желаемое расположение этого региона указывается внутри самого ЕХЕ-файла. По умолчанию базовый адрес ЕХЕ-файла - 0x00400000 (но при компоновке это значение может быть изменено). И отмечает, что физическая память, увязанная с зарезервированным регионом, - ЕХЕ-файл на диске.
2. Затем загрузчик просматривает таблицу импорта, содержащуюся в этом файле, и пытается найти и спроецировать на адресное пространство нового процесса все необходимые DLLs. Желаемое расположение региона адресного пространства, куда будет спроецирована конкретная DLL, указывается внутри самого DLL-файла, по умолчанию базовый адрес DLL-файла - 0x10000000. Но у всех стандартных системных DLL модулей (в том числе и вышеперечисленных), входящих в комплект поставки Windows NT, разные базовые адреса. Затем загрузчик отмечает, что физическая память, увязанная с зарезервированным регионом, - DLL-файл на диске.
3. Затем загрузчик сохраняет адреса импортируемых идентификаторов (функций и переменных), используемых ЕХЕ-файлом, в особой таблице адресов импорта (Import Address Table). Всякий раз, когда приложение ссылается на один из таких идентификаторов, сгенерированный компилятором код выбирает его адрес из таблицы и предоставляет необходимую связь.
Приведенная выше схема загрузки и исполнения функций DLL-файла позволяет реализовать защиту на уровне системных сетевых DLLs следующими способами:
Первый способ связан с использованием таблиц адресов импорта (Import Address Table). Для того чтобы найти эту таблицу, нужно сначала найти по сигнатуре «.idata» в таблице секций, располагающейся после заголовка файла, описание секции .idata. Секция .idata содержит информацию о функциях и данных, импортируемых приложением из DLLs. В описании этой секции есть поле, содержащее виртуальный адрес, по которому загрузчик отобразил секцию .idata. Содержимое этой секции начинается с массива структур, по одной структуре, содержащей пять элементов, на каждую DLL. Первый элемент каждой структуры указывает на таблицу имен функций, четвертый является указателем на имя DLL, а пятый указывает на таблицу адресов функций. Найдя по таблице имен функций имя нужной функции, можно узнать ее адрес в соответствующем элементе таблицы адресов функций, и затем заменить этот адрес на адрес собственного обработчика. Собственный обработчик может располагаться в собственной DLL. После завершения необходимой обработки нужно перейти по сохраненному первоначальному адресу импортируемой функции. Для того чтобы собственная DLL загружалась в адресное пространство любого процесса GUI-приложения, нужно в реестре в ключе HKEY_ LOCAL_MACHINE\ SYSTEM\ Software\ Microsoft WindowsNT\ CurrentVersion \ Windows\APPINIT_DLLS включить имя этой DLL.
В этом способе нужно менять таблицы адресов импорта во всех процессах приложений, использующих системные DLLs. Но обычно процессов в системе не так уж много (несколько десятков). Можно разработать приложение, которое будет получать описатели объектов-процессов, соответствующих защищаемым приложениям, а затем осуществлять чтение и запись в их виртуальные адресные пространства, с помощью функций ReadProssMem() и WriteProssMem().
Секция .idata имеет атрибут «для чтения и записи», поэтому запись в нее возможна.
Второй способ - создание собственной DLL, в которой необходимо заменить только часть функций, непосредственно через которые проходят данные пользователя. Имена этих новых функций должны быть сохранены. При этом новая DLL должна иметь то же имя. Или же в ключе реестра HKEY_LOCAL_ MACHINE \ SYSTEM \ CurrentControlSet \ Control \ Session Manager \ KnownDLLs должна быть строка: «имя заменяемой DLL без расширения» «имя собственной DLL с расширением dll», тогда система загружает вместо первоначальной DLL собственную библиотеку DLL из каталога, указанного в параметре реестра DllDirectory.
Так как все системные DLL имеют определенные базовые адреса, по которым они проецируются в адресное пространство процесса приложения, то преобразованная DLL не должна перекрывать базовый адрес другой системной DLL.
Третий способ основан на изменении части кода функций (необязательно начальной) вышеперечисленных DLL так, чтобы передать управление (с помощью команд call или jmp) собственному коду, реализующему необходимые функции по защите. Этот собственный код может содержаться в собственной DLL. Это изменение может происходить до загрузки DLL (исправляя DLL-файл во время загрузки ОС с помощью приложения-сервиса), или же можно модифицировать функции DLL после того, как DLL загружена. Этот способ основан на том, что все эыполняемые приложения, импортирующие функции некоторой DLL, совместно используют один и тот же код этой DLL, загруженный в оперативную память. И если страницы, содержащие код DLL, изменить, то это изменение коснется всех приложений.
Для реализации этого способа нужно разработать собственное приложение (или сервис), которое будет подгружать системные DLLs в свое адресное пространство. В этом приложении нужно получить адрес начала кода требуемой функции (например, с помощью функции GetProcAddress(«HMfl функции»)). Затем в том случае, если команда перехода будет находить не в самом начале, вычислить адрес кода, который будет перезаписан командой перехода, и по этому адресу осуществить запись инструкции JMP или CALL на адрес собственного обработчика, при этом надо сохранить перезаписываемые инструкции.
Но запись в секцию кода не так-то просто осуществить, так как эта секция является исполняемой и предназначена для чтения. Один из способов решения этой проблемы состоит в отображении физического адреса, соответствующего виртуальному адресу региона с кодом на другой регион, в который запись разрешена, и затем осуществить в него запись нужных инструкций. (Получится, что двум разным регионам виртуального пространства соответствует одна и та же физическая память). Но подобные махинации можно проводить только в драйвере, следовательно, для реализации защиты потребуется разработка драйвера. Возможно, что можно обойтись и без драйвера, воспользовавшись тем, что физическая память в ОС Windows NT представляется объектом-секцией, содержащимся в пространстве имен диспетчера объектов под именем \Device\PhysicalMemory. Приложение может спроецировать физическую память в свое адресное пространство и затем манипулировать ее содержимым.
Несмотря на то, что вышеперечисленные способы реализации защиты на уровне системных DLLs, кажутся довольно надуманными и неосуществимыми, подобные программные продукты все же существуют, например PRUDENS SPY product series, реализует технологию перехвата вызовов любых DLLs, в том числе и системных.
Реализация защиты на уровне транспортного драйвера
Реализация защиты на уровне транспортного драйвера
Транспортные драйверы являются, фактически, стандартными драйверами про-[ежуточного уровня и реализуют в своей верхней части стандартный интерфейс, со-тветствующий TDI спецификации. Этот интерфейс в основном базируется на полу-ении и обработке пакетов IRP_MJ_INTERNAL_DEVICE_CONTROL, содержащих различные значения контрольных кодов TDI_XXX, определяемых TDI спецификаци-й. В своей нижней части TDI драйвер взаимодействует с NDIS библиотекой.
Разработка драйверов транспорта хорошо документирована в Windows NT DDK в паве Network drivers, в части Intermediate NDIS drivers and TDI drivers. Имеется при-юр транспортного драйвера в DDK\src\network\tdi.
Можно также реализовать драйвер-фильтр, который будет присоединяться к объек-ам-устройствам, создаваемым драйвером транспорта. Например, к объектам-устрой-твам \Device\Tcp и \Device\Udp, создаваемым драйвером транспорта TCP/IP.
В связи с тем, что драйвер транспорта должен предоставлять единый, хорошо до-ументированный интерфейс, облегчается задача его разработки. Вместе с тем, TDI-штерфейс является расширяемым интерфейсом, так как:
TDI предоставляет возможность расширения множества операций, позволяющих взаимодействовать TDI-клиенту с определенным транспортом, в том числе и операций, связанных с управлением и конфигурацией.
TDI предоставляет гибкую схему адресации, позволяющую определять и использовать множество форматов адресов.
TDI определяет механизм, с помощью которого драйвер транспорта может сигнализировать клиенту об интересующих клиента событиях, произошедших в сети (без предварительного запроса от клиента). Это происходит с помощью вызова драйвером транспорта функций, указатели на которые передаются TDI-клиентом драйверу транспорта в самом начале сетевых операций в пакете IRP_MJ_INTERNAL_DEVICE_ CONTROL с контрольным кодом TDI_SET_ EVENTJHANDLER, и регистрируются драйвером транспорта. TDI-клиент даже может использовать подобный механизм функций обратного вызова в качестве альтернативы обычным пакетам запросов к транспорту с контрольными кодами TDI_XXX. Когда драйвер транспорта вызывает подобную функцию, он может передать TDI-клиенту в качестве параметров некоторое ограниченное количество данных. При этом, если существует драйвер-фильтр, присоединенный к драйверу транспорта, то он не получит возможности проконтролировать эти данные.
Подобное свойство расширения возможностей взаимодействия клиента с определенным драйвером транспорта приводит к частичной закрытости интерфейса между ними. В результате чего сильно затрудняется разработка драйвера-фильтра, присоединяемого к транспортному драйверу, как и в случае с драйверами файловых систем.
В то же время сохраняется возможность разработки собственного драйвера транспорта с использованием документации DDK, который будет реализовать требуемые функции защиты.
Реализация защиты с помощью перехвата функций NDIS - библиотеки
Реализация защиты с помощью перехвата функций NDIS - библиотеки
Этот метод является трудоемким, совершенно не документированным, но в то же время чрезвычайно эффективным.
Реализация этого метода позволяет создать как бы оболочку над самой библиотекой NDIS. Этот метод аналогичен методу перехвата системных сервисов. В данном случае заменяются адреса необходимых функций библиотеки NDIS, в результате чего можно получить контроль над всеми сетевыми операциями в системе.
Рассмотрим упрощенно, какие NDIS-функции вызываются во время загрузки сетевых драйверов. Сначала инициализируется драйвер сетевой карты, при этом для него вызывается функция NdisMInitializeWrapper, предупреждающая NDIS о том, что инициализируется новый минипорт (драйвер сетевой карты). Затем вызывается функция NdisMRegisterMiniport, которая регистрирует точки входа MiniportAjcx минипорта для NDIS-библиотеки. Далее вызывается точка входа в драйвере сетевой карты Miniportlnitialize, которая готовит реальную или виртуальную сетевую карту для выполнения сетевых операций ввода/вывода, запрашивает все аппаратные ресурсы, необходимые сетевой карте, и размещает ресурсы, необходимые драйверу для выполнения сетевых операций ввода/вывода.
Затем начинают инициализироваться драйверы протоколов TCP/IP, NETBEUI, IPX/ SPX и т.д. Для каждого из них вызывается функция NdisRegisterProtocol, которая регистрирует точки входа ProtocoLAjcc драйвера и имя протокола для библиотеки NDIS.
После инициализации драйвера протокола и драйвера сетевой карты вызывается функция NdisOpenAdapter, которая устанавливает связь между вызвавшим эту функцию протоколом и определенным нижележащим драйвером сетевой карты или промежуточным драйвером. А затем уже начинается обмен пакетами между драйвером протокола и драйвером сетевой карты.
Из приведенного выше процесса инициализации сетевых драйверов видно, что, перехватив вызовы таких функций как NdisMInitializeWrapper, NdisMRegisterMiniport, NdisRegisterProtocol, NdisOpenAdapter, можно отследить загрузку сетевого драйвера, и установить адреса своих обработчиков для точек входа MiniportXxx-процедур (например, Miniportlnitialize, MiniportQuery Information, MiniportSetlnformation, MiniportSend, MiniportSendPackets, MiniportTransferData и т.д.) и для точек входа ProtocolXxx-процедур (например, ProtocolBindAdapter, ProtocolReceive, Protocol ReceiveComplete, ProtocolSend Complete, ProtocolTransferDataComplete, ProtocolStatus, ProtocolPnPEvent, ProtocolReceiyePacket, ProtocolUnbindAdapter, ProtocolUnload и т.д.), а затем контролировать все сетевые операции ввода/вывода, проходящие через него.
Важно, чтобы ваш драйвер, который должен заменить адреса NDIS-функций в таблице экспорта библиотеки NDIS на адреса собственных обработчиков, загружался сразу после загрузки драйвера Ndis.sys. Иначе, к моменту загрузки вашего драйвера может уже произойти инициализация некоторых сетевых драйверов.
В первых двух случаях
Рисунок .27
![](image/27.gif)
В первых двух случаях промежуточный драйвер выглядит для драйвера транспорта как драйвер виртуальной сетевой карты. Используя механизм привязок можно все транспорты привязать снизу к требуемому промежуточному драйверу, который таким образом получит возможность контролировать все пакеты, идущие в/из сети. Это позволит ему реализовать функции защиты типа: преобразования форматов пакетов, преобразования пользовательских данных в пакетах, фильтрации пакетов, регистрации пакетов, контроля содержимого пакетов и т.п.
Во втором случае NDIS драйвер промежуточного уровня будет взаимодействовать посредством использования пакетов IRP с драйвером устройства, не являющимся сетевой картой (следовательно, этот драйвер устройства не поддерживается интерфейсом NDIS, им может быть, например, драйвер последовательного устройства). Подобные NDIS драйверы промежуточного уровня поставляются с Windows NT, например asyncmac.sys, взаимодействующий с драйвером последовательного порта. Поэтому необходимость в их реализации возникает только в случае разработки собственного сетевого устройства (но тогда придется разрабатывать и драйвер этого устройства, куда можно встроить функции защиты), или в случае, когда необходимо полностью заменить встроенный драйвер (но в этом случае лучше реализовать драйвер-фильтр, присоединенный к драйверу устройства).
Третий случай соответствует случаю реализации драйвера транспорта, рассмотренного выше.
Во всех этих случаях промежуточный драйвер может реализовать в свой верхней части закрытый интерфейс, посредством использования пакетов IRP с вышележащим драйвером или приложением. (Для подобного взаимодействия вышележащий драйвер или приложение должны открыть устройство, созданное промежуточным драйвером.) Этот механизм используется в сетевых анализаторах, являющихся программными комплексами, состоящими из приложения и драйвера.
В DDK подробно описано, какие функции интерфейсов верхнего и нижнего уровней промежуточный драйвер должен регистрировать обязательно, а какие по желанию разработчика. Благодаря таким четко оговоренным правилам взаимодействия посредством использования библиотеки NDIS, встраивание промежуточного драйвера между драйвером транспорта, поддерживающим интерфейс NDIS в своей нижней части, и NDIS драйвером сетевой карты не приводит к нарушению работы стека сетевых драйверов.
Промежуточный драйвер, расположенный над драйвером сетевой карты, фактически эквивалентен драйверу-фильтру, присоединенному к драйверу физического устройства. Только последний встраивается в цепь драйверов, взаимодействующих посредством пакетов IRP.
Надо отметить, что драйвер ndiswan.sys сам по себе является промежуточным драйвером, поставляемым Microsoft, и участвующим в поддержке взаимодействия по глобальным сетям типа ISDN, FR, Switched 56. Драйвер ndiswan.sys во взаимодействии с ndistapi.sys может служить провайдером сервисов TAPI. Для того чтобы контролировать трафик на уровне этих драйверов, необязательно заменять их собственными аналогами со встроенными функциями защиты, можно создать промежуточный драйвер, реализующий функции защиты, и расположить его выше или ниже этих драйверов.
Промежуточные драйверы являются неотъемлемой частью многих систем защиты сетевых ресурсов, реализующих пассивный мониторинг сетевых пакетов. Примером такой системы безопасности может служить программный анализатор сетевого трафика Microsoft Network Monitor. Также подобные драйверы являются частью многих систем безопасности, выполняющих фильтрацию и шифрование сетевого трафика, например, Guardian Windows NT Firewall.
Структура NDIS-пакета и NDIS-буфера
Рисунок . 28. Структура NDIS-пакета и NDIS-буфера
![](image/28.gif)
Расположение промежуточных NDIS-драйверов
Рисунок . 29. Расположение промежуточных NDIS-драйверов
![](image/29.gif)
Расположение драйвера шифрования
Рисунок . 30. Расположение драйвера шифрования
![](image/30.gif)
Как уже отмечалось выше, спецификация NDIS позволяет добавлять заголовки (или хвост) к NDIS-пакету без необходимости его перекопирования, во время передачи пакета по стеку сетевых драйверов. Таким образом, промежуточный драйвер шифрования может зашифровать пакеты двумя способами:
1. Путем модификации исходного NDIS-пакета, переданного драйвером транспорта, с добавлением к нему (при необходимости) новых NDIS- буферов.
2. Путем создания собственного NDIS-пакета копированием в него исходного NDIS-пакета, переданного драйвером транспорта, а затем уже модификации собственного пакета.
Первый способ использовать не рекомендуется, так как он чреват ошибками из-за использования библиотекой NDIS зарезервированных областей в пакете (при этом они будут перезаписываться). Но в простейших случаях этот способ работает.
При реализации первого способа важно помнить, что после завершения операции отправки зашифрованного пакета в сеть, в функции ProtocolSendComplete перед возвращением описателя пакета драйверу транспорта необходимо преобразовать пакет в исходное состояние. То есть расшифровать его и отделить все добавленные NDIS-бу-фера.
Драйвер может осуществлять зашифрование всех данных пакета, кроме Ethernet и IP-заголовков, IP-заголовок, при этом, можно создать свой, а первоначальный зашифровать.
Ключ шифрования обычно передается в драйвер шифрования из кода пользовательского режима (библиотеки DLL или приложения) с помощью вызова функции DeviceloControl. Обмен ключами между компьютерами можно, например, осуществить по схеме ISAKMP/Oakley, реализовав приложение (или библиотеку DLL), использующее интерфейс API WinSocket.
Если зашифрованный пакет имеет длину большую, чем первоначальный пакет, то для того, чтобы драйвер протокола не мог послать пакет такой длиной, что после добавления к нему необходимого числа байт промежуточным драйвером, драйвер сетевой карты (или сама сетевая карта) обрезал бы его (например, если длина преобразованного пакета вместе с Ethernet заголовком - 1514 байт), то при обработке запроса от драйвера протокола на максимально возможную длину пакета, значение, которое в действительности получено от драйвера сетевой карты, уменьшается на необходимое число байт.
Для определения функций, в код которых необходимо вставить зашифрование или расшифрование, рассмотрим функции интерфейсов нижнего и верхнего уровней, поддерживаемые средой NDIS, которые участвуют в приеме и отправлении пакетов, и через которые эти пакеты проходят непосредственно:
Отправление:
1. MiniportSendPackets;
2. MiniportSend;
3. ProtocolSendComplete.
Получение:
1. ProtocolReceive;
2. ProtocolReceivePacket;
3. ProtocolTransferDataComplete;
4. MiniportReturnPacket;
5. MiniportTransferData.
Рассмотрим эти функции подробнее:
1. MiniportSendPackets - функция интерфейса верхнего уровня. Она получает несколько указателей на описатели NDIS-пакетов от драйвера транспорта. Во время инициализации, перед тем, как отправлять пакеты, драйвер транспорта опрашивает параметры конфигурации и характеристики нижележащего драйвера, в том числе и то, сколько пакетов одновременно он может передавать. Эта функция должна, по меньшей мере, заменить первоначальные описатели NDIS-пакетов, полученные от драйвера транспорта, на свои собственные, сохранив первоначальные описатели, а затем отослать обновленные описатели NDIS-пакетов ниже - драйверу сетевой карты с помощью функции Ndis SendPackets.
2. MiniportSend - функция интерфейса верхнего уровня, предназначенная для передачи по одному пакету нижележащему драйверу и требуется только в том случае, когда промежуточный драйвер не обеспечивает функцию MiniportSendPackets.
3. ProtocolSendComplete - функция интерфейса нижнего уровня. Она является завершающей функцией для функций NdisSendPackets и NdisSend. Она получает в качестве параметра статус завершения операции отправления пакета и описатель этого отправленного пакета (обновленный описатель). Эта функция, по меньшей мере, должна просигнализировать драйверу транспорта о завершении операции отправления, передав ему первоначальный описатель отправленного пакета.
4. ProtocolReceive - функция интерфейса нижнего уровня. Вызывается NDIS, после того как драйвер сетевой карты передал выше полученный пакет (или его часть).
По меньшей мере, эта функция должна скопировать предоставленные ей данные во вновь созданный NDIS-пакет и передать его выше драйверу транспорта (обычно описатель этого пакета и его буфера берутся, соответственно, из очереди NDIS-пакетов и очереди буферов, созданных во время инициализации драйвера). Если драйвер сетевой карты предоставил не весь пакет, то необходимо вызвать функцию NdisTransferData для получения оставшейся части пакета.
5. ProtocolReceivePacket - это необязательная функция интерфейса нижнего уровня. Она вовлекается в том случае, если промежуточный драйвер располагается над драйвером сетевой карты, поддерживающим многопакетное предоставление, и этот драйвер сетевой карты вызвал функцию NdisMIndicateReceivePacket либо с множеством пакетов, либо с одним пакетом, имеющим дополнительную информацию.
6. MiniportTransferData - это функция интерфейса верхнего уровня. Она вызывается для того, чтобы передать вышележащему драйверу транспорта оставшуюся часть полученного от драйвера сетевой карты пакета, ранее не переданную в драйвер транспорта с помощью функции NdisMXxxIndicateReceive. Эта функция требуется только в том случае, если промежуточный драйвер сигнализирует о полученных пакетах вышележащим драйверам путем вызова зависящих от типа сетевой карты функций NdisMXxxIndicateReceive (вместо Ххх могут быть Ethernet, TR, Fddi). Если же промежуточный драйвер всегда передает полученные пакеты наверх с по-
мощью вызова функции NdisMIndicateReceivePacket, то ему не надо обеспечивать функцию MiniportTransferData.
7. ProtocolTransferDataComplete - функция интерфейса нижнего уровня и является завершающей функцией для NdisTransferData. Она вызывается библиотекой NDIS, когда драйвер сетевой карты завершит операцию передачи оставшейся части пакета, ранее не переданной в ProtocolReceive. Эта функция, по меньшей мере, должна передать драйверу транспорта начало пакета, полученного ранее в функцию ProtocolReceive, вместе с остатком, полученным только что.
8. MiniportReturnPacket - функция интерфейса верхнего уровня и вызывается библиотекой NDIS, чтобы вернуть NDIS-пакет, который был ранее создан и предоставлен драйверу транспорта путем вызова функции NdisMIndicate ReceivePacket в функции ProtocolReceive или ProtocolReceivePacket или ProtocolTransferDataComplete.
Эта функция должна, по меньшей мере, разобрать размещенный промежуточным драйвером NDIS-пакет и вернуть сам пакет и его буфера в соответствующие очереди, чтобы их можно было использовать в дальнейшем.
При изучении этих функций видно, что процедуру зашифрования надо вставить в функцию MiniportSendPackets, либо если ее нет, то в MiniportSend, а расшифрования в функции ProtocolReceive, ProtocolTransferDataComplete, ProtocolReceivePacket, ProtocolSendComplete. Ниже следуют объяснения этого утверждения.
Зашифрование требуется перед тем, как пакеты передадутся драйверу сетевой карты для отправки в сеть, а это в промежуточном драйвере происходит в функции MiniportSendPackets, либо если ее нет, то в MiniportSend, в них и надо реализовывать процедуру зашифрования.
С расшифрованием дела обстоят гораздо сложнее, так как в процессе получения пакета из сети в промежуточном драйвере участвуют сразу несколько функций: ProtocolReceive, ProtocolTransferDataComplete, ProtocolReceivePacket, Minipor tRetumPacket, MiniportTransferData.
Так как в функцию ProtocolReceive может попасть не весь пакет, а только его начало, то расшифрование в этой функции осуществляется только в том случае, если в нее был передан весь пакет. Если в эту функцию попало только начало пакета, то будет вызвана функция NdisTransferData, которая заставит драйвер сетевой карты передать оставшуюся часть пакета, и тогда его расшифрование будет осуществляться в завершающей функции для функции NdisTransferData - функции ProtocolTransfer DataComplete, которая уже будет обладать полным пакетом.
ProtocolReceivePacket необязательная функция, нужная только в том случае, если есть уверенность, что промежуточный драйвер будет располагаться над драйвером сетевой карты, имеющим способность предоставлять сразу несколько пакетов, полученных из сети. Если такой уверенности нет, то эту функцию можно не регистрировать, то есть при инициализации обнулить соответствующий указатель. Если эта функция все же реализуется, то она должна содержать процедуру расшифрования.
Необходимость расшифрования пакетов ( в случае зашифрования первоначального пакета без его перекопирования), возвращаемых драйверу транспорта, в функции ProtocolSendComplete объясняется следующим образом. При отправлении данных из прикладной программы в сеть, переданные ею данные, проходя по стеку сетевых драйверов, не перекопируются в новые участки памяти, просто к ним добавляются разные сетевые заголовки, поэтому при зашифровании данных пакета в функции MiniportSendPackets или MiniportSend (если не создавался новый пакет и первоначальный не перекопировался в него) шифруются на самом деле данные в буфере, принадлежащем приложению, а оно вовсе может и не рассчитывать на это. Может даже произойти следующее: если ключ шифрования не изменять, то при повторной посылке данных в сеть, эти данные, наоборот, расшифруются и пойдут по сети в открытом виде. Чтобы избежать этой неприятности, необходимо, перед возвращением отправленного пакета драйверу транспорта со статусом операции отправления, расшифровать его.
Функция MiniportTransferData предназначена для того, чтобы передавать драйверу транспорта оставшуюся часть полученного от драйвера сетевой карты пакета, ранее не переданную в драйвер транспорта с помощью функции NdisMXxxIndicateReceive. Но если промежуточный драйвер всегда передает полученные пакеты наверх с помощью вызова функции NdisMIndicateReceivePacket, то ему не надо обеспечивать функцию MiniportTransferData.
При разработке драйвера шифрования важно помнить, что цепь NDIS-буферов в NDIS-пакете не всегда точно соответствует сетевым заголовкам (Ethernet, IP, TCP/UDP). NDIS-пакеты, передаваемые из драйвера протокола, например TCP/IP, в промежуточный драйвер для отправки, могут иметь очень разнообразную структуру, то есть разное количество NDIS-буферов и их содержимое. Вот лишь некоторые примеры (смотри Рисунок 31), которые удалось пронаблюдать с помощью программы-отладчика Soft Ice. (Разделение означает различные NDIS-буфера, заметьте, что Ethernet заголовок уже пристроен к пакету драйвером протокола ТСРЛР.)
При разборе пакета перед зашифрованием (чтобы определить, например, следует ли его шифровать) нужно учитывать, что данные пользователя и сетевые заголовки могут находиться в разных участках памяти, а иногда и вместе (в пакетах протокола ARP_RARP).
При разработке драйвера шифрования полезно использовать анализатор протоколов, например, Network Monitor, наблюдая с его помощью содержимое перехваченных пакетов. Если его драйвер-перехватчик, под названием bh.sys, привязать к реальной сетевой карте, то перехваченные им пакеты будут зашифрованными. Если же его привязать к виртуальной сетевой карте, создаваемой промежуточным драйвером шифрования, то перехваченные им пакеты будут уже расшифрованными.
Структуры NDIS-пакетов
Рисунок . 31. Структуры NDIS-пакетов
![](image/31.gif)
Синхронизация
Синхронизация
NDIS предоставляет механизм спин-блокировок, который может быть использован, чтобы синхронизировать доступ к общим ресурсам между потоками, имеющими одинаковый приоритет. Если два потока исполняются с различными приоритетами, то NDIS обеспечивает механизм временного повышения приоритета потока с более низким приоритетом. Любая функция драйвера, разделяющая ресурсы с процедурой ISR этого же драйвера, должна иметь возможность повышения своего IRQL до DIRQL, этот механизм обеспечивается NDIS.
Также NDIS предоставляет механизм извещения, необходимый в том случае, если исполнение потока зависит от появления события вне этого потока. Например, драйвер может нуждаться в механизме предупреждения об истечении какого-то периода времени, чтобы он мог проверить свои устройства. Или драйвер сетевой карты может выполнять периодический опрос сетевой карты. Этот механизм обеспечивают таймеры.
Спин-блокировка (Spin Lock). Поток должен сначала захватить спин-блокировку, прежде чем пытаться получить доступ к защищаемым ресурсам. Спин-блокировка удерживает все потоки, кроме одного потока-владельца спин-блокировкой, от использования ресурсов. Другие потоки ждут освобождения спин-блокировки. Сетевые драйверы должны минимизировать время захвата спин-блокировки.
Функции для работы со спин-блокировками:
VOID NdisAllocateSpinLock (IN PNDIS_SPIN_LOCK SpinLock);
VOID NdisAcquireSpinLpck (IN PNDIS_SPIN_LOCK SpinLock);
VOID NdisReleaseSpinLock (IN PNDIS_SPIN_LOCK SpinLock);
VOID NdisFreeSpinLock (IN PNDIS_SPIN_LOCK SpinLock);
Таймер. Драйвер создает таймер и ассоциирует с ним функцию, которая вызывается, когда истекает определенный период времени. Таймер может быть одноразовым (сработать один раз) или периодическим. Периодические таймеры срабатывают до тех пор, пока не будут сброшены.
Таймеры создаются и инициализируются путем вызова функции NdisMInitialize Timer, и устанавливаются с помощью вызова NdisMSetTimer, или (если это периодический таймер) с помощью вызова функции NdisMSetPeriodic Timer. Функция NdisMCancelTimer сбрасывает таймер.
События (Events). События обеспечивают механизм синхронизации исполнения потоков. Один поток инициализирует событие с помощью вызова NdisInitializeEvent. Другой поток (или тот же самый), исполняемый с приоритетом PASSIVE_LEVEL, может вызвать функцию NdisWaitEvent, чтобы усыпиться до момента возникновения события, либо до истечения определенного им промежутка времени (что произойдет быстрее). Событие устанавливается и сбрасывается с помощью функций NdisSetEvent и NdisResetEvent соответственно.
Сравнительный анализ способов реализации защиты
Сравнительный анализ способов реализации защиты
В табл. 11 дается сравнительный анализ реализаций средств защиты относительно следующих факторов:
1. Объем контролируемых данных. Этот фактор определяет, какие данные проходят через средство защиты, и, следовательно, могут им контролироваться и обрабатываться.
2. Сложность реализации. Определяет сложность реализации средства защиты, как с точки зрения ее недокументированности, так и сложности отладки. Этот фактор оценивается по 3-х бальной шкале: высокая, средняя, низкая. Низкая сложность означает, что при разработке средства защиты используются хорошо документированные интерфейсы и доступные средства отладки. Средняя - означает, что используются документированные интерфейсы, но отладка средства защиты уже не столь проста, в связи с тем, что данное средство исполняется в режиме ядра, а, следовательно, большинство ошибок в нем приводят к падению ОС, и, кроме того, при отладке приходится иметь дело с ассемблерным кодом. Высокая сложность означает, что к проблемам с отладкой прибавляется еще частичное или полное отсутствие документации для разработки средства защиты.
3. Возможность встраивания защиты. Этот фактор определяет, предоставляет ли операционная система возможность встраивания средства защиты и расширения своей функциональности на данном уровне.
4. Прозрачность защиты означает, должен ли пользователь предпринять какие-либо действия для того, чтобы защитить свои данные с помощью средства защиты.
5. Возможности, предоставляемые ОС коду средства защиты. В зависимости от того, исполняется ли средство защиты в режиме пользователя, или в привилегированном режиме - режиме ядра, ему предоставляются различные возможности. В режиме ядра разрешено выполнение всех команд процессора и доступна системная область памяти и оборудование, тогда как в пользовательском режиме некоторые команды запрещены, а системные области памяти недоступны.
Структура NDIS-пакетов
Структура NDIS-пакетов
Драйвер протокола выделяет ресурсы под NDIS-пакеты, заполняет их данными и посылает вниз следующему NDIS-драйверу. Драйверы сетевых карт выделяют ресурсы под NDIS-пакеты, чтобы поместить в них полученные из сети данные и передать наверх соответствующим драйверам. Иногда драйвер протокола размещает NDIS-na-кет и передает его драйверу сетевой карты с требованием, чтобы драйвер сетевой карты скопировал полученные из сети данные в этот пакет. NDIS обеспечивает функции, размещающие и обрабатывающие структуры, из которых состоит NDIS-пакет.
Описатель NDIS-пакета является структурой NDIS_PACKET, содержащей, помимо прочих, следующие поля (см. Рисунок 28):
1. закрытые области данных для драйвера минипорта и драйвера протокола;
2. флаги;
3. число физических страниц, содержащих пакет;
4. полную длину пакета;
5. указатели на описатели первого и последнего буфера пакета.
Описатель буфера является структурой NDIS_BUFFER (в действительности, NDIS_BUFFER определяется как тип MDL), содержащей, помимо всего прочего, следующее:
1. начальный виртуальный адрес буфера;
2. смещение буфера относительно страницы;
3. длину буфера в байтах;
4. указатель на описатель следующего буфера (или NULL, если его нет).
Основные функции для работы с NDIS-пакетами и NDIS-буферами:
1) NdisAllocatePacketPool - размещает и инициализирует пространство для пула описателей пакетов;
2) NdisAllocatePacket - размещает и инициализирует описатель пакета;
3) NdisReinitializePacket - удаляет все присоединенные буфера из пакета и инициализирует его для повторного использования;
4) NdisCopyFromPacketToPacket;
5) NdisQueryPacket - возвращает информацию о «шкете;
6) NdisFreePacket;
7) NdisAllocateBufferPool - возвращает указатель, с помощью которого затем можно разместить описатели буферов, вызвав NdisAllocateBufFer;
8) NdisAllocateBuffer-создает описатель буфера;
9) NdisChainBufferAtBack (NdisChainBufferAtFront) - присоединяет описатель буфера в хвост (в начало) цепи описателей буферов, присоединенных к пакету;
10) NdisCopyBuffer; И) NdisFreeBuffer;
12) NdisGetFirstBufferFromPacket - возвращает указатель на буфер первый в цепи буферов пакета;
13) NdisUnchainBufferAtBack, NdisUnchainBufferAtFront.
Сравнительный анализ реализаций средств защиты
Таблица 11. Сравнительный анализ реализаций средств защиты
Реализация защиты на уровне: | Объем контролируемых данных | Сложность реализации | Возможность встраивания защиты | Прозрачность защиты | Возможности, предоставляемые ОС | ||||||
Приложения | Только данные самого приложения | Низкая | Да | - | Минимальные | ||||||
Собствен ной DLL | Данные приложений, использующих эту DLL | Низкая | Да | Минимальные | |||||||
Системной DLL | Данные приложений, использующих сис темную DLL | Высокая | Нет | + | Зависит от способа реализации | ||||||
Сетевого сервиса | Зависит от сетевого сервиса | Высокая | Нет | + | Зависит от способа реализации | ||||||
"Родного" API | Данные всех прило- жений | Высокая | Нет | + | Максимальные | ||||||
Драйвера файловой системы | Данные приложений, использующих соот- ветствующее сетевое API | Высокая | Да | + | Максимальные | ||||||
Транс- портного драйвера | Данные приложений, использующих этот транспорт + приложений, взаимодействующих с др. транспорта напрямую | Высокая | Да | + | Максимальные | ||||||
Драйвера Ndis.sys | Данные всех приложений | Высокая | Нет | + | Максимальные | ||||||
Промежуточного драйвера | Данные приложений, использующих транспорты, привя- занные снизу к этому промежуточному драйверу + приложе- ний, взаимодейст- вующих с промежу- точным драйвером напрямую | Средняя | Да | + | Максимальные | ||||||
Драйвера сетевого устройства | Данные всех приложений | Средняя | Да | + | Максимальные |
Средства защиты уровня ядра могут использовать внутренние интерфейсы для взаимодействия с компонентами исполнительной системы. Модуль защиты, исполняющийся в режиме ядра, может повышать или понижать текущий IRQL процессора, маскируя тем самым прерывания с равными или меньшими IRQL.
Модуль защиты, исполняющийся в режиме пользователя, не может получить доступа к системным данным иначе, как, вызвав предоставляемые операционной системой функции, которые в свою очередь вызывают системные сервисы, осуществив предварительную проверку параметров вызова.
Следовательно, относительно этого фактора логично оценивать средства защиты по 2-х бальной системе: если средство защиты реализуется как компонент уровня ядра, то ему будут предоставлены максимальные возможности со стороны ОС, если средство защиты реализуется как компонент уровня пользователя, то - минимальные.
Если для реализации защиты на уровне системной DLL или сетевого сервиса был разработан компонент, исполняющийся в режиме ядра, то это средство защиты также может использовать максимальные возможности, предоставляемые ОС. Для реализации защиты на уровне «родного» API в любом случае должен использоваться компонент уровня ядра.
Необходимо реализовать программу, обеспечивающую безопасный
Таблица 12
Требования к системе безопасности |
Рекомендуемый уровень реализации средства защиты |
Необходимо реализовать программу, обеспечивающую безопасный обмен данными по компьютерной сети |
Реализация на уровне приложения и DLL |
Необходимо обеспечить безопасный обмен данными по сети между приложениями, использующими конкретное сетевое API или контроль доступа к сетевому API |
Реализация на уровне системной DLL, предоставляющей этот API, или на уровне "родного" API, или на уровне соответствующего драй- вера файловой системы |
Необходимо обеспечить контроль доступа к сетевым сервисам |
Реализация на уровне сетевого сервиса (которая сводится к реализации защиты на уровне системной DLL rpcrt4 или "родного" API) или реализация на уровне сетевых драйверов для контроля адресов |
Необходимо обеспечить безопасный обмен данными по сети между приложениями, использующими конкретный транспортный протокол, или анализ трафика по этому протоколу |
Реализация на уровне драйвера ndis.sys или драйвера транспорта или промежуточного драйвера или драйвера устройства |
Необходимо обеспечить безопасный обмен данными по сети между любыми приложениями, или анализ всего трафика в сети |
Реализация на уровне драйвера ndis.sys или промежуточного драй- вера или драйвера устройства |
Точка входа DriverEntry
Точка входа DriverEntry
Точка входа DriverEntry промежуточного драйвера должна по крайней мере:
1. вызвать NdisMInitializeWrapper и сохранить возвращенный описатель NdisWrapperHandle\
2. вызвать функцию NdisIMRegisterLayeredMiniport, чтобы зарегистрировать свои точки входа MiniportA3cc;
3. вызвать функцию NdisRegisterProtocol, чтобы зарегистрировать свои точки входа ProtocoLEcc (если драйвер привязывается к нижележащему NDIS-драйверу);
4. вызвать функцию NdisIMAssociateMiniport, чтобы информировать библиотеку NDIS о том, что определенные ранее интерфейсы нижнего и верхнего уровней для минипорта и протокола соответственно, принадлежат одному и тому же промежуточному драйверу.
DriverEntry может инициализировать спин-блокировки для любых глобальных разделяемых ресурсов, размещаемых промежуточным драйвером.
Точки входа MiniportXxx
Точки входа MiniportXxx
Возможные обязательные и необязательные функции минипортовой части промежуточного драйвера перечислены ниже (подробное их описание смотри в DDK):
1. MiniportHalt - эта функция вызывается библиотекой NDIS, например, когда нижележащая сетевая карта зависла, и NDIS останавливает драйвер сетевой карты, или, например, когда ОС выполняет контролируемое закрытие системы.
2. Miniportlnitialize - эта функция вызывается в результате вызова промежуточным драйвером функции NdisIMInitializeDevicelnstance, чтобы инициализировать ми-нипортовые операции для инициализируемой виртуальной сетевой карты.
3. MiiuportQuerylnformation - эта функция получает запросы вида ОID_ХХХ, организованные (или просто передаваемые далее) вышележащим драйвером, вызвавшем NdisRequest с типом запроса NdisRequestQuerylnformation.
4. MiniportReset. NDIS может вызвать эту функцию промежуточного драйвера по приказу вышележащего драйвера протокола, вызвавшего NdisReset. Обычно, однако, драйвер протокола не инициирует сброс. NDIS, главным образом, инициирует сброс нижележащего драйвера сетевой карты и вызывает функции промежуточного драйвера ProtocolStatus и ProtocolStatusComplete, для того, чтобы информировать промежуточный драйвер о том, что нижележащий минипорт сбрасывает свою сетевую карту.
5. MiniportSetlnformation. Эта функция обрабатывает запросы вида OID_ХХХ, сделанные (или просто передаваемые далее) вышележащим драйвером, который вызвал NdisRequest с типом запроса NdisRequestSet Information.
6. MiniportSend. NDIS вызывает эту функцию для передачи одного пакета для нижележащего драйвера сетевой карты (или драйвера устройства). Функция MiniportSend (или функция MiniportWanSend) требуется, если промежуточный драйвер не обеспечил функцию MiniportSendPackets. Но лучше, чтобы всегда обеспечивалась функция MiniportSendPackets, чем функция MiniportSend (если только промежуточный драйвер не располагается всегда между драйверами, передающими по одному пакету за раз, или, если он не привязывается к нижележащему WAN NIC драйверу).
7. MiniportSendPackets. Эта функция получает массив из одного или более указателей на описатели пакетов для передачи в сеть. Лучше, чтобы каждый промежуточный драйвер обеспечивал функцию MiniportSendPackets, чем MiniportSend, если только он не привязывается к нижележащему WAN NIC драйверу, и должен при этом обеспечить функцию MiniportWanSend. Функция MiniportSendPackets обеспечивает лучшую производительность в независимости от того, располагается ли промежуточный драйвер над драйвером сетевой карты, который может передавать по несколько пакетов за раз, или только по одному пакету. И вне зависимости от того, располагается ли промежуточный драйвер под драйвером протокола, отправляющим по несколько пакетов за раз, или только по одному пакету.
8. MiniportTransferData. Эта функция вызывается, чтобы передать оставшуюся часть полученного из сети пакета, ранее представленного в буфере lookahead, переданном промежуточным драйвером в функцию NdisMA!ja:Indicate Receive. Этот пакет может быть конвертированным пакетом, полученным перед этим в
функции промежуточного драйвера ProtocolReceive или ProtocolReceivePacket. Функция MiniportTransferData требуется, если промежуточный драйвер представляет вышележащим драйверам полученные из сети пакеты путем вызова любой зависимой от среды функции NdisMA'Jalndicate Receive, кроме NdisMWan IndicateReceive. Если промежуточный драйвер всегда представляет пакеты путем вызова NdisMIndicateReceivePacket, то ему не нужно обеспечивать функцию MiniportTransferData.
9. MiniportReturnPacket. Эта функция получает возвращенный описатель пакета, который перед этим был представлен вышележащему драйверу путем вызова NdisMIndicateReceivePacket, тем самым возвращается контроль над ресурсами, представленными вышележащему драйверу. После того как каждое такое представление было обработано вышележащим драйвером, описатель пакета, размещенный промежуточным драйвером, и ресурсы, которые он описывает, будут возвращены функции MiniportReturnPacket, Функция Miniport ReturnPacket не нужна, если промежуточный драйвер всегда представляет пакеты наверх путем вызова зависящей от среды функции NdisMA3cdndicate Receive, или, если он всегда устанавливает статус в блоке данных ООВ, ассоциированном с каждым описателем пакета, в NDIS_STATUS_ RESOURCES, прежде чем вызвать NdisMIndicateReceivePacket.
10. MiniportCheckForHang. Эта функция вызывается через интервал времени, определенный библиотекой NDIS или промежуточным драйвером. Обычно, промежуточным драйверам не обязательно реализовать функцию MiniportCheckForHang, потому что подробные драйверы не могут удостовериться, что нижележащая сетевая карта зависла. Возможно, промежуточному драйверу следует обеспечить эту функцию, если он располагается над драйвером, не поддерживающим среду NDIS, чье состояние не доступно библиотеке NDIS.
Точки входа промежуточного NDIS- драйвера
Точки входа промежуточного NDIS- драйвера
Промежуточный NDIS-драйвер обычно экспортирует функции MiniportXxx на своем верхнем уровне и функции ProtocolXxx на своем нижнем уровне (см. Рисунок 29).
Реже промежуточный драйвер может экспортировать MiniportXxx функции на своем верхнем уровне, а в своей нижней части предоставлять частный закрытый интерфейс нижележащему драйверу, не являющемуся NDIS-драйвером. Например, промежуточный драйвер может управлять сетевыми запросами ввода/вывода для устройства, соединенного с последовательным портом. Подобный промежуточный драйвер будет экспортировать ряд функций MiniportXxx, чтобы взаимодействовать с NDIS в своей верхней части, а в своей нижней части использовать стандартные пакеты запроса ввода/вывода (IRP), чтобы взаимодействовать с драйвером последовательного устройства.
Если реализуемый промежуточный драйвер должен поддерживать ориентированный на соединение (Connection-Oriented) интерфейс нижнего уровня, либо поддерживать работу с NDISWAN, то необходимо реализовать как ряд дополнительных точек входа, так и изменить некоторые из описанных в этом разделе точек входа.