2009-09-17 5 views
4

개인 키 입력 로거에서 작업 중이며 어제에 관한 질문과 관련하여 질문했습니다. While loop using a lot of CPU.C++ Win32 키보드 이벤트

이 프로그램의 문제는 CPU 사용량이 너무 많아서 사람들이 키 이벤트를 기반으로 입력을 제안했습니다.

필자는 Win32 API를 처음 사용 했으므로 폴링 기반이 아닌 이벤트 기반으로 키보드 입력을 작성하는 방법을 알려주는 참조 및 자습서를 찾으려고합니다. 그러나 문제는 완전한 뉴비를 이해하기가 어려웠 기 때문에 견고한 예제 나 참조를 찾을 수 없었습니다.

대부분은 이벤트 기반 프로그래밍이 GUI 응용 프로그램에 있다고 언급했지만이 키 스트로크 로거 응용 프로그램을 콘솔 응용 프로그램으로 사용하길 원합니다. 이 모든에서

내 두 가지 질문은 다음과 같습니다

  • 내가는 Win32 API와 이벤트 기반 콘솔 키 스트로크 로거를 쓸 수 있습니까? 그렇지 않은 경우 내 옵션은 무엇입니까?

  • 누구든지 나를 이벤트 기반 키 입력을 캡처하는 방법을 이해하는 데 도움이되는 참조 웹 사이트가 있습니까?

추가 정보가 필요하면 GCC 컴파일러가 설치된 Windows XP에서 코드 블록을 사용하고 있습니다.

답변

7

키 로거 응용 프로그램은 Win32 Hooks과 같은 메커니즘을 사용합니다. 특히 WH_KEYBOARD 후크를 설정해야합니다.

자신 만의 키보드 드라이버를 만드는 것처럼 움직이는 고급 기술이 있지만 출발 후크는 좋은 선택입니다.

편집 : 후크 절차가 어떻게 생겼는지 생각해 보려면 개인 유틸리티에서 조각을 게시하십시오.

// ... 
thehook = SetWindowsHookEx(WH_KEYBOARD_LL, hook_proc, hwnd, 0); 
// ... 

/** 
* 
* wParam, one of the: WM_KEYDOWN, WM_KEYUP, WM_SYSKEYDOWN, or WM_SYSKEYUP 
    lParam: pointer to a KBDLLHOOKSTRUCT structure 

    (*) "The hook procedure should process a message in less time than the 
    data entry specified in the LowLevelHooksTimeout value in the following registry key: 
    HKEY_CURRENT_USER\Control Panel\Desktop 

    The value is in milliseconds. If the hook procedure does not 
    return during this interval, the system will pass the message to the next hook." 

* 
*/ 
LRESULT CALLBACK 
hook_proc(int code, WPARAM wParam, LPARAM lParam) 
{ 
    static long ctrl_cnt = 0; 
    static bool mmode = false; 
    static DWORD time; 

    KBDLLHOOKSTRUCT* kbd = (KBDLLHOOKSTRUCT*)lParam; 

    if ( code < 0 
    || (kbd->flags & 0x10) // ignore injected events 
    ) return CallNextHookEx(thehook, code, wParam, lParam); 

    long ret = 1; // by default I swallow the keys 
    if ( mmode ) { // macro mode is ON 
    if ( WM_KEYDOWN == wParam ) 
     PostMessage(mainwnd, WM_MCR_ACCUM, kbd->vkCode, 0); 

    if ( WM_KEYUP == wParam ) 
     switch (kbd->vkCode) { 
     case VK_ESCAPE: 
      mmode = false; 
      keys.removeall(); 
      PostMessage(mainwnd, WM_MCR_HIDE, 0, 0); 
      break; 

     case VK_RETURN: 
      PostMessage(mainwnd, WM_MCR_EXEC, 0, 0); 
      break; 

     case VK_LCONTROL: 
      mmode = false; 
      PostMessage(mainwnd, WM_MCR_HIDE, 0, 0); 
      PostMessage(mainwnd, WM_MCR_EXEC, 0, 0); 
      break; 
     } 

    /* Which non printable keys allow passing? */ 
    switch(kbd->vkCode) { 
     case VK_LCONTROL: 
     case VK_CAPITAL: 
     case VK_LSHIFT: 
     case VK_RSHIFT: 
     ret = CallNextHookEx(thehook, code, wParam, lParam); 
    } 
    } 
    else { // macro mode is OFF 
    /* Ctrl pressed */ 
    if ( kbd->vkCode == VK_LCONTROL && WM_KEYDOWN == wParam ) { 
     ctrl_cnt = 1; 
     time = kbd->time; 
    } 

    /* Prevent ctrl combinations to activate macro mode */ 
    if ( kbd->vkCode != VK_LCONTROL ) 
     ctrl_cnt = 0; 

    /* Ctrl released */ 
    if ( ctrl_cnt == 1 && WM_KEYUP == wParam ) { 
     if ( kbd->time - time > 40 ) { 
     mmode = true; 
     PostMessage(mainwnd, WM_MCR_SHOW, 0, 0); 
     } 
    } 

    ret = CallNextHookEx(thehook, code, wParam, lParam); // let it pass 
    } 

    return ret; 
} 
+0

다른 프로그램의 HINSTANCE를 어떻게 얻습니까? –

+0

@ MatoušVrba, 당신은 다른 프로그램의 핸들을 얻을 필요가 없습니다. –

+0

그래, 이제 알았어, 고마워! –

5

SetWindowsHookEx API를 살펴보십시오.

콘솔 앱 일 수도 있고 창 응용 프로그램 일 수도 있습니다. 자신의 키보드가 아닌 다른 프로세스에서 키 입력을 캡처 할 수 있도록 키보드 훅을 DLL에 넣어야합니다.

샘플 코드 here가 있습니다.

+0

호기심, 후크가 정확히 무엇을합니까? 나는 그것이 다른 프로그램에 자신을 주입한다는 것을 읽었거나 이해할 수 있습니다. 또한, 이것은 키 스트로크 로거가 사용하는 CPU 사용량을 줄입니까? –

+1

선택한 이벤트가 발생할 때 후크가 함수에 콜백을 추가합니다. 끊임없이 키보드를 폴링하는 루프가 필요하지 않습니다. 필요한 경우에만 코드가 실행됩니다. – Ferruccio

+0

이 토론을 참조하십시오. http://stackoverflow.com/questions/3134183/understanding-the-low-level-mouse-and-keyboard-hook-win32/3134570#comment27597902_3134570 (exe가 * _LL 메시지에서도 작동하지만 dll은 다른 어떤 것에 대해서 필요하다). – rogerdpack