Windows hook mechanism details

  • 2020-04-02 02:25:29
  • OfStack

I. overview:

Anyone familiar with Windows programming knows that Windows programs run on the basis of messaging, and almost all program activity is driven by messages. The hook mechanism can be considered as a message relay station, which controls the processing and delivery of the message sent by the system. With hooks, we can intercept messages sent by the system to the application and, after processing, decide whether to send the message to the next application. Using this feature of hooks, we can create a monitor that collects and controls messages sent by the system.

Two, Windows hook program preparation

Windows hook program, need to use several SDK API functions. The following are the prototypes and descriptions of these functions:


HHOOK SetWindowsHookEx( int idHook, HOOK_PROC lpfn, HINSTANCE hMod,DWORD dwThreadID);

Parameter description:
IdHook: the type of hook
LPFN: hook handler address
HMod: the module handle that contains the hook function
DwThreadID: the hook's monitoring thread

Function description:
The idHook () function attaches a hook of the type specified by idHook to the system and monitors and processes specific messages.


BOOL UnhookWindowsHookEx( HHOOK hhk );

Function description: this function will undo the hook specified by HHK.


LRESULT CallNextHookEx( HHOOK hhk, int nCode, WPARAM wParam, LPARAM lParam );

Function description: the function passes the message down and the next hook processing intercepts the message.

Because the hook processing involves the data address problem between modules and processes, the general processing is to integrate the hook into a dynamic link library (DLL), and set up a global data Shared data segment, in order to store some global variables, keep the state of the last hook message event. The global Shared data segment can be defined in the following format:


#pragma data_seg("PublicData")
HHOOK hhook=NULL; //Globally Shared data
#pragma data_seg()

In the sample program included with this article, we demonstrate how to program a WH_MOUSE hook. This program monitors the Windows system mouse message, during the monitoring, the program can be the user click the number of times the left mouse button. Other types of hook programs are written similarly to the sample program.

The establishment of sample program and code analysis

As mentioned above, the hook process needs to be integrated into the dynamic link library when creating a hook program, so two projects need to be created in the routine.

1. Establish dynamic link library for hook processing:

(1) select MFC AppWizard(DLL) to create a new Project, named "Spy";

(2) select the MFC Extension DLL type

(3) create a new header file named "Hook. H "and modify it as follows


extern "C" LRESULT CALLBACK MouseProc(int code,
WPARAM wParam,LPARAM lParam); //Hook handler
extern "C" BOOL WINAPI StartHook(); //Bootstrap hook function
extern "C" BOOL WINAPI StopHook(); //Undo hook function
extern "C" int WINAPI GetResult(); //Gets a function of the number of mouse clicks

(4) modify the spy.cpp file code as follows (the bold part is to add content)


#include "stdafx.h"
#include <afxdllx.h>
#include "spyhook.h"
 ... //Omit parts of machine generated code
#pragma data_seg("PublicData") //Define global data segments
HHOOK hhook=NULL; //Handle to the hook
HINSTANCE pInstance=NULL; //Hook module handle
UINT MouseClick=0; //Variable that records the number of mouse clicks
#pragma data_seg()
 ... //Omit parts of machine generated code
extern "C" int APIENTRY
DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{ if (dwReason == DLL_PROCESS_ATTACH)
{  ... //Omit parts of machine generated code
new CDynLinkLibrary(SpyDLL);
pInstance=hInstance; //Gets the module handle
}
else if (dwReason == DLL_PROCESS_DETACH)
{ TRACE0("SPY.DLL Terminating!n");
AfxTermExtensionModule(SpyDLL);
}
return 1; 
}
extern "C" LRESULT CALLBACK MouseProc(int code,WPARAM wParam,
LPARAM lParam) //Hook handler
{ if (code < 0) //If code<0, returns by calling CallNextHookEx directly
return CallNextHookEx(hhook, code, wParam, lParam);
if(wParam==WM_LBUTTONDOWN)
{ MouseClick++; //Record the number of mouse clicks
}
return CallNextHookEx(hhook, code, wParam,lParam);
}

extern "C" BOOL WINAPI StartHook() //Bootstrap hook function
{ hhook=SetWindowsHookEx(WH_MOUSE,MouseProc,pInstance,0); //Hang hooks
if(hhook!=NULL)
return TRUE;
else return FALSE;
}
extern "C" BOOL WINAPI StopHook() //Undo hook function
{ return UnhookWindowsHookEx(hhook); //Revocation of the hook
}
extern "C" int WINAPI GetResult() //Returns the number of mouse clicks
{ return MouseClick;
}

(5) modify the spy.def file as follows


LIBRARY "SPY"
DEs criptION 'SPY Windows Dynamic Link Library'
EXPORTS
StartHook @1
StopHook @2
GetResult @3

(6) compile the Project and generate the spy.dll file and spy.lib file

2. Create an application that USES hooks

A Project that generates a single document executable (EXE)
Modify the main menu in the resource, add a menu item "monitor", there are three sub-menu items, respectively "start", "undo", "take out"
Add the spy.lib file and the Hook. H file to the Project
Modify the Command response functions of "start", "undo" and "fetch" menu items as follows:


#include "hook.h"
 ... //Omit parts of machine generated code
void CMainFrame::OnStartSpy() //Launch the response function for the menu item
{ StartHook();
}

void CMainFrame::OnReleaseSpy() //The response function for the "undo" menu item
{ StopHook();
}

void CMainFrame::OnGet() //Take out the response function of the menu item
{ int Result=GetResult();
char buffer[40];
wsprintf(buffer," You click the mouse while the program is running %d time ",Result);
::MessageBox(this->m_hWnd,buffer,"Message",MB_OK); 
}

Compile the Project and drop the spy.dll into the directory of the generated executable to run the program. At runtime, select the "start" menu item in the "monitor" menu, and the hook starts to work to monitor the mouse activity. Select "undo" menu item, the system will undo hook; Select the "take out" menu item, and the program reports how many times the user clicked the left mouse button during monitoring.


Related articles: