메뉴 여닫기
개인 메뉴 토글
로그인하지 않음
만약 지금 편집한다면 당신의 IP 주소가 공개될 수 있습니다.

키보드 후킹 윈도우 api 이용

데브카페

AutoIt에서 다른 프로그램의 입력 키를 후킹(hooking)하는 방법

  • 이 기능은 AutoIt의 핵심 강점 중 하나이며, 다양한 접근 방식이 있습니다.
  • 다른 프로그램에서 발생하는 키 입력을 가로채서 처리하는 방법은 크게 두 가지로 나눌 수 있습니다.
  • 방법1) HotKeySet 함수를 이용한 전역(Global) 핫키 설정
    • 가장 간단하고 일반적인 방법
    • 특정 키 조합(예: Ctrl + A, F12, ~)이 눌렸을 때 특정 함수를 실행하도록 설정합니다.
    • 이 방식은 프로그램이 포커스를 잃더라도 작동합니다.
  • 방법2) 윈도우 API를 이용한 저수준(Low-Level) 키보드 후킹
    • 이 방법은 HotKeySet보다 훨씬 더 강력하고 유연합니다. ** _WinAPI_SetWindowsHookEx 함수를 사용해 키보드 메시지가 발생할 때마다 알림을 받는 WH_KEYBOARD_LL 훅을 설치합니다. 이 방식을 사용하면 모든 키 입력을 감지할 수 있습니다.

방법 1: HotKeySet을 이용한 전역 핫키 설정

  • 이 방법은 특정 키 조합(예: A, B, C와 같은 개별 키)을 감지하는 용도보다는, 매크로 실행과 같은 특정 동작을 트리거하는 데 더 적합합니다.
  • 예제: 사용자가 Ctrl + Alt + P를 누르면 "Hello World"를 출력하는 스크립트
HotKeySet("^+p", "MyFunction") ; Ctrl + Alt + P 를 누르면 MyFunction 실행

While 1
    Sleep(100)
WEnd

Func MyFunction()
    MsgBox(0, "핫키 감지", "Ctrl + Alt + P 키가 눌렸습니다.")
EndFunc
  • HotKeySet("^+p", "MyFunction"):
  * ^ : Ctrl 키
  * + : Alt 키
  * p : P 키
  * "^+p"는 Ctrl + Alt + P를 의미합니다.
  • 장점: 사용하기 매우 쉽고 간단합니다.
  • 단점: 모든 키 입력을 후킹하기는 어렵고, 특정 조합만 감지할 수 있습니다.

방법 2: 윈도우 API를 이용한 저수준 키보드 후킹

  • 이 방법은 다른 프로그램에서 발생하는 모든 키 입력을 실시간으로 감지하고 처리하는 데 사용됩니다.
  • 하지만 이 방법은 스크립트의 복잡성이 증가하며, 관리자 권한이 필요할 수 있고, 잘못 사용하면 다른 프로그램의 정상적인 키 입력을 방해할 수 있으므로 주의해야 합니다.
  • 예제: 키보드 입력을 후킹하여 어떤 키가 눌렸는지 실시간으로 출력하는 스크립트
#include <MsgBoxConstants.au3>
#include <WinAPISys.au3>
#include <WinAPI.au3>
#include <WindowsConstants.au3>

; 전역 변수 선언
Global $g_hHook

; 윈도우 API를 이용한 키보드 후킹 설치
; WH_KEYBOARD_LL (13) : 저수준 키보드 이벤트 후킹
$g_hHook = _WinAPI_SetWindowsHookEx($WH_KEYBOARD_LL, "_KeyboardProc", @ScriptFullPath)

; 후킹 설치 실패 시 경고
If Not $g_hHook Then
    MsgBox($MB_SYSTEMMODAL, "오류", "키보드 훅 설치 실패! 스크립트를 관리자 권한으로 실행해보세요.")
    Exit
EndIf

MsgBox($MB_SYSTEMMODAL, "키보드 훅 설치됨", "이제 모든 키보드 입력이 감지됩니다.")

; 스크립트가 종료될 때 후킹 해제
_OnExit_Register("OnExitFunc")

; 이벤트 루프 (스크립트가 종료되지 않도록 대기)
While 1
    Sleep(100)
WEnd

