Как грамотно поставить глобальный хук?

Тема в разделе "WASM.BEGINNERS", создана пользователем MYXOMOP, 27 мар 2009.

  1. MYXOMOP

    MYXOMOP New Member

    Публикаций:
    0
    Регистрация:
    26 янв 2009
    Сообщения:
    3
    Hello, World! 73!

    Прочитал одну полезную статью "Hooks - аспекты реализации" Алексея Павлова <!-- saved from url=(0052)http://www.sources.ru/delphi/dll/hooks_aspects.shtml --> очень познавательно уже то. что переменная в моей dll не помнит сохранённого в ней хендла хука когда этот хук сработал в чужом приложении (проверял месиджбоксами). Павлов убеждает в необходимости всё-таки передавать этот хендл функции CallNextHookEx, хотя тот же Михаил Фленов с чистой совестью передаёт ноль вместо хендла в CallNextHookEx и всё работает, а примеры Павлова нет-нет да и вызовут GP на winxp. Прочитал на RSDN http://www.rsdn.ru/article/baseserv/winhooks.xml что первый аргумент CallNextHookEx (то бишь хендл хука полученного вызовом SetWindowsHookEx) игнорируется windows. Нужно ли извращаться чтобы передать hHook функции фильтру? Подкиньте, пожалуйста, грамотный пример мышинного или клавиатурного глобал хука(что доктор Билл прописал). Есть идея сделать прогу , органичение доступа к окнам (чужим окнам не передавть события ввода, отсеивая по ImagePath например). Обрубание проводников или клавиш в реестре не есть гуд. Тем более в нужном приложении-сервисе может быть кнопочка About откуда можно IE вызвать, а где IE там и explorer запущенный от System.
     
  2. bendme

    bendme New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    179
    >очень познавательно уже то. что переменная в моей dll не помнит сохранённого в ней хендла хука когда этот хук сработал в чужом приложении (проверял месиджбоксами).


    Если бы ты хотя бы до середины прочитал статью, то нашел бы ответ на свой вопрос:

    "Теперь поговорим о том, как избежать неприятных ситуаций, используя глобальные ловушки.
    Для того, что бы все экземпляры DLL, находящиеся в разных процессах, имели доступ к дескриптору ловушки, надо выделить какую-то область, доступ к которой будут иметь все "желающие". Для этого воспользуемся одним из мощнейших механизмов Windows под названием "Файлы, отображённые в память" (Memory Mapped Files). В цели данной статьи не входит углубление в подробности работы с данным механизмом, так что если он кого-то заинтересует всерьёз - рекомендую почитать о нём в литературе, общие же понятия я постараюсь вкратце осветить. Механизм файлов, отображённых в память (MMF - Memory Mapped Files) позволяет резервировать определённую область АП системы Windows, для которой назначаются страницы физической памяти. Таким образом, с помощью MMF можно отображать в память не только файлы, но и данные, ссылаясь на них из своих программ с помощью указателей. В первом приближении работу механизма MMF можно представить следующим образом: Process1 создаёт отображение, которое связывает с некими данными (будь то файл на диске или значение неких переменных в самом Process1) и может изменять отображённые данные; затем Process2 так же отображает некие свои данные в тоже отображение, что и Process1, таким образом, изменения, внесённые Process1 в отображённые данные, будут видны Process2 и наоборот (см. рис.1 - красный овал c именем Global Data и есть зарезервированное под совместные нужды двух процессов АП). Данное приближение, вообще говоря, грубое, потому что всё намного сложнее, но для наших "нужд" этого будет вполне достаточно. Мы не будем создавать никаких временных файлов для передачи информации между процессами, мы воспользуемся файлом подкачки Windows (файл страничного обмена), таким образом, нам не придётся ни создавать ни уничтожать файлы, а придётся просто создать некоторое АП, которое будет доступно нашим приложениям и которое будет автоматически освобождаться системой, когда в нём отпадёт необходимость. К тому же, ясно, что работа с файлом подкачки куда быстрее, чем с обычным файлом, хранящимся на диске. Таким образом, к рассмотренному вами ранее Example1 можно применить следующий сценарий: при загрузки вашей программой (MainProg1.exe) библиотеки hook_dll1.dll эта библиотека создаёт отображённый в память файл, в котором сохраняет значение дескриптора установленной ловушки; затем некий процесс, в котором произошло событие, на которое была установлена ловушка, отображает на своё АП код hook_dll1.dll и уже новый экземпляр hook_dll1.dll, находящийся в АП другого процесса использует то же отображение, что и библиотека, из который была установлена ловушка, т.е. будет иметь доступ к сохранённому значению дескриптора установленной ловушки. Таким образом, вызов функции CallNextHookEx(Hook_Handle, Code, wParam, lParam); будет происходить вполне корректно, т.к. значение Hook_Handle будет содержать не 0, как в примере1, а значение, возвращённое функцией SetWindowsHookEx из первого экземпляра DLL. Возможно, данные объяснения кажутся вам запутанными, но после просмотра примера и повторного прочтения этих объяснений всё встанет на свои места. "
     
  3. bendme

    bendme New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    179
    И вместо Павловых и Кулибиных читай лучше Джеффри Рихтера. У него же и примеров кучу найдешь.
     
  4. MYXOMOP

    MYXOMOP New Member

    Публикаций:
    0
    Регистрация:
    26 янв 2009
    Сообщения:
    3
    Это я читал. Маленькое уточнение опять по статье Павлова. В первом примере, где он передает 0 вместо хедла hHook обе ловушки у меня (WinXP SP2) чудесным образом работают. А пример 2 с извращениями с Memory Mapped Files после сработки первой ловушки у меня вызывают исключение (попытка прочитать не выделенныю область памяти). А вторую статью я сюда приплёл потому, что там оговорено, что hHook просто игнорируется при вызове CallNextHookEx. Так стоит ли копья ломать , то есть городить огород с MMF?

    ЗЫ К Рихтеру уже пошёл)
     
  5. bendme

    bendme New Member

    Публикаций:
    0
    Регистрация:
    10 мар 2009
    Сообщения:
    179
    В текущих версиях винды первый параметр игнорируется. В последующих версиях винды ВОЗМОЖНО этот параметр будет необходим и твоя прога не будет работать. Так что, решай сам.

    Вместо MMF проще использовать Shared секции.
    Пишешь в своей длл:
    #pragma data_seq("Shared")
    HHOOK g_hook=NULL;
    #pragma data_seq()
    #pragma comment(linker, "/section:Shared,rws")

    После этого переменная g_hook будет одной и тойже для всех экземпляров длл.