Implementing a Windows Keylogger in Python Using ctypes and Win32 API
This tutorial explains how to build a Windows keylogger in Python by importing Win32 DLLs with ctypes, registering a low‑level keyboard hook, defining the hook procedure and data structures, and handling installation, event processing, and cleanup, while providing full source code and usage notes.
In this tutorial we demonstrate how to create a Windows keylogger (spy program) in Python, covering four main topics: Win32 API, basic Python with ctypes, C language basics, and hooking.
The program works by registering a hook to capture system events. A hook (hook function) intercepts calls before they are executed, allowing modification or termination of the message.
To register a hook we first import the DLLs using ctypes:
<code>user32 = CDLL("user32.dll")
kernel32 = CDLL("kernel32.dll")</code>user32.dll provides Windows UI functions such as creating windows and sending messages, while kernel32.dll handles memory management, I/O, and interrupt processing.
We then use SetWindowsHookExA to install a low‑level keyboard hook ( WH_KEYBOARD_LL = 13 ) that monitors keyboard input.
<code>HHOOK SetWindowsHookExA(int idHook, HOOKPROC lpfn, HINSTANCE hmod, DWORD dwThreadId);</code>The parameters are explained: idHook selects the hook type, lpfn is a pointer to the hook procedure, hmod is the module handle obtained via kernel32.GetModuleHandleW , and dwThreadId set to 0 to hook all threads on the desktop.
In Python we define the hook procedure using WINFUNCTYPE (stdcall calling convention) because we are on Windows:
<code>HOOKPROC = WINFUNCTYPE(c_int, c_int, c_int, POINTER(DWORD))</code>We also define the KBDLLHOOKSTRUCT structure to read key information:
<code>class KBDLLHOOKSTRUCT(Structure):
_fields_ = [
('vkCode', DWORD),
('scanCode', DWORD),
('flags', DWORD),
('time', DWORD),
('dwExtraInfo', DWORD)
]</code>The hook procedure checks nCode ; if it is less than zero we pass the message to CallNextHookEx , otherwise we process the key event, optionally printing characters or handling special keys such as Ctrl to uninstall the hook.
Installation and removal functions are provided:
<code>def installHookProc(hooked, pointer):
hooked = user32.SetWindowsHookExA(13, pointer, kernel32.GetModuleHandleW(), 0)
return hooked is not None
def uninstallHookProc(hooked):
if hooked:
user32.UnhookWindowsHookEx(hooked)
hooked = None</code>The main loop calls user32.GetMessageA to keep the hook alive until the program exits or the hook is uninstalled.
Finally the full script is presented, and an example screenshot of the keylogger output is shown. The article notes that additional features such as data transmission or screen capture can be added.
Python Programming Learning Circle
A global community of Chinese Python developers offering technical articles, columns, original video tutorials, and problem sets. Topics include web full‑stack development, web scraping, data analysis, natural language processing, image processing, machine learning, automated testing, DevOps automation, and big data.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.