The MASM Forum Archive 2004 to 2012

General Forums => The Campus => Topic started by: Ksbunker on January 27, 2007, 07:36:22 AM

Title: Mouse Hook
Post by: Ksbunker on January 27, 2007, 07:36:22 AM
My intentions are as follows. To code a program that records the location (i.e. [x,y]) of left mouse button clicks in a specific target window.

I understand all of iczelions mouse hook tute. But I am having difficulty figuring out how to make it so that only left mouse button clicks are recorded from within a specified window. *I think* i've got it so that only when the cursor is over the target window the message will get process however as for when the left mouse button is pressed, im bamboozled! ;-(

MouseProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD

.data

szTarget db "target_class", 0

.code

invoke CallNextHookEx,hHook,nCode,wParam,lParam
mov edx,lParam
assume edx:PTR MOUSEHOOKSTRUCT
invoke WindowFromPoint,[edx].pt.x,[edx].pt.y
Invoke GetClassName, eax, ADDR szClass, SIZEOF szClass
invoke lstrcmp, ADDR szTarget, ADDR szClass
cmp eax, 0
jne FIN
invoke PostMessage,hWnd,WM_MOUSEHOOK,eax,0
FIN:
assume edx:nothing
xor eax,eax
ret
MouseProc endp


...
szFormat db "(%d, %d), 0
...
.IF uMsg == WM_MOUSEHOOK

Invoke wsprintf, ADDR szBuffer, ADDR szFormat, [edi].pt.x, [edi].pt.y
Invoke SetDlgItemText, hWnd, IDC_EDIT, ADDR szBuffer

.ENDIF


The above doesn't work ;-( Puzzled
Title: Re: Mouse Hook
Post by: TomRiddle on January 27, 2007, 08:59:18 AM
Quote from: Ksbunker on January 27, 2007, 07:36:22 AM
...
szFormat db "(%d, %d), 0
...
.IF uMsg == WM_MOUSEHOOK

Invoke wsprintf, ADDR szBuffer, ADDR szFormat, [edi].pt.x, [edi].pt.y
Invoke SetDlgItemText, hWnd, IDC_EDIT, ADDR szBuffer

.ENDIF


szFormat db "(%d, %d), 0

Shouldn't there be an end quotation there?
Title: Re: Mouse Hook
Post by: MichaelW on January 27, 2007, 09:56:34 AM
In your hook procedure (MouseProc) check wParam for the mouse message WM_LBUTTONDOWN.
Title: Re: Mouse Hook
Post by: Ksbunker on January 27, 2007, 11:56:01 AM
I appreciate your help guys. Thanks a lot. However I still have several errors, must noticeably in the EXE with the WM_MOUSEHOOK command and the [edi].pt.x and [edi].pt.y     

DLL;

MouseProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD

invoke CallNextHookEx,hHook,nCode,wParam,lParam
mov edx,lParam
assume edx:PTR MOUSEHOOKSTRUCT

invoke WindowFromPoint,[edx].pt.x,[edx].pt.y

mov ebx, wParam
.IF ebx == WM_LBUTTONDOWN

  Invoke PostMessage, hWnd, WM_MOUSEHOOK, eax, 0

.ENDIF

assume edx:nothing
xor eax,eax
ret

MouseProc endp


EXE; (Fails to Assemble the EXE at line 'Invoke wsprintf...' says pt is the error. Exact message commented below)

.elseif uMsg == WM_MOUSEHOOK

Invoke wsprintf, ADDR szBuffer, ADDR szFormat, eax, [edi].pt.x, [edi].pt.y ;Error! Undefined symbol : pt
invoke SendMessage, hList, LB_ADDSTRING,0, ADDR szBuffer
Invoke SendMessage, hList, WM_VSCROLL, SB_BOTTOM, 0
Title: Re: Mouse Hook
Post by: TomRiddle on January 27, 2007, 12:17:02 PM
Okay, here is the problem, the [edx] ptr was ONLY for the DLL, what your WM_MOUSEHOOK is sending is the Window Handle that the point was on, it is located in wParam.