; -----------------------------------------------------------
; 키보드 후킹 핸들러 함수
; -----------------------------------------------------------
Func _KeyboardProc($nCode, $wParam, $lParam)
    ; $nCode가 0보다 작을 경우 메시지 처리를 다른 후킹 프로그램에 넘깁니다.
    If $nCode < 0 Then
        Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
    EndIf

    ; $wParam 값은 키보드 메시지 (WM_KEYDOWN, WM_KEYUP 등)
    ; $lParam 값은 키보드 입력 정보가 담긴 구조체 포인터

    ; 눌린 키의 가상 키 코드(VK code)를 추출
    Local $sVKCode = DllStructGetData(DllStructCreate("long;long;long;long", $lParam), 1)

    ; 키가 눌렸을 때 (WM_KEYDOWN 또는 WM_SYSKEYDOWN)
    If $wParam = $WM_KEYDOWN Or $wParam = $WM_SYSKEYDOWN Then
        ; VK 코드를 문자열로 변환하여 출력
        ConsoleWrite("키 입력 감지: " & Hex($sVKCode) & " (" & Chr($sVKCode) & ")" & @CRLF)
        
        ; 원하는 동작 수행:
        ; If $sVKCode = 0x41 Then ; 'A' 키가 눌렸을 때
        ;   MsgBox(0, "알림", "A 키가 눌렸습니다!")
        ; EndIf
    EndIf

    ; 다른 프로그램들도 키 입력을 받도록 다음 훅 체인으로 메시지를 전달합니다.
    ; 만약 특정 키 입력을 차단하고 싶다면 이 부분을 제거하고 1을 반환하면 됩니다.
    Return _WinAPI_CallNextHookEx($g_hHook, $nCode, $wParam, $lParam)
EndFunc

; -----------------------------------------------------------
; 스크립트 종료 시 후킹 해제 함수
; -----------------------------------------------------------
Func OnExitFunc()
    If $g_hHook Then
        _WinAPI_UnhookWindowsHookEx($g_hHook)
        ConsoleWrite("키보드 훅 해제됨." & @CRLF)
    EndIf
EndFunc


  • _WinAPI_SetWindowsHookEx: 키보드 후킹을 설치하는 윈도우 API 함수를 호출합니다.
  • $WH_KEYBOARD_LL: 키보드 이벤트를 저수준으로 감지하도록 지정하는 상수입니다.
  • "_KeyboardProc": 키보드 이벤트 발생 시 호출될 함수 이름입니다.
  • @ScriptFullPath: 후킹 스레드를 지정합니다. 이 경우 현재 스크립트의 경로를 전달합니다.
  • _KeyboardProc: 키보드 이벤트가 발생할 때마다 호출되는 핸들러 함수입니다.
  • $lParam: 키보드 입력에 대한 상세 정보(가상 키 코드, 스캔 코드 등)가 담긴 포인터입니다. DllStructCreate를 사용하여 이 포인터의 데이터를 읽어옵니다.
  • 주의: $lParam을 이용해 키 정보를 읽는 방식은 키보드 구조체의 정의에 따라 달라질 수 있습니다. 위의 예제는 가장 일반적인 경우입니다.
  • _WinAPI_CallNextHookEx: 매우 중요한 함수입니다. 이 함수를 호출해야 현재 훅 다음의 다른 후킹 프로그램이나 윈도우가 정상적으로 키 입력을 받을 수 있습니다. 이 함수를 호출하지 않으면 다른 프로그램의 키 입력이 먹통이 되는 부작용이 발생할 수 있습니다.
  • _WinAPI_UnhookWindowsHookEx: 스크립트 종료 시 후킹을 해제하여 메모리 누수나 시스템 불안정 문제를 방지합니다.

요약 및 결론

  • 간단한 매크로나 특정 키 조합만 감지하고 싶다면 HotKeySet을 사용하세요. 스크립트가 훨씬 간단하고 안전합니다.
  • 모든 키 입력, 특히 다른 프로그램의 모든 키 입력을 실시간으로 감지하고 싶다면 _WinAPI_SetWindowsHookEx를 사용하세요. 이 방법은 강력하지만, 윈도우 API와 스레드 개념에 대한 이해가 필요하고, 잘못 사용하면 시스템에 영향을 줄 수 있습니다.

_WinAPI_SetWindowsHookEx는 AutoIt의 DLLCall 기능을 활용하여 C++ 수준의 윈도우 API를 사용하는 것과 동일합니다.

Comments