Вопрос 3. Хуки в ОС Windows , назначение, типы. Приведите фрагмент программы, устанавливающей хук на некоторое сообщение (по заданию комиссии).


Добавил:DMT
Дата создания:30 декабря 2007, 18:55
Дата обновления:30 декабря 2007, 18:55
Просмотров:9584 последний сегодня, 8:26
Комментариев: 3

Вопрос 3. Хуки в ОС Windows , назначение, типы. Приведите фрагмент программы, устанавливающей хук на некоторое сообщение (по заданию комиссии).

up

Комментарии для "Вопрос 3. Хуки в ОС Windows , назначение, типы. Приведите фрагмент программы, устанавливающей хук на некоторое сообщение (по заданию комиссии)."


Пользователь: ruslan
Сообщений: 23
Статус: Незримый
Зарегистрирован:
5 января 2008, 2:42
Был:29 января 2008, 21:23
ruslan
smsup
Дата: 5 января 2008, 2:59 Сообщение № 1
В операционной системе Microsoft® 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).
Приложения Windows используют функции SetWindowsHookEx, UnhookWindowsHookEx, и CallNextHookEx для управления очередью функций-фильтров хука.
Функция SetWindowsHookEx добавляет функцию-фильтр к хуку. Эта функция принимает четыре аргумента:
 Целочисленный код, описывающий хук, к которому будет прикреплена фильтрующая функция. Эти коды определены в WINUSER.H и будут описаны позднее.
 Адрес функции-фильтра. Эта функция должна быть описана как экспортируемая включением ее в секцию EXPORTS файла определения приложения или библиотеки динамической линковки (DLL), или использованием соответствующих опций компилятора.
 Хэндл модуля, содержащего фильтрующую функцию. В Win32 (в отличие от Win16), этот параметр должен быть NULL при установке хука на поток (см. ниже), но данное требование не является строго обязательным, как указано в документации. При установке хука для всей системы или для потока в другом процессе, нужно использовать хэндл DLL, содержащей функцию-фильтр.
 Идентификатор потока, для которого устанавливается хук. Если этот идентификатор ненулевой, установленная фильтрующая функция будет вызываться только в контексте указанного потока. Если идентификатор равен нулю, установленная функция имеет системную область видимости и может быть вызвана в контексте любого потока в системе. Приложение или библиотека могут использовать функцию GetCurrentThreadId для получения идентификатора текущего потока.
SetWindowsHookEx возвращает хэндл установленного хука (тип HHOOK). Приложение или библиотека должны использовать этот хэндл для вызова функции
Для удаления функции-фильтра из очереди хука вызовите функцию UnhookWindowsHookEx. Эта функция принимает хэндл хука, полученный от SetWindowsHookEx и возвращает логическое значение, показывающее успех операции.
Фильтрующие (хуковые) функции - это функции, прикрепленные к хуку. Из-за того, что эти функции вызываются Windows, а не приложением, их часто называют функциями обратного вызова (callback functions).

LRESULT CALLBACK FilterFunc(int nCode, WPARAM wParam, LPARAM lParam)

nCode (код хука) – целое значение, которое передает функции дополнительную информацию.
Второй параметр функции-фильтра, wParam, имеет тип WPARAM, и третий параметр, lParam, имеет тип LPARAM. Эти параметры передают информацию фильтрующим функциям. У каждого хука значения wParam и lParam различаются.
Когда хук уже установлен, Windows вызывает первую функцию в очереди, и на этом ее ответственность заканчивается. После этого функция ответственна за то, чтобы вызвать следующую функцию в цепочке. В Windows имеется функция CallNextHookEx для вызова следующего фильтра в очереди фильтров. CallNextHookEx принимает четыре параметра. Первый параметр – это значение, возвращенное функцией SetWindowsHookEx. В настоящее время Windows игнорирует это значение. Следующие три параметра – nCode, wParam, и lParam – Windows передает дальше по цепочке функций.
Пользователь: ruslan
Сообщений: 23
Статус: Незримый
Зарегистрирован:
5 января 2008, 2:42
Был:29 января 2008, 21:23
ruslan
smsup
Дата: 5 января 2008, 3:05 Сообщение № 2
Типы хуков

WH_CALLWNDPROC. Windows вызывает этот хук при каждом вызове функции SendMessage. Фильтрующей функции передается код хука, показывающий, была ли произведена посылка сообщения из текущего потока, а также указатель на структуру с информацией о сообщении.

WH_CBT. Чтобы написать приложение для интерактивного обучения (CBT application), разработчик должен координировать его работу с работой приложения, для которого оно разрабатывается. Для достижения этой цели Windows предоставляет разработчикам хук WH_CBT. Windows передает фильтрующей функции код хука, показывающий, какое произошло событие, и соответствующие этому событию данные.

WM_QUEUESYNC. Часто приложение интерактивного обучения (Computer Based Training application или CBT-приложение) должно реагировать на события в процессе, для которого оно разработано. Обычно такими событиями являются события от клавиатуры или мыши.
CBT-приложение может использовать сообщение WM_QUEUESYNC для определения момента окончания нужного действия. Для определения момента окончания обработки события, CBT-приложение делает следующее:
1. Ждет от Windows вызова хука WH_CBT с кодом HCBT_CLICKSKIPPED или HCBT_KEYSKIPPED. Это происходит при удалении из системной очереди события, которое приводит к срабатыванию обработчика в главном приложении.
2. Устанавливает хук WH_JOURNALPLAYBACK. CBT-приложение не может установить этот хук, пока не получит код HCBT_CLICKSKIPPED или HCBT_KEYSKIPPED. Хук WH_JOURNALPLAYBACK посылает CBT-приложению сообщение WM_QUEUESYNC. Когда CBT-приложение получает такое сообщение, оно может выполнить необходимые действия, например, послать главному приложению серию клавиатурных нажатий.

WH_DEBUG. Windows вызывает этот хук перед вызовом какой-либо фильтрующей функции. Фильтры не могут изменять значения, переданные этому хуку, но могут предотвратить вызов фильтрующей функции, возвратив ненулевое значение.

WH_FOREGROUNDIDLE. Windows вызывает этот хук, когда к текущему потоку не поступает пользовательский ввод для обработки. Когда хук установлен как локальный, Windows вызывает его только при условии отсутствия пользовательского ввода у потока, к которому прикреплен хук.

WH_GETMESSAGE. Windows вызывает этот хук перед выходом из функций GetMessage и PeekMessage. Фильтрующие функции получают указатель на структуру с сообщением, которое затем (вместе со всеми изменениями) посылается приложению, вызвавшему GetMessage или PeekMessage.

Регистрационные хуки

Регистрационные хуки (journal hooks) используются для записи и воспроизведения событий. Они могут устанавливаться только как системные, и, следовательно, должны использоваться как можно реже. Эти хуки воздействуют на все приложения Windows; хотя десктоп и не позволяет такого другим хукам, регистрационные хуки могут записывать и воспроизводить последовательности событий и от десктопа, и для десктопа. Другой побочный эффект регистрационных хуков в том, что все системные входные очереди проходят через один поток, который установил такой хук.
Windows отключяет записывающий или воспроизводящий регистрационный хук, когда пользователь нажмет CTRL+ESC, ALT+ESC, или CTRL+ALT+DEL. Windows оповестит приложение, установившее этот хук, посылкой ему сообщения WM_CANCELJOURNAL.

WH_JOURNALRECORD. Windows вызывает этот хук при удалении события из системной очереди. Таким образом, фильтры этого хука вызываются для всех мышиных и клавиатурных событий, кроме тех, которые проигрываются регистрационным хуком на воспроизведение. Фильтрующие функции могут обработать сообщение (то есть, записать или сохранить событие в памяти, на диске, или и там, и там), но не могут изменять или отменять его. Фильтры этого хука могут находиться и внутри DLL, и в .EXE-файле.

WH_JOURNALPLAYBACK. Этот хук используется для посылки Windows клавиатурных и мышиных сообщений таким образом, как будто они проходят через системную очередь. Основное назначение этого хука - проигрывание событий, записанных с помощью хука WH_JOURNALRECORD, но его можно также с успехом использовать для посылки сообщений другим приложениям. Когда к этому хуку прикреплены фильтрующие функции, Windows вызывает первый фильтр в цепочке, чтобы получить событие. Windows игнорирует движения мыши, пока в системе установлен хук WH_JOURNALPLAYBACK. Все остальные события от клавиатуры и мыши сохраняется до тех пор, пока у хука WH_JOURNALPLAYBACK не останется функций-фильтров. Фильтры для этого хука могут располагаться как в DLL, так и в .EXE-файле.

