Обмен данными между драйвером и приложением.

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

  1. NENser

    NENser New Member

    Публикаций:
    0
    Регистрация:
    21 дек 2008
    Сообщения:
    5
    Есть задание: написать драйвер режима ядра и приложение (на Си), которое будет с ним взаимодействовать. Драйвер хукает три Zw-функции и если какой-либо процесс обращается ко всем трём, драйвер отправляет сообщение (PID этого процесса) приложению режима пользователя. Приложение выводит MessageBox c PID'ом и спрашивает разрешить процессу использовать Zw-функции или заблокировать. После выбора действия, приложение отправляет драйверу команду "разрешить/заблокировать". То есть это такое жалкое подобие Проактивной защиты, которая есть в Касперском или Аутпосте.

    Перехват функций я написал, определение PID'а процесса тоже. Никак не могу сделать обмен данными между приложением и драйвером. ПОнимаю, что это делается через IRP, но как именно?

    Если кто-то знает как это сделать или знает, где посмотреть хороший пример (не нашёл в интернете таких), поделитесь информацией, пожалуйста.
     
  2. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    http://www.wasm.ru/article.php?article=drvw2k04
    http://www.wasm.ru/article.php?article=drvw2k08
    http://www.wasm.ru/article.php?article=drvw2k09
     
  3. NENser

    NENser New Member

    Публикаций:
    0
    Регистрация:
    21 дек 2008
    Сообщения:
    5
    Freeman
    Спасибо! А есть примеры именно приложения (желательно на языке Си/С++)? Всего-то нужно пару байт переслать в обе стороны, я чувствую, что это несложно, но не знаю как =)
     
  4. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    NENser
    На osronline был такой пример, поищи
     
  5. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    плохо искал
     
  6. NENser

    NENser New Member

    Публикаций:
    0
    Регистрация:
    21 дек 2008
    Сообщения:
    5
    на osronline такая путанная навигация, нужно регистрироваться чуть ли не каждый раз, при прочтении новой темы.. Ладно, буду сам разбираться, уже вторую неделю мучаюсь. Всем спасибо, если кому интересно, потом результатом поделюсь.
     
  7. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Код (Text):
    1. //
    2. // Kernel mode driver for Windows NT
    3. //
    4. // (C) Great, 2006-2008
    5. //
    6.  
    7. extern "C"
    8. {
    9. #include <ntddk.h>
    10. }
    11.  
    12.  
    13. UNICODE_STRING DeviceName;
    14. UNICODE_STRING SymbolicLinkName;
    15. PDEVICE_OBJECT deviceObject;
    16.  
    17. // Unload routine
    18. void DriverUnload(IN PDRIVER_OBJECT DriverObject)
    19. {
    20.     IoDeleteSymbolicLink (&SymbolicLinkName);
    21.     if(deviceObject)
    22.         IoDeleteDevice (deviceObject);
    23.  
    24.     KdPrint(("[+] Driver unloaded\n"));
    25. }
    26.  
    27. // Dispath routines for the device
    28. NTSTATUS DriverIoControl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    29. {
    30.     PIO_STACK_LOCATION pisl     = IoGetCurrentIrpStackLocation(Irp);
    31.     NTSTATUS           status   = STATUS_UNSUCCESSFUL;
    32.     ULONG              BuffSize = pisl->Parameters.DeviceIoControl.InputBufferLength;
    33.     PUCHAR             pBuff    = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
    34.  
    35.     Irp->IoStatus.Information = 0;
    36.  
    37.     switch(pisl->Parameters.DeviceIoControl.IoControlCode)
    38.     {
    39.         case 0x1234:
    40.             // Input  buffer length:   pisl->Parameters.DeviceIoControl.InputBufferLength
    41.             // Output buffer length:   pisl->Parameters.DeviceIoControl.OutputBufferLength
    42.             // System buffer:          pBuff
    43.             // set Irp->IoStatus.Information as number of bytes to copy to user buffer
    44.             status = STATUS_SUCCESS;
    45.         break;
    46.     }  
    47.  
    48.     Irp->IoStatus.Status = status;
    49.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
    50.     return status;
    51. }
    52.  
    53. NTSTATUS DriverReadWrite(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    54. {
    55.     PIO_STACK_LOCATION pisl = IoGetCurrentIrpStackLocation(Irp);
    56.     PUCHAR pBuff = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
    57.     NTSTATUS st = STATUS_UNSUCCESSFUL;
    58.  
    59.     Irp->IoStatus.Information = 0;
    60.  
    61.     if(pisl->MajorFunction == IRP_MJ_READ)
    62.     {
    63.         KdPrint(("[~] IRP_MJ_READ\n"));
    64.         // Length: pisl->Parameters.Read.Length;
    65.         // Buffer: pBuff
    66.         // Set Irp->IoStatus.Information = number of bytes read
    67.         st = STATUS_SUCCESS;
    68.     }
    69.     else if(pisl->MajorFunction == IRP_MJ_WRITE)
    70.     {
    71.         KdPrint(("[~] IRP_MJ_WRITE\n"));
    72.         // Length: pisl->Parameters.Write.Length
    73.         // Buffer: pBuff
    74.         // Set Irp->IoStatus.Information as number of bytes written
    75.         st = STATUS_SUCCESS;
    76.     }
    77.    
    78.     Irp->IoStatus.Status = st;
    79.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
    80.     return st;
    81. }
    82.  
    83. // create & close dispath routine
    84. NTSTATUS DriverCreateClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    85. {
    86.     PIO_STACK_LOCATION pisl = IoGetCurrentIrpStackLocation(Irp);
    87.  
    88.     switch(pisl->MajorFunction)
    89.     {
    90.     case IRP_MJ_CLOSE:
    91.         KdPrint(("[~] IRP_MJ_CLOSE request\n"));
    92.         break;
    93.     case IRP_MJ_CREATE:
    94.         KdPrint(("[~] IRP_MJ_CREATE request\n"));
    95.         break;
    96.     }
    97.  
    98.     Irp->IoStatus.Information = 0;
    99.     Irp->IoStatus.Status = STATUS_SUCCESS;
    100.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
    101.     return STATUS_SUCCESS;
    102. }
    103.  
    104. // Driver entry point
    105. NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
    106. {
    107.     NTSTATUS status;
    108.  
    109.     KdPrint(("[~] Driver loading\n"));
    110.  
    111.     RtlInitUnicodeString(&DeviceName, L"\\Device\\testdevice");
    112.     RtlInitUnicodeString(&SymbolicLinkName, L"\\DosDevices\\testdevice");
    113.  
    114.     status = IoCreateDevice(DriverObject,
    115.                             0,
    116.                             &DeviceName,
    117.                             FILE_DEVICE_UNKNOWN,
    118.                             0,
    119.                             TRUE,
    120.                             &deviceObject);
    121.    
    122.     if (!NT_SUCCESS(status))
    123.     {
    124.         KdPrint(("[-] Failed to create first device. IoCreateDevice returned %x\n", status));
    125.         return STATUS_UNSUCCESSFUL;
    126.     }
    127.    
    128.     deviceObject->Flags |= DO_BUFFERED_IO;
    129.     status = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
    130.     if (!NT_SUCCESS(status))
    131.     {
    132.         KdPrint(("[-] Failed to create first symbolic link. IoCreateSymbolicLink returned %x\n", status));
    133.         IoDeleteDevice(deviceObject);
    134.         return STATUS_UNSUCCESSFUL;
    135.     }
    136.  
    137.     // Set dispath routines
    138.        
    139.     DriverObject->DriverUnload = DriverUnload;
    140.  
    141.     DriverObject->MajorFunction [IRP_MJ_READ  ] =
    142.     DriverObject->MajorFunction [IRP_MJ_WRITE ] = DriverReadWrite;
    143.  
    144.     DriverObject->MajorFunction [IRP_MJ_CREATE] =
    145.     DriverObject->MajorFunction [IRP_MJ_CLOSE ] = DriverCreateClose;
    146.     DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL ] = DriverIoControl;
    147.  
    148.     KdPrint(("[+] Driver initialization successful\n"));
    149.  
    150.     return STATUS_SUCCESS;
    151. }
    в юзермоде CreateFile("\\\\.\\testdevice", GENERIC_READ|GENERIC_WRITE, ....);
    WriteFile / ReadFile / DeviceIoControl (hDev, ..., 0x1234, ...)
     
  8. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Все там в норме. http://www.osronline.com/article.cfm?article=39
     
  9. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.317
    привет, Сережа!)))))))
     
  10. NENser

    NENser New Member

    Публикаций:
    0
    Регистрация:
    21 дек 2008
    Сообщения:
    5
    Вот отрывок кода для обработки IRP
    Код (Text):
    1. int Pid;   //PID процессаЮ который нужно передать приложению
    2. wchar_t *Data;   //Буфер, через который идёт обмен информацией
    3.  
    4. VOID OnUnload(IN PDRIVER_OBJECT pDriverObject)
    5. {
    6.     PDEVICE_OBJECT pNextDevObj;
    7.     int i;
    8.     DbgPrint("OnUnload");
    9.     pNextDevObj = pDriverObject->DeviceObject;
    10.     for(i=1; pNextDevObj!=NULL; i++)
    11.     {
    12.         PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)pNextDevObj->DeviceExtension;
    13.         UNICODE_STRING *pLinkName = &(dx->ustrSymLinkName);
    14.         pNextDevObj = pNextDevObj->NextDevice;
    15.         DbgPrint("OnUnload Deleting device (%d) : pointer to PDO = %X.", i, dx->pdo);
    16.         DbgPrint("OnUnload Deleting symlink = %ws.", pLinkName->Buffer);
    17.         IoDeleteSymbolicLink(pLinkName);                            //Удаляем символическую ссылку
    18.         IoDeleteDevice(dx->pdo);                                    //Удаляем устройство
    19.     }
    20.  
    21.     MyUNHOOK(); //СНимаем хуки
    22.     DbgPrint("OnUnload: done.");
    23. }
    24. //обработчик IRP-прерываний
    25. NTSTATUS CompleteIrp(IN PDEVICE_OBJECT pFDO, IN PIRP pIRP)
    26. {
    27.     DbgPrint("CompleteIrp: started.");
    28.  
    29.     pIRP->IoStatus.Status = STATUS_SUCCESS;
    30.     IoCompleteRequest(pIRP, IO_NO_INCREMENT);
    31.  
    32.     DbgPrint("CompleteIrp: done.");
    33.  
    34.     return STATUS_SUCCESS;
    35. }
    36.  
    37. NTSTATUS DriverRead_Write(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
    38. {  
    39.     WCHAR szTemp[512];
    40.  
    41.     PIO_STACK_LOCATION pisl;
    42.     NTSTATUS status = STATUS_SUCCESS;
    43. //получаем текущий IRP
    44.     pisl=IoGetCurrentIrpStackLocation(Irp);
    45. //в зависимости от ввода/вывода осуществляем
    46.     if(pisl->MajorFunction == IRP_MJ_WRITE)
    47.     {
    48.         if(LengthData>0) ExFreePool(Data); //освобождаем Data
    49.         LengthData=pisl->Parameters.Write.Length;
    50.         Data = ExAllocatePool(PagedPool, LengthData);
    51.         RtlZeroMemory(Data, LengthData);        //зануляем
    52.         RtlCopyMemory(Data, Irp->AssociatedIrp.SystemBuffer, LengthData);
    53.         Irp->IoStatus.Information=0;
    54.     }
    55.     else
    56.     if (pisl->MajorFunction == IRP_MJ_READ)
    57.     {  
    58.         if(LengthData>0)
    59.         {  
    60.             RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Data, ReadLength);
    61.             Irp->IoStatus.Information=ReadLength;
    62.         }
    63.         else Irp->IoStatus.Information=0;
    64.     }
    65.     Irp->IoStatus.Status = status;
    66.     IoCompleteRequest(Irp, IO_NO_INCREMENT);
    67.    
    68.     return status;
    69. }
    70.  
    71. //Точка входа в драйвер
    72. NTSTATUS DriverEntry (IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING pRegistryPath)
    73. {
    74.     int i,pid;
    75.  
    76.     NTSTATUS status = STATUS_SUCCESS;   //статус завершения
    77.     PDEVICE_OBJECT pdo;                 //указатель на устройство
    78.     UNICODE_STRING devName;            
    79.     UNICODE_STRING symLinkName;
    80.     PDEVICE_EXTENSION dx;               //указатель на расширение устройства
    81.     PDRIVER_DISPATCH *ppdd;
    82.     DbgPrint("Entering DriverEntry");
    83.     DbgPrint("RegistryPath = %ws.", pRegistryPath->Buffer);
    84.     //Создаём экземпляры строк UNICODE для имен устройства
    85.     // и символической ссылки
    86.     RtlInitUnicodeString(&devName, L"\\Device\\MYDRV");                                                                            
    87.     RtlInitUnicodeString(&symLinkName, L"\\DosDevices\\MYDRV");    
    88.  
    89.  
    90.  
    91. //Создаём утройство
    92.     status = IoCreateDevice(pDriverObject, sizeof(DEVICE_EXTENSION), &devName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pdo);
    93.     if(!NT_SUCCESS(status))
    94.     {
    95.         DbgPrint("DriverEntry IoCreateDevice error");
    96.         return status;
    97.     }
    98.    
    99.     dx = (PDEVICE_EXTENSION)pdo->DeviceExtension;
    100.     dx->pdo = pdo;
    101.     dx->ustrSymLinkName = symLinkName;
    102. //Устанавливаем буферизированный ввод/вывод
    103.     pdo->Flags = DO_BUFFERED_IO;
    104. //создаём символическую ссылку устройства  
    105.     status = IoCreateSymbolicLink(&symLinkName, &devName);
    106.     if(!NT_SUCCESS(status))
    107.     {
    108.         IoDeleteDevice(pdo);
    109.         return status;
    110.     }
    111.     Mass_NULL();
    112.     //Устанавливаем хуки
    113.     MyHOOK();
    114.     //объявляем процедуры обработки ввода-вывода 
    115.  
    116.     ppdd = pDriverObject->MajorFunction;               
    117.     ppdd[IRP_MJ_CREATE]=ppdd[IRP_MJ_CLOSE]=ppdd[IRP_MJ_READ]=DriverRead_Write;
    118.     ppdd[IRP_MJ_WRITE]=DriverRead_Write;
    119.    
    120.     DbgPrint("DriverEntry successfully completed.");
    121.    
    122.     pDriverObject->DriverUnload = OnUnload;
    123.     return status;
    124. }
    Так вот вопрос, как мне в буфер wchar_t *Data поместить переменную int Pid, чтобы передать его через это:
    Код (Text):
    1.     if (pisl->MajorFunction == IRP_MJ_READ)
    2.     {  
    3.         if(LengthData>0)
    4.         {  
    5.             RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, Data, ReadLength);
    6.             Irp->IoStatus.Information=ReadLength;
    7.         }
    8.         else Irp->IoStatus.Information=0;
    9.     }
    Или есть какой-то другой способ, который проще?