Перестал работать драйвер. Объясните, пожалуйста, что случилось и как это исправить. Скомпилировал "filter-hook" драйвер, который drop'ал все TCP/IP пакеты, такойже как в статье "Способы фильтрации сетевого траффика в Windows 9x/2000/Net.2003 Server" (http://www.wasm.ru/article.php?article=netfilter), только написанный на Си. Написал приложение для его "запуска" и "остановки" с помощью функций SCM менеджера. Приложение также запускало сервис ipfilterdriver, но не останавливало его. Драйвер нормально стартовал и работал. При вводе ping 127.0.0.1 результат: узел не доступен. После нескольких запусков приложения подряд результатом ввода ping 127.0.0.1 стал BSOD. При следующей попытке запуска драйвера функция старта StartService() в GetLastError() выдаёт 2. Вот то, что написано на синем экране: A problem has been detected and Windows has been shut down to prevent damage to your computer. IRQL_NOT_LESS_OR_EQUAL ***stop: 0x0000000A (0x00000080,0x00000000,0x8051B9C2)
Inkognito Испортилось все после пинга 127 или до этого пинг работал ? Где-то в ХП есть опции что делать с драйвером(сервисом) при BSOD. В частности там есть опция отключения в реестре его запуска.
Дело было так: запускаю драйвер (с помощью своего приложения), набираю ping 127 - узел не доступен, как и должно быть, исходя из кода драйвера, "удаляю" драйвер (опять же приложением), набираю ping 127 - происходит обмен пакетами, как и должно быть, опять запускаю, набираю - всё нормально (пакеты фильтруются, не пропускаются), удаляю - всё нормально (пакеты пропускаются, узел "доступен"). После очередного запуска (не знаю какого по счёту) и набора ping 127 - комп неожиданно перезагрузился и написал, что файл [i Windows\Prefetch\NET.EXE01A53C2F[/i] поврежден или не может быть прочитан. Я решил переустановить винду, но ограничился только "восстановлением системы". После чего запуск драйвера и набор ping 127 стал приводить к синему экрану. Запускается он вроде только "по-требованию", и зачем мне его отключать? Мне его нужно до ума довести.
Inkognito Система сама реестр меняет для глючных драйверов и сервисов. Теперь там не "по требованию" стоит, а запрет запуска. А причина одна - драйвер портит "чужую память". После нескольких запусков портит "капитально".
Баг-чек IRQL_NOT_LESS_OR_EQUAL крайне неинформативен, поэтому вдобавок к "код в студию!" покажи весь креш-дамп...
Код (Text): typedef ULONG IPAddr, IPMask; #include <pfhook.h> typedef struct IPHeader { UCHAR iph_verlen; // Version and length UCHAR iph_tos; // Type of service USHORT iph_length; // Total datagram length USHORT iph_id; // Identification USHORT iph_offset; // Flags, fragment offset UCHAR iph_ttl; // Time to live UCHAR iph_protocol; // Protocol USHORT iph_xsum; // Header checksum ULONG iph_src; // Source address ULONG iph_dest; // Destination address } IPHeader; PDEVICE_OBJECT fdo = NULL; UNICODE_STRING devName, symLinkName; VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject); NTSTATUS set_hook(PacketFilterExtensionPtr hook_fn); PF_FORWARD_ACTION hook_proc( unsigned char *PacketHeader, unsigned char *Packet, unsigned int PacketLength, unsigned int RecvInterfaceIndex, unsigned int SendInterfaceIndex, IPAddr RecvLinkNextHop, IPAddr SendLinkNextHop); #pragma code_seg("INIT") NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath) { NTSTATUS status = STATUS_SUCCESS; int i; theDriverObject->DriverUnload = UnloadRoutine; #if DBG DbgPrint("=Example= In DriverEntry."); DbgPrint("=Example= RegistryPath = %ws.", theRegistryPath->Buffer); #endif RtlInitUnicodeString( &devName, L"\\Device\\EXAMPLE" ); status = IoCreateDevice(theDriverObject, 0, &devName, FILE_DEVICE_UNKNOWN, 0,FALSE, &fdo); if(!NT_SUCCESS(status)) return status; #if DBG DbgPrint("=Example= FDO %X, DevExt=%X.",fdo,dx); #endif RtlInitUnicodeString( &symLinkName, L"\\DosDevices\\Example" ); status = IoCreateSymbolicLink( &symLinkName, &devName ); if (!NT_SUCCESS(status)) { IoDeleteDevice( fdo ); return status; } #if DBG DbgPrint("=Example= DriverEntry successfully completed."); #endif status = set_hook(hook_proc); if (status != STATUS_SUCCESS) //if (!NT_SUCCESS(status)) return status; return STATUS_SUCCESS; } #pragma code_seg() NTSTATUS CompleteIrp( PIRP Irp, NTSTATUS status, ULONG info) { Irp->IoStatus.Status = status; Irp->IoStatus.Information = info; IoCompleteRequest(Irp,IO_NO_INCREMENT); return status; } /* set or remove IP firewall hook */ NTSTATUS set_hook(PacketFilterExtensionPtr hook_fn) { UNICODE_STRING ipfilter_name; NTSTATUS status; PFILE_OBJECT fileobj = NULL; PDEVICE_OBJECT devobj; PF_SET_EXTENSION_HOOK_INFO hook_nfo; PIRP irp = NULL; IO_STATUS_BLOCK isb; RtlInitUnicodeString(&ipfilter_name, DD_IPFLTRDRVR_DEVICE_NAME); status = IoGetDeviceObjectPointer( &ipfilter_name, STANDARD_RIGHTS_ALL, &fileobj, &devobj); if (status != STATUS_SUCCESS) goto done; hook_nfo.ExtensionPointer = hook_fn; irp = IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER, devobj, &hook_nfo, sizeof(hook_nfo), NULL, 0, FALSE, NULL, &isb); if (irp == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto done; } status = IoCallDriver(devobj, irp); irp = NULL; done: if (fileobj != NULL) ObDereferenceObject(fileobj); return status; } /* firewall callback hook proc */ PF_FORWARD_ACTION hook_proc( unsigned char *PacketHeader, unsigned char *Packet, unsigned int PacketLength, unsigned int RecvInterfaceIndex, unsigned int SendInterfaceIndex, IPAddr RecvLinkNextHop, IPAddr SendLinkNextHop) { IPHeader *ipp; ipp=(IPHeader*)PacketHeader; #if DBG DbgPrint("hook_proc:%s\n",ipp->iph_ttl); #endif return PF_DROP; } #pragma code_seg("PAGE") VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject) { PDEVICE_OBJECT pNextDevObj; int i; #if DBG DbgPrint("-Example- In Unload Routine."); #endif set_hook(NULL); pNextDevObj = pDriverObject->DeviceObject; for(i=0; pNextDevObj!=NULL; i++) { UNICODE_STRING *pLinkName = &symLinkName; pNextDevObj = pNextDevObj->NextDevice; #if DBG DbgPrint("-Example- Deleted device (%d) : pointer to FDO = %X.", i,dx->fdo); DbgPrint("-Example- Deleted symlink = %ws.", pLinkName->Buffer); #endif IoDeleteSymbolicLink(pLinkName); IoDeleteDevice( fdo ); } } #pragma code_seg() Ошибка по-моему возникает из-за неправильного обращения к данным содержащимся в структуре IPHeader (к стати, неужели эту структуру нужно определять так как я это сделал, может быть она должна находиться где-то в другом месте?), как правильно получить доступ, например, к длине пакета ( iph_length)? steelfactor Креш-дамп - это файлик *.dmp? Тогда как я могу его показать?
он самый заливаешь на sendspace.com и даешь нам ссылку. никаких "по моему" Скомпилируй драйвер с отладочной информацией, загрузи Syser-ом. По идее будут 2 варианта отображения отладки - асм-код и исходником. Вот по исходнику пройдись отладчиком.Строка за строкой. Найди где происходит БСОД. Далее смотри, что делал не так в этой строке или в строках выше. Посмотри содержание переменных.
Inkognito Я имел ввиду анализ крешдампа. Загрузи дамп в windbg, команда !analyze -v и выложи сюда весь анализ... Можешь и сам крешдамп куда-нить выложить
Здесь должен находиться креш-дамп файл http://www.sendspace.com/file/b25tt5 Отладчик пока ещё никакой не скачал (интернет закончился), поэтому сам посмотреть файл не могу. По поводу этой ошибки ( 0x0000000A (0x00000080,0x00000000,0x8051B9C2)) у Солдатова написано следующее Драйвер пытается получить доступ к странично организованной памяти при работе на уровне привилегий IRQL равном DISPATCH_LEVEL или выше, причем эта страница в момент обращения отсутствует в оперативной памяти (ситуация не может быть перехвачена обработчиком PAGE FAULT). 0x8051B9C2 - я так понимаю адрес инструкции, которая выполняла некорректное обращение, и что это даёт? Это утилита какая-то?
Inkognito Syser - это кернел-дебаггер Вот анализ твоего крешдампа Код (Text): IRQL_NOT_LESS_OR_EQUAL (a) An attempt was made to access a pagable (or completely invalid) address at an interrupt request level (IRQL) that is too high. This is usually caused by drivers using improper addresses. If a kernel debugger is available get the stack backtrace. Arguments: Arg1: 00000080, memory referenced Arg2: 00000002, IRQL Arg3: 00000000, value 0 = read operation, 1 = write operation Arg4: 8051b9c2, address which referenced memory Debugging Details: ------------------ READ_ADDRESS: 00000080 Nonpaged pool CURRENT_IRQL: 2 FAULTING_IP: nt!_output+64d 8051b9c2 803800 cmp byte ptr [eax],0x0 DEFAULT_BUCKET_ID: DRIVER_FAULT BUGCHECK_STR: A TRAP_FRAME: b60742cc -- (.trap ffffffffb60742cc) ErrCode = 00000000 eax=00000080 ebx=00000073 ecx=7ffffffe edx=b6074629 esi=b6074384 edi=80508797 eip=8051b9c2 esp=b6074340 ebp=b60745a8 iopl=0 nv up ei pl nz na pe nc cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202 nt!_output+64d: 8051b9c2 803800 cmp byte ptr [eax],0x0 Resetting default context LAST_CONTROL_TRANSFER: from 80507fbe to 8051b9c2 STACK_TEXT: b60745a8 80507fbe b60745c4 f74c63e0 b6074864 nt!_output+0x64d b60745e4 80508702 b6074620 00000200 f74c63e0 nt!_vsnprintf+0x2f b607483c 80508793 80508796 ffffffff 00000000 nt!vDbgPrintExWithPrefix+0x91 b6074858 f74c64fb f74c63e0 00000080 86403040 nt!DbgPrint+0x1a b607486c b6209097 86403040 85faf040 00000008 0xf74c64fb b60748bc b620a03b 86403040 85faf040 00000008 0xb6209097 b60748f0 b6f70373 86403040 85faf040 00000008 0xb620a03b b6074a30 b6f5ab85 b6f8e480 863336e0 85faf020 0xb6f70373 b6074ac4 b6f5a4cd 0100007f 0100007f 00000008 0xb6f5ab85 b6074b5c b6f96d28 8665b840 00000fa0 85d96014 0xb6f5a4cd b6074ba8 b6f96c56 85d96000 00001ff8 8665b840 0xb6f96d28 b6074bcc b6f5a625 86455758 864557c8 00000000 0xb6f96c56 b6074bf0 b6f967b7 86455758 864557c8 8629fab8 0xb6f5a625 b6074c08 b6f52ef6 8635c860 86455758 8629fab8 0xb6f967b7 b6074c40 804e19ee 8635c860 86455758 80703410 0xb6f52ef6 b6074c50 8057184c 864557c8 86118500 86455758 nt!IopfCallDriver+0x31 b6074c64 80582cef 8635c860 86455758 86118500 nt!IopSynchronousServiceTail+0x60 b6074d00 8058ecc3 00000790 00000774 00000000 nt!IopXxxControlFile+0x5ef b6074d34 804ddf0f 00000790 00000774 00000000 nt!NtDeviceIoControlFile+0x2a b6074d34 7c90eb94 00000790 00000774 00000000 nt!KiFastCallEntry+0xfc 0006f9a8 00000000 00000000 00000000 00000000 0x7c90eb94 FOLLOWUP_IP: nt!_output+64d 8051b9c2 803800 cmp byte ptr [eax],0x0 FOLLOWUP_NAME: MachineOwner SYMBOL_NAME: nt!_output+64d MODULE_NAME: nt IMAGE_NAME: ntkrnlmp STACK_COMMAND: .trap ffffffffb60742cc ; kb BUCKET_ID: 0xA_nt!_output+64d Followup: MachineOwner --------- Попробуй функции hook_proc и set_hook расположить в paged pool
steelfactor ты че? зачем функции куда-то переносить, если ошибка очевидна по анализу stack backtrace очевидно, что передается неправильный адрес (0x80) в KdPrint(DbgPrint) zoool Угу и поди отличи потом, бсодит сайсер или дров. Лучше уж softice
Great Ты о чем, старая? Нелады с адекватным восприятием окружающей действительности? Ну-ка покажи мои слова, желательно цитированием, что "причина ошибки в ...". Я не говорю, в чем причина ошибки, я предлагаю ее возможное решение. Bugcheck 0x0000000A показывает, что процесс ядра или драйвер пытались обратиться к памяти, к которой у них нет разрешения обращаться. В том, что в DbgPrint передается неверный указатель, понятно и младенцу. Я так думаю, что это понятно и топикстартеру. Я лишь предлагаю вариант исправления ситуации, потому что у меня в подобных случаях насильное расположение функций в paged pool помогало избавится от IRQL_NOT_LESS_OR_EQUAL.
steelfactor хамить будешь в другом месте =) как ты не крути, обращение по адресу 00000080 ничем хорошим не закончатся в любом случае. если только не поправишь соответствующий PTE на Valid.
Great Согласен на все 100. Адрес обращения странен и ненормален, эт понятно. За неимением лучшего, ничего лучшего, чем размещение в paged pool в голову не лезет, если честно... ))