WH_KEYBOARD. Windows вызывает этот хук, когда функции GetMessage или PeekMessage собираются вернуть сообщения WM_KEYUP, WM_KEYDOWN, WM_SYSKEYUP, WM_SYSKEYDOWN, или WM_CHAR. Когда хук установлен как локальный, эти сообщения должны поступать из входной очереди потока, к которому прикреплен хук. Фильтрующая функция получает виртуальный код клавиши и состояние клавиатуры на момент вызова клавиатурного хука. Фильтры имеют возможность отменить сообщение.

WH_MOUSE. Windows вызывает этот хук после вызова функций GetMessage или PeekMessage при условии наличия сообщения от мыши. Подобно хуку WH_KEYBOARD фильтрующие функции получают код – индикатор удаления сообщения из очереди (HC_NOREMOVE), идентификатор сообщения мыши и координаты x и y курсора мыши. Фильтры имеют возможность отменить сообщение. Фильтры для этого хука должны находиться в DLL.

WH_MSGFILTER. Windows вызывает этот хук, когда диалоговое окно, информационное окно, полоса прокрутки или меню получают сообщение, либо когда пользователь нажимает комбинацию клавиш ALT+TAB (или ALT+ESC) при активном приложении, установившем этот хук. Данный хук устанавливается для конкретного потока, поэтому его безопасно размещать как в самом приложении, так и в DLL.

WH_SHELL. Windows вызывает этот хук при определенных действиях с окнами верхнего уровня – top-level windows (то есть, с окнами, не имеющими владельца). Когда хук установлен как локальный, он вызывается только для окон, принадлежащих потоку, установившему хук. Этот хук является информирующим, поэтому фильтры не могут изменять или отменять событие.

WH_SYSMSGFILTER. Этот хук идентичен хуку WH_MSGFILTER за тем исключением, что он имеет системную область видимости. Windows вызывает этот хук, когда диалоговое окно, информационное окно, полоса прокрутки или меню получает сообщение, либо когда пользователь нажимает комбинации клавиш ALT+TAB или ALT+ESC. Фильтр получает те же коды, что и фильтры хука WH_MSGFILTER.

Пользователь: ruslan
Сообщений: 23
Статус: Незримый
Зарегистрирован:
5 января 2008, 2:42
Был:29 января 2008, 21:23
ruslan
smsup
Дата: 5 января 2008, 3:11 Сообщение № 3
Фрагмент содержимого приложения, устанавливающего системный хук

Код на C++
  1. // Обработчик события нажатия на кнопку «Установить хук»
  2. {
  3. HANDLE DLLHook = LoadLibrary("Hook.dll")
  4. HANDLE InstHook = GetProcAddress(DLLHook, "InstHook");
  5. }
  6. // Обработчик события нажатия на кнопку «Снять хук»
  7. {
  8. HANDLE DelInstHook = GetProcAddress(DLLHook, "UnHook");
  9. }
  10.  
При использовании обязательна ссылка на http://DMTSoft.ru


Содержимое файла “Hook.dll”

Код на C++
  1. HHOOK hHook = NULL;
  2. HINSTANCE DLLInst = NULL;
  3. int WinAPI DLLEntryPoint(HINSTANCE hInst, DWORD notify, LPVOID lp)
  4. {
  5. DLLInst = hInst;
  6. // создание и запись в swap-файл глобальных переменных
  7. }
  8. bool InstHook()
  9. {
  10. hHook = SetWindowHookEx(WM_*, HookFunc, DLLInst, 0);
  11. if( hHook ) return true;
  12. else return false;
  13. }
  14. LRESULT CALLBACK HookFunc(int code, wParam wp, lParam lp)
  15. {
  16. if(code < 0) return CallNextHookEx(hHook, code, wp, lp);
  17. // Содержимое функции-фильтра
  18. }
  19. bool UnHook()
  20. {
  21. return UnhookWindowsHookEx(hHook);
  22. }
  23.  
При использовании обязательна ссылка на http://DMTSoft.ru