|
|
|
Страница 1 из 3 Тема про хуки является популярной на многих форумах программистов. Материал этих статей рассчитан на начинающего пользователя, примеры будут на Delphi. В этой статье будут изложены основные принципы механизма хуков, и будет написан пример клавиатурного шпиона.
Итак, приступим, что же такое механизм хуков в Windows? В операционной системе Windows хуком называется механизм перехвата особой функцией событий (таких как сообщения, ввод с мыши или клавиатуры) до того, как они дойдут до приложения. Эта функция может затем реагировать на события и, в некоторых случаях, изменять или отменять их. Функции, получающие уведомления о событиях, называются фильтрующими функциями и различаются по типам перехватываемых ими событий. Пример - фильтрующая функция для перехвата всех событий мыши или клавиатуры. Если к одному хуку прикреплено несколько фильтрующих функций, Windows реализует очередь функций, причем функция, прикрепленная последней, оказывается в начале очереди, а самая первая функция - в ее конце. Когда к хуку прикреплена одна или более функций-фильтров и происходит событие, приводящее к срабатыванию хука, Windows вызывает только первую функцию из очереди функций-фильтров. Вызов каждого следующего обработчика полностью зависит от предыдущего обработчика. Если какой-либо обработчик не вызовет следующий, то целевому окну не придёт искомое сообщение, а следовательно и не будет вызвана его оконная функция. Хуки предоставляют мощные возможности для приложений Windows. Приложения могут использовать хуки в следующих целях: - Обрабатывать или изменять все сообщения, предназначенные для всех диалоговых окон (dialog box), информационных окон (message box), полос прокрутки (scroll bar), или меню одного приложения (WH_MSGFILTER).
- Обрабатывать или изменять все сообщения, предназначенные для всех диалоговых окон, информационных окон, полос прокрутки, или меню всей системы (WH_SYSMSGFILTER).
- Обрабатывать или изменять все сообщения в системе (все виды сообщений), получаемые функциями GetMessage или PeekMessage (WH_GETMESSAGE).
- Обрабатывать или изменять все сообщения (любого типа), посылаемые вызовом функции SendMessage (WH_CALLWNDPROC).
- Записывать или проигрывать клавиатурные и мышиные события (WH_JOURNALRECORD, WH_JOURNALPLAYBACK).
- Обрабатывать, изменять или удалять клавиатурные события (WH_KEYBOARD).
- Обрабатывать, изменять или отменять события мыши (WH_MOUSE).
- Реагировать на определенные действия системы, делая возможным разработку приложений компьютерного обучения - computer-based training (WH_CBT).
- Предотвратить вызов другой функции-фильтра (WH_DEBUG).
Работа с хуками осуществляется через функции SetWindowsHookEx, UnhookWindowsHookEx, вызов следующего обработчика осуществляется через функцию CallNextHookEx. До версии 3.1 Windows предоставляла для управления хуками функции SetWindowsHook, UnhookWindowsHook, и DefHookProc. Эти функции до сих пор реализованы в Win32, только лишь для совместимости со старыми приложениями, и использовать их в новых проектах не рекомендуется.
Начнём сначала, для установки хука успользуется функция SetWindowsHookEx HHOOK SetWindowsHookEx( int idHook, HOOKPROC lpfn, HINSTANCE hMod, DWORD dwThreadId ); Первый параметр это числовая константа WH_* которая задаёт тип устанавливаемого хука. Второй параметр это адрес функции-фильтра. Третий параметр это хэндл модуля, содержащего фильтрующую функцию. Этот параметр должен быть равен нулю при установке хука на поток, но данное требование не является строго обязательным, как указано в документации. При установке хука для всей системы или для потока в другом процессе, нужно использовать хэндл DLL, содержащей функцию-фильтр. Четвёртый параметр это идентификатор потока, для которого устанавливается хук. Если он не равен нулю, то хук устанавливается только на указанный поток. Если идентификатор равен нулю, то хук устанавливается на всю систему. Некоторые хуки можно ставить как на всю систему, так и на некоторый поток, некоторые хуки можно поставить только на всю систему. Функция возвращает хендл хука, в случае неудачи функция возвратит ноль. Для снятия хука нужно использовать функцию UnhookWindowsHookEx, которая принимает в качестве единственного параметра хендл установленного хука.
Теперь надо сделать небольшое лирическое отступление от данной темы, для лучшего понятия описываемого механизма. В 32-битных (а далее в 64-битных) операционных системах Windows каждый процесс в системе имеет своё собственное обособленное адресное пространство. Обратиться к чужому адресному пространству можно только через несколько API функций и имея определённые привилегии. Т.е. по одному и тому же адресу в разных процессах могут быть совершенно разные данные. Для того чтобы фильтрующая функция могла обработать сообщение, она должна находиться в памяти именно того процесса, которому принадлежит целевое окно и оконная функция. Итак, если хук устанавливается на всю систему, то фильтрующая функция должна быть загружена в каждый процесс, у которого есть хотя бы один цикл сообщений c использованием функций GetMessage или PeekMessage. Единственный стандартный способ загрузки нашего кода в чужой процесс, это использование DLL. Т.е. для нормального функционирования хуков установленных на всю систему необходимо использовать DLL. Едем, далее. Все фильтрующие функции должны быть описаны следующим образом: LRESULT CALLBACK FilterFunc(int nCode, WPARAM wParam, LPARAM lParam) Так написано в MSDN. Тип LRESULT это тот же integer, WPARAM и LPARAM это тоже integer. CALLBACK это тоже что и stdcall. Чтобы было понятнее, приведу наиболее правильное и логичное (по моему мнению) объявление на pascal:
Function FilterFunc(Code:integer; wParam, lParam:DWORD):DWORD; stdcall; Это общий прототип функции для всех типов хуков. Параметры интерпретируются по-разному, в зависимости типа хука. Очень часто встречается одна и та же ошибка: объявление параметра wParam как WORD. Это грубая ошибка, которая приводит к непредсказуемым последствиям в работе хуков, так как тип WORD имеет размерность 16 бит, а DWORD 32 бита, в результате чего половина информации, передаваемая через этот параметр, теряется. Первый параметр во всех типах хуков интерпретируется в основном одинаково: если он меньше нуля, то надо сразу же вызвать следующую функцию через CallNextHookEx, и вернуть результат её вызова. Если код равен HC_ACTION, то можно обработать это сообщение. Впрочем, это только рекомендации и всё полностью зависит от самой функции и программиста, который её написал.
Для вызова следующей функции в очереди хуков предназначена функция CallNextHookEx LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam ); Отличие от оконной функции лишь в первом параметре, который, кстати, в системах семейства Windows NT (Windows NT/XP/2003 и далее) игнорируется. Для того чтобы не передавать дальше обработку сообщения, достаточно просто не вызывать эту функцию в обработчике. В данном случае это сообщение просто блокируется и не приходит адресату. Итак, основные сведения о хуках мы получили. Теперь надо приступить к практике. Наиболее часто встречающийся проблемы поднимаемые на форумах программистов, связанный с хуками, это проблемы с написанием клавиатурных шпионов. Именно клавиатурный шпион мы сейчас и напишем.
|
|
-
Delphi,
Написание внешних компонент для 1С на Delphi
Насколько мне известно, многие 1С-ники хотели бы изучить написание внешних компонент, чтобы поднять свое магическое искусство 1С на качественно иную ступень. Что этому может помешать? Во-первых, известный синдром компонентофобии (который исторически берет свое начало от криво написанных внешних компонент). Во-вторых –синдром клинически запутанного кода. OLE-программирование – это не самая простая штука, и, как говорится, «не всякая птица долетит до середины Днепра&...
-
Delphi,
Вывод графиков функций в Delphi
Изучая доступную литературу по программированию, которую я нашел в Интернете, а также некоторые программы, я пришел к выводу, что программисты то ли не осознают, то ли не хотят напрягаться на эту тему, и всё делают, как в школе учили. Строят графики, как на бумаге. Тем самым умаляя возможности компьютера. Оставляя те же недостатки метода построения, и даже усугубляя их....
-
Delphi,
Приемы работы с базами данных в Delphi
Данная статья предназначена в основном для тех, кто начинает работать с базами данных. Здесь собраны приемы, направленные на оптимизацию и ускорение работы с базами данных. Описанные примеры являются результатом многолетней работы автора с СУБД MS SQL Server, Oracle и Access. Примеры описываются в общем виде, без привязки к какой-либо конкретной СУБД....
-
Delphi,
Работа с потоками в Delphi
Данная статья предназначена для начинающих программистов, которые никогда не работали с потоками, и хотели бы узнать основы работы с ними. Желательно, чтоб читатель знал основы ООП и имел какой-нибудь опыт работы в Delphi. Для начала давайте определимся, что под словом "поток" я подразумеваю именно Thread, который еще имеет название "нить"....
-
Delphi,
Message методы, или обработка сообщений классами в Delphi
Данная статья предназначения для более глубокого понимания того, как реализована обработка сообщений Windows в VCL и как это можно и нужно использовать в своих целях и использовать правильно....
-
Delphi,
Запись CD-DVD дисков в Delphi
Доброго времени суток уважаемые любители Delphi. В этой статье я расскажу про запись CD\DVD дисков в среде Delphi. Общие принципы, изложенные в этой статье подойдут не только для языка Delphi, но и для языка С++. Для прочтения этой статьи с максимальной пользой, читателю рекомендуется получить базовые понятия об OLE\COM, впрочем даже незнание этих понятий вряд ли помешает понимаю этой статьи, так как классы и компоненты Delphi (так же как и классы С++), которые мы будет использовать полностью ск...
-
Delphi,
Перехват API функций в Delphi с помощью сплайсинга
Сегодня я расскажу довольно таки эффективную методику перехвата API функций. Не следует думать, что если мы хотим перехватить API функции, то мы пишем либо троян, вирус и ещё какую-нибудь заразу, с помощью перехвата API функций осуществляются многие защитные механизмы, перехват API функций это довольно-таки нужная и полезная вещь. Для прочтения данной статьи с максимальной пользой обязательны, нужны, как минимум, начальные знания низкоуровневого программирования и хотя бы какие-нибудь знания арх...
-
Delphi,
Delphi: Работа с устройствами в Windows
Функции, которые осуществляют работу с устройствами, находятся в системных библиотеках cfgmgr32.dll и setupapi.dll. К сожалению, в стандартных заголовочных файлах Delphi нет объявлений функций, констант и структур которые используются этими библиотеками. Эти заголовочные файлы можно скачать с сайта проекта Delphi-JEDI. Те, кому не нравятся модули от проекта Delphi-JEDI могут воспользоваться моим модулем setupapi.pas, но в нём далеко не полный список функции и структур....
|
|
|