Как запустить драйвер фильтр без reboot

Тема в разделе "WASM.NT.KERNEL", создана пользователем katrus, 28 авг 2007.

  1. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Добавляю фильтр через регитр:
    Код (Text):
    1. 1. HKLM\SYSTEM\CurrentControlSet\Services\my_driver
    2. 2. HKLM\SYSTEM\CurrentControlSet\Control\Class\{...}]
    3. "UpperFilters"= ... my_driver
    После инсталяции, или каждый раз после изменения драйвера необходимо перегрузить комп. А можно ли как-нить (пере)запустить подобный драйвер без reboot?
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    А это фильтр чего?
     
  3. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Great
    клавиатуры.
     
  4. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    KeAttachDeviceToDeviceStack в функции DriverEntry
     
  5. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    gilg

    Код (Text):
    1. PDEVICE_OBJECT
    2.   IoAttachDeviceToDeviceStack(
    3.     IN PDEVICE_OBJECT  SourceDevice,
    4.     IN PDEVICE_OBJECT  TargetDevice
    5.     );
    А где взять TargetDevice
     
  6. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Читаешь из HKLM\System\CurrentControlSet\Services\Kbdclass\Parameters поле KeyboardDeviceBaseName базовое имя устройства и прибавляешь к нему последовательно цыфурки: <BaseName>1, <BaseName>2, ... . Количество устройств можно прочитать из HKLM\System\CurrentControlSet\Services\Kbdclass\Enum поле Count. Будут вопросы с перечислением, посмотри исходники KbdClass из DDK Samples.

    С помощью IoGetDeviceObjectPointer получаешь FileObject, в нем FileObject->DeviceObject будет как раз будет TargetDevice.
     
  7. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    gilg
    Большой спасиб!
     
  8. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    gilg
    а не проще IoAttachDevice, которая сама откроет файл обжект, выдерет related device object и вызовет IoAttachDeviceToDeviceStack?

    Кстати резонный вопрос - а как щас твой дров без него работает? о_О
     
  9. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Какая разница?
     
  10. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    кода меньше) че велосипед изобретать
     
  11. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Одна беда осталась: в DriverUnload IoDetachDevice(...) приводит к BSoDу. Пишет - что IRQL не passive, хотя KeGetCurrentIrql() дает, что текущий IRQL - PASSIVE_LEVEL
     
  12. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    IRQL не passive он пишет еще и когда идет обращение к неверной памяти. Вероятно, передаешь неверный DeviceObject. IoDeleteDevice вызываешь после IoDetach?
     
  13. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    кстати выгружать драйвер-фильтр не очень безопасно. подробнее можно прочитать у Four-F, а в двух словах - если будет инициирована выгрузка, пока выполняются FastIo или IoCompletion обработчики или чтонибудь такое, то после выгрузки будет бсод почти со 100% вероятностью.
    Можно посмотреть у того же FileMon - код DriverUnload обернут в #if DBG / #endif
    Снизить вероятность бсода можно, мухлюя с евентами.
    Это так, к слову.

    покажи код
     
  14. katrus

    katrus New Member

    Публикаций:
    0
    Регистрация:
    7 мар 2007
    Сообщения:
    612
    Great
    Я поудалял ненужные детали:

    Код (Text):
    1. #include <ntddk.h>
    2. #include <ntddkbd.h>
    3.  
    4. typedef struct _DEVICE_EXTENSION
    5. {
    6.     PDEVICE_OBJECT top_of_stack;
    7. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
    8.  
    9. VOID DriverUnload(IN PDRIVER_OBJECT Driver);
    10. NTSTATUS driver_add_device(IN PDRIVER_OBJECT driver_object, IN PDEVICE_OBJECT device_object);
    11. NTSTATUS device_open(PDEVICE_OBJECT device_object, PIRP irp);
    12. NTSTATUS device_close(PDEVICE_OBJECT device_object, PIRP irp);
    13. NTSTATUS device_read(IN PDEVICE_OBJECT device_object, IN PIRP irp);
    14. NTSTATUS device_write(IN PDEVICE_OBJECT device_object, IN PIRP irp);
    15. NTSTATUS device_general(IN PDEVICE_OBJECT device_object, IN PIRP irp);
    16. NTSTATUS install_user_space_connection(IN PDRIVER_OBJECT driver_object);
    17.  
    18. NTSTATUS DriverEntry(IN PDRIVER_OBJECT driver_object,
    19.                      IN PUNICODE_STRING registry_path)
    20. {
    21.     ULONG i;   
    22.     UNICODE_STRING device_name;
    23.     NTSTATUS status;
    24.     PFILE_OBJECT file_object;
    25.     PDEVICE_OBJECT device_object;
    26.  
    27.     DbgPrint("DriverEntry <%s, %s>", __DATE__, __TIME__);
    28.     driver_object->DriverUnload = DriverUnload;
    29.     // setup driver functions
    30.     for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    31.         driver_object->MajorFunction[i] = device_general;
    32.     driver_object->MajorFunction[IRP_MJ_CREATE] = device_open;
    33.     driver_object->MajorFunction[IRP_MJ_CLOSE] = device_close;
    34.     driver_object->MajorFunction[IRP_MJ_READ] = device_read;
    35.     driver_object->MajorFunction[IRP_MJ_WRITE] = device_write;
    36.    
    37.     RtlInitUnicodeString(&device_name, L"\\Device\\KeyboardClass0");
    38.     status = IoGetDeviceObjectPointer(&device_name, GENERIC_ALL, &file_object, &device_object);
    39.     driver_add_device(driver_object, device_object);
    40.    
    41.     return STATUS_SUCCESS;
    42. }
    43.  
    44. VOID DriverUnload(IN PDRIVER_OBJECT driver_object)
    45. {
    46.     PDEVICE_EXTENSION device_extension = (PDEVICE_EXTENSION)driver_object->DriverExtension;
    47.     IoDetachDevice(device_extension->top_of_stack);
    48. }
    49.  
    50. NTSTATUS driver_add_device(IN PDRIVER_OBJECT driver_object, IN PDEVICE_OBJECT device_object)
    51. {
    52.     PDEVICE_EXTENSION device_extension;
    53.     IO_ERROR_LOG_PACKET error_log_entry;
    54.     PDEVICE_OBJECT device;
    55.     NTSTATUS status = STATUS_SUCCESS;
    56.     // create a filter device and attach it to the device stack
    57.     status = IoCreateDevice(driver_object,                  
    58.                             sizeof(DEVICE_EXTENSION),
    59.                             NULL,                    
    60.                             FILE_DEVICE_KEYBOARD,  
    61.                             0,                    
    62.                             FALSE,                
    63.                             &device);
    64.     if (! NT_SUCCESS(status))
    65.     {
    66.         DbgPrint("cannot create kbd filter device");
    67.         return (status);
    68.     }
    69.     RtlZeroMemory(device->DeviceExtension, sizeof(DEVICE_EXTENSION));
    70.     device_extension = (PDEVICE_EXTENSION) device->DeviceExtension;
    71.     device_extension->top_of_stack = IoAttachDeviceToDeviceStack(device, device_object);
    72.     ASSERT(device_extension->top_of_stack);
    73.     device->Flags |= (DO_BUFFERED_IO | DO_POWER_PAGABLE);
    74.     device->Flags &= ~DO_DEVICE_INITIALIZING;
    75.     return status;
    76. }
    77.  
    78. NTSTATUS read_complete_callback(IN PDEVICE_OBJECT device_object, IN PIRP irp, IN PVOID context)
    79. {
    80.     PIO_STACK_LOCATION irp_stack_location;
    81.     PKEYBOARD_INPUT_DATA key_data;
    82.     int num_keys, i;
    83.     irp_stack_location = IoGetCurrentIrpStackLocation(irp);
    84.     if (NT_SUCCESS(irp->IoStatus.Status))
    85.     {
    86.         key_data = irp->AssociatedIrp.SystemBuffer;
    87.         num_keys = (int) (irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA));
    88.         for(i = 0; i < num_keys; i++)
    89.         {          
    90.             // ...
    91.         }
    92.     }
    93.     // mark the Irp pending if required
    94.     //
    95.     if(irp->PendingReturned)
    96.         IoMarkIrpPending(irp);
    97.     return irp->IoStatus.Status;
    98. }
    99.  
    100. NTSTATUS device_open(PDEVICE_OBJECT device_object, PIRP irp)
    101. {
    102.     PDEVICE_EXTENSION device_extension = (PDEVICE_EXTENSION)device_object->DeviceExtension;
    103.     IoSkipCurrentIrpStackLocation(irp);
    104.     return IoCallDriver(((PDEVICE_EXTENSION)device_object->DeviceExtension)->top_of_stack, irp);
    105. }
    106.  
    107. NTSTATUS device_close(PDEVICE_OBJECT device_object, PIRP irp)
    108. {
    109.     return STATUS_SUCCESS;
    110. }
    111.  
    112. NTSTATUS device_read(IN PDEVICE_OBJECT device_object, IN PIRP irp)
    113. {
    114.     PDEVICE_EXTENSION device_extension = (PDEVICE_EXTENSION)device_object->DeviceExtension;
    115.     PIO_STACK_LOCATION current_irp_stack;
    116.     PIO_STACK_LOCATION next_irp_stack;
    117.     current_irp_stack = IoGetCurrentIrpStackLocation(irp);
    118.     next_irp_stack = IoGetNextIrpStackLocation(irp);    
    119.     *next_irp_stack = *current_irp_stack;
    120.     IoSetCompletionRoutine(irp, read_complete_callback, device_object, TRUE, TRUE, TRUE);
    121.     return IoCallDriver(device_extension->top_of_stack, irp);
    122. }
    123.  
    124. NTSTATUS device_write(PDEVICE_OBJECT device_object, PIRP irp)
    125. {
    126.     PDEVICE_EXTENSION device_extension = (PDEVICE_EXTENSION)device_object->DeviceExtension;
    127.     IoSkipCurrentIrpStackLocation(irp);
    128.     return IoCallDriver(((PDEVICE_EXTENSION)device_object->DeviceExtension)->top_of_stack, irp);
    129. }
    130.  
    131. NTSTATUS device_general(IN PDEVICE_OBJECT device_object, IN PIRP irp)
    132. {
    133.     PDEVICE_EXTENSION device_extension;
    134.     device_extension = (PDEVICE_EXTENSION)device_object->DeviceExtension;
    135.     IoSkipCurrentIrpStackLocation(irp);
    136.     return IoCallDriver(((PDEVICE_EXTENSION)device_object->DeviceExtension)->top_of_stack, irp);
    137. }
     
  15. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    хехе))
    может нужно DeviceExtension всетаки,а не DriverExtension?
    да и IoDeleteDevice не помешает потом.

    зЫ.
    вот как раз это приведет к бсоду при выгрузке - о чем я говорил выше
     
  16. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Кстати, да. У драйвера клавиатуры всегда стоит в очереди незавершенный IRP. В completion routine собственно и производится обработка нажатой клавиши. В статье http://www.wasm.ru/article.php?article=drvw2k16 by FourF есть код, корректно выгружающий фильтр клавиатуры. Плюс поищи Rootkits:Subverting Windows Kernel, там тоже был пример клавиатурного фильтра.
     
  17. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    нету там такого кода, он просто сбрасывает DriverObject->DriverUnload если нужно аттачиться, делая дров невыгружаемым)))

    Насчет конкретно фильтра клавиатуры - действительно у него всегда есть один незавершенный IRP, тут ситуацию спасет добавление в конец функции IoCompletion кода вида KeSetEvent( &CanUnloadEvent, 0, FALSE ), в начало IrpDispatch добавление KeClearEvent( &CanUnloadEvent, 0, FALSE ), а в DriverUnload нужно ожидать этот евент между вызовами IoDetachDevice и IoDeleteDevice, давая завершиться последней IoCompletion.
    Тогда можно сильно снизить вероятность бсода при выгрузке драйвера-фильтра клавиатуры, но все равно к нулю она не сведется, поскольку это будет работать только если всего 1 IRP в очереди остался. Если 2 и больше, то установка евента будет до момента завершения всех IRP и бсод) Тут придется глобальный счетчик незавершенных IRP делать

    UPDATE: Хотя хз, у меня не получилось сделать так, чтобы у клавы оставалось больше одного irp. Но все равно с другими фильтрами такая фигня может быть (
     
  18. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    http://www.rootkit.com/newsread.php?newsid=398
     
  19. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Занятный способ с созданием второго IRP
     
  20. asmfan

    asmfan New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2006
    Сообщения:
    1.004
    Адрес:
    Abaddon
    Задам вопрос здесь. Постоянно в драйверах-фильтрах встречается такой код
    Код (Text):
    1. for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    2.         driver_object->MajorFunction[i] = device_general;
    Но,
    , также как и
    .
    Т.е. в цикле мы этот обработчик (IRP_MJ_PNP / IRP_MJ_PNP_POWER) получается игнорируем. Вопрос - почему?