TDI фильтр BSOD
От: -prus-  
Дата: 30.05.08 18:12
Оценка:
Привет Всем.
Помогите плз разобраться с проблемой.
Имею драйвер, который аттачу к \Device\Tcp. В драйвере отслеживаю коннекты на удаленные узлы. Все ок.
Но если я запускаю драйвер, делаю прогой коннект (telnet в моем случае), коннект не рву и выгружаю драйвер, то потом, когда закрываю telnet выскакивает BSOD
Следующего содержания:

*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

DRIVER_VERIFIER_IOMANAGER_VIOLATION (c9)
The IO manager has caught a misbehaving driver.
Arguments:
Arg1: 00000004, Invalid Device object passed to IoCallDriver
Arg2: 817ba200, the Device object , 3/4 — 0
Arg3: 00000000
Arg4: 00000000

Debugging Details:
------------------


PEB is paged out (Peb.Ldr = 7ffdf00c). Type ".hh dbgerr001" for details

PEB is paged out (Peb.Ldr = 7ffdf00c). Type ".hh dbgerr001" for details

BUGCHECK_STR: 0xc9_4

DRIVER_VERIFIER_IO_VIOLATION_TYPE: 4

DEVICE_OBJECT: 817ba200

DRIVER_OBJECT: 817ba1e0

IMAGE_NAME: €ˆëˆëÀ;

DEBUG_FLR_IMAGE_TIMESTAMP: 0

MODULE_NAME: €ˆëˆëÀ;

FAULTING_MODULE: 00000000

DEFAULT_BUCKET_ID: INTEL_CPU_MICROCODE_ZERO

PROCESS_NAME: telnet.exe

LAST_CONTROL_TRANSFER: from 80647152 to 805266db

STACK_TEXT:
f6756b94 80647152 000000c9 00000004 817ba200 nt!KeBugCheckEx+0x19
f6756bcc f6c17111 814911f0 81124ef0 806c96e0 nt!IovCallDriver+0xdf
f6756bf8 f6c16a57 81124ef0 00000000 00000000 afd!AfdBeginDisconnect+0x242
f6756c34 f6c167e4 815bd030 815bf100 804eca36 afd!AfdCleanup+0x349
f6756c40 804eca36 815bd030 822b4f00 806c91a8 afd!AfdDispatch+0xb8
f6756c50 80647111 8167f4e0 822b4f00 822b4f10 nt!IopfCallDriver+0x31
f6756c74 80586cda 8167f4c8 8179b900 00000001 nt!IovCallDriver+0x9e
f6756ca8 805812b4 81125528 815bd030 001f01ff nt!IopCloseFile+0x261
f6756cd8 80581108 81125528 8167f4e0 8179b900 nt!ObpDecrementHandleCount+0x119
f6756d00 8058132d e1780fb8 8167f4e0 00000760 nt!ObpCloseHandleTableEntry+0x14b
f6756d48 8058136e 00000760 00000001 00000000 nt!ObpCloseHandle+0x85
f6756d58 804da140 00000760 00000000 817af838 nt!NtClose+0x19
f6756d58 7ffe0304 00000760 00000000 817af838 nt!KiSystemService+0xc4
0088fee4 00000000 00000000 00000000 00000000 SharedUserData!SystemCallStub+0x4


STACK_COMMAND: kb

FOLLOWUP_NAME: MachineOwner

FAILURE_BUCKET_ID: 0xc9_4_VRF_IMAGE_____ˆëˆëÀ;

BUCKET_ID: 0xc9_4_VRF_IMAGE_____ˆëˆëÀ;

Followup: MachineOwner


Вообще странно, что после выгрузки драйвера его еще вызвать система пытается. В процедуре выгрузки делаю следующее:

VOID DriverUnload(IN PDRIVER_OBJECT pDriverObject)
{
    
    UNICODE_STRING ustrDeviceName;        // Имя нашего устройства
    UNICODE_STRING ustrSymbolicLink;    // Имя символической ссылки нашего устройства
    
    // Получаем расширение устройства
    PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDriverObject->DeviceObject->DeviceExtension;

    // Инициализируем имя устройства
    RtlInitUnicodeString(&ustrDeviceName, DEVICE_NAME);
    // Инициализируем символическую ссылку на устройства
    RtlInitUnicodeString(&ustrSymbolicLink, SYM_LINK_NAME);

    // Отсоединяем наш драйвер от стека
    IoDetachDevice(pDevExt->pDeviceObject);
    // Удаляем символическую ссылку
    IoDeleteSymbolicLink(&ustrSymbolicLink);
    // Удаляем устройство
    IoDeleteDevice(g_pDeviceObject);

    // Очищаем список
    ClearConnInfoList();

    // Освобождаем память под спин-лок
    ExFreePoolWithTag(g_pClientConnToSrvListSpinLock, KSPIN_LOCK_POOL_TAG);

    DbgPrint("DriverUnload: SUCCESS");

}


