Модераторы: feodorv, GremlinProg, xvr, Fixin

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Key hook, перехват нажатия клавиш, Без использования dll, как сделать? 
:(
    Опции темы
ReFleX
Дата 30.10.2006, 19:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 26.9.2004
Где: Таллинн

Репутация: нет
Всего: 3



Добрый день!

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

Из кучи примеров у меня получилось собрать именно тот который мне нужен:

DLL:
Код

#include <windows.h>
#include <iostream>

#ifdef __cplusplus
extern "C" {
#endif

HHOOK hHKeyBrd = NULL;

LRESULT CALLBACK KeyBrdProc(int nCode, WPARAM wParam, LPARAM lParam)
{
    if (nCode >= 0){
        MessageBox(NULL,"Hook","Information",MB_OK);
    }
    return CallNextHookEx (hHKeyBrd,nCode,wParam,lParam);
}

__declspec(dllexport) bool SetHooks(HINSTANCE hModule)
{
    hHKeyBrd = SetWindowsHookEx(WH_KEYBOARD, KeyBrdProc, (HINSTANCE) hModule, NULL);
    return true; 
}

__declspec(dllexport) bool UnHook()
{
    return true;
}

#ifdef __cplusplus
}
#endif


EXE
Код

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

HHOOK hH;

typedef bool(*dllProc)(HINSTANCE);

int _tmain(int argc, _TCHAR* argv[])
{    
    HINSTANCE hDll;
    dllProc prAddr;

    char *DllFile = "HookDll.dll";

    HINSTANCE  hModule = GetModuleHandle(DllFile);
    if ((hDll = LoadLibrary(DllFile))!=NULL){
        prAddr = (dllProc)GetProcAddress(hDll,"SetHooks");
    }else{
        printf("Can't load DLL");
        Sleep(3000);
        return 0;
    }
    (prAddr)(hDll);
    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return 0;
}


Вопрос остаётся тот же, возможно ли объеденить DLL вместе с EXE?
Просто не очень хочеться тоскать библиотеку, пускай лучше EXE будет немного больше.

Я слышал, что microsoft позволяет работать с Hook как в DLL так и для EXE, но примера я нигде не нашёл, решил обратиться с помощью на любимый форум. smile 
PM WWW   Вверх
SergeCpp
Дата 30.10.2006, 19:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


 
**


Профиль
Группа: Участник
Сообщений: 955
Регистрация: 8.8.2005
Где: At Home

Репутация: 10
Всего: 124



Попробуйте вот так

char* DllFile = "HookExe.exe"; // и перенесите все функции в EXE

PM MAIL WWW ICQ   Вверх
ReFleX
Дата 30.10.2006, 19:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 26.9.2004
Где: Таллинн

Репутация: нет
Всего: 3



Не думаю что это будет правильно... smile 
PM WWW   Вверх
anwe
Дата 30.10.2006, 20:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 748
Регистрация: 2.9.2006

Репутация: 1
Всего: 23



А такой хук не всегда требует нахождения функции-фильтра в отдельной длл-ке. Можно устанавливать и в своем приложении. Только и ловится будут свои сообщения.
PM MAIL   Вверх
ReFleX
Дата 30.10.2006, 20:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 26.9.2004
Где: Таллинн

Репутация: нет
Всего: 3



Мне надо чтобы ловились нажатия клавиш вне программы, этого я добился, но так же нужно чтобы библиотеки небыло, чтобы не таскаться с ней.
PM WWW   Вверх
anwe
Дата 30.10.2006, 21:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 748
Регистрация: 2.9.2006

Репутация: 1
Всего: 23



Все системные хуки и хуки для потоков в другом приложении должны находиться в DLL.
PM MAIL   Вверх
Dude03
Дата 31.10.2006, 02:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 257
Регистрация: 28.4.2006

Репутация: 1
Всего: 6



Цитата(ReFleX @  30.10.2006,  20:34 Найти цитируемый пост)
Мне надо чтобы ловились нажатия клавиш вне программы, этого я добился, но так же нужно чтобы библиотеки небыло, чтобы не таскаться с ней. 

А в чем проблема?=) Почему нельзя загружать либу из ресурсов приложения.
Пусть тебя не смущает асм-код. Просто посмотри какие надо юзать функции(их имена после invoke):
Код

