AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

WinEventHook example...
Goto page 1, 2, 3, 4, 5, 6  Next
 
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions
View previous topic :: View next topic  
Author Message
JGR



Joined: 15 Jun 2006
Posts: 52
Location: Unavailable until ~30th August

PostPosted: Sun May 20, 2007 9:49 am    Post subject: WinEventHook example... Reply with quote

The archive contains a small sample AHK script which uses a tiny DLL file loaded only into the AHK process to hook certain system events.
ie. window creation/deletion, menu navigation, alt-tab, selection changes, scrolling, window activation, foreground, etc., by using the SetWinEventHook function as found here: http://msdn2.microsoft.com/en-us/library/ms696160.aspx
The SendMessage function is used to inform the script, where lParam points to the hook callback function parameters on stack.

http://www.autohotkey.net/~JGR/wineventhook.rar

I first tried CBT hooks but overall things were flaky and unreliable...

I am also writing a multiple generic callback DLL, but the code is in such a mess as I tried to integrate a CBT hook into the same DLL, that I'm not going to post it now. It is mostly untested and needs fixing...

JGR
Back to top
View user's profile Send private message
SKAN



Joined: 26 Dec 2005
Posts: 5581

PostPosted: Sun May 20, 2007 10:03 am    Post subject: Reply with quote

I have been waiting for something like this for a long time and much excited to see this.

Many Thanks!.

I downloaded and tried and the script prompts a missing "GetDeRefInteger()"

Please look into it.

Smile

PS: Wow! The DLL is just 2.52KB and can be easily included in an uncompiled script! Very Happy
Back to top
View user's profile Send private message
JGR



Joined: 15 Jun 2006
Posts: 52
Location: Unavailable until ~30th August

PostPosted: Sun May 20, 2007 10:10 am    Post subject: Reply with quote

I'm sure that I got it of of these forums or the AHK manual or something, but I can't find it now: so here it is, with it's accompanying functions:

Code:
InsertInteger(pInteger, ByRef pDest, pOffset = 0, pSize = 4)
; The caller must ensure that pDest has sufficient capacity.  To preserve any existing contents in pDest,
; only pSize number of bytes starting at pOffset are altered in it.
{
   Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
      DllCall("RtlFillMemory", UInt, &pDest + pOffset + A_Index-1, UInt, 1, UChar, pInteger >> 8*(A_Index-1) & 0xFF)
}

ExtractInteger(ByRef pSource, pOffset = 0, pIsSigned = false, pSize = 4)
; pSource is a string (buffer) whose memory area contains a raw/binary integer at pOffset.
; The caller should pass true for pSigned to interpret the result as signed vs. unsigned.
; pSize is the size of PSource's integer in bytes (e.g. 4 bytes for a DWORD or Int).
; pSource must be ByRef to avoid corruption during the formal-to-actual copying process
; (since pSource might contain valid data beyond its first binary zero).
{
   Loop %pSize%  ; Build the integer by adding up its bytes.
      result += *(&pSource + pOffset + A_Index-1) << 8*(A_Index-1)
   if (!pIsSigned OR pSize > 4 OR result < 0x80000000)
      return result  ; Signed vs. unsigned doesn't matter in these cases.
   ; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart:
   return -(0xFFFFFFFF - result + 1)
}


GetDeRefInteger(pSource, pIsSigned = false, pSize = 4)
; pSource is an integer pointer to a raw/binary integer
; The caller should pass true for pSigned to interpret the result as signed vs. unsigned.
; pSize is the size of PSource's integer in bytes (e.g. 4 bytes for a DWORD or Int).
{
   Loop %pSize%  ; Build the integer by adding up its bytes.
      result += *(pSource + A_Index-1) << 8*(A_Index-1)
   if (!pIsSigned OR pSize > 4 OR result < 0x80000000)
      return result  ; Signed vs. unsigned doesn't matter in these cases.
   ; Otherwise, convert the value (now known to be 32-bit) to its signed counterpart:
   return -(0xFFFFFFFF - result + 1)
}

