|
14 / 13 / 1
Регистрация: 30.09.2011
Сообщений: 160
|
|||||||
Сетевая фильтрация url и ip адресов в wfp03.11.2014, 22:13. Показов 8224. Ответов 22
Метки нет (Все метки)
Доброго времени суток!
Решил изучить технологию WFP (Windows Filtering Platform) и написать драйвер режима ядра для фильтрации url-адресов и ip-адресов с портами. Что нужно конкретно:
Собственно, прочитав советы товарища Убежденный, то понял, что для версий <=ХР нужно юзать TDI,NDIS или LSA, но так как я ориентируюсь писать как минимум, =>Win 7, то нашел технологию WFP. Почитав msdn, я немного прояснил структуру этого WFP, но, я не понял ничего про то, КАК реализовать драйвер и из каких библиотек\заголовочных файлов брать нужные функции. В частности, пока мне не понятно вот этот момент :
Кликните здесь для просмотра всего текста
Руссинович, Соломон "Внутреннее устройство Windows 2000";
Свен Шрайбер "Недокументированные возможности Windows 2000"; Дж.Рихтер "Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows"; http://www.ozon.ru/context/detail/id/116668/ Walter Oney "Programming the microsoft windows driver model"; http://www.ozon.ru/context/detail/id/3137491/ Солдатов "Программирование драйверов Windows"; http://www.ozon.ru/context/detail/id/28515104/ "Даниель А. Нортон. Написание драйверов для Windows"; http://www.ozon.ru/context/detail/id/28515104/ P.Orwick, G.Smith "Developing Drivers with the Windows Driver Foundation"; http://www.ozon.ru/context/detail/id/3963383/ live ISBN 978-5-9775-0185-9, 978-5-7502-0364-2, 978-0-7356-2374-3; 2008 г. О.Зайцев "Rootkits, SpyWare/AdWare, Keyloggers & BackDoors. Обнаружение и защита (+ CD-ROM)"; http://www.ozon.ru/context/detail/id/2811431/ Варианты вот такого =>
0
|
|||||||
| 03.11.2014, 22:13 | |
|
Ответы с готовыми решениями:
22
Фильтрация URL адресов в Cisco 2911
|
|
14 / 13 / 1
Регистрация: 30.09.2011
Сообщений: 160
|
||||||
| 03.11.2014, 22:16 [ТС] | ||||||
|
Вот то, что я нашел более менее вменяемое и наглядное:
0
|
||||||
|
14 / 13 / 1
Регистрация: 30.09.2011
Сообщений: 160
|
||||||
| 03.11.2014, 22:18 [ТС] | ||||||
0
|
||||||
|
Ушел с форума
|
|
| 04.11.2014, 11:21 | |
Сообщение было отмечено NickoTin как решение
Решение
Здесь я постараюсь дать небольшой обзор WFP, а также затронуть некоторые
технические моменты. Без каких-либо претензий на полноту, точность и т.д. Часть 1, Основы. Что такое WFP ? WFP расшифровывается как Windows Filtering Platform, платформа фильтрации Windows. Внимание ! Не путать с технологией WPF из .NET ! WFP - это универсальная технология фильтрации сети, охватывающая все основные уровни, от транспортного (TCP/UDP) до канального (Ethernet), и дающая разработчикам массу интересных возможностей. Почему WFP ? До WFP разработчики фаерволов, спам-фильтров, родконтролей и других программ такого плана были вынуждены использовать сложные, разрозненные, а часто просто недокументированные способы, которые во многих отношениях не давали нужного эффекта или требовали высокой квалификации и учета многочисленных деталей, с которыми то и дело возникали проблемы при переносе на другие версии Windows. Пример таких технологий - TDI, LSP, NDIS, а также старые Filter-Hook Drivers и Firewall-Hook Drivers. В WFP многие типовые проблемы этих технологий были учтены, некоторые решения вообще не имеют аналогов, либо тяжелореализуемы в TDI/LSP/NDIS. Сама технология имеет достаточно простую и понятную объектную модель, хорошо документирована и при желании ее может освоить человек весьма средней квалификации. Добавлю, что WFP - единственная на сегодняшний день технология, позволяющая полноценно фильтровать трафик от modern-приложений на Windows 8 и выше. И не только. Например, TDI и LSP в настоящее время уже не справляются даже с Internet Explorer 11 на Windows 7. Поэтому при выборе технологии для нового проекта следует в первую очередь рассматривать WFP, и только потом (если есть причины, например совместимость с XP или отсутствие каких-то важных функций WFP на целевых версиях Windows) другие. Краткая история. Появилась в Windows Vista, с тех пор постепенно развивается и дополняется. В Windows 7 появилась возможность фильтрации на уровне Ethernet, возможность делать редиректы соединений (как исходящих, так и входящих), а также разные вспомогательные функции, например для своевременной очистки ресурсов. В Windows 8 появилось то, чего так долго ждали некоторые разработчики - возможность многократно перекидывать соединение с одного прокси на другой. Раньше из-за отсутствия этой возможности было почти нереальным иметь в системе, к примеру, параллельно работающий фаервол и какой-нибудь спам-фильтр от разных производителей. Есть и другие изменения, все они описаны в MSDN. Ложка дегтя. Лично для меня ложкой дегтя в WFP является то, что наиболее "вкусные" вещи в ней появились только в Windows 7 - Windows 8 и для того, чтобы сделать коммерческий продукт, реально совместимый со всей современной линейкой Windows, не списывая со счетов XP и Vista, все равно приходится использовать TDI/LSP вместе с WFP. Также я замечал, что документация местами недостаточно детальная, а кое-где содержит ошибки. В итоге приходилось иногда закапываться надолго в отладчик, чтобы узнать, в чем дело. И в WFP, как и в любой технологии, есть недочеты и даже ошибки. Сам я с ними на практике не сталкивался, но не раз слышал о проблемах с Teredo, например, в результате чего система выпадает в синий экран (BSOD). Документация и исходники. Главный источник информации по WFP - конечно же, MSDN. Обращаю внимание, что WFP имеет функции как в kernel mode, так и в user mode, поэтому одну часть документации следует искать в разделе о программировании драйверов, а вторую - в разделе "network programming" из WinAPI: Windows Filtering Platform http://msdn.microsoft.com/en-u... 85%29.aspx Windows Filtering Platform Callout Drivers http://msdn.microsoft.com/en-u... 85%29.aspx Аналогично, исходники примеров для WFP есть как в Windows SDK Samples (diagevents и msnfilter) и в Windows Driver Kit Samples (ddproxy, inspect, msnmntr и stmedit). Вероятно, на MSDN Gallery можно найти и другие исходники, а где-нибудь на codeproject, sourceforge и других опенсорсных хостингах - исходники проектов с использованием WFP. В следующей части: Архитектура WFP, объектная модель, принципы работы.
4
|
|
|
Ушел с форума
|
|
| 04.11.2014, 15:19 | |
|
Часть 2, Архитектура.
Введение. Рассмотрим типичный жизненный цикл обмена информацией по протоколу TCP. 1. Приложение (клиент) вызывает функцию connect, указывая адрес и порт пункта назначения, а также семейство и тип протокола. Или же (сервер) оно вызывает accept в ожидании подключений. 2. Через некоторое время соединение установлено. Клиенту возвращается управление из функции connect (ну или приходит соответствующий сигнал, как в случае с моделью select или асинхронным I/O - это уже за рамками темы), серверу возвращается новый сокет, связанный с клиентом. 3. Приложения обмениваются данными посредством функций send и recv. 4. Приложения закрывают свои концы соединений функцией shutdown. Когда оба конца закрыты, связь завершается, соединение считается разомкнутым. Представим, что мы пишем фильтр TCP-трафика, и нас на каждом шаге этой последовательности интересуют определенные данные: 1. Адрес и порт пункта назначения, ID процесса, который выполнил connect/accept. Имя и вообще контекст безопасности пользователя, которому принадлежит процесс. 2. Статус операции connect (успех или ошибка). 3. Буферы, передаваемые через send и recv. Предположим, мы хотим блокировать нежелательные соединения (по набору запрещенных IP-адресов и портов, а также по процессам или пользователям). Мы также хотим получать уведомление о закрытии соединения (п.4), чтобы освободить все связанные с ним данные. WFP для решения этой задачи предлагает несколько абстракций: Layers - уровни фильтрации. Каждым уровнем обслуживается определенный этап обработки соединения или передачи данных. Например, установка соединения обрабатывается на уровне ALE (будет рассмотрен ниже), а работа с буферами send/recv - на уровне Stream. У каждого уровня своя специфика и свой набор свойств, с которыми можно работать. Часто ту информацию, что можно достать на одном уровне, уже нельзя увидеть на других. Аналогично, не все функции, которые работают на одних уровнях, работают на других. Sublayers - подуровни. Нужны для организации более гибкой стратегии фильтрации. Например, можно зарегистрировать проверки на разных Sublayers и они будут выполняться по очереди. Filters - фильтры. Задают разные условия, при которых должна (или не должна) выполняться фильтрация. Например, можно фильтровать только трафик, идущий на порт 80, а остальной игнорировать. Фильтры определяют не только условия, но и действия, т.е. что делать с трафиком, когда условие срабатывает. Основные операции: разрешить, заблокировать, задержать, либо вызвать соответствующий Callout. Про Callout-ы будет написано ниже. Conditions - условия, заданные в фильтре. В фильтре может быть несколько условий. Shims - исполнительные объекты, расположенные во всех ключевых точках сетевого стека. Если Filters и Conditions только задают правила, что делать с трафиком, то Shims отвечают за само выполнение этих правил, т.е. блокировка, задержка трафика, вызов Callout-а и так далее. Callout - блок функций, которые обрабатывают трафик и решают, что конкретно с ним делать. Callout Driver - драйвер, реализующий один или несколько Callout-ов. Provider - поставщик. Объединяет логически связанные Filters, Sublayers и Callouts, принадлежащие одной программе, одной задаче/политике, или объединенные какими-то другими общими признаками. Filter Engine (Engine) - функциональное ядро WFP, которое управляет фильтрами, Shim-ами, Callout-ами и остальными объектами технологии. Base Filter Engine (BFE) - служба, отвечающая за координацию компонентов WFP, за регистрацию новых фильтров, за хранение конфигурации, настройки безопасности и т.д. Ссылки по теме: WFP Architecture http://msdn.microsoft.com/en-u... 85%29.aspx Object Model http://msdn.microsoft.com/en-u... 85%29.aspx Как это работает. Когда в сетевом стеке происходит какое-то событие, например установка или закрытие соединения, приход дейтаграммы, получение буфера с данными и т.п., Filter Engine с помощью Filters определяет, нужно ли как-то обрабатывать это событие. В терминах WFP данный процесс называется классификацией (classify). Если хотя бы один Condition срабатывает, вызывается Shim, который, в зависимости от того, что задано в фильтре, выполняет нужное действие. В частности, Shim может вызвать ваш зарегистрированный Callout, точнее, одну из его функций (из всего три). Все остальное выполняет Callout, в соответствии с логикой фильтрации трафика. Если, к примеру, Callout работает на уровне ALE, то в функцию ему будут переданы адрес и порт пункта назначения и источника, тип протокола, ID приложения, полный путь к exe и другая полезная информация. Если на уровне Stream, там будут другие данные - направление трафика (входящий/исходящий), флаги и т.д. Далее Callout может поступать с данными на свое усмотрение: блокировка, игнор, редирект, анализ, задержка трафика и многое другое. Все ограничено лишь фантазией разработчика. Выше была описана типичная последовательность операций при работе с TCP. Давайте посмотрим, как она будет фильтроваться WFP. 1. Установка соединения (connect). Здесь будут срабатывать фильтры на уровне FWPS_LAYER_ALE_AUTH_CONNECT_V4. Здесь же можно заблокировать соединение. 2. Соединение установлено. Сработают фильтры на уровне FWPS_LAYER_ALE_FLOW_ESTABLISHED_V4. Добавлю, что на этом уровне блокировать коннект не рекомендуется, он создан только для того, чтобы Callout получил уведомление о том, успешно или нет создано соединение. Здесь же можно установить связь между коннектом и потоком данных. 3. Передача данных. Будут срабатывать фильтры на уровне FWPS_LAYER_STREAM_V4, причем как для send (outgoing data), так и для recv (incoming data). 4. Закрытие соединения. Если с потоком данных был ассоциирован контекст, будет вызвана одна из функций Callout-а. Также на Windows 7 есть специальные уровни для очистки ресурсов - FWPS_LAYER_ALE_RESOURCE_RELEASE_V4. Еще определения. Flow (поток данных). Каждое соединение - это отдельный двунаправленный поток данных. Если, к примеру, программа создает два коннекта на один и тот же адрес, вы будете в драйвере видеть два разных потока данных, каждый со своим состоянием. Flow Context (контекст потока). 64-битное число, ассоциированное с определенным потоком данных. Нужно, чтобы отличать потоки друг от друга. Fixed Values. Фиксированный набор аргументов, приходящий в Callout. Описан здесь: Data Field Identifiers http://msdn.microsoft.com/en-u... 85%29.aspx Для каждого Layer-а свой набор аргументов. Например, на уровне FWPS_LAYER_ALE_CONNECT_REDIRECT_V4 (установка соединения) через Fixed Values можно получить имя пользователя, а на уровне FWPS_LAYER_STREAM_V4 его уже нет. Meta Values. Аналогично Fixed Values. Информация здесь: Metadata Fields at Each Filtering Layer http://msdn.microsoft.com/en-u... 85%29.aspx Итак, Callout, заглядывая в Fixed Values и Meta Values, решает, что делать с данным событием/трафиком и предпринимает определенные действия, после чего весь цикл повторяется заново. Доступ к буферам с данными осуществляется через структуру NET_BUFFER (будет описана в следующих частях).
4
|
|
|
14 / 13 / 1
Регистрация: 30.09.2011
Сообщений: 160
|
|
| 04.11.2014, 17:36 [ТС] | |
|
хорошо, тогда как мне написать фильтрацию в kernel-mode? я имею в виду, взять и переделать семпл-пример из WDK (strmedit or WFPSampler), или можно с нуля писать фильтрацию, дергая функции из fwpkclnt.sys (из файлов-заголовков а-ля ntifs.h, fwpmk.h и другие)?
я просто не могу понять подхода этого..
0
|
|
|
Ушел с форума
|
|
| 04.11.2014, 18:41 | |
|
Для начала нужно зарегистрировать своего провайдера и связать с ним
нужные Sublayers, Callouts и Filters. Для этого есть такие функции: FwpmProviderAdd0, FwpmSubLayerAdd0, FwpmFilterAdd0. Хэндл Filter Engine получается вызовом FwpmEngineOpen0, лучше обернуть операцию установки и удаления в транзакцию - FwpmTransactionBegin0 и FwpmTransactionCommit0. Не забываем использовать флаг FWPM_XXXX_FLAG_PERSISTENT, тогда регистрация драйвера сохранится после перезагрузки. Обычно регистрацию выполняет установщик. В самом Callout-е всего три функции: ClassifyFn, NotifyFn и FlowDelete. ClassifyFn выполняет классификацию трафика и, к примеру, блокировку. NotifyFn опциональна и нужна для получения уведомлений, происходящих с Filter Engine (например, добавление новых фильтров). Ну а FlowDelete вызывается при уничтожении Flow, чтобы иметь возможность очистить связанные с ним ресурсы. Для фильтрации TCP можно поступить так: зарегистрировать два Callout-а, один на уровне FWPM_LAYER_ALE_AUTH_CONNECT_V4 (установка соединения), второй на уровне FWPM_LAYER_STREAM_V4 (передача данных). См. функцию FwpsCalloutRegister0, например. Когда сработает Callout на ALE, получаем IP-порт из Fixed/Meta Values, и если надо, блокируем коннект (FWP_ACTION_BLOCK). Если нужно анализировать данные дальше, ничего не делаем. Дальше будет срабатывать Callout на уровне Stream. Здесь нужно вытаскивать данные из буферов (см. третий параметр функции ClassifyFn), анализировать их, и при случае блокировать передачу (также FWP_ACTION_BLOCK). Все данные передаются в формате NET_BUFFER, описание есть в MSDN и на CodeMachine. Я собирался написать это в ближайших двух-трех частях, а уже потом отвечать на вопросы.
2
|
|
|
14 / 13 / 1
Регистрация: 30.09.2011
Сообщений: 160
|
|
| 04.11.2014, 18:56 [ТС] | |
|
охх... тогда жду части)
довольно познавательно!!!
0
|
|
|
Ушел с форума
|
|||||||||||||||||||||
| 05.11.2014, 22:56 | |||||||||||||||||||||
|
Часть 3-а, Регистрация в системе.
Регистрация выполняется в режиме пользователя, обычно эта функция возлагается на установщик программы. Впрочем, никто не мешает регистрировать драйвер каждый раз при запуске программы, WFP дает такую возможность. Регистрация начинается с функции FwpmEngineOpen0. Кстати, небольшое отступление. В WFP, как и в некоторых других специфических компонентах Windows, принята своя система именования: ПрефиксТипОбъектОперацияВерсия. Префикс - Fwp, общий для подсистемы WFP. Тип - означает тип операции, managed (m) или run-time (s). Все, что managed, относится к user mode, а run-time относится к kernel mode. Например, при регистрации из user mode в качестве Layer передается константа FWPM_LAYER_INBOUND_IPPACKET_V4, а в kernel mode она же фигурирует под именем FWPS_LAYER_INBOUND_IPPACKET_V4. Объект - указывает сущность, к которой применяется операция. В данном случае Engine. Open - операция. 0 - номер версии. Похожие соглашения можно встретить в Windows еще кое-где (например, в WDF). Итак, FwpmEngineOpen0:
В простейшем случае Session достаточно заполнить нулями, указав только displayData.name и displayData.description. Отдельно стоит отметить флаг FWPM_SESSION_FLAG_DYNAMIC - при его использовании регистрация действует до того момента, когда будет закрыт хэндл hEngine (или до того момента, когда приложение завершится). MSDN настоятельно рекомендует оборачивать операции установки и удаления внутрь транзакции, и я не вижу причин, по которым не стоит следовать этому совету. Для этого нам помогут функции FwpmTransactionBegin0 и FwpmTransactionCommit0, а также FwpmTransactionAbort0. Все очень просто: сразу после FwpmEngineOpen открываем транзакцию и все остальные объекты регистрируем между Begin и Commit. Если что-то пошло не так, зовется функция Abort, отменяющая все сделанные изменения. Следующий необходимый шаг - регистрация провайдера. Как нетрудно догадаться, для этого нужна функция FwpmProviderAdd0. И здесь все достаточно тривиально, обойдемся без комментариев. Обращаю внимание на флаг FWPM_PROVIDER_FLAG_PERSISTENT: если его не поставить, то после перезагрузки компьютера можно с удивлением обнаружить, что никакого провайдера в системе нет. Аналогичные флаги персистентности есть у Filters, Callouts и Sublayers.
При чтении документации WFP становится не сразу понятно, зачем вообще нужны подуровни и почему нельзя поставить свой фильтр на какой-нибудь существующий уровень/подуровень. Ответ находится здесь: Filter Arbitration http://msdn.microsoft.com/en-u... 85%29.aspx Если вкратце, смысл вот в чем. Представьте, что на одном и том же подуровне сидят два фильтра от разных провайдеров, которые анализирут трафик и решают, пропускать его или нет. В этом случае, если верхний фильтр (т.е. тот, который вызывается раньше другого) явным образом разрешит прохождение трафика (FWP_ACTION_PERMIT), нижний фильтр вообще не будет участвовать в "голосовании". Почему - спросите у разработчиков WFP. Так задумано. Но в таком случае это поведение нарушает логику работы второго фильтра, который при других обстоятельствах запретил бы трафик. Впрочем, вы можете посадить фильтр на какой-нибудь предопределенный подуровень и не мучиться. Только потом не удивляйтесь, если ваш Callout не всегда будет срабатывать. Добавить Sublayer очень просто, как и все остальное:
Более "тяжелые" Sublayer-ы обрабатываются первыми. Этот параметр нужен для упорядочивания своих Sublayer-ов, а вовсе не для того, чтобы записать туда 0xFFFF в надежде быть всегда первым. Регистрируем Callout:
Здесь я зарегистрировал Callout на уровне FWPM_LAYER_ALE_AUTH_CONNECT_V4. Вы можете использовать другой уровень, можете добавить еще один или несколько Callout-ов или Sublayer-ов, WFP это позволяет.
4
|
|||||||||||||||||||||
|
Ушел с форума
|
|||||||||||
| 05.11.2014, 22:59 | |||||||||||
|
Часть 3-б, Регистрация.
Регистрация фильтров. Переходим к самому сложному этапу:
2) порт 80. Таким образом, мы хотим ловить весь трафик, проходящий по TCP на 80 порту (обычно HTTP). В каждом условии fieldKey задает признак, который будет проверяться. Их достаточно много: Filtering Condition Identifiers http://msdn.microsoft.com/en-u... 85%29.aspx Кроме этого, можно проверять также различные флаги, например на Windows 8 с помощью флага FWP_CONDITION_FLAG_IS_PROXY_CONNECTION можно проверить, является ли соединение проксируемым. Полный список здесь: Filtering Condition Flags http://msdn.microsoft.com/en-u... 85%29.aspx Но будьте осторожны ! Как и в случае с Fixed Values / Meta Values, конкретные свойства и флаги доступны только на конкретных уровнях. Filtering Conditions Available at Each Filtering Layer http://msdn.microsoft.com/en-u... 85%29.aspx matchType задает тип проверки - равно/не равно, больше/меньше, проверка диапазона и т.д. Например, если бы я вместо FWP_MATCH_EQUAL поставил FWP_MATCH_GREATER, фильтр стал бы срабатывать на всех соединениях с номером порта больше 80. Вот список доступных типов проверки:
значение, которое требуется сравнивать. Фильтр устанавливается на конкретном Sublayer-е (Filter.subLayerKey) и, как и другие объекты, имеет схожие флаги. "Вес" фильтра имеет значение, когда у вас на одном Sublayer сидят два или более фильтров. В других случаях конкретное значение роли не играет. Но на всякий случай все равно советую заглянуть сюда: Filter Weight Assignment http://msdn.microsoft.com/en-u... 85%29.aspx Filter Weight Identifiers http://msdn.microsoft.com/en-u... 85%29.aspx Ну и ключевой момент: в action.type указывается тип действия, которое будет выполняться при срабатывании фильтра. Возможных значений всего пять: FWP_ACTION_BLOCK Заблокировать трафик. FWP_ACTION_PERMIT Разрешить трафик. FWP_ACTION_CALLOUT_TERMINATING FWP_ACTION_CALLOUT_INSPECTION FWP_ACTION_CALLOUT_UNKNOWN Вызвать Callout. Разница между TERMINATING, INSPECTION и UNKNOWN только в том, что позволено делать Callout-у. TERMINATING-Callout обязан явным образом либо разрешить, либо заблокировать соединение. INSPECTION-Callout может только наблюдать. UNKNOWN-Callout может, но не обязан, блокировать или разрешать трафик. Если вы ассоциируете с фильтром Callout, то должны указать его GUID в поле action.calloutKey. Пока Callout Driver еще не написан, так что делать этот фильтр ничего полезного не будет. Кстати, здесь может возникнуть вопрос: а зачем вообще нужен Callout, если можно создать правило и установить в фильтре action.type = FWP_ACTION_BLOCK, блокируя нежелательные соединения ? Правильно, так можно и нужно делать, если этого достаточно для вашей задачи. Добавлю, что в WFP есть несколько предопределенных Callout-ов для некоторых задач, собраны они здесь: Built-in Callout Identifiers http://msdn.microsoft.com/en-u... 85%29.aspx Но все же FWP_ACTION_BLOCK и встроенных Callout-ов часто бывает недостаточно. Если вам нужно анализировать, а тем более изменять трафик, работая с буферами данных, то без написания Callout-драйвера не обойтись. Итак, подытожим. Мы создаем хэндл Engine, открываем транзакцию, затем внутри транзакции регистрируем своего провайдера, связываем с ним один или несколько Sublayers, добавляем Callouts и Filters на нужные уровни/подуровни, остается только позвать FwpmTransactionCommit0 и позакрывать хэндлы. С этого момента ваши объекты вступают в "игру" в сетевом стеке Windows. Отмена регистрации - обратная процедура, еще более простая. Функции FwpmEngineOpen0 и FwpmTransactionBegin0 должны быть уже вам знакомы, они и здесь используются. Для удаления фильтров используйте FwpmFilterDeleteByKey0, для удаления Callout-ов - FwpmCalloutDeleteByKey0, затем можно удалить Sublayer - FwpmSubLayerDeleteByKey, и наконец, провайдера - FwpmProviderDeleteByKey0, после чего завершаете транзакцию и закрываете хэндлы. В следующей части: реализация Callout в драйвере.
3
|
|||||||||||
|
Ушел с форума
|
||||||
| 09.11.2014, 23:32 | ||||||
|
Часть 4-а, реализация Callout-драйвера.
Переходим к реализации Callout-драйвера. Первое, что нужно сделать - создать устройство (DEVICE_OBJECT), для этого используется функция IoCreateDevice. Далее вызываем FwpsCalloutRegister0 столько раз, сколько Callout-ов нам требуется зарегистрировать:
classifyFn, notifyFn и flowDelete. Вы можете использовать одни и те же функции для разных Callout-ов. Кстати, в Windows 7 и выше доступна функция FwpsCalloutRegister1, а в Windows 8 - FwpsCalloutRegister2. Они предоставляют более интересные возможности, например редирект соединений. Обращаю внимание на флаг FWP_CALLOUT_FLAG_CONDITIONAL_ON_FLOW: если установить его, Callout будет срабатывать только для данных, с которыми связан определенный Flow Context. Иными словами, можно выборочно контролировать определенный трафик, игнорируя остальные. Также замечу, что если необходимые фильтры уже зарегистрированы, Callout начинает действовать сразу же, еще до выхода из функции FwpsCalloutRegister0, так что если у вас есть какие-то общие данные, разделяемые с Callout-ом, они должны быть инициализированы до того, как эта функция будет вызвана. Удалить Callout также просто: FwpsCalloutUnregisterById0, функция принимает единственный аргумент - ID Callout-а. После удаления Callout-ов не забудьте удалить устройство, созданное IoCreateDevice.
3
|
||||||
|
Ушел с форума
|
|||||||||||||||||||||||||||||||
| 09.11.2014, 23:41 | |||||||||||||||||||||||||||||||
|
Часть 4-б, функции Callout-а.
Их всего три: classifyFn, notifyFn и flowDelete, причем notifyFn может быть реализована очень просто, а flowDelete опциональна и вместо нее можно передать NULL (если вы не работаете с Flow Context). classifyFn
над Callout-драйвером. Разберем по порядку параметры: pInFixedValues - Массив Fixed Values (рассматривалось выше). Вытаскивать данные из этого массива следует примерно так:
pInMetaValues - Массив Meta Values. Перед тем, как обращаться к полям этого массива, следует проверить, присутствует ли значение в нужном поле. Например:
Здесь может быть либо NULL, в зависимости от условий, либо указатель на структуру FWPS_STREAM_CALLOUT_IO_PACKET0 (для stream-уровней, таких как FWPS_LAYER_STREAM_V4), либо NET_BUFFER. Так или иначе все сведется к работе с NET_BUFFER (будет описана в одной из следующих частей). Состав данных, которые приходят в pLayerData, сильно зависит от уровня фильтрации, на котором зарегистрирован Callout. Например, обрабатывая TCP-поток на уровне FWPS_LAYER_STREAM_V4, вы не увидите в данных заголовков IP-пакетов и т.п. pFilter - указатель на Filter, по условию которого сработал ваш Callout. Здесь находятся важные данные, которые нельзя проигнорировать. Отнеситесь с вниманием к флагам FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT и FWPS_FILTER_FLAG_PERMIT_IF_CALLOUT_UNREG ISTERED, как описано здесь: FWPS_FILTER0 structure http://msdn.microsoft.com/en-u... 85%29.aspx Если FWPS_FILTER_FLAG_CLEAR_ACTION_RIGHT установлен, вы должны сбросить флаг FWPS_RIGHT_ACTION_WRITE в соответствующей структуре (будет описана ниже), если завершаете classifyFn с кодом FWP_ACTION_PERMIT (разрешить) или FWP_ACTION_BLOCK (заблокировать). Обычно сбрасывать FWPS_RIGHT_ACTION_WRITE требуется только при FWP_ACTION_BLOCK. Флаг FWPS_FILTER_FLAG_PERMIT_IF_CALLOUT_UNREG ISTERED означает, что если Callout не зарегистрирован, вам следует пропустить трафик дальше, не блокируя его. В поле action фильтра будет указан тип Callout-а, в зависимости от которого вам разрешается или нет использовать соответствующие коды завершения, об этом я уже писал выше: FWP_ACTION_CALLOUT_TERMINATING требует, чтобы Callout установил для трафика FWP_ACTION_PERMIT или FWP_ACTION_BLOCK, FWP_ACTION_CALLOUT_INSPECTION может только наблюдать (FWP_ACTION_CONTINUE) и т.д. Вы не должны нарушать эти требования, иначе правильная система фильтрации не гарантируется. На таких принципах, кстати, построено очень многое во взаимодействии фильтрующих драйверов, не только сетевых: вам дается большая гибкость и разнообразие средств, но вместе с тем вы должны придерживаться определенных правил и не ставить "палки в колеса" другим драйверам. FlowContext - название говорит само за себя. Здесь передается значение, связанное с потоком данных, при условии, что вы задали его где-то раньше. Это значение вы можете использовать на свое усмотрение, например передавать через него адрес каких-то структур данных или функций, связанных именно с этим потоком, либо что-то еще. Размер поля FlowContext - 64 бита, хватит на все, единственное ограничение - нельзя иметь Flow Context, равный нулю. Про Flow Context и потоки данных будет написано в одной из следующих частей. pClassifyOut - сюда вы указываете, как хотите поступить с трафиком. Поле actionType: FWP_ACTION_PERMIT - разрешить; FWP_ACTION_BLOCK - заблокировать; FWP_ACTION_CONTINUE - передать запрос на рассмотрение в другой фильтр. Вы можете установить любой код, если он не противоречит условиям action фильтра, описанным выше. Обратите внимание, что если флаг FWPS_RIGHT_ACTION_WRITE в поле rights сброшен, то вы не имеете права ничего писать в actionType, кроме FWP_ACTION_BLOCK. То есть, либо пишете FWP_ACTION_BLOCK, либо оставляете поле как есть, без изменений. Попробуем сложить все вместе. Пример ниже подразумевает, что в фильтре указан action.type FWP_ACTION_CALLOUT_UNKNOWN, т.е. Callout может возвращать и permit, и block, и continue:
составлять суть вашей программы, кроется за комментариями "//...". Напоследок добавлю, что вы не можете просто взять и изменить данные в pLayerData. Для подобных вещей в WFP принято несколько схем: "close-reinject", "drop-reinject", и т.д. То есть, чтобы изменить данные, следует сначала заблокировать (FWP_ACTION_BLOCK) нужный фрагмент (см. структуру FWPS_STREAM_CALLOUT_IO_PACKET0), а затем вставить новый - FwpsStreamInjectAsync0. Если требуется отложить обработку трафика, например задать вопрос пользователю в интерактивном режиме, следует использовать специальные функции: на ALE-уровнях есть FwpsPendOperation0/FwpsCompleteOperation0, на Stream- уровнях есть FwpsCloneStreamData0/FwpsStreamInjectAsync0 и т.д. Собственно, здесь все достаточно хорошо расписано, еще и с примерами: Inspecting Packet and Stream Data http://msdn.microsoft.com/en-u... 85%29.aspx notifyFn
Сюда приходят уведомления о добавлении и удалении фильтров: FWPS_CALLOUT_NOTIFY_ADD_FILTER и FWPS_CALLOUT_NOTIFY_DELETE_FILTER. Все, что вам нужно - вернуть STATUS_SUCCESS, либо код ошибки, если вы не хотите, чтобы фильтр был добавлен в Filter Engine. Своего рода фильтр для фильтров. flowDeleteFn
Здесь последняя возможность очистить связанные с потоком данные, используя значение FlowContext. Если вы не используете FlowContext, можете игнорировать эту функцию или вообще установить ее в NULL при регистрации Callout-а. Не забывайте, что все три функции Callout-а вызываются на IRQL <= DISPATCH_LEVEL. В следующей части: потоки данных, работа с Flow Context, как отличить данные одного соединения от другого.
4
|
|||||||||||||||||||||||||||||||
|
14 / 13 / 1
Регистрация: 30.09.2011
Сообщений: 160
|
|
| 18.11.2014, 15:04 [ТС] | |
|
ждём продолжения))
и если можно, чуть детальной про IRQL и unreferenced parameter...
0
|
|
|
Почетный модератор
|
|
| 18.11.2014, 21:45 | |
|
X-Cod, продолжение будет здесь Краткий обзор Windows Filtering Platform, подписывайтесь
1
|
|
|
14 / 13 / 1
Регистрация: 30.09.2011
Сообщений: 160
|
|
| 19.11.2014, 12:45 [ТС] | |
|
NickoTin, пасяб)
0
|
|
|
0 / 0 / 0
Регистрация: 04.11.2014
Сообщений: 3
|
|
| 30.12.2014, 14:55 | |
|
Добрый день. По документации, примерам ddk, и информации из Вашей статьи дошел до такого: драйвер(регистрирует 3 callouts - FWPM_LAYER_ALE_AUTH_CONNECT_V4, FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4, FWPM_LAYER_STREAM_V4). На уровне connect с помощью WokrItem получаю UserName, Domain процесса. На уровне
0
|
|
|
Ушел с форума
|
|
| 30.12.2014, 15:58 | |
|
0
|
|
|
0 / 0 / 0
Регистрация: 04.11.2014
Сообщений: 3
|
|
| 30.12.2014, 16:05 | |
|
Добрый день. По документации, примерам ddk, и информации из Вашей статьи дошел до: драйвер (регистрирует 3 колаута - FWPM_LAYER_ALE_AUTH_CONNECT_V4, FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4, FWPM_LAYER_STREAM_V4).
- на уровне FWPM_LAYER_ALE_AUTH_CONNECT_V4 с помощью WorkItems получаю UserName, Domain и путь к файлу процесса, ассоциирую информацию с уровнем FLOW_ESTABLISHED; - на уровне FWPM_LAYER_ALE_FLOW_ESTABLISHED_V4 получаю удалённый адрес и порт, ассоциирую информацию с уровнем STREAM; - на уровне FWPM_LAYER_STREAM_V4 уходит/приходит http трафик; Хочу добиться сбора url и названия посещённых страниц. Что делаю: использую RTL_AVL_TABLE для хранения информации о соединениях; При ESTABLISHED создаю в RTL_AVL_TABLE элемент(также записываю в него данные path, user, domain, remote/local port,...); При STREAM изменяю(дополняю) элемент в RTL_AVL_TABLE, запросом GET и ответом на него. (POST, HEAD и др. игнорирую); При STREAM_DELETE помечаю элемент в RTL_AVL_TABLE как completed для дальнейшей работы над ним; Создание, изменение, пометка элемента как completed происходит в 3х разных WorkItem -ах. Как я понял они работают асинхронно; Иногда получается что код из Stream_WorkItem выполняется раньше чем код Established_WorkItem; В голову приходит такое решение: 1) сделать отдельный поток и через список со спинлоком передавать в него информацию из ESTABLISHED, STREAM и STREAM_DELETE . Таким образом добиться обработки ESTABLISHED->STREAM->STREAM_DELETE по порядку; 2) сделать вместо 3х WorkItem-ов сделать один WorkItem, и возможно это решит данную проблему(хотя не совсем уверен); Какое из решений будет правильнее с точки зрения производительности(либо оба неправильные), с учётом парсинга http страницы для получения заголовка страницы(<title>)? Заранее спасибо. Добавлено через 54 секунды )))
0
|
|
|
Ушел с форума
|
|
| 30.12.2014, 16:15 | |
|
А что мешает парсить поток данных прямо из classifyFn ?
0
|
|
|
0 / 0 / 0
Регистрация: 04.11.2014
Сообщений: 3
|
|
| 30.12.2014, 16:28 | |
|
Хотя да, я что-то сильно намудрил с воркайтемами. Вся информация передаётся с CONNECT в ESTABLISHED, а с ESTABLISHED в STREAMclassify.
Еще раз спасибо.
0
|
|
| 30.12.2014, 16:28 | |
|
Помогаю со студенческими работами здесь
20
Сетевая фильтрация Организация URL адресов Фильтрация MAC адресов в модеме DLINK 2540U Смена URL адресов страниц Создание дружественных адресов URL Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
Модель заражения группы наркоманов
alhaos 17.04.2026
Условия задачи сформулированы тут
Суть:
- Группа наркоманов из 10 человек.
- Только один инфицирован ВИЧ.
- Колются одной иглой.
- Колются раз в день.
- Колются последовательно через. . .
|
Мысли в слух. Про "навсегда".
kumehtar 16.04.2026
Подумалось тут, что наверное очень глупо использовать во всяких своих установках понятие "навсегда". Это очень сильное понятие, и я только начинаю понимать край его смысла, не смотря на то что давно. . .
|
My Business CRM
MaGz GoLd 16.04.2026
Всем привет, недавно возникла потребность создать CRM, для личных нужд. Собственно программа предоставляет из себя базу данных клиентов, в которой можно фиксировать звонки, стадии сделки, а также. . .
|
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . .
а удачный момент так и не приходит.
|
|
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица.
Задача: зафиксировать три левых колонки в отчете.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
/ / . . .
|
Настройки VS Code
Loafer 13.04.2026
{
"cmake. configureOnOpen": false,
"diffEditor. ignoreTrimWhitespace": true,
"editor. guides. bracketPairs": "active",
"extensions. ignoreRecommendations": true,
. . .
|
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2.
Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива.
Было так:. . .
|
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2.
Задача: реализовать контроль корректности заполнения дат назначения. . .
|