News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Catching global keystrokes ?

Started by gelatine1, June 22, 2014, 02:32:37 AM

Previous topic - Next topic

gelatine1

How to write a program that catches the global keystrokes ? (it also catches the keystrokes even if that window does not have the focus)

Can it be done with a normal messageloop ? (I mean something like below)

mov eax,uMsg
cmp eax,WM_GLOBALKEYDOWN
...

dedndave

there are a number of ways to read the keyboard

but, it sounds like you want to use a hook....

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx

gelatine1

Do I have to make my own dll for that ?

dedndave

oh no - you have to write a hook procedure

let me see if i can find an example.....


gelatine1

I did just as you did in the example and I changed the code but it seems like it doesnt catch the keystrokes anyway.
I run the program from the command line and my window pops up, i minimize it and I go back to the command line and there I type something but the program doesn't notice I wrote something. Why is this ? Am I missing something ?
A part of my code below:

WinMain proc:

invoke GlobalAlloc,GHND,BUFFER_SIZE
mov hmem,eax

invoke GlobalLock,hmem
mov pmem,eax

invoke GetCurrentThreadId
invoke SetWindowsHookEx,WH_KEYBOARD,KeyboardProc,NULL,eax
mov [hhk],eax

__MessageLoop:
invoke GetMessage,Addr msg,NULL,0,0
cmp eax,0
jz __BreakMessageLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp __MessageLoop

__BreakMessageLoop:
invoke UnhookWindowsHookEx,hhk

invoke GlobalUnlock,hmem
invoke GlobalFree,hmem

invoke ExitProcess, msg.wParam


KeyBoardProc:

KeyboardProc proc nCode:SDWORD,wParam:WPARAM,lParam:LPARAM

test    nCode,80000000h
jz      __kproc0

INVOKE  CallNextHookEx,hhk,nCode,wParam,lParam
ret

__kproc0:
mov eax,wParam

mov ecx,[pmem]
mov edx,[bytesToWrite]
mov dword ptr [ecx +edx],eax
inc edx
mov [bytesToWrite],edx
cmp edx,BUFFER_SIZE
jnz __kproc1

invoke AppendFile ; my own written procedure to append the data in pmem to a file

__kproc1: ret

KeyboardProc endp

dedndave

that may not have been the best example of a KeyboardProc

i wrote that a few years ago
but - i seem to recall that the hook procedure should always exit via CallNextHookEx
so - the part where i use RET is not so good   :(

before you start writing to files - try a Beep or something to get it going

gelatine1

A beep ? what exactly do you mean ?

dedndave

http://msdn.microsoft.com/en-us/library/windows/desktop/ms644984%28v=vs.85%29.aspx

QuoteIf code is less than zero, the hook procedure must return the value returned by CallNextHookEx.

If code is greater than or equal to zero, and the hook procedure did not process the message, it is highly recommended that you call CallNextHookEx and return the value it returns; otherwise, other applications that have installed WH_KEYBOARD hooks will not receive hook notifications and may behave incorrectly as a result. If the hook procedure processed the message, it may return a nonzero value to prevent the system from passing the message to the rest of the hook chain or the target window procedure.

by "less than zero", they mean that the sign bit of nCode is set (bit 31)

anyways - for testing you can try something like this
it will let you know if your hook is working

KeyboardProc proc nCode:SDWORD,wParam:WPARAM,lParam:LPARAM

        INVOKE  Beep,800,30

INVOKE  CallNextHookEx,hhk,nCode,wParam,lParam
ret

KeyboardProc endp

gelatine1

This beep function does not really work for me. I tried to use it outside the hook function but it didn't work either. I checked the debugger and right after calling the beep function LastErr changes from ERROR_SUCCES to C0000008. There is no errorcode for this so I have no clue what this means and the value of eax is 1 and as I have read this means no error happened. What's going wrong ? This is what I read about the Beep function:

Quote
If the function succeeds, the return value is nonzero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.

RuiLoureiro

and
           invoke      MessageBeep, MB_ICONASTERISK ; (or MB_ICONHAND. ...)
works ?

Vortex

Hi gelatine1,

Tutorial 24: Windows Hooks :

http://win32assembly.programminghorizon.com/tut24.html

dedndave

yah - sorry about that
Beep is not supported under Vista   :(
you can use MessageBeep, as Rui suggested

but, i would use...
        INVOKE  MessageBeep,-1

just a beep - no control over the tone or duration
with other values, i think you get a MessageBox

hutch--

gelatine1,

Tell us this much, why do you need to globally hook keystrokes ? We have to be careful with questions of this type as it can be misused by the idiot fringe for keyloggers and the like.

gelatine1

Yes, Hutch in fact that was exactly what I was making. I set it for myself as goal/project to work on simply because I had no other ideas. I have learned already pretty much now on my way there such as memory and file management and now I'm learning about those hooks to. (I'm a slow learner though)

I was not planning to use this in any inappropriate way, I just need a project or goal to learn from instead of just small exercises or anything but although I understand your concerns so I believe I should change my project to something else but I wouldn't have a clue to what. Maybe any of you guys could tell me some project I could work on ? (not too big)

Thanks in advance
Jannes