SetDeRefInteger(pInteger, pDest, pSize = 4)
; The caller must ensure that *pDest has sufficient capacity and that pDest is a valid dereferencable integer pointer.
; To preserve any existing contents at *pDest, only pSize number of bytes are altered.
{
   Loop %pSize%  ; Copy each byte in the integer into the structure as raw binary data.
      DllCall("RtlFillMemory", UInt, pDest + A_Index-1, UInt, 1, UChar, pInteger >> 8*(A_Index-1) & 0xFF)
}
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3593
Location: Belgrade

PostPosted: Sun May 20, 2007 3:35 pm    Post subject: Reply with quote

Extraordinary work, thx.

So, does CBT hook works OK or not ?
_________________
Back to top
View user's profile Send private message MSN Messenger
JGR



Joined: 15 Jun 2006
Posts: 52
Location: Unavailable until ~30th August

PostPosted: Sun May 20, 2007 4:29 pm    Post subject: Reply with quote

The CBT hook only appeared to work on certain processes (not including explorer), I also managed to temporarily lock up my system while debugging it. The DLL has to be injected into all processes to work properly. Only about half of my running processes got injected.

The fact that the DLL is spread across multiple contexts introduces lots of headaches. I even needed to use a mutex...

I'm not going to continue working on the CBT hook, as it is too much of a pain, and didn't work well anyway... (A dodgy AHK script could bring the system to its knees quite easily)

JGR
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3593
Location: Belgrade

PostPosted: Sun May 20, 2007 4:49 pm    Post subject: Reply with quote

Injection is not the problem. There are thousand of ways.

If it works correctly in those half its OK.

You can test your hook if you set your dll to be loaded in all processes via 1 registry key (cant recall the name atm). That is one of the ways and it is limited as dll is loaded in all processes on next start up.

Quote:
I am also writing a multiple generic callback DLL, but the code is in such a mess as I tried to integrate a CBT hook into the same DLL
Good idea.
_________________
Back to top
View user's profile Send private message MSN Messenger
JGR



Joined: 15 Jun 2006
Posts: 52
Location: Unavailable until ~30th August

PostPosted: Sun May 20, 2007 5:02 pm    Post subject: Reply with quote

As for the automatic injection, I tried that, the key is: HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs. That didn't work either.

The callback DLL is done now and is here (with hooks un-integrated): http://www.autohotkey.com/forum/viewtopic.php?t=19370

I'll post the hook dll (it should work with any of the windows hooks). Code to use it is clearly commented out in the archive in the first post.
I won't be making any more changes to it...

http://www.autohotkey.net/~JGR/cbthook.rar

JGR
Back to top
View user's profile Send private message
majkinetor



Joined: 24 May 2006
Posts: 3593
Location: Belgrade

PostPosted: Sun May 20, 2007 5:10 pm    Post subject: Reply with quote

I will test it during next week and tell you what I think.

Thx again.
_________________
Back to top
View user's profile Send private message MSN Messenger
Supercalifragilistic
Guest





PostPosted: Sun May 20, 2007 5:31 pm    Post subject: Reply with quote

Sorry if I distrub the genius corner Very Happy Very Happy Very Happy
But I'm a noob in hooking. I know what the hooking process is supposed to do, but ... what is the purpose of your prog ?
I seen that AppsKey and End stops the hooking process, but I didn't seen what it does.
How your prog works ? What does it do ?
Is there a working example ?
What are the events which are hooked ?
More explanations, please....
Back to top
JGR



Joined: 15 Jun 2006
Posts: 52
Location: Unavailable until ~30th August

PostPosted: Sun May 20, 2007 5:43 pm    Post subject: Reply with quote

The posted example displays a debug message whenever a (sub)window is created or sent to the foreground.
To see it you will need a debug viewer like this one, or just change the code to something more obvious, like FileWrite. (Don't try messagebox, you'll regret it).

