Перехватчики в системах Windows обладают очень мощными функциями. Благодаря этой технологии практически все сообщения в системах Windows можно перехватывать, отслеживать и обрабатывать. Эта технология может широко использоваться в различном программном обеспечении, особенно в программном обеспечении, требующем мониторинга, автоматической записи и других функций мониторинга системы. В данной статье обсуждается эта тема в надежде послужить справочной информацией для читателей.
1. Механизм и тип крючка.
Все приложения Windows управляются сообщениями, и работа приложения зависит от типа и содержания получаемого сообщения. Хуки аналогичны механизму обработки перехвата прерываний Dos. Hook — это платформа механизма обработки сообщений Windows. Установив различные перехватчики, приложение может настроить на нем подпрограммы для отслеживания определенных сообщений в указанном окне и обработки сообщения до того, как оно достигнет целевого окна.
В Windows существует два типа перехватчиков: один — системный перехватчик (RemoteHook), который отслеживает сообщения внутри всей системы, а другой — перехватчик потока (LocalHook), который перехватывает сообщения только внутри процесса. Для системных перехватчиков функция перехвата (HookFunction) должна быть реализована в библиотеке динамической компоновки (DLL) системы Windows. Для перехватчиков потоков функция перехвата может быть реализована в DLL или в соответствующем приложении. Это связано с тем, что когда разработчик создает перехватчик, Windows сначала создает в системной памяти структуру данных, содержащую информацию о перехватчике, а затем добавляет структуру в существующий список перехватчиков, и новые перехватчики будут отсортированы перед старыми. крючки. При возникновении события, если установлен локальный перехватчик, будет вызвана функция перехватчика в текущем процессе. Если это удаленный перехват, система должна вставить функцию перехвата в адресное пространство других процессов. Для этого функция перехвата должна находиться в динамической библиотеке, поэтому, если вы хотите использовать удаленный перехват, вы должны поместить его. ловушка Поместите функцию в динамическую библиотеку. Для типов сообщений, отслеживаемых перехватчиками, Windows предоставляет следующие типы: Как показано в таблице 1:
Таблица 1. Типы сообщений Windows
Идентификатор константы типа сообщения | ценить | Тип сообщения | Область применения |
WH_CALLWNDPROC | 4 | сообщение в окно | поток или система |
WH_CALLWNDPROCRET | 12 | Сообщение, возвращаемое окном | поток или система |
WH_CBT | 5 | Сообщения, такие как изменения окон и настройки фокуса. | поток или система |
WH_DEBUG | 9 | Выполнять ли хуки других хуков | поток или система |
WH_FOREGROUNDIDLE | 11 | Программа переднего плана простаивает | поток или система |
WH_GETMESSAGE | 3 | Сообщения, отправленные в очередь сообщений | поток или система |
ВОСПРОИЗВЕДЕНИЕ WH_JOURNAL | 1 | Воспроизведение записанных сообщений | система |
WH_JOURNALRECORD | 0 | Отслеживайте и регистрируйте входящие сообщения | система |
WH_KEYBOARD | 2 | Сообщения клавиатуры | поток или система |
WH_MOUSE | 7 | сообщение мыши | поток или система |
WH_MSGFILTER | -1 | Полосы прокрутки меню, диалоговые сообщения | поток или система |
WH_SHELL | 10 | сообщения оболочки | поток или система |
WH_SYSMSGFILTER | 6 | Полосы прокрутки меню, диалоговые сообщения для всех тем | система |
2. Реализация хуков в программировании VB
(1) Формат функции крючка (функция HOOK). Функция-перехватчик на самом деле является функцией. Если это системный перехват, функция должна быть помещена в динамическую библиотеку. Эта функция имеет определенный формат параметров, который в VB выглядит следующим образом:
Частная функция HookFunc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) Пока |
Среди них nCode представляет ситуацию, при которой генерируется перехват, и существуют разные наборы возможных значений в зависимости от перехватчика. Возвращаемые значения параметров wParam и lParam включают содержимое отслеживаемого сообщения, которое варьируется; с типом сообщения, отслеживаемого перехватчиком. Он различается в зависимости от значения nCode. Для функций-перехватчиков, установленных с помощью VB, общая форма структуры выглядит следующим образом:
Частная функция HookFunc(ByVal nCode As Long, ByVal wParam As Long, ByVal lParam As Long) Пока Выберите регистр nCode случай ncode<0:hookfunc=callnexthookex(hHookFunc, nCode, wParam, lParam) значение регистра 1: Обработка 1: HookFunc=X1 case2:Процесс обработки 2:HookFunc=X1 … конец выбора Конечная функция |
Возвращаемое значение функции. Если сообщение должно быть обработано, передайте 0, в противном случае передайте 1 и съешьте сообщение.
(2) Установка и установка крючков. Для установки перехватчиков используются несколько функций API: Вы можете использовать функцию API SetWindowsHookEx() для установки определяемой приложением подпрограммы перехватчиков в список перехватчиков. Объявление функции SetWindowsHookEx() выглядит следующим образом:
Объявить функцию SetWindowsHookEx Lib user32 Псевдоним SetWindowsHookExA(ByVal idHook As Long, ByVal lpfn As Long, ByVal hmod As Long, ByVal dwThreadId As Long) As Long |
Значение idHook — это тип сообщения, которое он обрабатывает; значение lpfn — это указатель адреса подпрограммы-перехватчика. Если параметр dwThreadId равен 0 или является идентификатором потока, созданного другим процессом, lpfn должен указывать на подпрограмму-перехватчик в DLL. Кроме того, lpfn может указывать на код подпрограммы-перехватчика текущего процесса. Значение hMod — это дескриптор приложения, идентифицирующий DLL, содержащую подпрограмму, на которую указывает lpfn. Если dwThreadId идентифицирует поток, созданный текущим процессом, и код подпрограммы находится в текущем процессе, hMod должен быть равен 0. Значение dwThreadId — это идентификатор потока, связанного с установленным подпроцессом-перехватчиком. Если оно равно 0, подпроцесс-перехватчик связан со всеми потоками. Если перехватчик установлен успешно, будет возвращен дескриптор подпроцесса перехватчика. В случае неудачи будет возвращен 0.
Кроме того, функцию CallNextHookEx() обычно следует вызывать в подпрограмме перехватчика для выполнения следующей подпрограммы перехватчика, на которую указывает список перехватчиков. В противном случае приложения с другими установленными перехватчиками не будут получать уведомления о перехватчиках, что приведет к неверным результатам. Объявление функции CallNextHookEx() выглядит следующим образом:
Объявить функцию CallNextHookEx Libuser32 Псевдоним CallNextHookEx(ByVal hHook As Long, ByVal ncode As Lonog, ByVal wParam As Long, lParam As Any) As Long |
Значение hHook — это возвращаемое значение функции SetWindowsHookEx(), а nCode, wParam и lParam — это три параметра функции Hook. Прежде чем программа завершится, необходимо вызвать функцию UnhookWindowsHookEx(), чтобы освободить системные ресурсы, связанные с перехватчиком. Функция UnhookWindowsEx() объявляется следующим образом:
Объявить функцию Unhook WindowsHookEx Lib user32 Псевдоним Unhook WindowsHookEx(ByVal hHook As Long)As Long |
hHook — возвращаемое значение при установке перехватчика, то есть дескриптор подпроцесса перехватчика.
(3) Проблемы, на которые следует обратить внимание при установке хуков в VB. Параметр lpfn — это адрес HookFunc. В VB указано, что код HookFunc должен быть помещен в стандартный модуль .BAS и передан как адрес HookFunc. Его нельзя поместить в модуль класса или прикрепить к вышестоящей форме. Для RemoteHook HookFunc должен быть включен в библиотеку динамической компоновки, поэтому, если вы используете RemoteHook в VB, вам также потребуется использовать две функции API: GetModuleHandle() и GetProcAddress(). Их объявления следующие:
Объявить функцию GetModuleHandle Libkernel32 Alias GetModuleHandleA(ByVal lpModuleName As String) как длинную Объявить функцию GetProcAddress Lib kernel32 Alias GetProcAddress(ByVal hModule As Long, ByVal lpProcName As String) As Long |
Значение hmod — это дескриптор имени модуля, содержащий процесс перехвата. Если это LocalHook, значение может быть нулевым (0 передается в VB), а если это RemoteHook, вы можете использовать GetModuleHandle (name.dll) для его передачи. .