Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Помогите с установкой хука  (Прочитано 13402 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Kultura
Помогающий

ru
Offline Offline

« : 07-11-2008 16:49 » 

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

Работает только, когда ее окошко активно. Хотя устанавливаю хук для всей системы.

Вот код установки\снятия хука:
Код:
void PeonEventHandlers::OnWork ()
{
hhookDll = LoadLibrary ("PeonHooks.dll");
if (!hhookDll)
throw std::runtime_error ("Can't load library 'PeonHooks.dll'");

// Find set-hook for share function adress:
void (* pSetHookHandle) (HHOOK);
(FARPROC &) pSetHookHandle = GetProcAddress(hhookDll, "SetHookHandle");
if(!pSetHookHandle)
{
FreeLibrary(hhookDll);
throw std::runtime_error ("Can't GetProcAddress 'SetHookHandle'");
}

// Find hook-function adress:
HOOKPROC pKeybProc = (HOOKPROC) GetProcAddress(hhookDll, "?KeybProc@@YGJHIJ@Z");
if(!pKeybProc)
{
FreeLibrary(hhookDll);
throw std::runtime_error ("Can't GetProcAddress '?KeybProc@@YGJHIJ@Z'");
}

// Setting hook:
hookKeyboard = SetWindowsHookEx (WH_KEYBOARD, pKeybProc, hhookDll, NULL);
if(!hookKeyboard)
{
FreeLibrary(hhookDll);
throw std::runtime_error ("Can't SetWindowsHookEx");
}
(* pSetHookHandle) (hookKeyboard);
}
void PeonEventHandlers::OnStop ()
{
UnhookWindowsHookEx(hookKeyboard);
FreeLibrary(hhookDll);
hhookDll = NULL;
hookKeyboard = NULL;
}

Вот код dll:
Код:
WPARAM tempwParam = 0;

// Main:
BOOL APIENTRY DllMain( HANDLE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
)
{
    return TRUE;
}
       // Shared-variables:
#pragma data_seg(".HKT")
HHOOK  g_hHookKeyboard = NULL;
#pragma data_seg ()
#pragma comment(linker, "/SECTION:.HKT,RWS")

      // ...
extern "C" _declspec(dllexport)
void SetHookHandle(HHOOK hookKeyboard)
{
    g_hHookKeyboard = hookKeyboard;
}

      // Hook-function:
_declspec(dllexport)
LRESULT CALLBACK KeybProc(int nCode, WPARAM wParam, LPARAM lParam)
{
static std::ofstream out ("out.txt");
    if(nCode == HC_ACTION)
    {
if (tempwParam != wParam)
out << wParam << " " << (char) wParam << " " << std::endl;
tempwParam = wParam;       
    }

    if(g_hHookKeyboard != NULL)
        return CallNextHookEx(g_hHookKeyboard, nCode, wParam, lParam);
    else
        return 0;
}

Этот код работает, будто хук установлен локально. Хотя параметры SetWindowsHookEx
задаю, вроде бы, для всей системы. Как сделать правильно?
Записан
zubr
Гость
« Ответ #1 : 07-11-2008 19:08 » 

Хендл хука hookKeyboard должен быть глобальным. У тебя он инициализирован только в твоем процессе. Когда хуковая длл будет подгружаться в чужой процесс, в котором произошло хуковое событие, то переменная g_hHookKeyboard будет NULL. Выход: передавать хендл хука через файл-маппинг или расшаренную память.
Записан
Kultura
Помогающий

ru
Offline Offline

« Ответ #2 : 07-11-2008 19:51 » 

Перепроверил, вроде, в коде dll как раз и использую расшареную память.
Вот в таком виде:
Код:
      // Shared-variables:
#pragma data_seg(".HKT")
HHOOK  g_hHookKeyboard = NULL;
#pragma data_seg ()
#pragma comment(linker, "/SECTION:.HKT,RWS")
Записан
zubr
Гость
« Ответ #3 : 08-11-2008 09:18 » 

Хмм.., да невнимательно посмотрел, память у тебя расшарена. Есть подозрение, что в последнем параметре SetWindowsHookEx надо не NULL а 0 поставить. По крайней мере в msdn речь идет о зеро.
Записан
Kultura
Помогающий

ru
Offline Offline

« Ответ #4 : 08-11-2008 09:38 » 

Сделал 0, к сожалению, не помогло.
Странно, в чем же все таки проблема  Не понял. Стоит у меня win XP, пользуюсь Visual c++ 2008. Не понятно
Записан
zubr
Гость
« Ответ #5 : 08-11-2008 09:43 » 

Попробуй SetWindowsHookEx вынести в саму dll, а вместо hhookDll делать ::GetModuleHandle("DllName")
Записан
Kultura
Помогающий

ru
Offline Offline

« Ответ #6 : 08-11-2008 10:36 » 


Попробуй SetWindowsHookEx вынести в саму dll, а вместо hhookDll делать ::GetModuleHandle("DllName")

Сделал, теперь код в приложении выглядит так:
Код:
void PeonEventHandlers::OnWork ()
{
hhookDll = LoadLibrary ("PeonHooks.dll");
if (!hhookDll)
throw std::runtime_error ("Can't load library 'PeonHooks.dll'");

// Find set-hook for share function adress:
BOOL (* pRunHook) ();
(FARPROC &) pRunHook = GetProcAddress(hhookDll, "RunHook");
if(!pRunHook)
{
FreeLibrary(hhookDll);
throw std::runtime_error ("Can't GetProcAddress 'RunHook'");
}
BOOL bresult = (* pRunHook) ();
if (!bresult)
{
FreeLibrary(hhookDll);
throw std::runtime_error ("Can't RunHook");
}
}

Код dll:
Код:
//...
// Shared-variables:
#pragma data_seg(".HKT")
HHOOK  g_hHookKeyboard = NULL;
#pragma data_seg ()
#pragma comment(linker, "/SECTION:.HKT,RWS")

// Hook-function:
_declspec(dllexport)
LRESULT CALLBACK KeybProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    static std::ofstream out ("out.txt");
    if(nCode == HC_ACTION)
    {
if (tempwParam != wParam)
out << wParam << " " << (char) wParam << " " << std::endl;
tempwParam = wParam;       
    }

    if(g_hHookKeyboard != NULL)
        return CallNextHookEx (g_hHookKeyboard, nCode, wParam, lParam);
    else
        return 0;
}

