Подмена нажатия клавиатуры.

Тема в разделе "WASM.WIN32", создана пользователем WIN32, 3 дек 2008.

  1. WIN32

    WIN32 Member

    Публикаций:
    0
    Регистрация:
    20 янв 2007
    Сообщения:
    338
    Приветствую.
    Передо мной стоит задача на лету "заменять" коды клавиш клавиатуры. Как это сделать?
    Я перехватывал с помощью глобального хука все нажатия в системе
    Код (Text):
    1. #define _DEBUG_
    2. #include "stdafx.h"
    3. #include <stdio.h>
    4. #include "debug.h"
    5. #pragma comment(linker, "/SECTION:.rds,RWS")
    6. #pragma data_seg(".rds")//Shared data among all instances.
    7. HHOOK g_MainHhook = 0;
    8. struct HINSTANCE__ * g_MainHandle = 0;
    9. struct HINSTANCE__ * g_hThread = 0;
    10. DWORD g_ThreadId = 0;
    11. #pragma data_seg()
    12.  
    13.  
    14. extern "C" LRESULT __declspec(dllexport) CALLBACK KeyboardProc(
    15.                               int nCode,
    16.                               WPARAM wParam,
    17.                               LPARAM lParam)
    18. {
    19.     LRESULT RetVal;
    20.    
    21.     DbgPrintEx("%c[0x%02X | 0x%08X] key\n",wParam ,wParam, wParam);
    22.  
    23.     RetVal = CallNextHookEx( g_MainHhook, nCode, wParam, lParam );
    24.     return  RetVal;
    25. }
    26. //-----------------------------------------------------------------------
    27. extern "C" __declspec(dllexport)  BOOL __stdcall HookAddProc()
    28. {
    29.     g_MainHhook = SetWindowsHookEx(WH_KEYBOARD,(HOOKPROC)KeyboardProc,g_MainHandle,0);
    30.     if(!g_MainHhook)
    31.     {
    32.         DbgPrintEx("Error set hook : %d\n",GetLastError());
    33.         return FALSE;
    34.     }   else    {
    35.         DbgPrintEx("Hooks injected : 0x%08X\n",(ULONG)g_MainHhook);
    36.         return TRUE;
    37.     }
    38. }
    39. //-----------------------------------------------------------------------
    40. extern "C" __declspec(dllexport)  BOOL __stdcall HookDelProc()
    41. {
    42.     if(!g_MainHhook)
    43.     {
    44.         DbgPrintEx("Error delete hook : %d no handle\n",GetLastError());
    45.         return FALSE;
    46.     }   else    {
    47.         UnhookWindowsHookEx(g_MainHhook);
    48.         DbgPrintEx("Hooks deleted: 0x%08X\n",(ULONG)g_MainHhook);
    49.         return TRUE;
    50.     }
    51. }
    52. //-----------------------------------------------------------------------
    53. BOOL APIENTRY DllMain( HANDLE hModule,
    54.                        DWORD  ul_reason_for_call,
    55.                        LPVOID lpReserved
    56.                      )
    57. {
    58.     DbgPrintEx("Hook Library : %s\n","loaded");
    59.     if(ul_reason_for_call == DLL_PROCESS_ATTACH)
    60.     {
    61.         g_MainHandle = (struct HINSTANCE__ *)hModule;
    62.     }
    63.     return TRUE;
    64. }
    65. //-----------------------------------------------------------------------
    Перехватываются но не заменяются, т.е. в замена wParam в CallBack функции никчему не приводит...

    Решил попробовать Subclassing, но остановился на том что не могу перечислить адреса функций окон..
    Код (Text):
    1. #include "stdafx.h"
    2. #include <windows.h>
    3. #include "debug.h"
    4.  
    5. void EnableDebugPrivilege()
    6. {
    7.     HANDLE hToken;
    8.     TOKEN_PRIVILEGES tokenPriv;
    9.     LUID luidDebug;
    10.  
    11.     if(OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
    12.     {
    13.  
    14.         if(LookupPrivilegeValue(NULL,   SE_DEBUG_NAME  , &luidDebug))
    15.         {  
    16.             tokenPriv.PrivilegeCount   = 1;
    17.             tokenPriv.Privileges [0].Luid = luidDebug;
    18.             tokenPriv.Privileges [0].Attributes = SE_PRIVILEGE_ENABLED;
    19.             AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(tokenPriv), NULL, NULL);
    20.         }  
    21.  
    22.         if(LookupPrivilegeValue(NULL,SE_MACHINE_ACCOUNT_NAME,&luidDebug))
    23.         {
    24.             tokenPriv.PrivilegeCount   = 2;
    25.             tokenPriv.Privileges [0].Luid = luidDebug;
    26.             tokenPriv.Privileges [0].Attributes = SE_PRIVILEGE_ENABLED;
    27.             AdjustTokenPrivileges(hToken, FALSE, &tokenPriv, sizeof(tokenPriv), NULL, NULL);
    28.         }
    29.  
    30.     }
    31. }
    32.  
    33. BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)
    34. {
    35.     WNDPROC pProc = 0;
    36.     //printf("\tChild : HANDLE : 0x%08X, PARAM : 0x%08X, WNDPROC : 0x%08X\n",hwnd,lParam,pProc);
    37.  
    38.     if(IsWindowUnicode(hwnd))
    39.     {
    40.         pProc = (WNDPROC)GetWindowLongW(hwnd,GWL_WNDPROC);
    41.     }   else    {
    42.         pProc = (WNDPROC)GetWindowLongA(hwnd,GWL_WNDPROC);
    43.     }
    44.  
    45.     if(pProc != 0)
    46.     {
    47.         DbgPrintEx("\t\t_PROC : %d\n",pProc);
    48.     }
    49.     return TRUE;
    50. }
    51.  
    52. BOOL CALLBACK EnumWindowsProc(HWND hwnd,LPARAM lParam)
    53. {
    54.     WNDPROC pProc = 0;
    55.     if(IsWindowUnicode(hwnd))
    56.     {
    57.         pProc = (WNDPROC)GetWindowLongW(hwnd,GWL_WNDPROC); <----------- ERROR ACCESS DENIED !
    58.     }   else    {
    59.         pProc = (WNDPROC)GetWindowLongA(hwnd,GWL_WNDPROC);
    60.     }
    61.     DbgPrintEx("HANDLE : 0x%08X, PARAM : 0x%08X, WNDPROC : 0x%08X\n",hwnd,lParam,pProc);
    62.     EnumChildWindows(hwnd,&EnumChildProc,lParam);
    63.     return TRUE;
    64. }
    65.  
    66. int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
    67. {
    68.     EnableDebugPrivilege();
    69.     EnumWindows(EnumWindowsProc,0);
    70.     return 0;
    71. }
    Может быть, кто-нибудь уже делал такое? Буду благодарен.
     
  2. _Aspire

    _Aspire New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2008
    Сообщения:
    62
    WIN32
    Попробуй подменять в хуке на мессаги.

    Сам не пробовал. Ща попробую.
     
  3. WIN32

    WIN32 Member

    Публикаций:
    0
    Регистрация:
    20 янв 2007
    Сообщения:
    338
    _Aspire
    SendMessage/PostMessage ? А как мне получить HWND ? Пробовал HWND_BROADCAST, не получается..
     
  4. _Aspire

    _Aspire New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2008
    Сообщения:
    62
    WIN32 Проверил, работает.

    GetForegroundWindow?
     
  5. WIN32

    WIN32 Member

    Публикаций:
    0
    Регистрация:
    20 янв 2007
    Сообщения:
    338
    _Aspire мой код работает? Хм..что-же за хрень..

    upd. можешь выложить проект?
     
  6. _Aspire

    _Aspire New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2008
    Сообщения:
    62
    WIN32

    Не...я не твой проверял )) Я проверил лишь то,что если изменять значение виртуального кода нажатой клавиши в хуке на WH_GETMESSAGE, то мы увидим то, что ожидаем.
    В хуке WH_KEYBOARD_LL - это работать не будет.
     
  7. _Aspire

    _Aspire New Member

    Публикаций:
    0
    Регистрация:
    1 дек 2008
    Сообщения:
    62
    Код (Text):
    1. GetMsgProc proc nCode:DWORD, wParam:DWORD, lParam:DWORD
    2.       cmp   nCode,0
    3.       jnz   @ret  
    4.     mov edi, lParam
    5.     mov eax, dword ptr [edi+4]
    6.     .if  eax == WM_CHAR
    7.         add edi, 8
    8.         mov al, 'a'     ;тут вводишь тот символ, который тебе нужен
    9.         stosb
    10.     .endif
    11. @ret:
    12. invoke CallNextHookEx,hHook,nCode,wParam,lParam
    13. ret
    14. GetMsgProc endp
     
  8. WIN32

    WIN32 Member

    Публикаций:
    0
    Регистрация:
    20 янв 2007
    Сообщения:
    338
    Спасибо большое. Тему можно закрыть