It doesn't actually do anything useful at the moment per se, the idea is that you write the functional bit yourselves.

As for how it works: See here. The callback function is in the dll, and sends AHK a message, with a pointer to the parameters of the callback in lParam.

My advice, is that you read carefully about hooking before trying to use it. As if you're not careful, your system will take a *huge* performance hit/hanging.
Back to top
View user's profile Send private message
Supercalifragilistic
Guest





PostPosted: Sun May 20, 2007 7:55 pm    Post subject: Reply with quote

I'd tried your script with DebugView and ... I did not seen anything (I tried to open a sub-window by open a file in PSPad). It's probably too clever for me. Anyways, thanks for the explanations.
Back to top
majkinetor



Joined: 24 May 2006
Posts: 3593
Location: Belgrade

PostPosted: Mon May 21, 2007 8:33 am    Post subject: Reply with quote

What is the difference between SetEvenHook and SetWindowsHookEx

I never heard until today for the first one.

BTW, you should probably create better example with more clear hook unloading. Currently if you don't press a hotkey that says nothing, hook never gets unloaded.
_________________


Last edited by majkinetor on Mon May 21, 2007 10:22 am; edited 1 time in total
Back to top
View user's profile Send private message MSN Messenger
majkinetor



Joined: 24 May 2006
Posts: 3593
Location: Belgrade

PostPosted: Mon May 21, 2007 8:38 am    Post subject: Reply with quote

Argh, I see... SetWinEventHook is acctually wrapper itself of Active Accessibility
_________________
Back to top
View user's profile Send private message MSN Messenger
majkinetor



Joined: 24 May 2006
Posts: 3593
Location: Belgrade

PostPosted: Mon May 21, 2007 10:12 am    Post subject: Reply with quote

This is working example:


Code:
DetectHiddenWindows, On
   event :=  0x00008000   ;EVENT_OBJECT_CREATE
   hwnd:=WinExist("ahk_pid " . DllCall("GetCurrentProcessId","Uint"))
   msg := 0x550
   hook_dll = wineventhook\wineventhook.dll

   hHookModule := API_LoadLibrary(hook_dll)
   hHook := Hook(hwnd, msg, event, event, "HookHandler")
return

!e:
   Msgbox % "Unhook: " Unhook(hHook,msg)
return
   
HookHandler(wParam, lParam, msg, hwnd) {
   msgbox Hello from hook

}

Hook(comm_hwnd, comm_msg, s_event, e_event, function, wparam=0) {
   global hook_dll
   
   r := DllCall(hook_dll "\reghook", "UInt", comm_hwnd, "UInt", COMM_MSG, "UInt", s_event, "UInt", e_event, "UInt", wparam)
   if !r
      return 0

   OnMessage(COMM_MSG, function)
   return r
}

Unhook(handle, com_msg) {
   OnMessage(com_msg)
   return DllCall("UnhookWinEvent", "UInt", handle)
}

API_LoadLibrary( dll ) {
   return DllCall("LoadLibrary", "str", dll)
}


_________________
Back to top
View user's profile Send private message MSN Messenger
new_noobie
Guest





PostPosted: Mon May 21, 2007 10:22 am    Post subject: Reply with quote

Can anyone say for sure wheather this will work on win9x systems. I don't
have access to my XP box right now, so I tried the "EnumWindows.ahk" script
included in JGR's archive and corrupt's post in this thread, and they both
produce a message box with no output (well corrupt's shows Output1 and
Output2 without and data).

I did look at the msdn link given in the "WinEventHook example..." thread in
this forum and it says that SetWinEventHook is supported in win98 and later.
The box I tried the examples on is win98se. Can anyone show me what might be
needed to get it to work?

@JGR, can the dll be made to function on win9x if it does not now?

thx
Back to top
Display posts from previous:   
Post new topic   Reply to topic    AutoHotkey Community Forum Index -> Scripts & Functions All times are GMT
Goto page 1, 2, 3, 4, 5, 6  Next
Page 1 of 6

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group