Главная » Статьи » Программирование » WinApi |
Для установки глобального хука на C# потребуются системные функции Windows, а также отдельная dll. В отдельной библиотеке классов dll разместятся системные функции установки, удаления хука и функция-фильтр для обработки перехватываемой информации. Однако, думаю, не стоит обрабатывать в фильтре массивы данных, а лучше посылать их тому приложению, в которое встраиваем dll, так как перехваченные данные нужны именно приложению, а не самой dll. Поэтому для пересылки воспользуемся системной функцией SendMessage, чтобы отослать пользовательское сообщение в процедуру обработки системных сообщений WndProc. Можно воспользоваться также функцией PostMessage, чтобы поставить наши сообщения в очередь на обработку системой. Приведем неполный список необходимых системных функций:
С помощью функции SendMessage будем отсылать сообщение оконной процедуре того приложения, в котором хотим обработать полученную информацию. Функция SetWindowsHookEx установит наш хук, а функция UnhookWindowsHookEx его отменит. Функция CallNextHookEx необходима для организации цепочки windows хуков, если таковая есть. Если нам понадобится пересылать в главное окно приложения строку (например, название приложения, связанного с клавиатурным вводом), то мы используем тогда такую функцию:
Еще для "правильного" хука нам понадобится ряд системных функций для получения описателя окна того приложения, куда мы отсылаем сообщение; и для получения описателя окна того приложения, с которым связан ввод, чтобы затем получить его название. Эти функции в C#-стиле получат следующий вид:
Функция FindWindow найдет окно приложения, оконная процедура которого должна обработать полученное сообщение. А GetForegroundWindow даст нам возможность получить описатель окна,в который производится ввод — оно активно в это время. Полученный описатель нам потребуется в GetWindowText, третьим параметром которой передадим полученную длину заголовка этого окна из функции GetWindowTextLength. Глобальный хук клавиатуры в стиле C# также нуждается в некоторых постоянных. Так как в нашем случае мы хотим установить глобальный хук именно на клавиатурный ввод, то воспользуемся фильтром WH_KEYBOARD_LL, для чего установим постоянное целое:
Первое постоянное описывает фильтр хука, который отлавливает низкоуровневые клавиатурные события, но им мы будем отлавливать сообщения нажатия клавиши, для чего используем постоянное целое WM_KEYDOWN, описывающее сообщение нажатия клавиши. HC_ACTION проверяет надо ли обрабатывать полученное сообщение или передавать его дальше по цепочке. А WM_USER — пользовательское сообщение. Кроме всего выше сказанного, нам понадобится еще функция-обработчик, где будет происходить процесс обработки данных. Ее мы прикрепим к делегату, который должно будет передать в функцию SetWindowsHookEx, вторым параметром. В С++ передавали бы в данном случае указатель на функцию-обработчик. Делегат имеет следующий вид:
Теперь, можно представить примерный код устанавливаемого хука. Ниже, приведем код, размещаемый в отдельной dll:
Функция HookCallBack — как раз и есть функцией-обработчиком, которая цепляется к делегату. В ней мы проверяем параметр nCode — если он ниже нуля значит хук передается по цепочке обработчиков далее, а если он выше или равен 0 и одновременно в wParam передается значение нажатой клавиши, то мы обрабатываем поступившее событие.Строчка 24 описывает получение кода нажатой клавиши; на следующей строчке мы получаем описатель окна, оконной процедуре которого мы хотим отправить сообщение. В строчке 26 мы получаем описатель активного окна, в который осуществляется ввод, а на следующей строке получаем длину заголовка этого окна. Далее, строим пустую строку на основе длины заголовка, которую передаем как второй параметр в GetWindowText, чтобы получить значение заголовка окна ahandle. На следующем шаге отсылаем пользовательское сообщение окну handle. В нем в виде строкового параметра передаем название окна и значение кода нажатой клавиши. Функцией SetHook мы устанавливаем собственно сам глобальный хук, передавая в функцию SetWindowsHookEx наш клавиатурный фильтр и экземпляр делегата. SetHook возвращает описатель хука. Функцией UnsetHook мы отменяем установленный хук. Далее, приведем пример перегруженной оконной процедуры окна, получающего сообщение от функции-обработчика глобального хука. В стиле C# она будет примерно такой:
Где WM_KEYSTROK — ничто иное как наш WM_USER + 775. Если это событие приходит в оконную процедуру, то в сообщении m нас интересует параметр LParam, из которого получаем нашу строку, а далее выводим ее на экран. Короткий итог В этой статье описан простой механизм установки C# глобального хука клавиатуры. Приведены примеры возможного кода, который позволит осуществить перехват нажатой клавиши и отослать информацию о ней оконному приложению. Данный вариант кода можно использовать для приложений типа "Родительский контроль", в которых, например, может применяться функция кейлоггера. Ключевые слова: как установить хук, как отменить хук, хуки C#, глобальный хук C#, С# хук клавиатуры, С# глобальный хук клавиатуры | |
Просмотров: 6284 | Комментарии: 89 | | |
Всего комментариев: 0 | |