Application of Windows message interception technology

Source: Internet
Author: User
Tags function prototype

Windows application of message interception technology

Civil Aviation Hefei Air Pipe Center Joey

First, preface

It is well known that the operation of Windows programs depends on the events that occur to drive them. In other words, the program waits for a message to occur, then makes a judgment about the type of the message and then handles it appropriately. After processing this message, we return to the waiting state. From the above analysis of the Windows program operating mechanism is not difficult to find that the message between the user and the program to communicate between the role of a middle "language". The protagonist of receiving and processing messages in the program is the window, which receives messages through the message pump and processes the messages accordingly through a window procedure.

The implementation of message interception is to intercept the message before the window process processes the message and to do the relevant processing before sending it to the original window procedure. Typically, a programmer can process a received message during a window, which requires that the window process must be completed at the time of development, but in some applications it is often necessary to acquire and process messages from other applications or other unit modules, and the techniques for implementing such functions are the subject of this article-message interception technology.

Ii. Understanding Windows Messaging Mechanisms

Before delving into the principles of message interception, let's review the fundamentals of Windows Messaging mechanism.

1, the generation of the message

As the "language" in which the program communicates with the outside world, it comes naturally from outside, but the outside world is not simply referring to programs or software systems, but to modules, Windows systems, other applications, and hardware that are outside the message processing module. It is usually divided into two main classes, hardware messages and software messages, based on the way messages are generated. Hardware messages, often referred to as events generated by a hardware appliance (such as a mouse or keyboard being pressed), are placed in a system message queue (the system queue) and sent to the application message queue by the message processing authority. Software messages, often referred to as messages sent by Windows systems or other applications, are placed directly into the application message queue (application queue), which is then passed to the appropriate window by the application Message Processing authority.

2, the composition of the message

A message consists of a message name (UINT), and two parameters (Wparam,lparam). The system sends a message to a window when the user enters or changes the state of the window. For example, when a menu is transferred, a WM_COMMAND message is sent, and WParam (HiWord (WParam)) is the ID number of the command, which is the menu ID of the menu. Of course, users can also define their own message names, or they can use custom messages to send notifications and transfer data.

3. Recipient of the message

A message must be received by a window. In the window procedure (WNDPROC), the message can be parsed to handle the messages that the application requires processing, and for messages that do not require application processing, the default processing is simply called. For example, if you want to process the menu selection, you can define the code to process the WM_COMMAND, and if you want to do the graphics output in the window, you must process the WM_PAINT.

4. Handling of messages

When a window receives a message sent to itself, the message structure is invoked as a parameter to process the message accordingly. You can treat a window procedure as a collection of message-handling code, and the prototype of a window procedure function is:

Long far PASCAL WndProc (HWND hwnd,word message,word wparam,long lParam);
Where the HWND is the window handle, message is the name, and Wparam,lparam is a two parameter.

In Windows, the application does not call any window functions directly, but instead waits for Windows to call the window function to request completion of the task or return information. To ensure that Windows calls this window function, this function must first register with Windows and then callback when Windows implements the appropriate action, so the window function is called the callback function. WndProc is a primary callback function, and Windows has at least one callback function. It is registered with Windows when the application makes a window class registration.

Third, the use of hooks (hook) to intercept messages

1, what is hook (hook)?

The hook mechanism allows an application to intercept processing of window messages or specific events. There are similarities to the DOS interrupt interception processing mechanism. Hooks are a platform for Windows message processing, where an application can set up a subroutine to monitor a message for a specified window, and the window being monitored can be created by another process. When a message arrives, the hook can handle it before the target window handles the function and can block the delivery of the message. Each hook has a list of pointers associated with it, called the chain of hooks, and the pointers in that list point to each of the handlers of the hooks. There are many kinds of hooks, each of which can intercept and process messages of the corresponding kind. When the message that is monitored by the hook appears, Windows calls the first hook in the linked list, and the first procedure completes the next hook in the linked list until all the hook routines in the list are executed (note: If there is a hook in it that does not perform message delivery before execution is complete), The subsequent hook procedure and the original window procedure will no longer receive the message. ) After the message is returned to the window procedure.