invoke FindResource, NULL, ADDR mres, RT_RCDATA
test eax, eax
je WMDESTROY
mov [hRes], eax
invoke SizeofResource, [hInstance], eax
mov [SizeRes], eax
invoke LoadResource, NULL, [hRes]
invoke LockResource, eax

PM MAIL   Вверх
ReFleX
Дата 31.10.2006, 02:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 26.9.2004
Где: Таллинн

Репутация: нет
Всего: 3



Т.е. если я правильно понял, включить dll в приложение а после уже при открытие EXE работать с включённой библиотекой.


Цитата(Dude03 @  31.10.2006,  02:01 Найти цитируемый пост)
Пусть тебя не смущает асм-код.
тут с WinAPI голову сломаешь, а тут ещё и ассемблер smile  smile  smile 

PM WWW   Вверх
Earnest
Дата 31.10.2006, 08:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 33
Всего: 183



Эта DLL, содержащаю хук, должна подгружаться во все процессы, в которых будет выполняться код, так что
anwe прав: только локальные хуки можно ставить, используя процедуру, которая находится в EXE.
Цитата(MSDN)

The global hooks are a shared resource, and installing one affects all applications in the same desktop as the calling thread. All global hook functions must be in libraries. 



--------------------
...
PM   Вверх
SergeCpp
Дата 31.10.2006, 08:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


 
**


Профиль
Группа: Участник
Сообщений: 955
Регистрация: 8.8.2005
Где: At Home

Репутация: 10
Всего: 124



Код
BOOL WINAPI DllMain(
  HINSTANCE hinstDLL,
  DWORD fdwReason,
  LPVOID lpvReserved
);

int WinMain(
    HINSTANCE hInstance,
    HINSTANCE hPrevInstance,
    LPSTR lpCmdLine,
    int nCmdShow
);


Остаётся лишь распознать вызов LoadLibrary (по третьему параметру) и подкорректировать стек.

Не так велики ухищрения. Сделать можно.

Естественно, Entry Point должна быть своя — не та, что берётся из CRT0.C и CRTDLL.C, например (имена файлов VC).

PM MAIL WWW ICQ   Вверх
ReFleX
Дата 31.10.2006, 11:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 499
Регистрация: 26.9.2004
Где: Таллинн

Репутация: нет
Всего: 3



Цитата(SergeCpp @  31.10.2006,  08:42 Найти цитируемый пост)
Не так велики ухищрения. Сделать можно

 smile А можешь пример сделать, я просто в WinAPI не совсем хорошо разбираюсь. Так с лёту догнать написанное не могу.
PM WWW   Вверх
v2v
Дата 6.11.2006, 18:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1620
Регистрация: 20.9.2006
Где: Киев

Репутация: нет
Всего: 56



Вероятно это уже не актуально, но я хотел бы поделиться своими изыскаиями в области перехвата нажатия кнопки клавиатуры.
Не обязательно создавать длл для перехвата нажатий в текущем окне, но вот если вы хотите перехватывать нажатия из других окон...
единственный выход - это длл.
Если кому то интересно, могу выложитькод, где я перехватываю нажатия выполненные в этом окне



--------------------
PM   Вверх
Yra
Дата 30.12.2006, 14:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 115
Регистрация: 12.9.2006
Где: Украина, Киев

Репутация: нет
Всего: нет



v2v,  Выкладывай!!!! Или если не трудно - на мыло мне скинь пожалуйста : [email protected]
 smile 
PM MAIL   Вверх
jonie
Дата 3.1.2007, 01:44 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 5613
Регистрация: 21.8.2005
Где: Владимир

Репутация: 7
Всего: 118



погавариват что есть еще и хуки низкого уровня... и они не требуют типа без длл. Я честно маловерю) хотите - проверяйте) да и на делфях)...
Код

 LT> Установка системных WH_KEYBOARD_LL и WH_MOUSE_LL, т.е. хуков низкого 
 LT> уровня, не требуют библиотеки. 
 DVS> жаль только Delphi о них понятия не имеет. 


