Почему перестал работать драйвер?

Тема в разделе "WASM.BEGINNERS", создана пользователем Inkognito, 21 мар 2008.

  1. Inkognito

    Inkognito New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2008
    Сообщения:
    25
    Перестал работать драйвер. Объясните, пожалуйста, что случилось и как это исправить.
    Скомпилировал "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)
     
  2. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Inkognito
    Испортилось все после пинга 127 или до этого пинг работал ?

    Где-то в ХП есть опции что делать с драйвером(сервисом) при BSOD.
    В частности там есть опция отключения в реестре его запуска.
     
  3. Inkognito

    Inkognito New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2008
    Сообщения:
    25
    Дело было так: запускаю драйвер (с помощью своего приложения), набираю ping 127 - узел не доступен, как и должно быть, исходя из кода драйвера, "удаляю" драйвер (опять же приложением), набираю ping 127 - происходит обмен пакетами, как и должно быть, опять запускаю, набираю - всё нормально (пакеты фильтруются, не пропускаются), удаляю - всё нормально (пакеты пропускаются, узел "доступен"). После очередного запуска (не знаю какого по счёту) и набора ping 127 - комп неожиданно перезагрузился и написал, что файл [i Windows\Prefetch\NET.EXE01A53C2F[/i] поврежден или не может быть прочитан. Я решил переустановить винду, но ограничился только "восстановлением системы". После чего запуск драйвера и набор ping 127 стал приводить к синему экрану.
    Запускается он вроде только "по-требованию", и зачем мне его отключать? Мне его нужно до ума довести.
     
  4. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    ошибка в 25ой строчке кода
     
  5. valterg

    valterg Active Member

    Публикаций:
    0
    Регистрация:
    19 авг 2004
    Сообщения:
    2.105
    Inkognito
    Система сама реестр меняет для глючных драйверов и сервисов. Теперь там не "по требованию" стоит, а запрет запуска. А причина одна - драйвер портит "чужую память". После нескольких запусков портит "капитально".
     
  6. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Баг-чек IRQL_NOT_LESS_OR_EQUAL крайне неинформативен, поэтому вдобавок к "код в студию!" покажи весь креш-дамп...
     
  7. Inkognito

    Inkognito New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2008
    Сообщения:
    25
    Код (Text):
    1. typedef ULONG IPAddr, IPMask;
    2. #include <pfhook.h>
    3.  
    4. typedef struct IPHeader {
    5.   UCHAR  iph_verlen;  // Version and length
    6.   UCHAR  iph_tos;  // Type of service
    7.   USHORT  iph_length;  // Total datagram length
    8.   USHORT  iph_id;  // Identification
    9.   USHORT  iph_offset;  // Flags, fragment offset
    10.   UCHAR  iph_ttl;  // Time to live
    11.   UCHAR  iph_protocol;  // Protocol
    12.   USHORT  iph_xsum;  // Header checksum
    13.   ULONG  iph_src;  // Source address
    14.   ULONG  iph_dest;  // Destination address
    15. } IPHeader;
    16.  
    17. PDEVICE_OBJECT fdo = NULL;
    18. UNICODE_STRING  devName, symLinkName;
    19.  
    20.  
    21. VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject);
    22. NTSTATUS set_hook(PacketFilterExtensionPtr hook_fn);
    23. PF_FORWARD_ACTION hook_proc(
    24.         unsigned char *PacketHeader, unsigned char *Packet, unsigned int PacketLength,
    25.         unsigned int RecvInterfaceIndex, unsigned int SendInterfaceIndex,
    26.         IPAddr RecvLinkNextHop, IPAddr SendLinkNextHop);
    27.  
    28. #pragma code_seg("INIT")
    29.  
    30. NTSTATUS
    31. DriverEntry(IN PDRIVER_OBJECT theDriverObject,
    32.         IN PUNICODE_STRING theRegistryPath)
    33. {
    34.     NTSTATUS status = STATUS_SUCCESS;
    35.     int i;
    36.  
    37.       theDriverObject->DriverUnload = UnloadRoutine;
    38.  
    39.     #if DBG
    40.     DbgPrint("=Example= In DriverEntry.");
    41.     DbgPrint("=Example= RegistryPath = %ws.", theRegistryPath->Buffer);
    42.     #endif
    43.  
    44.    RtlInitUnicodeString( &devName, L"\\Device\\EXAMPLE" );
    45.  
    46.    status = IoCreateDevice(theDriverObject, 0, &devName, FILE_DEVICE_UNKNOWN, 0,FALSE, &fdo);
    47.     if(!NT_SUCCESS(status))
    48.         return status;
    49.  
    50.     #if DBG
    51.     DbgPrint("=Example= FDO %X, DevExt=%X.",fdo,dx);
    52.        #endif
    53.        
    54.    RtlInitUnicodeString( &symLinkName, L"\\DosDevices\\Example" );
    55.    
    56.    status = IoCreateSymbolicLink( &symLinkName, &devName );
    57.     if (!NT_SUCCESS(status))
    58.     {
    59.         IoDeleteDevice( fdo );
    60.         return status;
    61.     }
    62.  
    63.        #if DBG
    64.         DbgPrint("=Example= DriverEntry successfully completed.");
    65.        #endif
    66.    
    67.     status = set_hook(hook_proc);
    68.     if (status != STATUS_SUCCESS)
    69.         //if (!NT_SUCCESS(status))
    70.         return status;
    71.        
    72.     return STATUS_SUCCESS;
    73. }
    74. #pragma code_seg()
    75.  
    76.  
    77. NTSTATUS CompleteIrp( PIRP Irp, NTSTATUS status, ULONG info)
    78. {
    79.     Irp->IoStatus.Status = status;
    80.     Irp->IoStatus.Information = info;
    81.     IoCompleteRequest(Irp,IO_NO_INCREMENT);
    82.     return status;
    83. }
    84.  
    85. /* set or remove IP firewall hook */
    86. NTSTATUS
    87. set_hook(PacketFilterExtensionPtr hook_fn)
    88. {
    89.     UNICODE_STRING ipfilter_name;
    90.     NTSTATUS status;
    91.     PFILE_OBJECT fileobj = NULL;
    92.     PDEVICE_OBJECT devobj;
    93.     PF_SET_EXTENSION_HOOK_INFO hook_nfo;
    94.     PIRP irp = NULL;
    95.     IO_STATUS_BLOCK isb;
    96.    
    97.     RtlInitUnicodeString(&ipfilter_name, DD_IPFLTRDRVR_DEVICE_NAME);
    98.    
    99.     status = IoGetDeviceObjectPointer(
    100.             &ipfilter_name,
    101.             STANDARD_RIGHTS_ALL,
    102.             &fileobj,
    103.             &devobj);
    104.     if (status != STATUS_SUCCESS)
    105.         goto done;
    106.    
    107.     hook_nfo.ExtensionPointer = hook_fn;
    108.    
    109.     irp = IoBuildDeviceIoControlRequest(IOCTL_PF_SET_EXTENSION_POINTER,
    110.             devobj, &hook_nfo, sizeof(hook_nfo),
    111.             NULL, 0, FALSE, NULL, &isb);
    112.     if (irp == NULL) {
    113.         status = STATUS_INSUFFICIENT_RESOURCES;
    114.         goto done;
    115.     }
    116.    
    117.     status = IoCallDriver(devobj, irp);
    118.     irp = NULL;
    119.    
    120. done:
    121.     if (fileobj != NULL)
    122.         ObDereferenceObject(fileobj);
    123.    
    124.     return status;
    125. }
    126.  
    127. /* firewall callback hook proc */
    128. PF_FORWARD_ACTION
    129. hook_proc(
    130.         unsigned char *PacketHeader,
    131.         unsigned char *Packet,
    132.         unsigned int PacketLength,
    133.         unsigned int RecvInterfaceIndex,
    134.         unsigned int SendInterfaceIndex,
    135.         IPAddr RecvLinkNextHop,
    136.         IPAddr SendLinkNextHop)
    137. {
    138.     IPHeader *ipp;
    139.  
    140.    ipp=(IPHeader*)PacketHeader;
    141.    
    142.       #if DBG
    143.        DbgPrint("hook_proc:%s\n",ipp->iph_ttl);
    144.       #endif
    145.        
    146.     return PF_DROP;
    147. }
    148.  
    149. #pragma code_seg("PAGE")
    150. VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject)
    151. {
    152.     PDEVICE_OBJECT  pNextDevObj;
    153.     int i;
    154.  
    155.     #if DBG
    156.      DbgPrint("-Example- In Unload Routine.");
    157.     #endif
    158.    
    159.         set_hook(NULL);
    160.  
    161.     pNextDevObj = pDriverObject->DeviceObject;
    162.  
    163.     for(i=0; pNextDevObj!=NULL; i++)
    164.     {
    165.    
    166.         UNICODE_STRING *pLinkName = &symLinkName;
    167.         pNextDevObj = pNextDevObj->NextDevice;
    168.  
    169.         #if DBG
    170.         DbgPrint("-Example- Deleted device (%d) : pointer to FDO = %X.",
    171.                             i,dx->fdo);
    172.         DbgPrint("-Example- Deleted symlink = %ws.", pLinkName->Buffer);
    173.         #endif  
    174.  
    175.         IoDeleteSymbolicLink(pLinkName);
    176.         IoDeleteDevice( fdo );
    177.     }
    178. }
    179. #pragma code_seg()
    Ошибка по-моему возникает из-за неправильного обращения к данным содержащимся в структуре IPHeader (к стати, неужели эту структуру нужно определять так как я это сделал, может быть она должна находиться где-то в другом месте?), как правильно получить доступ, например, к длине пакета ( iph_length)?
    steelfactor
    Креш-дамп - это файлик *.dmp? Тогда как я могу его показать?
     
  8. zoool

    zoool New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2007
    Сообщения:
    412
    он самый
    заливаешь на sendspace.com и даешь нам ссылку.
    никаких "по моему"

    Скомпилируй драйвер с отладочной информацией, загрузи Syser-ом.
    По идее будут 2 варианта отображения отладки - асм-код и исходником.

    Вот по исходнику пройдись отладчиком.Строка за строкой.
    Найди где происходит БСОД.

    Далее смотри, что делал не так в этой строке или в строках выше.
    Посмотри содержание переменных.
     
  9. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Inkognito
    Я имел ввиду анализ крешдампа. Загрузи дамп в windbg, команда !analyze -v и выложи сюда весь анализ... Можешь и сам крешдамп куда-нить выложить
     
  10. Inkognito

    Inkognito New Member

    Публикаций:
    0
    Регистрация:
    21 мар 2008
    Сообщения:
    25
    Здесь должен находиться креш-дамп файл http://www.sendspace.com/file/b25tt5
    Отладчик пока ещё никакой не скачал (интернет закончился), поэтому сам посмотреть файл не могу.
    По поводу этой ошибки ( 0x0000000A (0x00000080,0x00000000,0x8051B9C2)) у Солдатова написано следующее Драйвер пытается получить доступ к странично организованной памяти при работе на уровне привилегий IRQL равном DISPATCH_LEVEL или выше, причем эта страница в момент обращения отсутствует в оперативной памяти (ситуация не может быть перехвачена обработчиком PAGE FAULT). 0x8051B9C2 - я так понимаю адрес инструкции, которая выполняла некорректное обращение, и что это даёт?
    Это утилита какая-то?
     
  11. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Inkognito
    Syser - это кернел-дебаггер
    Вот анализ твоего крешдампа
    Код (Text):
    1. IRQL_NOT_LESS_OR_EQUAL (a)
    2. An attempt was made to access a pagable (or completely invalid) address at an
    3. interrupt request level (IRQL) that is too high.  This is usually
    4. caused by drivers using improper addresses.
    5. If a kernel debugger is available get the stack backtrace.
    6. Arguments:
    7. Arg1: 00000080, memory referenced
    8. Arg2: 00000002, IRQL
    9. Arg3: 00000000, value 0 = read operation, 1 = write operation
    10. Arg4: 8051b9c2, address which referenced memory
    11.  
    12. Debugging Details:
    13. ------------------
    14. READ_ADDRESS:  00000080 Nonpaged pool
    15. CURRENT_IRQL:  2
    16.  
    17. FAULTING_IP:
    18. nt!_output+64d
    19. 8051b9c2 803800           cmp     byte ptr [eax],0x0
    20.  
    21. DEFAULT_BUCKET_ID:  DRIVER_FAULT
    22. BUGCHECK_STR:  A
    23. TRAP_FRAME:  b60742cc -- (.trap ffffffffb60742cc)
    24. ErrCode = 00000000
    25. eax=00000080 ebx=00000073 ecx=7ffffffe edx=b6074629 esi=b6074384 edi=80508797
    26. eip=8051b9c2 esp=b6074340 ebp=b60745a8 iopl=0         nv up ei pl nz na pe nc
    27. cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010202
    28. nt!_output+64d:
    29. 8051b9c2 803800           cmp     byte ptr [eax],0x0
    30. Resetting default context
    31. LAST_CONTROL_TRANSFER:  from 80507fbe to 8051b9c2
    32. STACK_TEXT:  
    33. b60745a8 80507fbe b60745c4 f74c63e0 b6074864 nt!_output+0x64d
    34. b60745e4 80508702 b6074620 00000200 f74c63e0 nt!_vsnprintf+0x2f
    35. b607483c 80508793 80508796 ffffffff 00000000 nt!vDbgPrintExWithPrefix+0x91
    36. b6074858 f74c64fb f74c63e0 00000080 86403040 nt!DbgPrint+0x1a
    37. b607486c b6209097 86403040 85faf040 00000008 0xf74c64fb
    38. b60748bc b620a03b 86403040 85faf040 00000008 0xb6209097
    39. b60748f0 b6f70373 86403040 85faf040 00000008 0xb620a03b
    40. b6074a30 b6f5ab85 b6f8e480 863336e0 85faf020 0xb6f70373
    41. b6074ac4 b6f5a4cd 0100007f 0100007f 00000008 0xb6f5ab85
    42. b6074b5c b6f96d28 8665b840 00000fa0 85d96014 0xb6f5a4cd
    43. b6074ba8 b6f96c56 85d96000 00001ff8 8665b840 0xb6f96d28
    44. b6074bcc b6f5a625 86455758 864557c8 00000000 0xb6f96c56
    45. b6074bf0 b6f967b7 86455758 864557c8 8629fab8 0xb6f5a625
    46. b6074c08 b6f52ef6 8635c860 86455758 8629fab8 0xb6f967b7
    47. b6074c40 804e19ee 8635c860 86455758 80703410 0xb6f52ef6
    48. b6074c50 8057184c 864557c8 86118500 86455758 nt!IopfCallDriver+0x31
    49. b6074c64 80582cef 8635c860 86455758 86118500 nt!IopSynchronousServiceTail+0x60
    50. b6074d00 8058ecc3 00000790 00000774 00000000 nt!IopXxxControlFile+0x5ef
    51. b6074d34 804ddf0f 00000790 00000774 00000000 nt!NtDeviceIoControlFile+0x2a
    52. b6074d34 7c90eb94 00000790 00000774 00000000 nt!KiFastCallEntry+0xfc
    53. 0006f9a8 00000000 00000000 00000000 00000000 0x7c90eb94
    54.  
    55. FOLLOWUP_IP:
    56. nt!_output+64d
    57. 8051b9c2 803800           cmp     byte ptr [eax],0x0
    58. FOLLOWUP_NAME:  MachineOwner
    59. SYMBOL_NAME:  nt!_output+64d
    60. MODULE_NAME:  nt
    61. IMAGE_NAME:  ntkrnlmp
    62. STACK_COMMAND:  .trap ffffffffb60742cc ; kb
    63. BUCKET_ID:  0xA_nt!_output+64d
    64. Followup: MachineOwner
    65. ---------
    Попробуй функции hook_proc и set_hook расположить в paged pool
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    steelfactor
    ты че? зачем функции куда-то переносить, если ошибка очевидна по анализу stack backtrace

    очевидно, что передается неправильный адрес (0x80) в KdPrint(DbgPrint)

    zoool
    Угу и поди отличи потом, бсодит сайсер или дров. Лучше уж softice
     
  13. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Great
    Ты о чем, старая? Нелады с адекватным восприятием окружающей действительности? Ну-ка покажи мои слова, желательно цитированием, что "причина ошибки в ...". Я не говорю, в чем причина ошибки, я предлагаю ее возможное решение.
    Bugcheck 0x0000000A показывает, что процесс ядра или драйвер пытались обратиться к памяти, к которой у них нет разрешения обращаться. В том, что в DbgPrint передается неверный указатель, понятно и младенцу. Я так думаю, что это понятно и топикстартеру.
    Я лишь предлагаю вариант исправления ситуации, потому что у меня в подобных случаях насильное расположение функций в paged pool помогало избавится от IRQL_NOT_LESS_OR_EQUAL.
     
  14. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    steelfactor
    хамить будешь в другом месте =)
    как ты не крути, обращение по адресу 00000080 ничем хорошим не закончатся в любом случае.
    если только не поправишь соответствующий PTE на Valid.
     
  15. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Great
    Согласен на все 100. Адрес обращения странен и ненормален, эт понятно. За неимением лучшего, ничего лучшего, чем размещение в paged pool в голову не лезет, если честно... ))