Driver IO BSOD

Тема в разделе "WASM.NT.KERNEL", создана пользователем VirMaker, 22 июн 2009.

  1. VirMaker

    VirMaker New Member

    Публикаций:
    0
    Регистрация:
    4 дек 2008
    Сообщения:
    20
    Изучаю перехват API в ring0 по статье http://www.wasm.ru/article.php?article=apihook_3


    В ней есть простой IO-драйвер
    Код (Text):
    1. #include <ntddk.h>
    2.  
    3. #define DEBUG
    4.  
    5. #ifdef DEBUG
    6.   #define DPRINT DbgPrint
    7. #else
    8.   #define DPRINT
    9. #endif
    10.  
    11. UNICODE_STRING DeviceName;
    12. UNICODE_STRING SymbolicLinkName;
    13. PDEVICE_OBJECT deviceObject = NULL;
    14.  
    15. VOID DriverUnload(IN PDRIVER_OBJECT DriverObject) {
    16.  
    17.     DPRINT("Driver unloaded");
    18.     IoDeleteSymbolicLink(&SymbolicLinkName); // удаляем символическую ссылку
    19.     IoDeleteDevice(deviceObject);                // удаляем устройство return;
    20.  
    21. }
    22.  
    23. NTSTATUS DriverDispatcher( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    24. {
    25. PIO_STACK_LOCATION pisl;
    26. NTSTATUS           ns = STATUS_SUCCESS;
    27. PCSTR              Data;
    28.  
    29.     pisl = IoGetCurrentIrpStackLocation(Irp);
    30.     Irp->IoStatus.Information = 0;
    31.  
    32.     if ( pisl->MajorFunction == IRP_MJ_WRITE) {
    33.    
    34.         ULONG Length = pisl->Parameters.Write.Length;
    35.         Data = Irp->UserBuffer;
    36.        
    37.         __try {
    38.             DbgPrint("%s", Data); }          
    39.         __except(EXCEPTION_EXECUTE_HANDLER)            
    40.         {
    41.             Irp->IoStatus.Information = 0;
    42.             ns = STATUS_IN_PAGE_ERROR;
    43.         }
    44.     }
    45.    
    46.     Irp->IoStatus.Status = ns;
    47.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
    48.     return ns;
    49. }
    50.  
    51. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
    52. {
    53.  
    54. NTSTATUS st;
    55. PCWSTR   dDeviceName = L"\\Device\\MyDriver";
    56. PCWSTR   dSymbolicLinkName = L"\\DosDevices\\MyDriver";
    57. PDRIVER_DISPATCH *ppdd;
    58.  
    59.     DPRINT("Driver loaded");
    60.  
    61.     RtlInitUnicodeString(&DeviceName, dDeviceName);
    62.     RtlInitUnicodeString(&SymbolicLinkName, dSymbolicLinkName);
    63.  
    64.     st = IoCreateDevice(DriverObject,       // указатель на DriverObject
    65.                         0,                  // размер памяти (device extension)
    66.                         &DeviceName,        // имя создаваемого устройства
    67.                         FILE_DEVICE_NULL,   // тип создаваемого устройства
    68.                         0,                  // характеристики устройства
    69.                         FALSE,              // "эксклюзивное" устройство
    70.                         &deviceObject);     // указатель на объект устройства if
    71.    
    72.    
    73.     (st == STATUS_SUCCESS) st
    74.       = IoCreateSymbolicLink(&SymbolicLinkName, // имя создаваемой символической ссылки
    75.                              &DeviceName);      // имя устройства
    76.  
    77.  
    78.     ppdd = DriverObject->MajorFunction;         // обьявляю процедуры обработки ввода-вывода ppdd
    79.     ppdd[IRP_MJ_CREATE] =
    80.     ppdd[IRP_MJ_CLOSE ] =
    81.     ppdd[IRP_MJ_WRITE ] = DriverDispatcher;
    82.  
    83.     DriverObject->DriverUnload = DriverUnload;
    84.  
    85.     return st;
    86. }
    Читаю символьную ссылку на обьект драйвер
    Код (Text):
    1.  HANDLE hDriver;
    2.  DWORD Written;
    3.  PCHAR Str;
    4.  hDriver = CreateFile("\\\\.\\MyDriver", GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, 0);
    5.  if (hDriver != INVALID_HANDLE_VALUE)
    6.  {
    7.       WriteFile(hDriver, Str, lstrlen(Str), &Written, NULL);
    8.  }
    9.  CloseHandle(hDriver);
    Возникает BSOD, по умолчанию в системе установлен малый дамп памяти 64кб.
    Возможно идентифицировать ошибку?
     
  2. VirMaker

    VirMaker New Member

    Публикаций:
    0
    Регистрация:
    4 дек 2008
    Сообщения:
    20
    Здесь тоже ошибка

    Было
    Код (Text):
    1. (st == STATUS_SUCCESS) st
    2.       = IoCreateSymbolicLink(&SymbolicLinkName, // имя создаваемой символической ссылки
    3.                              &DeviceName);
    Изменил на
    // (st == STATUS_SUCCESS)
    st = IoCreateSymbolicLink(&SymbolicLinkName, // имя создаваемой символической ссылки
    &DeviceName);
     
  3. VirMaker

    VirMaker New Member

    Публикаций:
    0
    Регистрация:
    4 дек 2008
    Сообщения:
    20
    И еще неверно озаглавлено, не BSOD, а моментальная перезагрузка
     
  4. VirMaker

    VirMaker New Member

    Публикаций:
    0
    Регистрация:
    4 дек 2008
    Сообщения:
    20
    Драйвер загружаю через KmdManager
     
  5. bendme

    bendme New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    179
    улыбнуло )) ты if потерял на предыдущей строке

    IF (st == STATUS_SUCCESS)
    st = IoCreateSymbolicLink(&SymbolicLinkName, // имя создаваемой символической ссылки
    &DeviceName);
     
  6. Rodin

    Rodin New Member

    Публикаций:
    0
    Регистрация:
    30 апр 2007
    Сообщения:
    125
    Код вроде правильный. Правда, не увидел инициализации передаваемой строки - по коду передается треш. Тогда будет падать на DbgPrint("%s", Data);

    Учись отлаживаться на тестовой
    http://silverstr.ufies.org/lotr0/windbg-vmware.html
     
  7. VirMaker

    VirMaker New Member

    Публикаций:
    0
    Регистрация:
    4 дек 2008
    Сообщения:
    20
    В статье нету никакого if'а, может потерялся
     
  8. VirMaker

    VirMaker New Member

    Публикаций:
    0
    Регистрация:
    4 дек 2008
    Сообщения:
    20
    И действительно передавался! Теперь все нормально
     
  9. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Если обращаешься к UserBuffer, нужно контролировать валидность данных.
    А лучше юзать Buffered I/O
     
  10. rdtsc

    rdtsc Параллелепипедов Артем

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    180
    Адрес:
    Москва
    мда, видимо узучение идет методом копипаста (это я нащет if ))
     
  11. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Да.

    Это некорректное утверждение. Каждый из методов передачи данных имеет свою сферу применения. Например, Buffered I/O совершенно точно не подойдёт для больших объёмов данных (больше 1 ГБ), в этом случае останется использоваться только Neither.
     
  12. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    x64
    Ну ясен пень, имелось в виду, что автору конкретно в данной ситуации для изучения дров и написания своего первого драйвера, который создает девайс объект, лучше всего подойдет именно buffered.
    Ну а про сферы применения ты, конечно, прав, тем более, что это все прекрасно описано в мсдн.

    Не надо цитировать мсдн:)
     
  13. bendme

    bendme New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    179
    st = IoCreateDevice(DriverObject, // указатель на DriverObject
    0, // размер памяти (device extension)
    &DeviceName, // имя создаваемого устройства
    FILE_DEVICE_NULL, // тип создаваемого устройства
    0, // характеристики устройства
    FALSE, // "эксклюзивное" устройство
    &deviceObject); // указатель на объект устройства IF


    (st == STATUS_SUCCESS) st
    = IoCreateSymbolicLink(&SymbolicLinkName, // имя создаваемой символической ссылки
    &DeviceName); // имя устройства
     
  14. VirMaker

    VirMaker New Member

    Публикаций:
    0
    Регистрация:
    4 дек 2008
    Сообщения:
    20
    bendme

    Ну я и говорю сьехал в коментарий

    rdtsc
    А Вы и так, не можете :P

    x64
    Что есть Buffered I/O?
     
  15. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    В MSDN и бегом давай. И чтоб духу твоего здесь не было покуда не наступит просветление. Воистину, ибо так. Аминь.
     
  16. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Read the f*cking msdn)
    А так же статьи Four-F
    http://www.wasm.ru/article.php?article=drvw2k04
    http://www.wasm.ru/article.php?article=drvw2k05

    deviceObject->Flags |= DO_BUFFERED_IO; // при инициализации

    А потом обращаться к системному буфферу в Irp->AssociatedIrp.SystemBuffer. В него скопируется входной пользовательский буффер (если таковое предполагается в запросе - IRP_MJ_WRITE / IRP_MJ_DEVICE_CONTROL)
    Число, указанное в Irp->IoStatus.Information, будет означать количество байт, которое нужно скопировать в пользовательский буффер (если таковое предполагается в запросе - IRP_MJ_READ / IRP_MJ_DEVICE_CONTROL, иначе это будет означать число фактически записанных байт - IRP_MJ_WRITE, возможны и другие варианты вроде бы).

    За подробностями в мсдн.