const 
  WH_KEYBOARD_LL = 13; 
  WH_MOUSE_LL = 14; 


  LLKHF_EXTENDED = KF_EXTENDED shr 8; 
  LLKHF_INJECTED = $00000010; 
  LLKHF_ALTDOWN = KF_ALTDOWN shr 8; 
  LLKHF_UP = KF_UP shr 8; 


  LLMHF_INJECTED = $00000001; 


{ Structure used by WH_KEYBOARD_LL } 
type 
  tagKBDLLHOOKSTRUCT  = packed record 
    vkCode : DWord; 
    scanCode : DWord; 
    flags : DWord; 
    time : DWord; 
    dwExtraInfo : PDWord; 
  end; 
  TKBDLLHOOKSTRUCT = tagKBDLLHOOKSTRUCT; 
  PKBDLLHOOKSTRUCT = ^TKBDLLHOOKSTRUCT; 


{ Structure used by WH_MOUSE_LL } 
  tagMSLLHOOKSTRUCT = packed record 
    pt : TPoint; 
    mouseData : DWord; 
    flags : DWord; 
    time : DWord; 
    dwExtraInfo : PDWord; 
  end; 
  tMSLLHOOKSTRUCT = tagMSLLHOOKSTRUCT; 
  PMSLLHOOKSTRUCT = ^TMSLLHOOKSTRUCT; 


  Вот, например, что когда-то предлагал Джеф Рихтер для 
  отключения любимых номеров (в вольном переводе): 


function  LowLevelKeyboardProc(nCode :Longint; awParam: WParam; alParam: 
LParam): DWord; stdcall; 
var 
  fEatKeystroke: Boolean; 
  p: PKBDLLHOOKSTRUCT; 
  buf: array [0..255] of Char; 
  sc: UINT; 
begin 
   fEatKeystroke := False; 


   if (nCode = HC_ACTION) then 
      case (awParam) of 
       WM_KEYDOWN, WM_SYSKEYDOWN, 
       WM_KEYUP, WM_SYSKEYUP: 
         begin 
          p := PKBDLLHOOKSTRUCT(alParam); 
          fEatKeystroke := 
            ((p.vkCode = VK_TAB) and (p.flags and LLKHF_ALTDOWN <> 0)) or 
            ((p.vkCode = VK_ESCAPE) and ((p.flags and LLKHF_ALTDOWN) <> 0)) or 
            ((p.vkCode = VK_ESCAPE) and ((GetKeyState(VK_CONTROL) and $8000) 
<>0)); 
         end; 
       end; 


   if fEatKeystroke then 
     Result := 1 
   else 
     Result := CallNextHookEx(0, nCode, awParam, alParam); 
end; 


var 
  hhk: HHOOK; 


procedure TForm1.Button1Click(Sender: TObject); 
begin 
  hhk:= SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, Hinstance, 0); 
end; 


procedure TForm1.Button2Click(Sender: TObject); 
begin 
  UnHookWindowsHookEx(hhk); 
end; 

а вообще можно и поэксперементировать с Dll-Exe-шкой)) SergeCpp писал...


--------------------
Что-то не поняли? -> Напейтесь до зеленых человечков... эта сверхцивилизация Вам поможет...
PM MAIL Jabber   Вверх
W4FhLF
Дата 3.1.2007, 08:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


found myself
****


Профиль
Группа: Участник Клуба
Сообщений: 2831
Регистрация: 2.12.2006

Репутация: 12
Всего: 121



Цитата

погавариват что есть еще и хуки низкого уровня... и они не требуют типа без длл. 


Подмена адресов в SDT чтоли?


Как бы там ни было, вы должны понять, что когда устанавливается хук в чужом адресном пространстве должен находится Ваш модуль. Dll можно легко подгрузить в чужое адресное пространство, там все смещения вычисляются с учётом поправок(reloc), т.е. базовый адрес dll в адресном пространстве процесса может быть динамическим. А вот подгрузить Exe уже не так просто, нужно учесть кучу тонкостей PE формата, мне даже лень перечислять все. А сделать так, чтобы твой exe работал параллельно с основным в одном процессе вообще гиблая идея.

Это сообщение отредактировал(а) W4FhLF - 3.1.2007, 08:52


--------------------
"Бог умер" © Ницше
"Ницше умер" © Бог
PM ICQ   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.1544 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.