Хук WH_JOURNALRECORD в Windows (C ++) - обратный вызов никогда не вызывался. - PullRequest
2 голосов
/ 01 июля 2010

Следующий код доставляет мне неприятности в течение последних нескольких часов.Я пытаюсь написать небольшую программу (основанную на некоторых учебниках из Интернета), которая использует хук Windows WH_JOURNALRECORD для регистрации нажатий клавиш.

Основной код:

#include "StdAfx.h"
#include <tchar.h>
#include <iostream>
#include <windows.h>

using std::cout;
using std::endl;

int _tmain(int argc, _TCHAR* argv[]) {  
    HINSTANCE hinst = LoadLibrary(_T("testdll3.dll")); 
    typedef void (*Install)();
    typedef void (*Uninstall)();
    Install install = (Install) GetProcAddress(hinst, "install");
    Uninstall uninstall = (Uninstall) GetProcAddress(hinst, "uninstall");

    install();
    int foo;
    std::cin >> foo; 

    cout << "Uninstalling" << endl;
    uninstall();
    return 0;
}

КодDLL:

#include <windows.h>
#include <stdio.h>
#include <tchar.h>

HHOOK hhk;
HHOOK hhk2;


LRESULT CALLBACK journalRecordProc(int code, WPARAM wParam, LPARAM lParam) {  
    FILE * fileLog = fopen("journal.txt", "a+");
    fprintf(fileLog,"loggedJournal\n");
    fclose(fileLog);
    CallNextHookEx(hhk,code,wParam,lParam);
    return 0;
}


LRESULT CALLBACK wireKeyboardProc(int code,WPARAM wParam,LPARAM lParam) {  
 FILE * fileLog = fopen("keyboard.txt", "a+");
 fprintf(fileLog,"loggedKeyboard\n");  
 fclose(fileLog);
 CallNextHookEx(hhk,code,wParam,lParam);
 return 0;
}

extern "C" __declspec(dllexport) void install() {
    HINSTANCE thisDllInstance = LoadLibrary(_T("testdll3.dll"));
    hhk = SetWindowsHookEx(WH_JOURNALRECORD, journalRecordProc, thisDllInstance, NULL);
    hhk2 = SetWindowsHookEx(WH_KEYBOARD, wireKeyboardProc, thisDllInstance, NULL);
}
extern "C" __declspec(dllexport) void uninstall() {
    UnhookWindowsHookEx(hhk); 
    UnhookWindowsHookEx(hhk2); 
}

BOOL WINAPI DllMain(  __in  HINSTANCE hinstDLL, __in  DWORD fdwReason, __in  LPVOID lpvReserved) {
 return TRUE;
}

По какой-то причине перехват клавиатуры (SetWindowsHookEx (WH_KEYBOARD, wireKeyboardProc, ..)) работает (файл 'keyboard.txt' создан), но перехватывает журналирование (SetWindowsHookEx (WH_JOURNALRECORD), journalRecordProc, ...)) нет.То есть обратный вызов для ловушки журналирования никогда не вызывается (файл journal.txt никогда не создается).

Я думаю, что это может иметь какое-то отношение к UAC Windows (который я обнаружил при поиске в Интернете),но отключение UAC и запуск программы с правами администратора не помогли.

Я не уверен, что теперь делать.Кто-нибудь может мне помочь?

Спасибо

Джорис

Дополнительная информация: я использую Windows 7 + Visual Studio 2010

Редактировать : Оказалось, что это действительно было связано с правами доступа.То есть, начиная с Windows Vista, перехватчики журнала (WH_JOURNALRECORD) отключены по соображениям безопасности (см. Также этот веб-сайт ).В конце концов, мы использовали совершенно другой подход для обеспечения аналогичной функциональности в нашем приложении (о котором я не буду вдаваться в подробности, поскольку я редактирую этот вопрос через 1,5 года после того, как задал этот вопрос, и я не помню вседетали нашего решения).

Ответы [ 3 ]

2 голосов
/ 01 июля 2010

WH_JOURNALRECORD отличается от других. Вам не нужно помещать это в DLL, но вам нужно иметь цикл обработки сообщений в вашем приложении, чтобы обработчик мог быть вызван (в контексте вашего приложения). Некоторое время назад я опубликовал пример на другом сайте: http://forum.4programmers.net/viewtopic.php?p=557297#id557297, хук ловит WM_MOUSEMOVE в примере и выводит результаты на консоль.

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

1 голос
/ 22 сентября 2014

Ответ по ссылке в редактируемом вопросе: http://www.wintellect.com/CS/blogs/jrobbins/archive/2008/08/30/so-you-want-to-set-a-windows-journal-recording-hook-on-vista-it-s-not-nearly-as-easy-as-you-think.aspx

Является:
1. Приложение должно работать с правами администратора.
2. Приложение должно быть запущено из (подкаталога) c: \ program files
3. Чтобы отключить диалог UAC, приложение должно иметь цифровую подпись.
Обратите внимание, что при активном UAC Windows (Vista и выше) не позволяет отлаживать исполняемый файл.

Или ... Вы можете отключить UAC (полезно при (отладке).

Вот диалог настроек для Visual Studio, проверим, могу ли я получить файл манифеста в формате XML enter image description here

1 голос
/ 01 июля 2010

MSDN заявляет следующее для ловушки Записи журнала:

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

Если вы переместите обратный вызов для перехвата Journal на ваш exe, это вызовет его?

Кроме того, не лучше ли вызвать GetModuleHandle () вместо LoadLibrary() в install(), поскольку DLL уже загружена?

Относительно UAC и прав администратора, ловушки могут работать при исполнении от имени обычного пользователя. Единственным побочным эффектом этого является то, что только процессы, работающие на этом уровне или ниже, будут подключены. Поэтому, если ваше приложение работает от имени обычного пользователя, любые процессы, выполняющиеся от имени обычного пользователя, будут подключены, а процессы, выполняемые от имени администратора, не будут подключены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...