윈도우 환경에서 Python을 사용하여 키보드 후킹을 하는 방법의 이해를 돕기 위한 예제 코드이다.
소스
# -*- coding: utf-8 -*- #!/usr/bin/python import sys from ctypes import * from ctypes.wintypes import MSG from ctypes.wintypes import DWORD user32 = windll.user32 kernel32 = windll.kernel32 WH_KEYBOARD_LL = 13 WM_KEYDOWN = 0x0100 CTRL_CODE = 162 class KeyRogue: def __init__(self): self.lUser32 = user32 self.hooked = None def installHookProc(self, pointer): self.hooked = self.lUser32.SetWindowsHookExA( WH_KEYBOARD_LL, pointer, kernel32.GetModuleHandleW(None), 0 ) if not self.hooked: return False return True def uninstallHookProc(self): if self.hooked is None: return self.lUser32.UnhookWindowsHookEx(self.hooked) self.hooked = None def bytes(self, integer): return divmod(integer, 0x10000) def getFPTR(self, fn): CMPFUNC = CFUNCTYPE(c_int, c_int, c_int, POINTER(c_void_p)) return CMPFUNC(fn) def startKeyLog(self): msg = MSG() user32.GetMessageA(byref(msg), 0, 0, 0) def getKeyCode(self, lParam): high, low = self.bytes(lParam[0]) return low def hookProc(nCode, wParam, lParam): if wParam is not WM_KEYDOWN: return user32.CallNextHookEx(keyRogue.hooked, nCode, wParam, lParam) keyCode = keyRogue.getKeyCode(lParam) hookedKey = chr(keyCode) print(hookedKey) if (CTRL_CODE == keyCode): print("ctrl pressed, call uninstallHook()") keyRogue.uninstallHookProc() sys.exit(-1) return user32.CallNextHookEx(keyRogue.hooked, nCode, wParam, lParam) keyRogue = KeyRogue() pointer = keyRogue.getFPTR(hookProc) if keyRogue.installHookProc(pointer): print("install success") keyRogue.startKeyLog() else: print("install failed")
문제 해결
- Python 3.7.5 64비트 버전에서 SetWindowsHookExA 호출 시에 0값이 리턴되면서 Hook 설치가 실패되는 일이 있었는데, 3.7.5 32비트 버전을 설치하니까 해결이 되었다. 그런데 3.6.5 64비트에서는 또 문제가 없고.. 잘 안될 경우는, 버전 혹은 비트 수를 변경해서 시도해볼 필요가 있다.
참고사항
<테스트 환경> - OS : Windows 10 - Python 버전 : 3.6.5(32/64bit), 3.7.5(32bit)
'1. 연구 모듈 > Python' 카테고리의 다른 글
[Python] 키보드 후킹 - 간편화 코드 시행 착오 (0) | 2020.12.23 |
---|---|
[Python] 키보드 후킹 - 2. 간편화 코드 (0) | 2020.12.23 |
[Python] .INI 파일에 설정 읽고 쓰기 - 2. 간편화 코드 (0) | 2020.12.18 |
[Python] .INI 파일에 설정 읽고 쓰기 - 1. 예제 코드 (0) | 2020.10.16 |
[Python] 인스턴스 메소드 vs. 정적 메소드 vs. 클래스 메소드 요약 (0) | 2020.09.21 |