Помогите плз...
С уважением,
Евгений
Re: TDI фильтр BSOD
От: TarasCo  
Дата: 30.05.08 19:39
Оценка: 1 (1)
Невозможно сделать выгружаемый TDI фильтр. Аминь.

Если хочется все таки выгружаться, надо делать не фильтр, а патчить мажор тейбл у \Driver\tcp.
Да пребудет с тобою сила
Re[2]: TDI фильтр BSOD
От: -prus-  
Дата: 31.05.08 11:15
Оценка:
Здравствуйте, TarasCo, Вы писали:

TC>Невозможно сделать выгружаемый TDI фильтр. Аминь.


Этого не знал. +1

TC>Если хочется все таки выгружаться, надо делать не фильтр, а патчить мажор тейбл у \Driver\tcp.


А разве такой вариант на висте и на 64 битных платформах работать будет?
С уважением,
Евгений
Re[3]: TDI фильтр BSOD
От: TarasCo  
Дата: 31.05.08 18:09
Оценка:
P>А разве такой вариант на висте и на 64 битных платформах работать будет?

Битность платформы тут не причем — целостность объекта DRIVER_OBJECT не контроллируется ни одной платформой. С вистой интереснее — если в стеке устройства \Device\tcp отсутствуют фильтры, то трафик идет вообще минуя это устройство. Для преодоления этого можно использовать такой "трик": сделать два драйвера — один с пустым фильтром над устройством \Device\tcp ( присутствие фильтра заставит драйвер afd.sys использовать TDI ), другой — с патчем мажор тейбл. Второй драйвер можно будет перегружать ( в принципе ).
Да пребудет с тобою сила
Re[4]: TDI фильтр BSOD
От: -prus-  
Дата: 03.06.08 07:10
Оценка:
Здравствуйте, TarasCo, Вы писали:

TC>Битность платформы тут не причем — целостность объекта DRIVER_OBJECT не контроллируется ни одной платформой. С вистой интереснее — если в стеке устройства \Device\tcp отсутствуют фильтры, то трафик идет вообще минуя это устройство. Для преодоления этого можно использовать такой "трик": сделать два драйвера — один с пустым фильтром над устройством \Device\tcp ( присутствие фильтра заставит драйвер afd.sys использовать TDI ), другой — с патчем мажор тейбл. Второй драйвер можно будет перегружать ( в принципе ).


Благодарю!
Еще маленький вопросик...
Всегда отправляемые приложением TCP-данные я смогу посмотреть в своем фильтре при наступлении TDI_SEND?
С уважением,
Евгений
Re[5]: TDI фильтр BSOD
От: TarasCo  
Дата: 03.06.08 07:14
Оценка: 2 (1)
P>Благодарю!
P>Еще маленький вопросик...
P>Всегда отправляемые приложением TCP-данные я смогу посмотреть в своем фильтре при наступлении TDI_SEND?

netbt.sys может использовать т.н "Direct Send" — вызывать напрямую ф. tcpip.sys, полученную ранее через IOCTL_TDI_QUERY_DIRECT_SEND_HANDLER. "Обычный" сокетный трафик, проходящий через afd.sys за этим замечен не был.
Да пребудет с тобою сила
Re[6]: TDI фильтр BSOD
От: -prus-  
Дата: 03.06.08 13:03
Оценка:
Здравствуйте, TarasCo, Вы писали:

TC>netbt.sys может использовать т.н "Direct Send" — вызывать напрямую ф. tcpip.sys, полученную ранее через IOCTL_TDI_QUERY_DIRECT_SEND_HANDLER. "Обычный" сокетный трафик, проходящий через afd.sys за этим замечен не был.


Меня сокетный трафик и интересует
Спасиб! +2
С уважением,
Евгений
Re[6]: TDI_SEND и Vista
От: -prus-  
Дата: 03.06.08 13:07
Оценка:
Еще спрошу...
Я пока на Висте не пробовал. Там тоже данные могу увидеть в TDI_SEND? Или там все на TDI_SEND_EVENT_HANDLER основано?
С уважением,
Евгений
Re[7]: TDI_SEND и Vista
От: TarasCo  
Дата: 03.06.08 14:44
Оценка:
P>Я пока на Висте не пробовал. Там тоже данные могу увидеть в TDI_SEND?

Да если вы установите фильтр в стек устройства \device\tcp — все будет точно также. Одно отличие — в висте ( в релизе, в первой бэте было не так ) устройство \Device\tcp обслуживает также TCPv6 трафик, в XP для этого есть отдельное устройство — \device\tcp6. Ну и стоит помнить, что драйвер tdx.sys нужен только для совместимости со старыми драйверами и возможно в Windows 7 его ( и соответственно TDI вообще ) не будет.
Да пребудет с тобою сила
Re[2]: TDI фильтр BSOD
От: foxgen  
Дата: 27.01.09 13:37
Оценка: -1
Здравствуйте, TarasCo, Вы писали:

TC>Невозможно сделать выгружаемый TDI фильтр. Аминь.


TC>Если хочется все таки выгружаться, надо делать не фильтр, а патчить мажор тейбл у \Driver\tcp.


-1
Еще как возможно.
Re[3]: TDI фильтр BSOD
От: x64 Россия  
Дата: 27.01.09 14:22
Оценка:
TC>>Невозможно сделать выгружаемый TDI фильтр. Аминь.
TC>>Если хочется все таки выгружаться, надо делать не фильтр, а патчить мажор тейбл у \Driver\tcp.
F>Еще как возможно.

Голословно как-то. Давай конкретику, раз такой умный.
Re[4]: TDI фильтр BSOD
От: foxgen  
Дата: 27.01.09 19:06
Оценка:
Здравствуйте, x64, Вы писали:

TC>>>Невозможно сделать выгружаемый TDI фильтр. Аминь.

TC>>>Если хочется все таки выгружаться, надо делать не фильтр, а патчить мажор тейбл у \Driver\tcp.
F>>Еще как возможно.

x64>Голословно как-то. Давай конкретику, раз такой умный.


Не вижу большой проблемы ....
Нужно дождаться пока сетевые запросы, которые прошли через фильтр завершатся
( закроются порты, снимутся callback-и ... ) и тогда делать Detach и выгружаться
Другое дело, что есть например тонкости : типа ресурсы могут и не освободиться
а в-общем и целом когда-то давно у меня был TDI фильтр который благополучно выгружался.
Re[5]: TDI фильтр BSOD
От: x64 Россия  
Дата: 27.01.09 23:17
Оценка:
F>Не вижу большой проблемы ....

Видишь ёжика? Нет? А он есть!

F>а в-общем и целом когда-то давно у меня был TDI фильтр который благополучно выгружался.


А я-то уж подумал нам сейчас расскажут ну хотя бы о какой-нибудь очередной недокументированной багофиче, которой можно определённым образом воспользоваться, чтобы сделать свой legacy-фильтр относительно стабильно выгружаемым. Ну ты на досуге подумай, к примеру, что будет, когда придёт запрос к \Device\Tcp при условии, если третий драйвер прицепился сверху на твой FiDO-девайс до того, как ты выгрузился. Подсказка: DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS.

Моё мнение: фактически при определённых условиях legacy-фильтр может быть выгружаемым, но для этого требуется уж слишком много совпадений, как то: девайсы драйвера должны быть самыми верхними на стеке, должен быть вызван соответствующий callback из fast I/O (хотя fast I/O в TDI-фильтрах не поддерживается) и т.п. Конечно, можно вспомнить ручную правку структур I/O менеджера и прочую гадость, но... В общем виде задача не решаема. Аминь.
Re[6]: TDI фильтр BSOD
От: foxgen  
Дата: 28.01.09 13:08
Оценка:
x64>А я-то уж подумал нам сейчас расскажут ну хотя бы о какой-нибудь очередной недокументированной багофиче, которой можно определённым образом воспользоваться, чтобы сделать свой legacy-фильтр относительно стабильно выгружаемым. Ну ты на досуге подумай, к примеру, что будет, когда придёт запрос к \Device\Tcp при условии, если третий драйвер прицепился сверху на твой FiDO-девайс до того, как ты выгрузился. Подсказка: DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS.

x64>Моё мнение: фактически при определённых условиях legacy-фильтр может быть выгружаемым, но для этого требуется уж слишком много совпадений, как то: девайсы драйвера должны быть самыми верхними на стеке, должен быть вызван соответствующий callback из fast I/O (хотя fast I/O в TDI-фильтрах не поддерживается) и т.п. Конечно, можно вспомнить ручную правку структур I/O менеджера и прочую гадость, но... В общем виде задача не решаема. Аминь.


Все так
Но, с моей точки зрения, стакан скорее наполовину полон ... С помощью зубила и молотка в-принципе дотачивается что угодно
Все зависит от постановки задачи.
Re[7]: TDI фильтр BSOD
От: x64 Россия  
Дата: 29.01.09 00:46
Оценка:
F>Но, с моей точки зрения, стакан скорее наполовину полон ...

Он не полон ни на половину ни на сотую часть. Задача не решаема, обсуждать тут нечего.

F>Все зависит от постановки задачи.


Задача "написать выгружаемый legacy-фильтр" не решаема. И даже с кучей дополнительных условий и формулировок никто не будет эту задачу решать, ибо бессмысленно, всё равно всё будет держаться на соплях.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.