Добрый день. Ситуация: На NDIS уровне определяю процесс, иницировавший отправку пакетов. Меня интересуют только исходящие пакеты. Использую PassThru драйвер, обработчик SendHandler. Во всех случаях процесс определяется без проблем. Вопрос: Можно ли считать данный способ определения процесса правильным? Если да, то почему, сколько читаю форумы, все в один голос утверждают, что на NDIS нельзя узнать процесс, нужно использовать только TDI?
Во-первых, о каком именно способе речь? Если ты тупо берёшь текущий процесс, то подумай, что будет в случае, если сверху сидит фильтр транспортного уровня (ну тот же TDI, к примеру), который обрабатывает и шлёт ниже запросы из выделенного ядерного потока. Более того, такой фильтр может вообще оригинальные IRP вниз не пускать, а создавать и слать ниже свои собственные. Очевидно, что контекст процесса в этом случае утерян. Да можно, в общем-то, но есть проблемы, сам понимаешь.
Если речь идет о Tcp и udp (что в большинстве случаев так и есть) пакетах, можно попробовать поработать с портами, так как каждый порт привязывается к конкретному приложению. Значит в принципе можно выяснить, что за программа послала пакет. Насколько я разумею верхний фильтр вряд-ли будет подменять порты на другие, если только он не что-то вроде ната, или socks сервера. Попробуйте ковырнуть утилиту Русиновича TcpView она как раз это и делает.
Вот так она это делает (точнее так, но один хрен всё к транспорту сводится). Только в ядре с этим могут быть проблемы, т.е. я не уверен, что этот запрос можно слать из Send-обработчика NDIS-фильтра. Тут как минимум могут быть проблемы с текущим IRQL, а также проблемы с актуальностью информации, которую транспорт возвращает по этому запросу. Например, опять же ситуация: верхний IM-драйвер уже обработал и отпустил оригинальный запрос, а данные вниз шлёт уже сам, соответственно, в момент, когда вызовут твой драйвер, процесс-инициатор всего этого может быть уже дохлый или, что ещё хуже, на его месте (т.е. с тем же ID) может быть создан другой процесс. В общем, как бы проблем слишком много, чтобы говорить об этом серьёзно.
Согласен, есть мысля. как правило IM драйверы как верхнего интерфейса так и нижнего работают на уровне DISPATCH_LEVEL, можно поступить другим способом. Пусть в SendXXX или XXXProtocol функциях, я будут только записывать нужные мне порты в буфер(чтобы не часто вызывать worker thread, поскольку производительность может реально просесть), а затем уже после того как у меня наберется достаточно портов, вызову worker thread, который работает как известно на PASSIVE_LEVEL, и уже из него определяют, какому порту соответствует какое приложение и сохраняю названия программ и их порты, затем полингом время от времени юзерлендовское приложение выуживает эту инфу. Или еще проще передаем юзермодовскому приложению набор портов, и оно уже само определяет какому порту какое приложение соответствует используя вашу ссылку на функции.
neutronion Это всё не решает проблему с актуальностью информации. Боюсь, что эта задача тупо не имеет решения в общем случае.
То есть причина, почему на NDIS уровне не определяют процесс, только в том, что какой-нибудь вышестоящий драйвер может изменить контекст процесса?
maxxx777 практически проблема решается но геморроя дофига мешают не только вышестоящий драйвер или лсп если дестинейшин-адрес отсутствует в арп-таблице то пакет откладывается и посылается после получения арп-реплая в контексте систем-идле внутри тсп-сессии большинство пакетов идет в контексте сисем-идле все ретраи идут там же ну и всё что выше очень любит перехватить и послать свой от себя для тсп надо посылать запрос через воркер-тред но только его не надо дергать на каждом пакете достаточно на SYN-е (пусть первый пропадет - не страшно - как раз на его задержке тред и отработает) при этом конечно надо вести свою таблицу сессий все таймауты есть в реестре Services\TCPIP\Parameters
Можно проще поступить, перехватывать момент, когда процесс вызывает, connect, тогда уже наверняка можно сказать, какой порт закреплен за каким приложением. И тогда вообще не нужно делать фильтр пакетов, так как список открытых портов уже есть, это значит, что тормозов трафика фильтром не будет, а значит на производительность никак не повлияет. И какие там фильтры внизу уже безразлично.