Хуки и SendMessage

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by desTiny, 8 May 2010.

  1. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    Если у меня установлен хук например WH_KEYBOARD, или даже WH_GETMESSAGE, то должен ли он вызываться после вызова SendMessage(hwnd, WM_KEYDOWN, character, keydata) или SendMessage(hwnd, WM_CHAR, character, keydata)?

    Если нет, то почему иногда вызывается (наблюдалось в сторонней программе, но там вообще какой-то ужас был: куча навешанных хуков и перехваченных WndProc'ов, и вся эта живность шлёт похожие SendMessage'ы, брр; но мне не удалось это повторить в лабораторных условиях)?

    hwnd - один единственный, созданный через RegisterClassEx и CreateWindow. В WndProc после SendMessage управление передаётся, а хуки не вызываются.
    Хотелось бы заставить всё-таки вызваться.
     
  2. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    2desTiny

    WH_KEYBOARD
    The KeyboardProc hook procedure is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function whenever an application calls the GetMessage or PeekMessage function and there is a keyboard message (WM_KEYUP or WM_KEYDOWN) to be processed.

    очевидно что хук обработчик будет вызыватся только для асинхронных сообщений посланных в поток который создал окно через PostMessage если этому окну отправят синхронное сообщение SendMessage хук обработчик не вызовется

    WH_GETMESSAGE
    The GetMsgProc function is an application-defined or library-defined callback function used with the SetWindowsHookEx function. The system calls this function whenever the GetMessage or PeekMessage function has retrieved a message from an application message queue. Before returning the retrieved message to the caller, the system passes the message to the hook procedure.

    таже история обрабатывать будет сообщения асинхронно отправленные окну PostMessage которые явно достаются из очереди GetMessage PeekMessage на них будет реагировать а на синхронные SendMessage гордо промолчит

    вообщем эти два вида хука вызываются только для обработки асинхронных сообщений
    в тот момент когда они вынимаются из очереди GetMessage или PeekMessage
    я когда то тоже с этим столкнулся мне надо было и синхронные и асинхронные сообщения вылавливать неважно как передавали сообщения окну через PostMessage или через SendMessage ловил все сообщения я сделал так выделяем shared секцию в DLL перед установкой хука SetWindowsHook пишем в нее хендл окна сообщения от которого надо похукать инжектим себя через WH_GETMESSAGE как только
    получаем DLL_PROCESS_ATTACH смотрим в общей секции хендл окна и делаем SetWindowLong сабклассинг этого окна и фильтруем синхронные и асинхронные сообщения например отправляем себе в программу WM_COPYDATA потом когда из своей проги делаем UnhookWindowsHookEx ловим DLL_PROCESS_DETACH и снова SetWindowLong ставим на место старый обработчик и собствено после этого длл отключается от адресного пространства ну и Вам можно так же установить хук
    и в функции сабклассинга смотреть нужные Вам WM_KEYDOWN или WM_CHAR
    посути Вам хук в этом сценарии нужен только для того чтобы Windows автоматически DLL инжектила в интересующий вас процесс :)
     
    #2 greki_hoy, 8 May 2010
    Last edited: 8 May 2010
    1 person likes this.
  3. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    Спасибо, действительно, PostMessage поправил ситуацию. Правда при
    Code:
    PostMessage(hwnd, WM_CHAR, 'w', 0x110001);
    
    или даже
    Code:
    PostMessage(hwnd, WM_KEYDOWN, 'w', 0x110001);
    PostMessage(hwnd, WM_CHAR, 'w', 0x110001);
    PostMessage(hwnd, WM_KEYUP, 'w', 0x110001);
    
    почему-то срабатывает только хук WH_GETMESSAGE, а клавиатурный молчит.
     
  4. greki_hoy

    greki_hoy Member

    Joined:
    4 Mar 2010
    Messages:
    326
    Likes Received:
    57
    Reputations:
    41
    2desTiny

    угу у меня так же

    а не проще после того как система dll заинжектит подменить адрес оконной процедуры для нужного окна ?
     
  5. desTiny

    desTiny Elder - Старейшина

    Joined:
    4 Feb 2007
    Messages:
    1,006
    Likes Received:
    444
    Reputations:
    94
    Да я сейчас никуда не инжектюсь:) Просто вот тут столкнулся с каким-то очень странным поведением SendMessage, когда после её вызова шла обработка хуков, что вместе с ещё некоторыми обстоятельствами (отсутствия ключа в реестре => fail глубокой функции в win32k.sys) приводило к чёрт-знает-чему. Тогда меня заинтересовало, а почему вообще с такой ошибкой хоть что-то работает. И вот видимо потому, что надо как-то Очень исхитриться, чтоб достичь такого эффекта.