|
-
Jan 6th, 2003, 10:05 AM
#1
Question about hooking....
Can someone provide me with some insight or code that will explain to me a little more about hooking a window?
basically this is my goal.. i want to hook a window to a program that is not one of my applications and view all the windows messages that are sent to it... i would have the class name or window handle of the target window... how could this be accomplished?
-
Jan 6th, 2003, 10:25 AM
#2
Frenzied Member
There are two types of windows hook that will be of use:- WH_CALLWNDPROC which is triggered whenever a message is added to a window's message queue using Sendmessage and the WH_GETMESSAGE hook type which is triggered whenever a window takes a messager off the queue using GetMessage or PeekMessage.
Unfortunately, these are very difficult to implement safely in VB.
-
Jan 6th, 2003, 10:34 AM
#3
merrion, can you give an example of their use?
and if possible can you explain their instability in VB?
-
Jan 6th, 2003, 10:55 AM
#4
Frenzied Member
Code hacked out of the EventVB.dll hook implementation...may be incomplete...
VB Code:
'\\ In a .Bas module:-
Public Enum enHookTypes
WH_CALLWNDPROC = 4
WH_CBT = 5
WH_DEBUG = 9
WH_FOREGROUNDIDLE = 11
WH_GETMESSAGE = 3
WH_HARDWARE = 8
WH_JOURNALPLAYBACK = 1
WH_JOURNALRECORD = 0
WH_MOUSE = 7
WH_MSGFILTER = (-1)
WH_SHELL = 10
WH_SYSMSGFILTER = 6
WH_KEYBOARD_LL = 13
WH_MOUSE_LL = 14
WH_KEYBOARD = 2
End Enum
Private Declare Function SetWindowsHookEx Lib "user32" Alias "SetWindowsHookExA" (ByVal idHook As enHookTypes, ByVal lpfn As Long, ByVal hMod As Long, ByVal dwThreadId As Long) As Long
Private Declare Function UnhookWindowsHookEx Lib "user32" (ByVal hHook As Long) As Long
Private Declare Function CallNextHookEx Lib "user32" (ByVal hHook As Long, ByVal ncode As Long, ByVal wParam As Long, lParam As Any) As Long
Private Type msg
hwnd As Long
Message As Long
wParam As Long
lParam As Long
time As Long
pt As Long 'MSG
End Type
Private Declare Sub CopyMemoryMSG Lib "kernel32" Alias "RtlMoveMemory" (Destination As msg, ByVal Source As Long, ByVal Length As Long)
'\\ [VB_HOOKGETMESSAGEPROC]------------------------------------------
'\\ typedef LRESULT (CALLBACK* HOOKPROC)(int code, WPARAM wParam, LPARAM lParam);
'\\ code - hook action,
'\\ Wparam, Lparam - message specific
'\\ --------------------------------------------------------------------------------
'\\ (c) 2001 - Merrion Computing.
'\\ Please check [url]http://www.merrioncomputing.com[/url] for updates.
'\\ -------------------------------------------------------------------------------
Public Function VB_HOOKGETMESSAGEPROC(ByVal Code As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
On Local Error Resume Next
'\\ Note: If the code passed in is less than zero, it must be passed direct to the next hook proc
If Code < 0 Then
VB_HOOKGETMESSAGEPROC = CallNextHookEx(lHookId, Code, wParam, lParam)
Exit Function
End If
'\\ Process the message here...
Dim msgIn As MSG
If CopyMemoryMSG(msgIn, lParam, len(msgIn)) Then
Debug.Print Hex(msgIn.Message) & " processed by window " & msgIn.hwnd
End If
lret = CallNextHookEx(lHookId, Code, wParam, lParam)
'\\ If the message isn't cancelled, return the next hook's message...
If lMsgRet = 0 Then
'\\ Return value to calling code....
VB_HOOKGETMESSAGEPROC = lret
Else
VB_HOOKGETMESSAGEPROC = lMsgRet
End If
End Function
...more to follow...
-
Jan 6th, 2003, 11:00 AM
#5
Frenzied Member
See this article on how to install global hooks...
-
Jan 6th, 2003, 11:05 AM
#6
thanks.. unfortunatly this is for something i am working on at home.. so i will have to wait till after work to try it out!
-
Jan 6th, 2003, 11:16 AM
#7
Frenzied Member
I have been working on this for the EventVB.dll...
So far I can get a thread-wide message hook thus:
VB Code:
Option Explicit
Dim WithEvents vbLink As EventVB.APIFunctions
Dim WithEvents vbHook As EventVB.ApiSystemHook
Private Sub Form_Load()
Set vbLink = New APIFunctions
Set vbHook = vbLink.System.Hooks
vbHook.StartHook WH_GETMESSAGE, HOOK_LOCAL_PROCESS
End Sub
Private Sub vbHook_AnyWindowMessageHandled(ByVal TargetWnd As EventVB.ApiWindow, ByVal Removed As Boolean, msg As EventVB.WindowMessages, wParam As Long, lParam As Long)
Debug.Print TargetWnd.WindowText & " received message " & msg
End Sub
But if I change HOOK_LOCAL_PROCESS to HOOK_GLOBAL it only receives one message, which it erroneously says is message #4110, then unhooks itself. I can only presume that the CopyMemory needs to be replaced with a call to ReadProcessmemory, but can't figure out what process the hook is being called from before getting the MSG structure.....
-
Jan 7th, 2003, 08:19 AM
#8
Frenzied Member
Did you get anywhere with this?
I'm thinking a small C++ dll for the global hook with a callback function for your VB app to use might be the best way forward.
-
Jan 7th, 2003, 08:24 AM
#9
Originally posted by MerrionComputin
Did you get anywhere with this?
I'm thinking a small C++ dll for the global hook with a callback function for your VB app to use might be the best way forward.
merrion.. unfortunatly i got tied up and couldn't work on it last night... but this is a high priority application that i want to make..
i have little knowledge of programmming in C so I am hoping it can be done via VB...
basically I am working on a plug in for AOL Instant Messanger.. and I need to know when an IM is receieved.. i have found code on PSC and such to manipulate AIM but they were really nothing more than a bunch of API calls to find the window, send text to it etc.. i want to hook the AIM window to find out when incoming messages are actually recieved.. and have not found any code to do this.. thats why i am trying it on my own... i figure a message has to be processed telling it to send a message to the window..
-
Jan 7th, 2003, 08:35 AM
#10
Let me in ..
Originally posted by MerrionComputin
Did you get anywhere with this?
I'm thinking a small C++ dll for the global hook with a callback function for your VB app to use might be the best way forward.
You cannot do this in VB, Can you ? I thought you need global hook which can only be installed inside a standard DLL. You cannot make standard Dll's in VB.
-
Jan 7th, 2003, 08:50 AM
#11
Frenzied Member
I thought you need global hook which can only be installed inside a standard DLL
This is true but I'm not so sure a global hook is required. Instead you can (possibly) convince the third party application to load your VB dll in it's thread context and install a thread local hook (which you can write in VB no problem).
-
Jan 7th, 2003, 09:18 AM
#12
Let me in ..
Originally posted by MerrionComputin
This is true but I'm not so sure a global hook is required. Instead you can (possibly) convince the third party application to load your VB dll in it's thread context and install a thread local hook (which you can write in VB no problem).
Geez, I'd like to know how to do that, if you do not mind telling us.
-
Jan 7th, 2003, 10:25 AM
#13
Frenzied Member
DLL Injection method 1: Only works for Windows NT4 or above...
First you need to open a handle to the remote process that has appropriate access rights to write to that processes' own virtual memory. You do this with the OpenProcess API call specifying PROCESS_VM_WRITE and PROCESS_CREATE_THREAD flags.
VB Code:
Public Enum ProcessAccessRights
PROCESS_TERMINATE = &H1
PROCESS_CREATE_THREAD = &H2
PROCESS_VM_OPERATION = &H8
PROCESS_VM_READ = &H10
PROCESS_VM_WRITE = &H20
PROCESS_DUP_HANDLE = &H40
PROCESS_CREATE_PROCESS = &H80
PROCESS_SET_QUOTA = &H100
PROCESS_SET_INFORMATION = &H200
PROCESS_QUERY_INFORMATION = &H400
End Enum
Public Declare Function OpenProcess Lib "kernel32" ( _
ByVal dwDesiredAccess As ProcessAccessRights, _
ByVal bInheritHandle As Long, _
ByVal Processid As Long) As Long
Public Declare Function CloseHandle Lib "kernel32" (ByVal HandleIn As Long) As Long
Then you need to allocate a page in the memory of the target process which will hold the DLL by using the VirtualAllocEx API call:
VB Code:
Public Enum VirtualMemoryAllocationTypes
MEM_COMMIT = &H1000
MEM_RESERVE = &H2000
MEM_FREE = &H10000
MEM_PRIVATE = &H20000
MEM_MAPPED = &H40000
MEM_RESET = &H80000
MEM_TOP_DOWN = &H100000
MEM_4MB_PAGES = &H80000000
End Enum
Public Enum MemoryPageProtectionFlags
PAGE_NOACCESS = &H1
PAGE_READONLY = &H2
PAGE_READWRITE = &H4
PAGE_WRITECOPY = &H8
PAGE_EXECUTE = &H10
PAGE_EXECUTE_READ = &H20
PAGE_EXECUTE_READWRITE = &H40
PAGE_EXECUTE_WRITECOPY = &H80
PAGE_GUARD = &H100
PAGE_NOCACHE = &H200
End Enum
Public Declare Function VirtualAllocEx Lib "kernel32" ( _
ByVal hProcess As Long, _
ByVal lpAddress As Long, _
ByVal dwSize As Long, _
ByVal flAllocationType As VirtualMemoryAllocationTypes, _
ByVal flProtect As MemoryPageProtectionFlags) As Long
And, of course, any memory so allocated must be freed again when you are done....
VB Code:
Public Enum VirtualMemoryFreeTypes
MEM_DECOMMIT = &H4000
MEM_RELEASE = &H8000
End Enum
Public Declare Function VirtualFreeEx Lib "kernel32" ( _
ByVal hProcess As Long, _
ByVal lpAddress As Long, _
ByVal dwSize As Long, _
ByVal dwFreeType As VirtualMemoryFreeTypes) As Long
Now you copy the memory that has the dll code in it in your process to the target process using the WriteProcessmemory API call:
VB Code:
Public Declare Function WriteProcessMemory Lib "kernel32" ( _
ByVal hProcess As Long, _
ByVal lpAddress As Long, _
ByVal lpSourceBuffer As Long, _
ByVal dwSize As Long, _
dwBytesWritten As Long) As Long
...continues....
-
Jan 7th, 2003, 10:27 AM
#14
Frenzied Member
...contiunued....
And you need to allocate memory and copy this for the parameters for the thread to use using the same VirtualAllocEx, WriteProcessmemory combination.
Then you make this block of memory into a thread using the CreateRemoteThread API call:
VB Code:
Public Declare Function CreateRemoteThread Lib "kernel32" ( _
ByVal hProcess As Long, _
ByVal lpSecurityAttributes As Long, _
ByVal dwStackSize As Long, _
ByVal lpThreadProc As Long, _
ByVal lpParameters As Long, _
ByVal dwCreateFlags As Long, _
lThreadId As Long) As Long
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|