I assume you want the cordinates it sends?  Hmm, make an equate WM_MOUSEHOOKPOINT, check for it in the App, and have wParam contain X and lParam contain Y.  That's about how I would do it anyways.

I hope this helps.

:D

P.S. We can probably help more if you attach your code.
Title: Re: Mouse Hook
Post by: MichaelW on January 27, 2007, 09:57:19 PM
To pass the coordinates of the mouse cursor you could encode them into a DWORD (using 16 bits for each coordinate) and pass it in the lParam parameter of the PostMessage function.
Title: Re: Mouse Hook
Post by: Ksbunker on January 28, 2007, 10:49:40 AM
I wasn't fully aware of how postmessage() worked with the last two parameters and all, but now I see you can store information/data in them. So basically, the only way I can transfer information across from the dll to my exe is if I include it in either wParam or lParam?

Hopefully there will be no more posts, however thats not a promise.
Title: Re: Mouse Hook
Post by: Ksbunker on January 28, 2007, 11:16:01 AM
After further investigation with OllyDbg, it never actually breaks on my WM_MOUSEHOOK message at all!? I can't seem to find any errors. I may put this project aside untill my progress with my asm. TomRiddle, as you requested is the entire source below ;)

exe;

Quote.386
.model   flat,stdcall
option   casemap:none

include      windows.inc
include      user32.inc
include      kernel32.inc
include      shell32.inc

includelib   user32.lib
includelib   kernel32.lib
includelib   shell32.lib

WndProc      PROTO   :HWND, :DWORD, :DWORD, :DWORD

;---------------------
;
.data

DllName            db 'DLL.dll',0
szInstallHook      db 'InstallHook',0
szFormat          db "(%d, %d)", 0

;---------------------
;
.data?

hInstance   HINSTANCE   ?
pInstallHook dd ?
hHookDll dd ?
hHook dd ?
hList dd ?

;---------------------
;
.const

IDD_DIALOG = 1000
IDC_EXIT = 1001
IDC_LISTBOX = 1002
WM_MOUSEHOOK equ WM_USER+6

;---------------------
;
.code

start:

   invoke GetModuleHandle, NULL
   mov    hInstance,eax
   
   invoke DialogBoxParam, hInstance, IDD_DIALOG, NULL, OFFSET WndProc, NULL
   invoke ExitProcess, eax

WndProc   proc   hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
LOCAL szBuffer[128]:byte
      
   .if uMsg == WM_INITDIALOG
   
      INVOKE SetWindowPos, hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOACTIVATE Or SWP_NOSIZE Or SWP_NOMOVE
      
      Invoke GetDlgItem, hWnd, IDC_LISTBOX
      mov hList, eax
      
      invoke LoadLibrary,OFFSET DllName
      mov hHookDll, eax
      invoke GetProcAddress,hHookDll,OFFSET szInstallHook
      mov pInstallHook,eax
      
      call pInstallHook
      mov hHook,eax
         
   .elseif uMsg == WM_MOUSEHOOK
      
      mov eax, wParam ;[edi].pt.x
      mov ebx, lParam ;[edi].pt.y
      
      Invoke wsprintf, ADDR szBuffer, ADDR szFormat, eax, ebx   
         
      invoke SendMessage, hList, LB_ADDSTRING,0, ADDR szBuffer
      Invoke SendMessage, hList, WM_VSCROLL, SB_BOTTOM, 0
      
   .elseif   uMsg == WM_COMMAND
   
      .if wParam == IDC_EXIT
         JMP thedoor
      .endif
      
   .elseif   uMsg == WM_CLOSE
      
      thedoor:
      
      invoke FreeLibrary,hHookDll
      invoke ExitProcess, 0   
      
   .endif
   
   xor   eax,eax
   ret
   
WndProc   endp


end start

.486
.model flat,stdcall
option casemap:none

