Как вызвать fuction-указатель из обратного вызова SetWindowsHookEx - PullRequest
0 голосов
/ 25 июня 2019

Я попытался вызвать указатель на функцию из библиотеки DLL, которая перехватывает сообщение WM_LBUTONDOWN или WM_TOUCH во всех окнах, отображаемых на экране.

У меня есть следующий исходный код DLL:

typedef void (*PtrFonct)(int nCode, WPARAM wParam, LPARAM lParam);
PtrFonct pf;
HHOOK global;

extern "C" __declspec(dllexport) LRESULT WINAPI procedure(int nCode, WPARAM wParam,LPARAM lParam)
{
    if (nCode == HC_ACTION){
        MSG* pMSG = (MSG*)lParam;
        if (pMSG->message == WM_LBUTTONDOWN){
            pf(nCode, wParam, lParam);
        }
    }
    return CallNextHookEx(global, nCode, wParam, lParam);
} 

extern "C" __declspec(dllexport) BOOL setCallback(void ((*callbackFunc)(int, WPARAM, LPARAM))){
    pf = callbackFunc;
    if (pf)
        return TRUE;
    return FALSE;
}

и мой исходный код слушателя следующий:

    MSG message;
    HMODULE lib = LoadLibrary(L"C:/HookTouch.dll");
    if (lib) {
        HOOKPROC procedure = (HOOKPROC)GetProcAddress(lib, "_procedure@12");
        dllFunct fonctionCallback = (dllFunct)GetProcAddress(lib, "setCallback");
        if (fonctionCallback)
            fonctionCallback(MyCallback);
        if (procedure)
            hook = SetWindowsHookEx(WH_GETMESSAGE, procedure, lib, 0);
    }
    else
        printf("Can't find dll!\n");

    while (GetMessage(&message, NULL, 0, 0))
    {
        TranslateMessage(&message);
        DispatchMessage(&message);
    }
    FreeLibrary(lib);
    UnhookWindowsHookEx(hook);

Вот мой собственный обратный вызов для отображения «Привет клик»:

void MyCallback(int nCode, WPARAM wParam, LPARAM lParam)
{
    printf("Hello Click\n");
}

Я знаю, что мой хук работает, потому что я могу отображать сообщение при нажатии, используя окно сообщения вместо pf(nCode, wParam, lParam), но когда я использую этот указатель на функцию, MyCallback не срабатывает. Я проверил, хорошо ли влияла моя функция на указатель на функцию pf, и все ли в порядке.

Знаете ли вы, почему вызов pf(nCode, wParam, lParam) не вызывает функцию MyCallback слушателя?

Ответы [ 2 ]

0 голосов
/ 25 июня 2019

Вы звоните setCallback только для DLL, который загружен в вашем процессе.Для DLL, которые будут введены SetWindowsHookEx во всех других процессах, не будет установлен обратный вызов.Кроме того, MyCallback определяется только в вашем собственном процессе;У DLL, внедренного в другие процессы, нет тривиального способа доступа к нему.

Поскольку вы не можете знать, какие процессы Windows внедрили для вас, вам потребуется Dll, чтобы передать вам свое «местоположение» через Inter-Process.общение, напримерИменованные трубы.Когда у вас есть ID процесса каждой из DLL, которые были внедрены, вы можете использовать CreateRemoteThread для вызова функции внутри Dll, например, setCallback .. еще нужно проделать определенную работу, чтобы Dll могла напрямую вызывать васобратный вызов: вам нужно будет указать Dll точное смещение вашего обратного вызова от базы модуля, а затем Dll потребуется использовать CreateRemoteThread для выполнения вызова.Все это быстро становится слишком утомительным, и вам было бы разумно просто использовать связь по именованным каналам вместо прямых вызовов функций.

Совет. Простой способ регистрировать события из других процессов - использовать OutputDebugString.Также можно записать в файл.

0 голосов
/ 25 июня 2019

Этот подход не будет работать.

Перехват сообщений выполняется в контексте каждого перехватываемого потока. Каждый подключенный процесс получит свою собственную копию вашей DLL. Таким образом, только копия, которая первоначально установила хук, будет иметь действительный указатель на функцию. Кроме того, вы все равно не можете вызывать функцию обратного вызова через границы процесса.

Вам нужно использовать другой механизм IPC, чтобы ваши внедренные хуки могли взаимодействовать с основным процессом приложения.

Например, вы можете создать скрытый HWND и сохранить его в блоке глобальной разделяемой памяти, а затем каждый введенный хук может отправлять ему оконные сообщения, например WM_COPYDATA. Или ваше главное приложение может открыть именованный канал, к которому каждый подключенный хук может подключиться и отправить данные.

...