2. Hook subroutine function

The hook thread is an application-defined callback function. Used to monitor a system or a specific type of event, which can be associated with a particular thread, or it can be an event for all threads in the system. Its function prototypes are:

LRESULT CALLBACK HookProc (int nCode, WPARAM WPARAM, LPARAM LPARAM);

Where the ncode parameter is the hook code, the hook thread uses this parameter to determine the task. The value of this parameter depends on the hook type, and each hook has its own hook code feature character set. The Windows system provides several types of hooks, each of which allows the application to monitor different types of system message handling mechanisms.

The values of the wparam and lparam parameters depend on the hook code, but their typical value is to contain information about sending or receiving messages.

3. Installation and uninstallation of hooks

The installation of the hooks is implemented through the SDK API SetWindowsHookEx (), which installs the hook Shuo into the system Hook list. Its function prototype

Hhook SetWindowsHookEx (int idhook,hookproc lpfn,hinstance hmod, DWORD dwthreadid);

Where Idhook refers to the type of hook. Table I lists the types of some hooks and their descriptions.

(Table i)

Type

Description

Wh_callwndproc

The system calls this subroutine before the message is sent to the receive window procedure

Wh_callwndprocret Hooks

Call this subroutine after the window procedure finishes processing the message

Wh_getmessage

Monitoring messages returned from the Getmessage/peekmessage function

Wh_keyboard

Monitoring keyboard messages entered into a message queue

Wh_mouse

Monitoring mouse messages entered into a message queue

Limited to space, other message types are not listed. See MSDN for content.

LPFN refers to the address pointer of the hook path. If the dwThreadID parameter is 0 or an identity of a thread created by another process, LPFN must point to the hook in the DLL. In addition, LPFN can point to a section of the current process's hook code.

Hmod refers to the handle of an application instance. Identifies the DLL that contains the Cheng referred to by LPFN. If dwThreadID identifies a thread created by the current process, and the subroutine code is in the current process, hmod must be null.

dwThreadID refers to the identifier of the thread associated with the installed hook child threads, and if 0, the hook is associated with all threads.

Successful function returns the handle of the hook, and the failure returns NULL.

Hooks need to be unloaded with UnhookWindowsHookEx () after use, otherwise it will cause trouble. Unloading hooks is simple, UnhookWindowsHookEx () has only one parameter. The function prototypes are as follows:

UnhookWindowsHookEx (Hhook hhk)

Where the parameter hhk is the SetWindowsHookEx () function returns the hook handle, so be sure to save the handle when designing the program so that it can be used when uninstalling. The function returns true successfully, otherwise false is returned.

4. System hooks and thread hooks

The Windows system divides the hooks into system hooks (global hooks) and thread hooks (local hooks) based on the scope of the hooks ' monitoring events. The last parameter of the SetWindowsHookEx () function determines whether the hook is a system hook or a thread hook. The line Cheng is used to monitor event messages for a specified thread. A line Cheng is typically within a thread that is derived from the current thread or when it is active. The system hook monitors the event messages for all threads in the system. Because the system hook affects all applications in the system, the hook function must be placed in a separate dynamic-link library (DLL). The system automatically maps the DLL containing the "Hook callback function" to the address space of all processes affected by the hook function, injecting the DLL into those processes.

5, the implementation of hooks

The example of this article implements the ability to intercept the WM_CHAR message of the Notepad (NotePad.exe) program. If the reader wants to implement other functions, the code can be added directly to the Hook subroutine function.

(1), select MFC AppWizard (DLL) to create the project Notepadhook and select the MFC Extension DLL (Shared MFC copy) type.

(2), create a NotePadHook.h file in which to build the hook class:

Class Afx_ext_class Cnotepadhook:public CObject

{

Public

Cnotepadhook (); The constructor of the hook class

~cnotepadhook (); A destructor for a hook class

BOOL Starthook (HWND hwnd); Install hook function

BOOL Stophook (); Unload hook function

};

(3), add # include "NotePadHook.h" in NotePadHook.cpp.

(4), add the shared data segment in NotePadHook.cpp:

#pragma data_seg ("sharedata")//Shared data segment, the variables within the segment can be shared by all instances of the hook.

Hhook Glhhook=null; A handle to the hook.

HINSTANCE Glhinstance=null; DLL instance handle.

#pragma data_seg ()

(5), define only one data segment can not achieve the purpose of sharing data, but also tell the compiler the properties of the segment. To be in. DEF file to set the segment's properties, open. def file, add the following code:

Setctions//As if to change to SECTIONS , or compile with error

Sharedata READ WRITE SHARED

Another method:

You can also set it directly in your code:
#pragma data_seg ("Sharedata")
..........
#pragma data_seg ()
#pragma COMMENT (linker, "/SECTION:SHAREDATA,RWS")

(6), add the Save DLL instance handle to the DllMain function in the main file NotePadHook.cpp:

DllMain (hinstance hinstance, DWORD dwreason, LPVOID lpreserved)

{

If you use the lpreserved parameter, delete the following line

Unreferenced_parameter (lpreserved);

if (Dwreason = = Dll_process_attach)

{

TRACE0 ("NOtePadHOOK.DLL initializing!/n");

Extension DLLs are initialized only once

if (! AfxInitExtensionModule (Notepadhookdll, hinstance))

return 0;

New CDynLinkLibrary (Notepadhookdll);

Adding DLLs to the dynamic MFC class Library

Glhinstance = hinstance;

Insert Save DLL Instance handle

}

else if (Dwreason = = Dll_process_detach)

{

TRACE0 ("NotePadHOOK.DLL terminating!/n");

Call it before terminating this link library

AfxTermExtensionModule (Notepadhookdll);

}

return 1;

}

(7), the specific implementation of the member functions of class Cnotepadhook:

Cnotepadhook::cnotepadhook () {}

Cnotepadhook::~cnotepadhook () {Stophook ();}

BOOL Cnotepadhook::starthook (HWND hwnd)//mounting hooks.

{

BOOL Bresult=false;

Glhhook=setwindowshookex (wh_callwndproc,notepadproc,glhinstance,0);

if (glhhook!=null) bresult=true;

return bresult;

}

Cnotepadhook::stophook ()

{

BOOL bresult = FALSE;

if (Glhhook) {

Bresult=unhookwindowshookex (Glhhook);

if (bresult) glhhook=null;

return bresult;

}

(8), hook the implementation of the process:

LRESULT WINAPI notepadproc (int ncode,wparam wparam,lparam LPARAM)

{

pcwpstruct pcs = NULL;

pcs = (pcwpstruct) LParam;

if (PCs && pcs->hwnd!=null)

{

TCHAR szclass[256];

GetClassName (Pcs->hwnd, szclass,255);//Gets the blocked window class name.

if (strcmp (Szclass, "Notepad") ==0)

{

if (pcs->message = = WM_CHAR)

{

AfxMessageBox ("HOOK NOTEPAD wm_char OK!!!");

}

}

}

return CallNextHookEx (Glhhook,ncode,wparam,lparam);//continue to deliver the message.

}

(9), compile the project to generate NotePadHook.dll.

Although the hook class has been completed, it is not possible to implement the hook function. We have to write a program to start the hook, inject the hook dll into the memory space of other programs, and add the hooks to the list of system hooks. Due to the limitation of space, in this article does not specifically describe the Hook launcher instance, only the writing of the startup program should note that the following notes:

(1), add Debug/notepadhook.lib in the Notepadhook project to the Project Settings Link tab.

(2), the Notepadhook project in the NotePadHook.h file include to stdafx.h.

(3), first need to create a Cnotepadhook class instance, the hook is invoked when the class member Starthook (), unload the hook when calling the class member Stophook ().

Iv. using Window sub-class (subclass) to intercept messages

As mentioned earlier, each window has a window procedure that is defined in its window class. The window procedure handles each message sent to the window. If you want to write your own window procedure, it is no problem to modify its behavior. However, if the window procedure belongs to someone else, there will be no source code to modify. For example, each button in an application is created by a system-supplied button window, and it has a window procedure that belongs entirely to itself. If you want to change the appearance of the window, you cannot do so by changing its wm_paint handler, because it is not available. So how can you change the appearance of these buttons without having to rewrite the original controls? Simply replace the address of the Window object's initial window procedure with the address of your own window procedure. This technique is also the topic discussed in this section – window sub-class technology.

1, the principle of window sub-class

The application registers this window's class with the Windows system before creating a new window, first filling in a WNDCLASS structure, where the structure parameter lpfnwndproc is the address of the class window function, and then calls RegisterClass () The function requests the Windows System to register this window class. At this point, Windows allocates a chunk of memory to hold all the information for that class, which is called the window class memory block.

The window sub-class technique is actually changing the parameters in the window memory block. Because this modification involves only one window of the window memory block, it does not affect the functionality and performance of other windows that belong to the same window class. The most common window subclass is to modify the window function address (lpfnwndproc) in the window memory block, so that it points to a new window function, so as to change the original Window function processing method to achieve the purpose of modifying its window procedure.

2, the realization of the window sub-class

The core of the window sub-class implementation is to change the address of the window procedure, which can be implemented by several functions provided by the SDK API. The steps are as follows:

A Writes a subclass window procedure function. The function must be in the form of a standard window procedure function:

LRESULT CALLBACK Subclasswndproc (HWND, UINT, WPARAM, LPARAM);

The parameter meaning of this function is similar to the window procedure function parameter described earlier.

b Call the GetWindowLong (hwnd, GWL_WNDPROC) function to get the address of the original window function and save it, where the parameter hWnd is the window handle to be sub-typed.

C Call SetWindowLong (HWnd, GWL_WNDPROC, Subclasswndproc) to set the window function to sub-class window function, complete the window sub-class.

In order to reduce the tedious work in the sub-class process, MFC provides support for subclasses, which simplifies the sub-class process and uses the CWnd class Subclasswindows () function to implement subclasses. In order for readers to have an intuitive understanding of the class-based process, the following MFC implements the subclass of an edit control.

(1), create a new control class Csubedit derived from the MFC control class CEdit.

(2), add Csubedit::P retranslatemessage (msg* pMsg)

BOOL Csubedit::P retranslatemessage (msg* pMsg)

{

if (Pmsg->message==wm_keydown&&pmsg->wparam==vk_return)

{

When you press ENTER on the edit control ...

.....

Limited to the length of processing content.

return TRUE;

}

CEdit::P retranslatemessage (PMSG);

}

(3), the control variable type is changed from CEdit to Csubedit in the header file of the dialog box that contains this control.

(4), subclass the Edit control in the dialog class file that contains the control, with the following code:

HWND hwnd;

GetDlgItem (Idc_sub_edit,&hwnd);//Where Idc_sub_edit is the control ID.

M_subedit.subclasswindow (HWND); M_subedit is the name of the control variable.

V. Summary

This paper discusses two methods to implement message interception, in which the hook technology is widely used, which can not only intercept the messages in the process, but also intercept other process messages. The subclass technology is mainly used to intercept the window messages in the same process unit module. Programmers can select one of the actual application requirements to achieve message blocking.

http://blog.csdn.net/jiangxinyu/article/details/5276538

Application of Windows message interception technology

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.