include windows.inc
include kernel32.inc
include user32.inc

includelib kernel32.lib
includelib user32.lib

MouseProc PROTO :DWORD, :DWORD, :DWORD
InstallHook PROTO :DWORD

.data?
hInstance dd ? ;Dll's module handle
hHook dd ? ;Hook handle
hWnd dd ?

.const

WM_MOUSEHOOK equ WM_USER+6

.code

DllEntry proc hInst:HINSTANCE, reason:DWORD, reserved1:DWORD
mov eax,hInst
mov hInstance,eax

.IF reason== DLL_THREAD_DETACH ||  reason== DLL_PROCESS_DETACH
.IF hHook
invoke UnhookWindowsHookEx,hHook
.ENDIF
.ENDIF

mov eax,TRUE
ret
DllEntry Endp

InstallHook proc hwnd:DWORD

push hwnd
pop hWnd

invoke SetWindowsHookEx, WH_MOUSE, OFFSET MouseProc, hInstance, 0

mov hHook,eax
ret

InstallHook endp

MouseProc proc nCode:DWORD,wParam:DWORD,lParam:DWORD

invoke CallNextHookEx,hHook,nCode,wParam,lParam
mov edx,lParam
assume edx:PTR MOUSEHOOKSTRUCT

Invoke WindowFromPoint,[edx].pt.x,[edx].pt.y

mov ebx, wParam
.IF ebx == WM_LBUTTONDOWN

            Invoke PostMessage, hWnd, WM_MOUSEHOOK, [edx].pt.x, [edx].pt.y

.ENDIF

assume edx:nothing
xor eax,eax
ret

MouseProc endp

End DllEntry
Title: Re: Mouse Hook
Post by: MichaelW on January 28, 2007, 12:20:44 PM
What about your resource definition?
Title: Re: Mouse Hook
Post by: Ksbunker on January 28, 2007, 12:38:28 PM
;This Resource Script was generated by WinAsm Studio.

#define IDC_EXIT 1001
#define IDD_DIALOG 1000
#define IDC_LISTBOX 1002

IDD_DIALOG DIALOGEX 10,10,137,101
CAPTION "WH_MOUSE Example"
FONT 0,""
STYLE 0x10ca0880
EXSTYLE 0x00000000
BEGIN
CONTROL "EXIT",IDC_EXIT,"Button",0x50010000,2,82,134,18,0x00000000
CONTROL "",IDC_LISTBOX,"ListBox",0x50010140,3,2,133,78,0x00000200
END
Title: Re: Mouse Hook
Post by: MichaelW on January 28, 2007, 09:45:19 PM
I can see three serious problems with your code:

WndProc is not preserving EBX.

The call to pInstallHook is not passing hWnd.

In MouseProc the call to WindowFromPoint is destroying the value in EDX.
Title: Re: Mouse Hook
Post by: Ksbunker on January 29, 2007, 02:12:43 AM
Much thanks to you!

Added 'push hWnd' before the call, fixed.

Removed the WindowFromPoint, fixed.

And added ..PROC uses ebx nCode:.....

However, now it appears as though only clicks from within my window get recorded. I'm sure ive read a solution to this by uer f-four somewhere on this board. Ill have a look. In the mean time, any idea on how to rectify that?
Title: Re: Mouse Hook
Post by: Ksbunker on January 30, 2007, 01:37:15 AM
As previously mentioned, the message only gets processed when a click occurs from within my program window. How can I fix this? I thought by Definition system wide hooks worked worked on the whole system, but for some reason that doesn't seem to the be case...
Title: Re: Mouse Hook
Post by: MichaelW on January 30, 2007, 07:47:16 AM
You obviously have access to the tutorial, I assumed you would find the solution.
Title: Re: Mouse Hook
Post by: Ksbunker on January 30, 2007, 08:11:18 AM
It said something about shared memory access for the hWnd dd ? and setting the shared section via link. However I didn't fully understand it.