extern "C" _declspec(dllexport)
BOOL RunHook ()
{
g_hHookKeyboard = SetWindowsHookEx (WH_KEYBOARD, KeybProc,
GetModuleHandle ("PeonHooks.dll"), 0);
if (!g_hHookKeyboard)
return FALSE;
return TRUE;
}
extern "C" _declspec(dllexport)
void StopHook ()
{
UnhookWindowsHookEx (g_hHookKeyboard);
}

Не помогло  Жаль. Работает точно как и первый вариант.
Записан
zubr
Гость
« Ответ #7 : 08-11-2008 11:17 » 

Попробуй сделать так:
Код:
// Hook-function:
_declspec(dllexport)
LRESULT CALLBACK KeybProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if(ncode <0)
    if(g_hHookKeyboard != NULL)
        return CallNextHookEx (g_hHookKeyboard, nCode, wParam, lParam);
    else
        return 0;

    static std::ofstream out ("out.txt");
   
    if (tempwParam != wParam)
   {
         out << wParam << " " << (char) wParam << " " << std::endl;
         tempwParam = wParam;       
   }
   
    if(g_hHookKeyboard != NULL)
        return CallNextHookEx (g_hHookKeyboard, nCode, wParam, lParam);
    else
        return 0;
}
Записан
Kultura
Помогающий

ru
Offline Offline

« Ответ #8 : 08-11-2008 11:35 » 

Нет, не сработало. Может в самой программе что-то криво? Хотя просто по нажатию кнопки вызывается RunHook из dll, при нажатии кнопки stop, вызывается StopHook. Включаю хук, переключаюсь на другое окошко, не работает. Возвращаюсь в свое окошко, работает.  Здесь была моя ладья...
Записан
zubr
Гость
« Ответ #9 : 08-11-2008 13:44 » 

Блин, я не обратил внимания. Посмотри на конструкцию static std::ofstream out ("out.txt"); Что при этом происходит? Когда хук работает с твоим приложением, то запись идет в файл out.txt, расположенный в одном каталоге с программой, а когда хук работает с чужим приложением куда запись идет? Ведь текущий путь будет каталог программы в которой сработал хук.
Записан
Kultura
Помогающий

ru
Offline Offline

« Ответ #10 : 08-11-2008 16:00 » 

Да уж, у меня по всему компу валяются файлы out.txt. Проблема решена  Улыбаюсь

Zubr, Спасибо!  Класс!
Записан
Cnukep
Гость
« Ответ #11 : 04-12-2008 23:02 » 

Да уж, у меня по всему компу валяются файлы out.txt. Проблема решена  Улыбаюсь

Zubr, Спасибо!  Класс!

Таже проблема была, протрахался с этим делом очень долго
прочитав сей пост -чуть со стула не упал Улыбаюсь Улыбаюсь Улыбаюсь тот же косяк оказался
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines