Tutorials to .com

Tutorials to .com » Software » Asm » WIN32 compilation: 24.WINDOWS hook function

WIN32 compilation: 24.WINDOWS hook function

Print View , by: iSee ,Total views: 25 ,Word Count: 4434 ,Date: Wed, 6 May 2009 Time: 7:04 PM

The twenty-fourth Division WINDOWS hook function


This lesson we will learn from WINDOWS to use the hook function. WINDOWS hook function is very powerful, you can detect it with other processes and other processes to change behavior.

Theory:

WINDOWS of the hook function can be regarded as one of the main features of WINDOWS. Use them, you can capture your own or other process in the process of events. Through the "hanging hook", you can give a treatment or filtration WINDOWS event callback function, which is also called the "hook function", when each of the events you are interested, WINDOWS will call the function. There are two types of hooks: local and remote.
  • Local hook hanging hook only process your own events.
  • Remote hook can also be linked to other processes hook events. And two remote hook:
    • It will catch on in other threads process the events of a particular thread. In short, that can be used to observe the other in the process of a particular thread of the events will occur.
    • System-wide system to capture all the process will be news events.
Hook function is installed will affect the performance of the system. Monitoring "system event" is particularly evident Hook. Because the system in dealing with all the related events will be called when your hook function, so that your system will be marked down. Therefore, should be used with caution, and immediately after unloading. Also, since you can advance the process of interception of other information, so once you hook function if the problem is bound to affect the other process. Remember: a powerful means that when used responsibly.
Hook function in the proper use, we first explain the working principle of the hook function. When you create a hook when, WINDOWS will be in memory to create a data structure, the data structure contains information hook, and then added to the structure that already exists in the list to hook. The new hook will be added to the front of the old. When an event occurs, if you have a local hook, your hook function in the process will be called. If it is a long-range hook, the system hook function must be inserted into the address space of other process, it is necessary to achieve this requirement hook function must be a dynamic link library, so if you want to use long-range hook, it is necessary to put the hook function on the dynamic-link library to. Of course, there are two exceptions: the work of logs and log playback hook hooks. The two hook in the hook function must be installed in the hook of the thread. The reason is: these two hook is used to compare the underlying hardware to monitor events, as is the recording and playback, all the events are on the course priorities. Therefore, if the callback function on the DLL, type of incident was recorded on several threads, so we can not guarantee the correct order. Therefore, the solution is: put the hook function in a single thread, such as the installation of the threaded hook.
A total of 14 kinds of hooks, the following is the time they are called:
  • When you call SendMessage when WH_CALLWNDPROC
  • When the SendMessage call WH_CALLWNDPROCRET return
  • WH_GETMESSAGE When you call GetMessage or PeekMessage when
  • WH_KEYBOARD When you call GetMessage or PeekMessage to query from the message queue or WM_KEYDOWN message WM_KEYUP
  • WH_MOUSE When you call GetMessage or PeekMessage to query from the message queue when the mouse event news
  • WH_HARDWARE When you call GetMessage or PeekMessage to inquiries from the message queue of non-mouse, keyboard message
  • WH_MSGFILTER When the dialog box, menu, or scroll bar to deal with a message. The hook is local. It for those who have their own message handling process of the design of the control object.
  • WH_SYSMSGFILTER and WH_MSGFILTER, the only system-wide
  • WINDOWS When WH_JOURNALRECORD obtained from the hardware message queue
  • When an event WH_JOURNALPLAYBACK hardware from the system input queue when the requested
  • WINDOWS Shell WH_SHELL when on the time of the incident, such as the task it needs to redraw the button.
  • When WH_CBT computer-based training (CBT) the time of the incident
  • WINDOWS their own use by WH_FOREGROUNDIDLE generally rarely used applications
  • WH_DEBUG debug function used to hook
Now we know some basic theory, will now proceed to explain how to install / uninstall a hook.
To install a hook, you can call SetWindowHookEx function. The function prototype is as follows:
SetWindowsHookEx proto HookType: DWORD, pHookProc: DWORD, hInstance: DWORD, ThreadID: DWORD
  • HookType our values listed above, for example: WH_MOUSE, WH_KEYBOARD
  • pHookProc is the hook function's address. If you are using a remote hook, it must be placed in a DLL, or on its own code
  • hook function hInstance instance handle of the DLL is located. If it is a local hook, the value is NULL
  • ThreadID is the installation of the hook function you want to monitor after the thread ID. The parameters can be decided that the hook is the partial or system-wide. If the value is NULL, then the hook will be interpreted as system-wide, that it can monitor all the processes and their threads. If you specify your own in the process of a thread ID number, then the hook is a local hook. If the thread ID is another process in a thread ID, and that the overall situation of the hook is a long-range hook. There are two special cases: WH_JOURNALRECORD and always on behalf of local WH_JOURNALPLAYBACK system-wide hook, say local, because there is no need to put them in a DLL. WH_SYSMSGFILTER is always a system-wide long-range hook. In fact, it and similar WH_MSGFILTER hook, if the ThreadID parameter set to 0, then, they had exactly the same.
If the function call is successful, it will be returned in eax handle hook, otherwise return NULL. You must save the handle, because behind it we have to uninstall the hook.
To uninstall the hook when a call UnhookWidowHookEx function, which is only one parameter, that is, want to uninstall the hook of the handle. If the call is successful, in eax to return non-0 value, otherwise return NULL.
Now you know how to install and uninstall a hook, and the next we will look at the hook function. .
The hook as long as you install the type of news events, WINDOWS will call the hook function. For example, your hook is installed WH_MOUSE type, so as long as there is a mouse event occurs, the hook function will be called. No matter when you have that type of hook, hook function prototype are the same as when:
    HookProc proto nCode: DWORD, wParam: DWORD, lParam: DWORD
    • nCode specifies whether the message need to be addressed
    • The wParam and lParam contain information additional information
HookProc can function as a placeholder name. As long as the function prototype in line to the function you can get any name. As more than a few parameters and return values of the specific meaning of different types of hook. For example:
WH_CALLWNDPROC
  • nCode only HC_ACTION, it represents a message sent to a window
  • wParam If non-0, the representative of the message being sent
  • lParam point-type structure CWPSTRUCT pointer variables
  • return value: not used, return 0
WH_MOUSE
  • nCode for HC_ACTION or HC_NOREMOVE
  • wParam contains the mouse event news
  • lParam point-type structure MOUSEHOOKSTRUCT pointer variables
  • return value: If you do not deal with the return 0, otherwise return to non-0 value
Therefore, you must check with your guide to the WIN32 API to get different types of hook the detailed definition of the parameters and return values of their significance. There is also a problem here needs attention: All the hooks are in a string list, the recent accession to the hook on the head list. When an event occurs, WINDOWS will be in accordance with the list from the list to the end of the first order of call. The hook function so you have the responsibility to spread the news of a chain hook function. Of course you can not do so, but you may want to understand the reasons for doing so at this time. In most cases, it is best to pass along the news events in order to have the opportunity to hook the other to obtain the opportunity to deal with this news. Call the next hook function can be called function CallNextHookEx. The function prototype is as follows:
CallNextHookEx proto hHook: DWORD, nCode: DWORD, wParam: DWORD, lParam: DWORD
  • hHook is hook your own handler function. Can traverse using the handle hook chain.
  • nCode, wParam and lParam your parameters as long as the incoming CallNextHookEx to be simple.
Please note: For long-range hook, hook DLL function must be put in, they will be mapped to the DLL in the other space to the process. WINDOWS mapping when the DLL to the other space to the process will not be the data mapping is also carried out. In short, all of the process only to share the DLL code, as the data above, each process will have its own copy. This is a very easily be overlooked. You may take it for granted that saved in the DLL in all the values of the process of mapping the shared DLL. Under normal circumstances, as a result of a process of mapping the DLL has its own data segment, so in most cases the procedure you have to have a good run. Hook function but they are not. Function for the hook, the DLL's data segment requirements of all the process must be the same. So you must be set above the data-sharing, which can be specified in the link switches to achieve the above properties. In MASM you can do:
/ SECTION: <section name>, S
Has the initial name of the paragraph. Data, uninitialized paragraph are. Bss. `Joined you want to write a hook function that contains the DLL, but would like to make it's uninitialized data segment shared between all processes, you must do this:
link / section:. bss, S / DLL / SUBSYSTEM: WINDOWS ..........
S is the share on behalf of the above paragraph.

Examples:

A total of two modules: one is the GUI part, and the other is to install and uninstall the hook DLL.

;--------------------------------------------- Main source Part code --------------------------------------
.386
. model flat, stdcall
option casemap: none
include \ masm32 \ include \ windows.inc
include \ masm32 \ include \ user32.inc
include \ masm32 \ include \ kernel32.inc
include mousehook.inc
includelib mousehook.lib
includelib \ masm32 \ lib \ user32.lib
includelib \ masm32 \ lib \ kernel32.lib

wsprintfA proto C: DWORD,: DWORD,: VARARG
wsprintf TEXTEQU <wsprintfA>

. const
IDD_MAINDLG equ 101
IDC_CLASSNAME equ 1000
IDC_HANDLE equ 1001
IDC_WNDPROC equ 1002
IDC_HOOK equ 1004
IDC_EXIT equ 1005
WM_MOUSEHOOK equ WM_USER +6

DlgFunc PROTO: DWORD,: DWORD,: DWORD,: DWORD

. data
HookFlag dd FALSE
HookText db "& Hook", 0
UnhookText db "& Unhook", 0
template db "% lx", 0

. data?
hInstance dd?
hHook dd?
. code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke DialogBoxParam, hInstance, IDD_MAINDLG, NULL, addr DlgFunc, NULL
invoke ExitProcess, NULL

DlgFunc proc hDlg: DWORD, uMsg: DWORD, wParam: DWORD, lParam: DWORD
LOCAL hLib: DWORD
LOCAL buffer [128]: byte
LOCAL buffer1 [128]: byte
LOCAL rect: RECT
. if uMsg == WM_CLOSE
. if HookFlag == TRUE
invoke UninstallHook
. endif
invoke EndDialog, hDlg, NULL
. elseif uMsg == WM_INITDIALOG
invoke GetWindowRect, hDlg, addr rect
invoke SetWindowPos, hDlg, HWND_TOPMOST, rect.left, rect.top, rect.right, rect.bottom, SWP_SHOWWINDOW
. elseif uMsg == WM_MOUSEHOOK
invoke GetDlgItemText, hDlg, IDC_HANDLE, addr buffer1, 128
invoke wsprintf, addr buffer, addr template, wParam
invoke lstrcmpi, addr buffer, addr buffer1
. if eax! = 0
invoke SetDlgItemText, hDlg, IDC_HANDLE, addr buffer
. endif
invoke GetDlgItemText, hDlg, IDC_CLASSNAME, addr buffer1, 128
invoke GetClassName, wParam, addr buffer, 128
invoke lstrcmpi, addr buffer, addr buffer1
. if eax! = 0
invoke SetDlgItemText, hDlg, IDC_CLASSNAME, addr buffer
. endif
invoke GetDlgItemText, hDlg, IDC_WNDPROC, addr buffer1, 128
invoke GetClassLong, wParam, GCL_WNDPROC
invoke wsprintf, addr buffer, addr template, eax
invoke lstrcmpi, addr buffer, addr buffer1
. if eax! = 0
invoke SetDlgItemText, hDlg, IDC_WNDPROC, addr buffer
. endif
. elseif uMsg == WM_COMMAND
. if lParam! = 0
mov eax, wParam
mov edx, eax
shr edx, 16
. if dx == BN_CLICKED
. if ax == IDC_EXIT
invoke SendMessage, hDlg, WM_CLOSE, 0,0
. else
. if HookFlag == FALSE
invoke InstallHook, hDlg
. if eax! = NULL
mov HookFlag, TRUE
invoke SetDlgItemText, hDlg, IDC_HOOK, addr UnhookText
. endif
. else
invoke UninstallHook
invoke SetDlgItemText, hDlg, IDC_HOOK, addr HookText
mov HookFlag, FALSE
invoke SetDlgItemText, hDlg, IDC_CLASSNAME, NULL
invoke SetDlgItemText, hDlg, IDC_HANDLE, NULL
invoke SetDlgItemText, hDlg, IDC_WNDPROC, NULL
. endif
. endif
. endif
. endif
. else
mov eax, FALSE
ret
. endif
mov eax, TRUE
ret
DlgFunc endp

end start

;------------------------------------------------- ---- DLL part of the source code --------------------------------------
.386
. model flat, stdcall
option casemap: none
include \ masm32 \ include \ windows.inc
include \ masm32 \ include \ kernel32.inc
includelib \ masm32 \ lib \ kernel32.lib
include \ masm32 \ include \ user32.inc
includelib \ masm32 \ lib \ user32.lib

. const
WM_MOUSEHOOK equ WM_USER +6

. data
hInstance dd 0

. data?
hHook dd?
hWnd dd?

. code
DllEntry proc hInst: HINSTANCE, reason: DWORD, reserved1: DWORD
. if reason == DLL_PROCESS_ATTACH
push hInst
pop hInstance
. endif
mov eax, TRUE
ret
DllEntry 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
invoke PostMessage, hWnd, WM_MOUSEHOOK, eax, 0
assume edx: nothing
xor eax, eax
ret
MouseProc endp

InstallHook proc hwnd: DWORD
push hwnd
pop hWnd
invoke SetWindowsHookEx, WH_MOUSE, addr MouseProc, hInstance, NULL
mov hHook, eax
ret
InstallHook endp

UninstallHook proc
invoke UnhookWindowsHookEx, hHook
ret
UninstallHook endp

End DllEntry

;---------------------------------------------- DLL's Makefile document ----------------------------------------------

NAME = mousehook
$ (NAME). Dll: $ (NAME). Obj
Link / SECTION:. Bss, S / DLL / DEF: $ (NAME). Def / SUBSYSTEM: WINDOWS / LIBPATH: c: \ masm \ lib $ (NAME). Obj
$ (NAME). Obj: $ (NAME). Asm
ml / c / coff / Cp $ (NAME). asm

Analysis:

The application's main window consists of three edit controls, they will show the current mouse cursor location of the window class name, window handle and process the address window. There are two buttons: "Hook" and "Eixt". When you press the Hook, the application will be linked to the mouse hook input events news, the text of the button will become "Unhook". When you put the mouse over a window marked clearance, the window will display the information in the main window. When you click "Unhook", the application will uninstall the hook. The main window using a dialog box as its main window. It defines a message from WM_MOUSEHOOK, used in the main window and the transmission of information between the DLL. When the main window to receive the message, wParam contains the location of the cursor's window handle. Of course, this arrangement is that we do. I do so only for the convenience. You can use your own method in the main applications and communication between the DLL.

. if HookFlag == FALSE
invoke InstallHook, hDlg
. if eax! = NULL
mov HookFlag, TRUE
invoke SetDlgItemText, hDlg, IDC_HOOK, addr UnhookText
. endif

The application to have a global variable, HookFlag, it is used to monitor the state of hook. If you come to hook it is TRUE, otherwise it is FALSE. When the user press the Hook button, the application checks whether the hook is already installed. If not, it will call the DLL function draws InstallHook to install it. We pay attention to the main dialog box to pass the handle to the DLL, so that the hook DLL will be able to WM_MOUSEHOOK messaging window to correct the. When the application is loaded, the hook DLL is loaded at the same time. The time taken in the main program is loaded into memory as soon after, DLL is loaded immediately. DLL entry point function main program contains the first statement before the implementation of pre-implemented. Therefore, when the main program execution, DLL has been initialized it. We set the entrance point Add the following code:

. if reason == DLL_PROCESS_ATTACH
push hInst
pop hInstance
. endif

The above code into its own DLL instance handle in a global variable saved. As the entry point function is a function call in all the former was executed, so always hInstance effective. We put the variable. Data in a process so that each one has its own value of the variable. Because when the mouse cursor in a window on the stop, the hook DLL is mapped into process address space. To join in the default load address of DLL Department has loads of other DLL, the hook DLL will be mapped to other addresses. hInstance will be updated as other values. When the user press Unhook then press Hook when, SetWindowsHookEx call will be again. This time, it will address the new handler as an example. In case this is wrong, DLL loading and the address has not changed. This hook will become a local, you can only hook hanging took place in your window the mouse event, this is hardly satisfactory.

InstallHook proc hwnd: DWORD
push hwnd
pop hWnd
invoke SetWindowsHookEx, WH_MOUSE, addr MouseProc, hInstance, NULL
mov hHook, eax
ret
InstallHook endp

InstallHook function is very simple. Transfer it from the window handle in hWnd stored in for later use. Then call the SetWindowsHookEx function to install a mouse hook. The return value of the function on the global variables in hHook, UnhookWindowsHookEx in the future would also like to use. In the SetWindowsHookEx call, the mouse started working on the hook. Regardless of when the incident occurred in the mouse, MouseProc function will be called:

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
invoke PostMessage, hWnd, WM_MOUSEHOOK, eax, 0
assume edx: nothing
xor eax, eax
ret
MouseProc endp

CallNextHookEx hook function first calls the hook function to allow other events to deal with the mouse. Then, WindowFromPoint call function to get the screen coordinates of a given position of the window handle. Note: we use the lParam pointing MOUSEHOOKSTRUCT-type structures of variable POINT member variables as the current mouse position. We call the PostMessage function WM_MOUSEHOOK message sent to the main program. You must remember one thing: in the hook function should not use SendMessage function, which can cause deadlock. MOUSEHOOKSTRUCT is defined as follows:

MOUSEHOOKSTRUCT STRUCT DWORD
pt POINT <>
hwnd DWORD?
wHitTestCode DWORD?
dwExtraInfo DWORD?
MOUSEHOOKSTRUCT ENDS

  • pt is the screen where the mouse position.
  • hwnd is the window to receive mouse messages handle. Usually it is the Department of the window where the mouse, but if you call the window SetCapture, mouse input will go to this window. Because we do not have the member variable instead WindowFromPoint function.
  • wHitTestCode designated hit-test value, which gives more value of the mouse position. It specified that the mouse position in the window. The value of the complete list, please refer to the Guide to the WIN32 API message WM_NCHITTEST.
  • dwExtraInfo the value contained in the relevant information. The general function of the value set by the mouse_event, you can call to get GetMessageExtraInfo.

When the main window to receive WM_MOUSEHOOK message, it wParam parameter to query the window handle of the message window.

. elseif uMsg == WM_MOUSEHOOK
invoke GetDlgItemText, hDlg, IDC_HANDLE, addr buffer1, 128
invoke wsprintf, addr buffer, addr template, wParam
invoke lstrcmpi, addr buffer, addr buffer1
. if eax! = 0
invoke SetDlgItemText, hDlg, IDC_HANDLE, addr buffer
. endif
invoke GetDlgItemText, hDlg, IDC_CLASSNAME, addr buffer1, 128
invoke GetClassName, wParam, addr buffer, 128
invoke lstrcmpi, addr buffer, addr buffer1
. if eax! = 0
invoke SetDlgItemText, hDlg, IDC_CLASSNAME, addr buffer
. endif
invoke GetDlgItemText, hDlg, IDC_WNDPROC, addr buffer1, 128
invoke GetClassLong, wParam, GCL_WNDPROC
invoke wsprintf, addr buffer, addr template, eax
invoke lstrcmpi, addr buffer, addr buffer1
. if eax! = 0
invoke SetDlgItemText, hDlg, IDC_WNDPROC, addr buffer
. endif

Redraw the text in order to avoid jitter, we have been in the editing room for the center line of the text and we will want to show the contrast. If the same can be ignored. Be the class name to call GetClassName, be a window and into GetClassLong procedure call GCL_WNDPROC signs, and turn them into a text format string and put related to the editing space.

invoke UninstallHook
invoke SetDlgItemText, hDlg, IDC_HOOK, addr HookText
mov HookFlag, FALSE
invoke SetDlgItemText, hDlg, IDC_CLASSNAME, NULL
invoke SetDlgItemText, hDlg, IDC_HANDLE, NULL
invoke SetDlgItemText, hDlg, IDC_WNDPROC, NULL

When the user press Unhook, the main program calls the DLL function UninstallHook. UnhookWindowsHookEx function of the function call. Then, it is the text of the button in exchange for "Hook", HookFlag set to the value FALSE and then removed the text in the edit control.
Linker switch options are as follows:

Link / SECTION:. Bss, S / DLL / DEF: $ (NAME). Def / SUBSYSTEM: WINDOWS

It has been designated. Bss paragraph to paragraph as a share of all the process of mapping the shared DLL uninitialized data segment. If you do not have the switch, the hook DLL that you can not normal work.



Assembly Language Tutorial Articles


Can't Find What You're Looking For?


Rating: Not yet rated

Comments

No comments posted.