import ctypes
import ctypes.wintypes
import win32con
import pythoncom
import atexit
user32 = ctypes.windll.user32
kernel32 = ctypes.windll.kernel32
# Constants
WH_KEYBOARD_LL = 13
WH_MOUSE_LL = 14
WM_KEYDOWN = 0x0100
LLKHF_INJECTED = 0x10
LLKHF_LOWER_IL_INJECTED = 0x02
LLMHF_INJECTED = 0x01
LLMHF_LOWER_IL_INJECTED = 0x02
# Structures
class (ctypes.Structure):
_fields_ = [
("vkCode", ctypes.wintypes.DWORD),
("scanCode", ctypes.wintypes.DWORD),
("flags", ctypes.wintypes.DWORD),
("time", ctypes.wintypes.DWORD),
("dwExtraInfo", ctypes.POINTER(ctypes.wintypes.ULONG)),
]
class MSLLHOOKSTRUCT(ctypes.Structure):
_fields_ = [
("pt", ctypes.wintypes.POINT),
("mouseData", ctypes.wintypes.DWORD),
("flags", ctypes.wintypes.DWORD),
("time", ctypes.wintypes.DWORD),
("dwExtraInfo", ctypes.POINTER(ctypes.wintypes.ULONG)),
]
# Keyboard callback
def low_level_keyboard_proc(nCode, wParam, lParam):
if nCode == win32con.HC_ACTION:
kbd = ctypes.cast(lParam, ctypes.POINTER(KBDLLHOOKSTRUCT)).contents
flags = kbd.flags
injected = bool(flags & LLKHF_INJECTED)
lower_il = bool(flags & LLKHF_LOWER_IL_INJECTED)
print(f"[KEY] VKCode: {kbd.vkCode} | Injected: {injected} | Lower IL: {lower_il}")
return user32.CallNextHookEx(None, nCode, wParam, lParam)
# Mouse callback
def low_level_mouse_proc(nCode, wParam, lParam):
if nCode == win32con.HC_ACTION:
mouse = ctypes.cast(lParam, ctypes.POINTER(MSLLHOOKSTRUCT)).contents
flags = mouse.flags
injected = bool(flags & LLMHF_INJECTED)
lower_il = bool(flags & LLMHF_LOWER_IL_INJECTED)
print(f"[MOUSE] Event: {wParam} | Injected: {injected} | Lower IL: {lower_il}")
return user32.CallNextHookEx(None, nCode, wParam, lParam)
# Function pointer definitions
CMPFUNC_KBD = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.wintypes.WPARAM, ctypes.wintypes.LPARAM)
CMPFUNC_MOUSE = ctypes.WINFUNCTYPE(ctypes.c_int, ctypes.c_int, ctypes.wintypes.WPARAM, ctypes.wintypes.LPARAM)
keyboard_pointer = CMPFUNC_KBD(low_level_keyboard_proc)
mouse_pointer = CMPFUNC_MOUSE(low_level_mouse_proc)
# Set hooks
keyboard_hook = user32.SetWindowsHookExA(WH_KEYBOARD_LL, keyboard_pointer, kernel32.GetModuleHandleW(None), 0)
mouse_hook = user32.SetWindowsHookExA(WH_MOUSE_LL, mouse_pointer, kernel32.GetModuleHandleW(None), 0)
# Cleanup on exit
atexit.register(user32.UnhookWindowsHookEx, keyboard_hook)
atexit.register(user32.UnhookWindowsHookEx, mouse_hook)
# Start message loop
pythoncom.PumpMessages()