Простейший драйвер под Windows

Тема в разделе "WASM.BEGINNERS", создана пользователем Lecko, 4 июл 2011.

  1. Lecko

    Lecko Андрей

    Публикаций:
    0
    Регистрация:
    20 дек 2010
    Сообщения:
    60
    Всем привет!

    Начал изучать кодинг в нулевом кольце по книжке Колисниченко "Руткиты под Windows". Попробовал собрать и запустить драйвер по примеру, приведенному в книге.

    Вот листинг:
    Код (Text):
    1. #include <ntddk.h>
    2. typedef struct _DEVICE_EXTENSION
    3. {
    4.     PDEVICE_OBJECT pdo;
    5.     UNICODE_STRING ustrSymLinkName;
    6. } DEVICE_EXTENSION,*PDEVICE_EXTENSION;
    7.  
    8.  
    9. DRIVER_UNLOAD MyUnload;
    10. VOID MyUnload(IN PDRIVER_OBJECT pDriverObject)
    11. {
    12.     PDEVICE_OBJECT pNextDevObj;
    13.     int i;
    14.     DbgPrint("Unloading driver");
    15.     pNextDevObj=pDriverObject->DeviceObject;
    16.     for(i=0; pNextDevObj!=NULL;i++)
    17.     {
    18.         PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)pNextDevObj->DeviceExtension;
    19.         UNICODE_STRING *pLinkName=& (dx->ustrSymLinkName);
    20.         pNextDevObj=pNextDevObj->NextDevice;
    21.         DbgPrint("MyUnload Deleting Device (%d) : pointer to PDO=%X",i,dx->pdo);
    22.         DbgPrint("MyUnload Deleting SymLink =%ws : pointer to PDO=%X",pLinkName->Buffer);
    23.         IoDeleteSymbolicLink(pLinkName);
    24.         IoDeleteDevice(dx->pdo);
    25.     }
    26. }
    27.  
    28. NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
    29. {
    30.     NTSTATUS status=STATUS_SUCCESS;
    31.     PDEVICE_OBJECT pdo;
    32.     UNICODE_STRING devName;
    33.     UNICODE_STRING symLinkName;
    34.     PDEVICE_EXTENSION dx;
    35.     DbgPrint("Entering DriverEntry...");
    36.     DbgPrint("RegistryPath=%ws",pRegistryPath->Buffer);
    37.     RtlInitUnicodeString(&devName,L"\\Device\\MyDevice");
    38.     RtlInitUnicodeString(&symLinkName,L"\\DosDevices\\MyDevice");
    39.     pDriverObject->DriverUnload=(PDRIVER_UNLOAD)MyUnload;
    40.     status=IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&devName, FILE_DEVICE_UNKNOWN,0,FALSE,&pdo);
    41.     if(!NT_SUCCESS(status))
    42.     {
    43.         DbgPrint("DriverEntry IoCreateDeviceError");
    44.         return status;
    45.     }
    46.     dx=(PDEVICE_EXTENSION)pdo->DeviceExtension;
    47.     dx->pdo=pdo;
    48.     dx->ustrSymLinkName=symLinkName;
    49.     status=IoCreateSymbolicLink(&symLinkName,&devName);
    50.     if(!NT_SUCCESS(status))
    51.     {
    52.         IoDeleteDevice(pdo);
    53.         return status;
    54.     }
    55.     DbgPrint("DriverEntry successfully completed");
    56.     return status;
    57. }
    Вопросы:
    1) При загрузке его утилитой instdrv, собранной по исходникам из этой же книги, не получается создать устройство.
    2) зачем нужна структура dx? в листинге она не используется. Подозреваю, что не хватает какого-то системного вызова, которому она передается в качестве аргумента
     
  2. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    1. Какой статус возвращается?
    2. Как это не используется? В ней же имя ссылки хранится, которое потом используется для уничтожения в Unload.
     
  3. Lecko

    Lecko Андрей

    Публикаций:
    0
    Регистрация:
    20 дек 2010
    Сообщения:
    60
    1) статус не возвращается - утилита для загрузки пишет "Can't get a handle to \\.\MyDevice".
    Отладочных сообщений не возникает. никаких.
    2) спасибо, не заметил)
     
  4. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    А что WinObj показывает? Устройство создалось?
     
  5. h0t

    h0t Member

    Публикаций:
    0
    Регистрация:
    3 апр 2011
    Сообщения:
    735
    1.Вы не обрабатывайте запрос create.
    2. структура нужна для специфицеских задач конкретного драйвера поэтому она разработчиком созжается
     
  6. Lecko

    Lecko Андрей

    Публикаций:
    0
    Регистрация:
    20 дек 2010
    Сообщения:
    60
    Mika0x65
    Да, устройство MyDevice создалось

    h0t
    Я правильно понимаю, что без специального обработчика функция CreateFile, которая пытается открыть устройство, как файл, работать не будет?
     
  7. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Lecko
    Если у тебя в драйвере нет обработчика IRP_MJ_CREATE, но ты при этом создаешь "устройство" и симлинк к нему, то
    пытаться открыть файл через CreateFile бессмысленно. I/O Manager не найдет адрес обработчика и вернет ошибку.
    Обычно в коде нужно предусматрить обработчики MJ*-функций, нечто типа
    Код (Text):
    1. for(i= 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
    2. {
    3.     driverObject->MajorFunction[i]= defaultDispatch;
    4. }
    5. driverObject->MajorFunction[IRP_MJ_CREATE]      = DispatchRead;
    6. driverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]  = DeviceControlDispatch;
    где простейший defaultDispatch для твоего "устройства" будет примерно таким
    Код (Text):
    1. NTSTATUS defaultDispatch(
    2.                          IN PDEVICE_OBJECT pDeviceObject,
    3.                          IN PIRP pIrp
    4.                         )
    5. {
    6.     pIrp->IoStatus.Information = 0;
    7.     pIrp->IoStatus.Status = STATUS_SUCCESS;
    8.     IofCompleteRequest(pIrp,IO_NO_INCREMENT);
    9.     return STATUS_SUCCESS;
    10.  
    11. }
     
  8. Lecko

    Lecko Андрей

    Публикаций:
    0
    Регистрация:
    20 дек 2010
    Сообщения:
    60
    Заработало, всем спасибо! как выяснилось, для полного счастья ему не хватало обработчика IRP_MJ_CREATE.
    Особое спасибо steelfactor

    Полный код драйвера, если у других читателей Колисниченко возникнет такой же трабл:
    Код (Text):
    1. #include <ntddk.h>
    2. typedef struct _DEVICE_EXTENSION
    3. {
    4.     PDEVICE_OBJECT pdo;
    5.     UNICODE_STRING ustrSymLinkName;
    6. } DEVICE_EXTENSION,*PDEVICE_EXTENSION;
    7.  
    8.  
    9. DRIVER_UNLOAD MyUnload;
    10. VOID MyUnload(IN PDRIVER_OBJECT pDriverObject)
    11. {
    12.     PDEVICE_OBJECT pNextDevObj;
    13.     int i;
    14.     DbgPrint("Unloading driver");
    15.     pNextDevObj=pDriverObject->DeviceObject;
    16.     for(i=0; pNextDevObj!=NULL;i++)
    17.     {
    18.         PDEVICE_EXTENSION dx=(PDEVICE_EXTENSION)pNextDevObj->DeviceExtension;
    19.         UNICODE_STRING *pLinkName=& (dx->ustrSymLinkName);
    20.         pNextDevObj=pNextDevObj->NextDevice;
    21.         DbgPrint("MyUnload Deleting Device (%d) : pointer to PDO=%X",i,dx->pdo);
    22.         DbgPrint("MyUnload Deleting SymLink =%ws : pointer to PDO=%X",pLinkName->Buffer);
    23.         IoDeleteSymbolicLink(pLinkName);
    24.         IoDeleteDevice(dx->pdo);
    25.     }
    26. }
    27.  
    28. NTSTATUS DriverDefaultHandler(IN PDEVICE_OBJECT pDeviceObject, IN PIRP Irp)
    29. {
    30.     PIO_STACK_LOCATION pSL = IoGetCurrentIrpStackLocation (Irp) ;
    31.    
    32.     switch (pSL->MajorFunction)
    33.     {
    34.         case IRP_MJ_CREATE :
    35.         case IRP_MJ_CLOSE :
    36.         case IRP_MJ_CLEANUP :
    37.             {
    38.                 Irp->IoStatus.Status = STATUS_SUCCESS;
    39.                 break;
    40.             }
    41.         default:
    42.                 { Irp->IoStatus.Status = STATUS_NOT_SUPPORTED ; }
    43.     }
    44.  
    45.     Irp->IoStatus.Information = 0;
    46.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
    47.     return Irp->IoStatus.Status;
    48. }
    49.  
    50. NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
    51. {
    52.     NTSTATUS status=STATUS_SUCCESS;
    53.     PDEVICE_OBJECT pdo;
    54.     UNICODE_STRING devName;
    55.     UNICODE_STRING symLinkName;
    56.     PDEVICE_EXTENSION dx;
    57.     int i;
    58.     DbgPrint("Entering DriverEntry...");
    59.     DbgPrint("RegistryPath=%ws",pRegistryPath->Buffer);
    60.     RtlInitUnicodeString(&devName,L"\\Device\\MyDevice");
    61.     RtlInitUnicodeString(&symLinkName,L"\\DosDevices\\MyDevice");
    62.     pDriverObject->DriverUnload=(PDRIVER_UNLOAD)MyUnload;
    63.     for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++)
    64.     pDriverObject->MajorFunction[i] = DriverDefaultHandler;
    65.     status=IoCreateDevice(pDriverObject,sizeof(DEVICE_EXTENSION),&devName, FILE_DEVICE_UNKNOWN,0,FALSE,&pdo);
    66.     if(!NT_SUCCESS(status))
    67.     {
    68.         DbgPrint("DriverEntry IoCreateDeviceError");
    69.         return status;
    70.     }
    71.     pdo->Flags &= ~DO_DEVICE_INITIALIZING;
    72.     dx=(PDEVICE_EXTENSION)pdo->DeviceExtension;
    73.     dx->pdo=pdo;
    74.     dx->ustrSymLinkName=symLinkName;
    75.     status=IoCreateSymbolicLink(&symLinkName,&devName);
    76.     if(!NT_SUCCESS(status))
    77.     {
    78.         IoDeleteDevice(pdo);
    79.         return status;
    80.     }
    81.     DbgPrint("DriverEntry successfully completed");
    82.     return status;
    83. }