The MASM Forum

General => The Campus => Topic started by: gelatine1 on June 22, 2014, 02:32:37 AM

Title: Catching global keystrokes ?
Post by: gelatine1 on June 22, 2014, 02:32:37 AM
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
...
Title: Re: Catching global keystrokes ?
Post by: dedndave on June 22, 2014, 02:36:22 AM
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 (http://msdn.microsoft.com/en-us/library/windows/desktop/ms644990%28v=vs.85%29.aspx)
Title: Re: Catching global keystrokes ?
Post by: gelatine1 on June 22, 2014, 03:18:16 AM
Do I have to make my own dll for that ?
Title: Re: Catching global keystrokes ?
Post by: dedndave on June 22, 2014, 03:23:48 AM
oh no - you have to write a hook procedure

let me see if i can find an example.....
Title: Re: Catching global keystrokes ?
Post by: dedndave on June 22, 2014, 03:25:41 AM
http://www.masmforum.com/board/index.php?topic=16480.msg136801#msg136801 (http://www.masmforum.com/board/index.php?topic=16480.msg136801#msg136801)
Title: Re: Catching global keystrokes ?
Post by: gelatine1 on June 22, 2014, 04:12:06 AM
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
Title: Re: Catching global keystrokes ?
Post by: dedndave on June 22, 2014, 05:48:36 AM
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
Title: Re: Catching global keystrokes ?
Post by: gelatine1 on June 22, 2014, 05:53:38 AM
A beep ? what exactly do you mean ?
Title: Re: Catching global keystrokes ?
Post by: dedndave on June 22, 2014, 06:17:30 AM
http://msdn.microsoft.com/en-us/library/windows/desktop/ms644984%28v=vs.85%29.aspx (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
Title: Re: Catching global keystrokes ?
Post by: gelatine1 on June 22, 2014, 07:02:38 AM
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.
Title: Re: Catching global keystrokes ?
Post by: RuiLoureiro on June 22, 2014, 07:13:53 AM
and
           invoke      MessageBeep, MB_ICONASTERISK ; (or MB_ICONHAND. ...)
works ?
Title: Re: Catching global keystrokes ?
Post by: Vortex on June 22, 2014, 07:28:36 AM
Hi gelatine1,

Tutorial 24: Windows Hooks :

http://win32assembly.programminghorizon.com/tut24.html
Title: Re: Catching global keystrokes ?
Post by: dedndave on June 22, 2014, 07:39:55 AM
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
Title: Re: Catching global keystrokes ?
Post by: hutch-- on June 22, 2014, 12:22:13 PM
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.
Title: Re: Catching global keystrokes ?
Post by: gelatine1 on June 22, 2014, 04:43:57 PM
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
Title: Re: Catching global keystrokes ?
Post by: jj2007 on June 22, 2014, 06:05:22 PM
Quote from: gelatine1 on June 22, 2014, 04:43:57 PMMaybe any of you guys could tell me some project I could work on ? (not too big)

Hi Jannes,

Logging keystrokes does indeed trigger an alarm, for the site owner and all those who want this site to remain open, so it might be better if you ask your questions via PM ;-)

Re projects, think of everything you need for your own use. An agenda, a database handling your personal belongings? A little editor? Programming tools? Many of us here have their own editors, libraries etc, although the only library that is really in widespread use is Masm32 itself.

You could also dive into the fascinating world of COM, or learn how to write complex macros. There is no lack of challenges...
Title: Re: Catching global keystrokes ?
Post by: gelatine1 on June 22, 2014, 06:38:00 PM
I might try to make my own editor something like notepad :) No syntax highlighting though so I guess it won't be actually helpful to use it but I believe it could be a good project for me.

But what did you mean with programming tools ? And what is this fascinating world of COM ? I assume you meant this? http://en.wikipedia.org/wiki/Component_Object_Model (http://en.wikipedia.org/wiki/Component_Object_Model)

And do you have any example of a complex macro ?
Title: Re: Catching global keystrokes ?
Post by: jj2007 on June 22, 2014, 07:59:52 PM
Quote from: gelatine1 on June 22, 2014, 06:38:00 PM
I might try to make my own editor something like notepad :) No syntax highlighting though so I guess it won't be actually helpful to use it but I believe it could be a good project for me.
TinyIDE is a 7.0 kBytes editor that offers a little bit more than Notepad... (http://masm32.com/board/index.php?topic=103.0)

QuoteBut what did you mean with programming tools ? And what is this fascinating world of COM ? I assume you meant this? http://en.wikipedia.org/wiki/Component_Object_Model (http://en.wikipedia.org/wiki/Component_Object_Model)
With COM, you can use built-in Windows functions. For example, with a handful of lines, you can launch a browser window.

QuoteAnd do you have any example of a complex macro ?
See deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019) - I could not live without that one ;-)

qWord has a remarkable set of math functions as macros - check his signature.
Title: Re: Catching global keystrokes ?
Post by: dedndave on June 22, 2014, 11:53:55 PM
for projects, just browse through the masm32\examples programs
when you see something you'd like to learn about - give it a try   :P

with windows, there are thousands of functions to learn about
so, as Jochen mentioned, there is no lack of challenges

if you want suggestions...
make a simple window app
then......
http://msdn.microsoft.com/en-us/library/dd162759%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd162759%28v=vs.85%29.aspx)
that'll keep you busy all summer   :P
Title: Re: Catching global keystrokes ?
Post by: Gunther on June 22, 2014, 11:58:45 PM
Dave,

Quote from: dedndave on June 22, 2014, 11:53:55 PM
if you want suggestions...
make a simple window app
then......
http://msdn.microsoft.com/en-us/library/windows/desktop/dd162759%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/dd162759%28v=vs.85%29.aspx)

always a good starting point.

Gunther
Title: Re: Catching global keystrokes ?
Post by: gelatine1 on June 23, 2014, 10:04:43 PM
Quote from: dedndave on June 22, 2014, 11:53:55 PM
if you want suggestions...
make a simple window app
then......
http://msdn.microsoft.com/en-us/library/dd162759%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/dd162759%28v=vs.85%29.aspx)
that'll keep you busy all summer   :P

Thanks! It seems interesting and I'm reading it through right now.  I've never actually used the WM_PAINT message and those functions related to it so I assume it will be very nice to read.

And I finally finished my exams! today I had my last one :D
Title: Re: Catching global keystrokes ?
Post by: dedndave on June 24, 2014, 02:57:38 AM
search the forum for "BeginPaint" (especially the old forum) - you'll find a lot of info
you can also play with windows controls....
http://msdn.microsoft.com/en-us/library/windows/desktop/bb773173%28v=vs.85%29.aspx (http://msdn.microsoft.com/en-us/library/windows/desktop/bb773173%28v=vs.85%29.aspx)

that's things like buttons, checkboxes, edit boxes, and so on