Перехват события от клавиатуры OS Windows (Keyboard Input WDF Filter Driver (Kbfiltr))
Вообщем, есть майкрософтовский стандартный драйвер клавы. Который по существу является верхним драйвер фильтром. "Лежит" между KbdClass драйвером и драйвером порта i8042prt.
This is an upper device filter driver sample for PS/2 keyboard. This driver layers in between the KbdClass driver and i8042prt driver and hooks the callback routine that moves keyboard inputs from the port driver to class driver. In its current state, it only hooks into the keyboard packet report chain, the keyboard initialization function, and the keyboard ISR, but does not do any processing of the data that it sees. (The hooking of the initialization function and ISR is only available in the i8042prt stack.) With additions to this current filter-only code base, the filter could conceivably add, remove, or modify input as needed.
but does not do any processing of the data that it sees . Мне не совсем понятно что значит это утверждение. Те есть он не может обрабатывать данные введенные с клавиатуры? Может ли он перехватить событие нажатие клавиши? Код объемный, поэтому не хочу выкладывать целиком. А какой именно кусок показать не знаю(
Ответы (1 шт):
Microsoft выложила этот драйвер в качестве каркаса, который можно дополнять своим функционалом. В текущей своей конфигурации, он не может менять данные, а только ведёт логи, о чём собственно и говорится в описании:
В своем текущем состоянии он подключается только к цепочке отчетов о пакетах клавиатуры, функции инициализации клавиатуры и ISR клавиатуры, но не выполняет никакой обработки данных, которые видит. (Подключение функции инициализации и ISR доступно только в стеке i8042prt.) С дополнениями к этой текущей базе кода, предназначенной только для фильтров, фильтр может предположительно добавлять, удалять или изменять входные данные по мере необходимости.
После того, как вы соберёте этот драйвер нужно будет посмотреть, приаттачился он к стеку-драйверов клавиатуры, или нет. Для этого можно воспользоваться отладчиком WinDbg, которому передать команды в сл.последовательности:
0: kd> !drvobj i8042prt
Driver object (fffffa8002c10d20) is for: \Driver\i8042prt
Device object list: fffffa8002c429f0, fffffa8002c309f0
Здесь видно, что код драйвера i8042prt.sys создаёт 2 объекта - это клавиатура и мышь PS/2. Теперь просматриваем стек первого "Device-Object", который как видим находится по адресу 0xfffffa8002c429f0:
0: kd> !devstack fffffa8002c429f0
!DevObj !DrvObj !DevExt ObjectName
fffffa8002abd060 \Driver\kbdclass fffffa8002abd1b0 KeyboardClass0
-> fffffa8002c429f0 \Driver\i8042prt fffffa8002c42b40
fffffa8002225530 \Driver\ACPI fffffa8001867360 00000071
!DevNode fffffa800222db10 :
DeviceInst is: "ACPI\PNP0303\4&1023c7d0&0"
ServiceName is: "i8042prt"
Из лога видно, что у меня нет никаких фильтр-драйверов между "kbdclass" и "i8042prt" (выделен стрелкой), а у вас он должен появиться. Поскольку есть уже адрес объекта, можно вывести и заполненную его структуру _DEVICE_OBJECT:
0: kd> dt _device_object fffffa8002c429f0
ntdll!_DEVICE_OBJECT
+0x000 Type : 0n3
+0x002 Size : 0x598
+0x004 ReferenceCount : 0n0
+0x008 DriverObject : 0xfffffa8002c10d20 _DRIVER_OBJECT
+0x010 NextDevice : (null)
+0x018 AttachedDevice : 0xfffffa8002abd060 _DEVICE_OBJECT
+0x020 CurrentIrp : (null)
+0x028 Timer : (null)
+0x030 Flags : 0x2004
+0x034 Characteristics : 0
+0x038 Vpb : (null)
+0x040 DeviceExtension : 0xfffffa8002c42b40 Void
+0x048 DeviceType : 0x27
+0x04c StackSize : 6
+0x050 Queue : <unnamed-tag>
+0x098 Alignment : 0
+0x0a0 DeviceQueue : _KDEVICE_QUEUE
+0x0c8 Dpc : _KDPC
+0x108 ActiveThreadCount : 0
+0x110 SecurityDesc : (null)
+0x118 DeviceLock : _KEVENT
+0x130 SectorSize : 0
+0x132 Spare1 : 1
+0x138 DevObjExtension : 0xfffffa8002c42f88 _DEVOBJ_EXTENSION
+0x140 Reserved : (null)
Если-же команде !drvobj передать аргумент(3), она вернёт более детальную инфу об указанном драйвере, вплоть до точек-входа в основные процедуры типа "Entry, StartIo, Unload, AddDevive", и даже список обслуживаемых кодов IRP_MJ_xx (здесь их всего 8):
0: kd> !drvobj i8042prt 3
Driver object (fffffa8002c10d20) is for: \Driver\i8042prt
Device Object list: fffffa8002c429f0, fffffa8002c309f0
DriverEntry: fffff880048ee070 i8042prt
DriverStartIo: fffff880048d86f8 i8042prt
DriverUnload: fffff880048eaae0 i8042prt
AddDevice: fffff880048e9f80 i8042prt
Dispatch routines:
[00] IRP_MJ_CREATE fffff880048e5cf8 i8042prt+0xfcf8
[02] IRP_MJ_CLOSE fffff880048ea390 i8042prt+0x14390
[09] IRP_MJ_FLUSH_BUFFERS fffff880048dc660 i8042prt+0x6660
[0e] IRP_MJ_DEVICE_CONTROL fffff880048ea7c0 i8042prt+0x147c0
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL fffff880048d7920 i8042prt+0x1920
[16] IRP_MJ_POWER fffff880048e5f40 i8042prt+0xff40
[17] IRP_MJ_SYSTEM_CONTROL fffff880048e5c7c i8042prt+0xfc7c
[1b] IRP_MJ_PNP fffff880048e5680 i8042prt+0xf680
Аналогичным образом можно получить информацию буквально о любом драйвере в системе, полный список которых возвращает утилита "WinObj" М.Руссиновича. Ведь мало написать сам драйвер, а нужно ещё и проверить, благополучно он вклинился в стек/цепочку, или нет. Только после этого можно ожидать от него каких-то результатов. По сути отладчик "WinDbg" должен быть в арсенале любого драйверо-писателя, тем более, что альтернативы ему пока нет.