Dmitry_177
Участник
Offline
|
|
« : 09-06-2007 23:41 » |
|
Подскажите пожалуйста где можно почитать про TDI и желательно с кодом.. Поискал по форуму на эту тему, Гром обещал накидать инфы по TDI еще давно, но так и нету.. Скачал коды tdi_fw, и попробовал разобраться в них.. Я как понял там создается девайс для приема IRP и еще создаются девайсы и аттачатся (IoAttachDevice) к "\\Device\\Tcp", "\\Device\\Udp", "\\Device\\RawIp". Так вот при приеме IRP_MJ_CREATE что нужно вообще сделать? А то в коде tdifw я почему-то не совсем пойму что там делается..
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #1 : 10-06-2007 07:00 » |
|
IRP_MJ_CREATE - функция, которая входит в набор обязательных функций, при подъеме системы на создании контекста запускается именно она. Ее стоит использовать для инициализации всех внутренних структур драйвера.
Я не понимаю вопросов типа - не пойму что и как вообще делать. Ставь вопросы конкретнее, чем могу - помогу.
По поводу кодов, я очень давно не работаю для виндовс, поэтому и не выкладывал нового материала. Но у меня есть некоторый опыт и старые код... Давай подробности, что и зачем ты делаешь - попробуем вместе разобраться и вспомнить.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #2 : 10-06-2007 12:07 » |
|
IRP_MJ_CREATE - функция, которая входит в набор обязательных функций, при подъеме системы на создании контекста запускается именно она. Ее стоит использовать для инициализации всех внутренних структур драйвера. Я это знаю.. Я имел ввиду нужно ли какнибудь TDI инициализировать или еще там что-то делать? Или в моем случае можно просто возвращать STATUS_SUCCESS? Я не понимаю вопросов типа - не пойму что и как вообще делать. Ставь вопросы конкретнее, чем могу - помогу. Я имел ввиду то что мне не ясно что там в tdi_fw делается в обработке IRP_MJ_CREATE, может и мне чего тоже нужно там инициализировать или еще чего.. По поводу кодов, я очень давно не работаю для виндовс, поэтому и не выкладывал нового материала. Но у меня есть некоторый опыт и старые код... Я думаю это будет не только мне интересно, а многим на этом форуме.. Давай подробности, что и зачем ты делаешь - попробуем вместе разобраться и вспомнить. Мне нужно создать TDI Filter. в общем задача такова, перехватывать принятые/отправляемые пакеты, "потрошить" их и сохранять все в файл..
|
|
|
Записан
|
|
|
|
lexer666
Гость
|
|
« Ответ #3 : 11-06-2007 08:02 » |
|
Мне нужно создать TDI Filter. в общем задача такова, перехватывать принятые/отправляемые пакеты, "потрошить" их и сохранять все в файл..
Почему TDI? C NDIS какие-то проблемы?
|
|
|
Записан
|
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #4 : 11-06-2007 16:23 » |
|
С NDIS я тоже поразбирался, но он мне ИМХО не подходит.. т.к. мне еще нужно узнавать какое приложение отправляет/принимает текущий пакет. И еще NDIS вроде не работает на виртуальных девайсах, вроде PPP. Да и вообще опять же ИМХО с TDI будет больше универсальности и надежности.
|
|
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #5 : 11-06-2007 19:12 » |
|
TDI проще тут ты прав... Завтра выложу код. Если я правильно помню, то диск у меня на работе. Если не найду, то тогда позже....
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #6 : 12-06-2007 12:05 » |
|
Буду с нетерпением ждать =)
|
|
|
Записан
|
|
|
|
lexer666
Гость
|
|
« Ответ #7 : 13-06-2007 21:46 » |
|
tdi так tdi вот исходники по теме:
|
|
|
Записан
|
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #8 : 14-06-2007 09:47 » |
|
lexer666, Спасибо! Хотелось бы еще взглянуть на код Грома..
|
|
|
Записан
|
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #9 : 14-06-2007 17:17 » |
|
Скажите пожалуйста, как сами данные из пакетов перехватывать? Какой вообще должен быть алгоритм? Что-то я как-то непойму никак..
|
|
|
Записан
|
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #10 : 15-06-2007 19:39 » |
|
У меня что-то не получается.. Приведу весь свой код TDI фильтра. Это мой первый драйвер, если что пожалуйста не пинайте ногами.. #include <ntddk.h> #include <tdikrnl.h>
PDEVICE_OBJECT g_TcpDeviceObject = NULL, // \Device\Tcp g_TcpOldDeviceObject = NULL, g_DeviceObject = NULL; // control device
NTSTATUS DeviceDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
if (IrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL) { switch (IrpStack->MinorFunction) { case TDI_SEND: if (Irp->MdlAddress) { UCHAR mdlBuffer[IrpStack->Parameters.SendLength];
mdlBuffer = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, LowPagePriority); if (mdlBuffer) { DbgPrint ("TDI_Driver[DROP]: Send: 0x%x\n", mdlBuffer); } }
break;
//case TDI_RECEIVE:
// break; } } // IoSkipCurrentIrpStackLocation(Irp); // return IoCallDriver(g_TcpOldDeviceObject, Irp); Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; }
VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject) { #if DBG DbgPrint ("TDI_Driver: UnloadRoutine called\n"); #endif }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_SUCCESS; int i; UNICODE_STRING usDeviceName; UNICODE_STRING usDeviceLinkName; UNICODE_STRING usTcpDeviceName;
RtlInitUnicodeString (&usDeviceName, L"\\Device\\tdifilter");
RtlInitUnicodeString (&usDeviceLinkName, L"\\??\\tdifilter");
status = IoCreateDevice (DriverObject, 0, // sizeof(DEVICE_EXTENSION) &usDeviceName, 0, // FILE_DEVICE_UNCNOWN 0, TRUE, &g_DeviceObject);
if (!NT_SUCCESS(status)) { #if DBG DbgPrint ("DriverEntry: g_DeviceObject IoCreateDevice error\n"); #endif return status; }
status = IoCreateSymbolicLink (&usDeviceLinkName, &usDeviceName);
if (!NT_SUCCESS(status)) { #if DBG DbgPrint ("DriverEntry: IoCreateSymbolicLink error\n"); #endif
IoDeleteDevice (g_DeviceObject);
return status; }
RtlInitUnicodeString (&usTcpDeviceName, L"\\Device\\Tcp");
status = IoCreateDevice (DriverObject, 0, NULL, FILE_DEVICE_UNKNOWN, 0, TRUE, // FALSE &g_TcpDeviceObject);
if (!NT_SUCCESS(status)) { #if DBG DbgPrint ("DriverEntry: g_TcpDeviceObject IoCreateDevice error\n"); #endif
IoDeleteDevice (g_DeviceObject); return status; }
g_TcpDeviceObject->Flags |= DO_DIRECT_IO; // DO_BUFFERED_IO
status = IoAttachDevice (g_TcpDeviceObject, &usTcpDeviceName, &g_TcpOldDeviceObject);
if (!NT_SUCCESS(status)) { #if DBG DbgPrint ("DriverEntry: g_TcpOldDeviceObject IoAttachDevice error\n"); #endif
IoDeleteDevice (g_TcpDeviceObject); IoDeleteDevice (g_DeviceObject);
return status; }
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) DriverObject->MajorFunction[i] = DeviceDispatch;
DriverObject->DriverUnload = UnloadRoutine;
return status; } У меня возник ряд вопросов: 1. Правильная ли сама реализация? 2. Почему-то компилятор ругается на: UCHAR mdlBuffer[IrpStack->Parameters.SendLength]; по идее в IrpStack->Parameters.SendLength содержится длина.. 3. Как правильно передавать IPR далее по стеку? так: IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(g_TcpOldDeviceObject, Irp); или так: Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
|
|
|
Записан
|
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #11 : 16-06-2007 21:45 » |
|
По поводу второго вопроса, наверно нужно создавать динамический массив, попробовал сделать так: CHAR *mdlBuffer;
mdlBuffer = (CHAR *)malloc (IrpStack->Parameters.SendLength);
mdlBuffer = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, LowPagePriority);
...
free(mdlBuffer); компилятор ругается: 1: 'malloc' undefined; assuming extern returning int 2: 'SendLength' : is not a member of '_unnamed' 3: 'free' undefined; assuming extern returning int Как тогда реализовывать динамический массив?
|
|
|
Записан
|
|
|
|
Алексей++
глобальный и пушистый
Глобальный модератор
Offline
Сообщений: 13
|
|
« Ответ #12 : 17-06-2007 04:32 » |
|
Dmitry_177, вместо malloc и free надо использовать new и delete - CHAR* mdlBuffer=new CHAR [...];
...
delete [] mdlBuffer;
а насчёт SendLength ничего не смогу подсказать... разбирайся с этими классами и их методами...
|
|
« Последнее редактирование: 17-06-2007 04:43 от Алексей1153++ »
|
Записан
|
|
|
|
Гром
Птычк. Тьфу, птычник... Вот!
Готовлюсь к пенсии
Offline
Пол:
Бодрый птах
|
|
« Ответ #13 : 17-06-2007 12:17 » |
|
malloc - функция из юзер мода - ищи и пользуйся кернелевскими.
|
|
|
Записан
|
А птичку нашу прошу не обижать!!!
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #14 : 17-06-2007 12:31 » |
|
Сделал я, создался у меня драйвер.. Создал программку для его запуска. И.. Полего его загрузки сразуже синий экран выскочил, я даже не успел прочитать что там у меня на экране, как сразу же перезагрузился компьютер.. С тех пор у меня драйвер почему-то больше не запускается.. Ошибка на функции CreateService..
|
|
|
Записан
|
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #15 : 17-06-2007 12:32 » |
|
Гром, пока Вы здесь.. что там с кодом?
|
|
|
Записан
|
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #16 : 17-06-2007 16:14 » |
|
ругается на char* mdlBuffer = new char[IrpStack->Parameters.SendLength]; 'new' undeclared identifier 'initializing' : 'char *' differs in levels of indirection from 'int' syntax error : missing ';' before 'type' syntax error : missing ';' before '[' ' ' : ignored on left of 'char' when no variable is declared
|
|
|
Записан
|
|
|
|
aks68
|
|
« Ответ #17 : 17-06-2007 20:08 » |
|
Добрый день.
То Dmitry_177: Настоятельно рекомендую ознакомится с архитектурой и принципами программирования памяти в ядре Windows.
Исчерпывающее описание архитектуры приводится у Русиновича(#) ch.7 - Memory Management.
По работе с памятью в режиме ядра можно прочитать в: А. Солдатов(*) гл 7.3 (погано написанно, зато по русски) Б. Бэйкер(**) - (примерно тоже, что и в Солдатове, но ,как не странно, более понятно, несмотря на то, что по англцки) В. Они(***) Ch. 3 Memory Management- (великолепное описание теории и практики работы с памятью, много но поделу)
(#) M.Russinovich, D.Solomon. Microsoft Windows Internals. (3-4 editions) (*) В.П. Солдатов, Программирование драйверов Windows. (**) A. Baker, J. Lozano. The Windows Device Drivers Book. (***) W. Oney. Programming WDM.
Все эти книги есть в сети. Русинович и, по-моему, Они еть на русском.
С уважением, Акс.
|
|
« Последнее редактирование: 18-06-2007 05:33 от aks68 »
|
Записан
|
|
|
|
StandAlone
Гость
|
|
« Ответ #18 : 17-06-2007 22:24 » |
|
CHAR *mdlBuffer; mdlBuffer = (CHAR *)malloc (IrpStack->Parameters.SendLength); mdlBuffer = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, LowPagePriority); free(mdlBuffer); Dmitry_177, похоже, Вас обманул код tdifw -) Там malloc и free, для удобства автора, сделаны макросами для ExAllocatePool\ExFreePool, в memstat.h. Вообще говоря, IMHO, tdifw полезен как удобный готовый источник, но стиль там довольно жуткий. Венгерская нотация, C-style форматирование...жуть -)) Намного приятней исходники PassThruEx, http://www.wd-3.com, Там аж три варианта. По поводу TDI в целом... большого смысла в нем нет, Vista в любом случае имеет капитально переписанный стек и TDI там, AFAIK, нету как класса. Решить же задачу с per-application распределением трафика можно банальной фильтрацией IRP поверх объектов устройств, созданных TCP\IP драйвером - device\\tcp, device\\udp, etc.Лелею надежду, что принципы I\O в Висте не изменились, и стеки объектов устройств остались -) Но тут обязательно нужно глубоко вдаться в тонкости обработки IRP - completion, cancellation, queueing..imho, Лучше всего - наглядней и подробнее - это сделано у Walter Oney, Chapter 5, "I/O". Есть в переводе, но на самом деле техническую литературу на английском достаточно просто читать даже с моим pre-intermediate level -). Из прочего Вам уже посоветовали .. добавлю еще "Программирование драйверов и систем безопасности". На русском, есть в сети. Сухая и краткая выжимка из DDK, но довольно неплоха (хотя до Они далеко - зато по-русски -))
|
|
« Последнее редактирование: 17-06-2007 22:34 от StandAlone »
|
Записан
|
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #19 : 18-06-2007 09:54 » |
|
Сделал так: #include <ntddk.h> #include <tdikrnl.h>
PDEVICE_OBJECT g_TcpDeviceObject = NULL, // \Device\Tcp g_TcpOldDeviceObject = NULL, //g_udpfltobj = NULL, // \Device\Udp //g_udpoldobj = NULL, //g_ipfltobj = NULL, // \Device\RawIp //g_ipoldobj = NULL, g_DeviceObject = NULL; // control device
KSPIN_LOCK g_SpinLock;
NTSTATUS DeviceDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp); UCHAR *mdlBuffer; UCHAR usBuffer; KIRQL irql; KeAcquireSpinLock(&g_SpinLock, &irql);
if (DeviceObject == g_TcpDeviceObject) // || DeviceObject == g_udpfltobj || DeviceObject == g_ipfltobj) { if (IrpStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL) { switch (IrpStack->MinorFunction) { case TDI_SEND: if (Irp->MdlAddress) { mdlBuffer = MmGetSystemAddressForMdlSafe (Irp->MdlAddress, LowPagePriority);
if (mdlBuffer) { DbgPrint ("tdifilter: Send[DROP]: %x\n", mdlBuffer); } }
KeReleaseSpinLock(&g_SpinLock, irql);
Irp->IoStatus.Status = STATUS_SUCCESS; //Irp->IoStatus.Information = 0;
if (Irp->PendingReturned) IoMarkIrpPending(Irp);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
//return IoCallDriver (g_TcpOldDeviceObject, Irp);
break;
//case TDI_RECEIVE:
// break; } } }
KeReleaseSpinLock (&g_SpinLock, irql);
Irp->IoStatus.Status = STATUS_SUCCESS;
//Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS; }
VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject) { UNICODE_STRING usDeviceLinkName;
#if DBG DbgPrint ("tdifilter: UnloadRoutine called\n"); #endif
IoDeleteDevice (g_TcpOldDeviceObject); IoDeleteDevice (g_TcpDeviceObject); RtlInitUnicodeString (&usDeviceLinkName, L"\\??\\tdifilter"); IoDeleteSymbolicLink(&usDeviceLinkName); IoDeleteDevice (g_DeviceObject);
#if DBG DbgPrint ("tdifilter: UnloadRoutine successfully comleted\n"); #endif }
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_SUCCESS; int i; UNICODE_STRING usDeviceName; UNICODE_STRING usDeviceLinkName; UNICODE_STRING usTcpDeviceName;
#if DBG DbgPrint ("tdifilter: In DriverEntry\n"); DbgPrint ("tdifilter: RegistryPath = %ws\n", RegistryPath->Buffer); #endif
DriverObject->DriverUnload = UnloadRoutine; for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) DriverObject->MajorFunction[i] = DeviceDispatch;
RtlInitUnicodeString (&usDeviceName, L"\\Device\\tdifilter");
status = IoCreateDevice (DriverObject, 0, //sizeof(DEVICE_EXTENSION), &usDeviceName, FILE_DEVICE_UNKNOWN, 0, TRUE, &g_DeviceObject);
if (!NT_SUCCESS(status)) { #if DBG DbgPrint ("tdifilter: g_DeviceObject IoCreateDevice error\n"); #endif return status; }
RtlInitUnicodeString (&usDeviceLinkName, L"\\??\\tdifilter");
status = IoCreateSymbolicLink (&usDeviceLinkName, &usDeviceName);
if (!NT_SUCCESS(status)) { #if DBG DbgPrint ("tdifilter: IoCreateSymbolicLink error\n"); #endif
IoDeleteDevice (g_DeviceObject);
return status; }
RtlInitUnicodeString (&usTcpDeviceName, L"\\Device\\Tcp");
status = IoCreateDevice (DriverObject, 0, NULL, FILE_DEVICE_UNKNOWN, 0, FALSE, &g_TcpDeviceObject);
if (!NT_SUCCESS(status)) { #if DBG DbgPrint ("tdifilter: g_TcpDeviceObject IoCreateDevice error\n"); #endif
IoDeleteSymbolicLink(&usDeviceLinkName); IoDeleteDevice (g_DeviceObject); return status; }
g_TcpDeviceObject->Flags |= DO_DIRECT_IO; //DO_BUFFERED_IO;
status = IoAttachDevice (g_TcpDeviceObject, &usTcpDeviceName, &g_TcpOldDeviceObject);
if (!NT_SUCCESS(status)) { #if DBG DbgPrint ("tdifilter: g_TcpOldDeviceObject IoAttachDevice error\n"); #endif
IoDeleteDevice (g_TcpDeviceObject); IoDeleteSymbolicLink(&usDeviceLinkName); IoDeleteDevice (g_DeviceObject);
return status; }
KeInitializeSpinLock(&g_SpinLock);
#if DBG DbgPrint ("tdifilter: DriverEntry successfully comleted\n"); #endif
return status; } Драйвер запускается, все нормальтно.. Но стоит только зайти на какойнибудь сайт или еще что-то, ну в общем чтобы TCPIP трафик пошел, как вылетает сразу синий экран..=( Подскажите пожалуйста что не так?
|
|
|
Записан
|
|
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #21 : 19-06-2007 09:13 » |
|
У меня получилось =))))))))
TDI_SEND перехватывается..=) Но вот TDI_RECEIVE почему-то нет..=( Может входящий трафик надо еще как-то???
Если я захожу на какойнибудь сайт, по идее там должны быть http-пакеты и html страничка.. Но этого почему-то нету..=(
|
|
|
Записан
|
|
|
|
Dmitry_177
Участник
Offline
|
|
« Ответ #22 : 19-06-2007 12:53 » |
|
Вообще прежде чем у меня заработало, я переделал драйвер.. У меня не создается девайс и не аттачится потом.. А перехватывается функция MajorFunction[IRP_MJ_INTERNAL_DEVICE_CONTROL] драйвера Tcp. Может это из-за этого ловится только исходящий трафик, а входящий нет? Хотя по идее не должно быть такого..
|
|
|
Записан
|
|
|
|
StandAlone
Гость
|
|
« Ответ #23 : 23-06-2007 13:44 » |
|
Dmitry_177, найди TDIMon и внимательно глянь на все TDI_SET_EVENT_XXX. При ресейве пакеты идут в коллбек-обработчик, зарегистрированный ранее.
|
|
|
Записан
|
|
|
|
|