Advertisement
fatalryuu

kernel keyboard driver

Dec 2nd, 2023
650
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.12 KB | None | 0 0
  1. #include <ntddk.h>
  2. #pragma warning( disable : 4189 )
  3.  
  4. typedef struct {
  5.     PDEVICE_OBJECT LowerKbdDevice;
  6. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
  7.  
  8. typedef struct _KEYBOARD_INPUT_DATA {
  9.     USHORT UnitId;
  10.     USHORT MakeCode;
  11.     USHORT Flags;
  12.     USHORT Reserved;
  13.     ULONG  ExtraInformation;
  14. } KEYBOARD_INPUT_DATA, *PKEYBOARD_INPUT_DATA;
  15.  
  16. PDEVICE_OBJECT myKbdDevice = NULL;
  17.  
  18. ULONG pendingKey = 0;
  19.  
  20. NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath);
  21.  
  22. VOID DriverUnload(PDRIVER_OBJECT DriverObject);
  23.  
  24. NTSTATUS DispatchPass(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
  25.     // копирование текущей структуры IRP в следующий элемент стека
  26.     IoCopyCurrentIrpStackLocationToNext(Irp);
  27.  
  28.     // вызов следующего в стеке драйвера для обработки IRP
  29.     return IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerKbdDevice, Irp);
  30. }
  31.  
  32. NTSTATUS ReadComplete(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) {
  33.     UNREFERENCED_PARAMETER(DeviceObject);
  34.     UNREFERENCED_PARAMETER(Context);
  35.     // массив строк для интерпретации флагов в структуре KEYBOARD_INPUT_DATA
  36.     CHAR* keyflag[4] = { "KeyDown", "KeyUp", "E0", "E1" };
  37.     // получение указателя на массив структур KEYBOARD_INPUT_DATA из буфера системного IRP
  38.     PKEYBOARD_INPUT_DATA Keys = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
  39.     // расчет количества структур KEYBOARD_INPUT_DATA в буфере
  40.     int structnum = (int) (Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA));
  41.     int i;
  42.     if (Irp->IoStatus.Status == STATUS_SUCCESS) {
  43.         // вывод информации о скан-коде и флагах в отладочную консоль
  44.         for (i = 0; i < structnum; i++) {
  45.             DbgPrintEx(0, 0, "the scan code is %x (%s)\n", Keys[i].MakeCode, keyflag[Keys[i].Flags]);
  46.         }
  47.     }
  48.  
  49.     // пометка IRP как ожидающего завершения, если это необходимо
  50.     if (Irp->PendingReturned) {
  51.         IoMarkIrpPending(Irp);
  52.     }
  53.  
  54.     // уменьшение счетчика ожидающих обработки запросов чтения
  55.     pendingKey--;
  56.  
  57.     return Irp->IoStatus.Status;
  58. }
  59.  
  60. NTSTATUS DispatchRead(PDEVICE_OBJECT DeviceObject, PIRP Irp) {
  61.     // копирование текущей структуры IRP в следующий элемент стека
  62.     IoCopyCurrentIrpStackLocationToNext(Irp);
  63.  
  64.     // устанавка обработчика завершения для IRP
  65.     IoSetCompletionRoutine(Irp, ReadComplete, NULL, TRUE, TRUE, TRUE);
  66.  
  67.     // увеличение счетчика ожидающих обработки запросов чтения
  68.     pendingKey++;
  69.  
  70.     // вызов следующего в стеке драйвера для обработки IRP
  71.     return IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerKbdDevice, Irp);
  72. }
  73.  
  74. NTSTATUS MyAttachDevice(PDRIVER_OBJECT DriverObject) {
  75.     NTSTATUS status;
  76.     UNICODE_STRING TargetDevice = RTL_CONSTANT_STRING(L"\\Device\\KeyboardClass0");
  77.  
  78.     // создание устройства
  79.     status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_KEYBOARD, 0, FALSE, &myKbdDevice);
  80.     if (!NT_SUCCESS(status)) {
  81.         return status;
  82.     }
  83.  
  84.     // установка флагов для устройства с буферизованным вводом/выводом
  85.     myKbdDevice->Flags |= DO_BUFFERED_IO;
  86.     // сброс флага инициализации устройства
  87.     myKbdDevice->Flags &= ~DO_DEVICE_INITIALIZING;
  88.  
  89.     // заполнение нулями расширенной структуры устройства
  90.     RtlZeroMemory(myKbdDevice->DeviceExtension, sizeof(DEVICE_EXTENSION));
  91.  
  92.     // присоединение устройства к клавиатуре
  93.     status = IoAttachDevice(myKbdDevice, &TargetDevice, &((PDEVICE_EXTENSION)myKbdDevice->DeviceExtension)->LowerKbdDevice);
  94.     if (!NT_SUCCESS(status)) {
  95.         // удаление устройства в случае неудачи
  96.         IoDeleteDevice(myKbdDevice);
  97.         return status;
  98.     }
  99.  
  100.     return STATUS_SUCCESS;
  101. }
  102.  
  103. VOID DriverUnload(PDRIVER_OBJECT DriverObject) {
  104.     LARGE_INTEGER interval = { 0 };
  105.     PDEVICE_OBJECT DeviceObject = DriverObject->DeviceObject;
  106.     interval.QuadPart = -10 * 1000 * 1000;
  107.  
  108.     // отсоединение устройства клавиатуры
  109.     IoDetachDevice(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->LowerKbdDevice);
  110.  
  111.     // ожидание завершения обработки всех оставшихся запросов чтения
  112.     while (pendingKey) {
  113.         KeDelayExecutionThread(KernelMode, FALSE, &interval);
  114.     }
  115.  
  116.     // удаление устройства клавиатуры
  117.     IoDeleteDevice(myKbdDevice);
  118.  
  119.     DbgPrintEx(0, 0, "DriverUnload\n");
  120. }
  121.  
  122. NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) {
  123.     UNREFERENCED_PARAMETER(RegistryPath);
  124.     NTSTATUS status;
  125.     int i;
  126.  
  127.     // установка функции, которая выполнится при выгрузке драйвера
  128.     DriverObject->DriverUnload = DriverUnload;
  129.  
  130.     // устанавка функций обработки по умолчанию для всех типов IRP
  131.     for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  132.         DriverObject->MajorFunction[i] = DispatchPass;
  133.     }
  134.  
  135.     // устанвока функции для перехвата операций чтения
  136.     DriverObject->MajorFunction[IRP_MJ_READ] = DispatchRead;
  137.  
  138.     // создание и присоединение устройства к драйверу
  139.     status = MyAttachDevice(DriverObject);
  140.     if (!NT_SUCCESS(status)) {
  141.         DbgPrintEx(0, 0, "Attaching is failed\n");
  142.     } else {
  143.         DbgPrintEx(0, 0, "Attaching is successful\n");
  144.     }
  145.     return status;
  146. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement