Перехват события от клавиатуры 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 шт):

Автор решения: PRODIGY

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" должен быть в арсенале любого драйверо-писателя, тем более, что альтернативы ему пока нет.

→ Ссылка