пишу секюрити продукт на базе TDI фильтра. заметил одну интересную особенность — исходящий трафик
проходит через обработчик TDI_SEND, так его легко получить из IRP. со входящими данными посложнее —
в обработке участвуют в той или иной мере TDI_RECEIVE, ReceiveCallback и ChainedReceiveCallback поочередно
(это не считая expedited трафика, о нем разговор отдельный). у меня два вопроса:
1) кого из них нужно перехватывать для полного анализа входящего трафика
2) есть ли четкая закономерность, как HTTP траффик распеределен по трем данным обработчикам, или
это когда как.
кроме того, слышал, в Висте и Семерке TDI не всегда корретно работчват, лучше юзать NPI/WFP, хотя
первый не документировани, а второй имеет ряд серьезный багов, особенно в семерке. стоит ли работать с NPI/WFP?
заранее благодарен
Re: TDI_RECEIVE, ReceiveCallback и ChainedReceiveCallback
C_>пишу секюрити продукт на базе TDI фильтра. заметил одну интересную особенность — исходящий трафик C_>проходит через обработчик TDI_SEND, так его легко получить из IRP.
Не всё идёт через TDI_SEND, кое-что идёт через TDI_DIRECT_SEND, например, SMB.
C_>1) кого из них нужно перехватывать для полного анализа входящего трафика
Достаточно фильтровать TDI_RECEIVE и ClientEventReceive, а установку обработчика ClientEventChainedReceive() можно фейлить на TDI_SET_EVENT_HANDLER. Нормальный клиент должен адекватно отреагировать на подобный отлуп. Во всяком случае, системные драйвера реагируют адекватно, следовательно, это эталонное поведение. Ну а если всё же очень хочется перехватить именно chained-вариант, то придётся заморочиться с грязнохуками, но я не уверен, что это нужно.
C_>2) есть ли четкая закономерность, как HTTP траффик распеределен по трем данным обработчикам, или C_>это когда как.
Нет, зависимости нет, однако начиная с Windows Vista, транспорт старается дёргать чаще chained-колбек, чем не-chained, т.к. он более производителен.
C_>кроме того, слышал, в Висте и Семерке TDI не всегда корретно работчват, лучше юзать NPI/WFP, хотя C_>первый не документировани, а второй имеет ряд серьезный багов, особенно в семерке. стоит ли работать с NPI/WFP?
Весь сокетный трафик (afd.sys), а также кое-что ещё, включая ядерный HTTP-сервер (http.sys), проходит через TDI. И на Windows 7 в том числе.
Re[2]: TDI_RECEIVE, ReceiveCallback и ChainedReceiveCallback
От:
Аноним
Дата:
09.07.11 08:16
Оценка:
Здравствуйте, x64, Вы писали: x64>Достаточно фильтровать TDI_RECEIVE и ClientEventReceive, а установку обработчика ClientEventChainedReceive() можно фейлить на TDI_SET_EVENT_HANDLER. Нормальный клиент должен адекватно отреагировать на подобный отлуп. Во всяком случае, системные драйвера реагируют адекватно, следовательно, это эталонное поведение.
Реанимирую тему: x64, сорри, может гулпқй вопрос, но (если речь идет о простом TDI-фильтре) что значит зафейлить хендлер ClientEventChainedReceive()?
К примеру есть код, устанавливающий такой обработчик:
А>...но (если речь идет о простом TDI-фильтре) что значит зафейлить хендлер ClientEventChainedReceive()?
Проблема в том, что перехватить chained receive обработчик просто так не получится. Вот представим ситуацию: клиент регистрирует chain receive обрабочик, но не регистрирует обычный receive обработчик и не шлёт TDI_RECEIVE, т.е. ждёт, когда ему транспортный драйвер будет давать прямой доступ к буферам. Допустим, мы перехватили этот обработчик. Что мы делаем, когда нас позвали? Производим некую обработку согласно нашему алгоритму, после чего мы должны вызвать оригинальный обработчик клиента. Если бы мы ранее перехватили обычный receive обрабочик, мы могли бы передать эти данные ему, но клиент его не зарегистрировал и это его право, никто не обязывает его делать это. Итак, мы вызвали chain receive обработчик клиента, тот вернул STATUS_PENDING. Теперь мы не можем вернуть данные транспорту, т.к. по документации мы должны дождаться, когда клиент вызовет TdiReturnChainedReceives(). Чтобы это сделать, мы должны перехватить TdiReturnChainedReceives(), например, пропатчив EAT соответствующего драйвера, а это уже никак не укладывается в рамки обычного фильтра. Сделать это, конечно, можно, если сильно охота, но во-первых, такое поведение вряд ли обойдут вниманием всякие антивирусы/антируткиты, т.е. можно поиметь проблем с ними, а значит и с пользователями твоего продукта, во-вторых, я не уверен, что модификация EAT сетевых драйверов будет работать на 64-битных системах, я даже на 99% думаю, что не будет, вроде бы даже видел где-то замечание на эту тему, ссылки вот только нет под рукой. Так что этот метод связан с определёнными проблемами и проще всего с этим просто не связываться. Гораздо проще в данном случае тупо завершить set event handler запрос с кодом STATUS_NOT_SUPPORTED, ну т.е. установить pIrp -> IoStatus и вызвать IoCompleteRequest().
Re[4]: TDI_RECEIVE, ReceiveCallback и ChainedReceiveCallback
От:
Аноним
Дата:
09.07.11 09:02
Оценка:
Здравствуйте, x64, Вы писали:
А>>...но (если речь идет о простом TDI-фильтре) что значит зафейлить хендлер ClientEventChainedReceive()?
x64, спасибо! Вы как всегда на высоте!
Re[5]: TDI_RECEIVE, ReceiveCallback и ChainedReceiveCallback
Не стоит.
Мои знания ничтожны.
Их может получить любой, кому реально надо разобраться в теме.
Другой вопрос в том, что народ у нас ленивый и им проще спросить.
Re[6]: TDI_RECEIVE, ReceiveCallback и ChainedReceiveCallback
Здравствуйте, x64, Вы писали:
x64>Не стоит. x64>Мои знания ничтожны. x64>Их может получить любой, кому реально надо разобраться в теме. x64>Другой вопрос в том, что народ у нас ленивый и им проще спросить.
А вот тут позволю себе не согласиться.
Дело в том, что у "любого" может просто не хватить интеллекта, для того чтобы разобраться в том или ином вопросе, как бы он этого ни хотел.
Могу привести не один пример, когда скажем так, кодеру "не дано сверху" разобраться в том или ином вопросе. Он не тупой, нет, ему просто "на дано".
Это как человек, знающий с десяток иностранных языков, нихрена не понимает в матанализе. Или разбирающийся в матанализе не может выучить и двух иностранных
слов. Таких примеров — масса. Знаю гениального верстальщика, который как программист — вообще никакой. Знаю сильного С-кодера, который не знает, что такое IDA, и при этом шестым чувством может находить баги в программе, не пользуясь отладчиками в принципе.
В целом — да, ленивому "быдлокодеру" проще спросить, как сложить 2+2 или поискать код в сети, но...
Но часто бывает, что тема, над который работаешь — недокументирована. И здесь может помочь только совет того, кто в этом понимает лучше тебя.
Я думаю, что в этом случае — спросить чужого совета не зазорно ничуть