A simple keyboard hook program

Source: Internet
Author: User

A simple keyboard hook program

A program that implements timely monitoring of the keyboard and saves key information in a TXT file

The Windows system is built on the event-driven mechanism, which is to put it bluntly that the entire system is implemented through message delivery. The hook is a very important system interface in Windows system, it can intercept and process the message to other applications, to accomplish the function that ordinary application is difficult to implement. There are many kinds of hooks, each hook can intercept and process the corresponding message, such as keyboard hooks can intercept keyboard messages, shell hooks can intercept, start and close the application of the message, and so on. In this paper, a simple keyboard hook program is implemented in VC6 programming environment, and the operation mechanism of WIN32 global hooks, the features of WIN32 DLL, MFC DLL in VC6 environment and the related knowledge of shared data are simply expounded.

A Win32 the operation mechanism of global hooks

A hook is actually a program segment that processes messages, and it is put into the system by a system call. Whenever a particular message is issued, the hook program captures the message before it reaches the destination window, i.e. the hook function gets control first. At this point the hook function can process (change) the message, or you can continue to pass the message without processing, and you can force the end of the message delivery. For each type of hook the system maintains a chain of hooks, the most recently installed hooks are placed at the beginning of the chain, and the first installed hooks are placed at the end, that is, the first to gain control over the added. To implement WIN32 system hooks, you must call the API function SetWindowsHookEx in the SDK to install this hook function, the prototype of this function is

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

Where the first parameter is the type of the hook, the second parameter is the address of the hook function, the third parameter is the module handle containing the hook function, and the fourth parameter specifies the monitored thread. If you specify a thread that is defined, it is a thread-specific hook, or a global hook if NULL is specified. Where the global hook function must be included in the DLL (dynamic-link library), the thread-specific hooks can also be included in the executable file. The hook function that gets control after processing the message, if you want the message to continue to pass, it must call the API function CallNextHookEx in the other SDK to pass it. The hook function can also discard the message by directly returning true, and block the delivery of the message.

Two Features of the Win32 DLL

The Win32 DLL differs greatly from the Win16 DLL, which is mainly determined by the design of the operating system. On the one hand, the program entry point function and exit point function (LibMain and WEP) are implemented separately in the Win16 DLL, whereas in the Win32 DLL it is implemented by the same function DllMain. Whenever a process or thread loads and unloads a DLL, the function is called, and its prototype is

BOOL WINAPI DllMain (hinstance hinstdll,dword fdwreason, LPVOID lpvreserved);

Where the first parameter represents the instance handle of the DLL; The third parameter system is reserved; Here is the second parameter, which has four possible values: Dll_process_attach (Process loading), Dll_thread_attach (thread loading), Dll_ Thread_detach (thread Offload), Dll_process_detach (process offload), in the DllMain function can be passed in the value of this parameter to distinguish, and according to the different parameter values of the DLL to do the necessary initialization or cleanup work. For example, when a process loads a DLL, the second parameter that the system assigns to the DLL is Dll_process_attach, and you can initialize the specific data based on this parameter. On the other hand, in the WIN16 environment, all applications are in the same address space, while in the WIN32 environment, all applications have their own private space, each process space is independent of each other, which reduces the interaction between applications, but also increases the difficulty of programming. As you know, in the WIN16 environment, the DLL's global data is the same for each process that loads it, while in the WIN32 environment, the situation changes, and when the process loads the DLL, the system automatically maps the DLL address to the private space of the process. It also replicates a copy of the DLL's global data to the process space, meaning that the value of the global data for the same DLL owned by each process is not necessarily the same. Therefore, in a Win32 environment, if you want to share data across multiple processes, you must make the necessary settings. That is, separating the data that needs to be shared, placing it in a separate data segment, and setting the attribute of that segment to shared.

Three Classification and characteristics of MFC DLLs in VC6

There are three forms of MFC DLLs in VC6 (which can be used and inherited from existing MFC classes), i.e. regular statically linked to MFC DLLs (standard statically linked MFC DLLs) and regular using the Shared MFC DLLs (Standard dynamic-link MFC DLLs) and extension MFC DLLs (extended MFC DLLs). The first DLL is characterized by the use of MFC code at compile time to add to the DLL, so in the use of the program does not require the existence of other MFC dynamic Link class library, but the disk space is larger; the second DLL is characterized by dynamically linking to the MFC class library at run time, thus reducing the footprint of space. However, it relies on the MFC dynamic Link class library at runtime, both of which can be used by MFC programs or WIN32 programs. The third kind of DLL features similar to the second, as an extension of the MFC class Library, can only be used by MFC programs.

Four Implementation of globally shared data in VC6

In the main file, create a new data segment with #pragma data_seg and define the shared data in the following format:
#pragma data_seg ("Shareddata")
HWND sharedwnd=null;//Shared data
#pragma data_seg ()

Defining only one segment of data does not achieve the purpose of sharing data, but also tells the compiler the properties of that segment, there are two ways to do that (the effect is the same), and one way is to do so. def file, add the following statement:


Another way is to include the following statement in the Project Settings link option:

Five Concrete implementation Steps

Since the global hook function must be included in the dynamic link library, this example is implemented by two program bodies.

1. Build Hook KeyboardHook.dll

(1) Select MFC AppWizard (DLL) to create the project Mousehook;

(2) Select MFC Extension DLL (Shared MFC copy) type;

(3) Since VC6 does not have a ready-made hook class, create a KeyboardHook.h file in the project directory where the hook class is built:
Class Afx_ext_class Ckeyboardhook:public CObject
Ckeyboardhook ();//The constructor of a hook class

Virtual ~ckeyboardhook ();//destructor of a hook class

BOOL Starthook (); Install hook function

BOOL Stophook ();//unload hook function

(4) Add # include "KeyboardHook.h" statement at the top of the KeyboardHook.cpp file;

(5) Add a global shared data variable at the top of the KeyboardHook.cpp file:
#pragma data_seg ("MyData")
Hhook Glhhook=null; Installed mouse HOOK clause handle
HINSTANCE Glhinstance=null; DLL instance handle
#pragma data_seg ()

(6) Define the segment properties in the Def file:

(7) Add the statement that holds the DLL instance handle in the DllMain function of the main file KeyboardHook.cpp:
glhinstance=hinstance;//Insert Save DLL instance handle

(8) The implementation of the keyboard hook function:
Keyboard hook function
LRESULT CALLBACK keyboardproc (int ncode,wparam wparam,lparam LPARAM)
Char ch=0;
if ((DWORD) lparam&0x40000000) && (Hc_action==ncode))//Key pressed
if ((wparam==vk_space) | | | (Wparam==vk_return) | | (wparam>=0x2f) && (wparam<=0x100))
Fl=fopen ("Key.txt", "A +"); Output to Key.txt file
if (Wparam==vk_return)
Ch= ";
BYTE ks[256];
Getkeyboardstate (KS);
UINT scan=0;
Toascii (wparam,scan,ks,&w,0);
Ch=mapvirtualkey (wparam,2); Turn the virtual key code into a character
Ch =char (W);
Fwrite (&ch, sizeof (char), 1, FL);
Fclose (FL);
Return CallNextHookEx (Glhhook, NCode, WParam, LParam);

(9) The concrete implementation of the member function of class Ckeyboardhook:
Ckeyboardhook::ckeyboardhook ()

Ckeyboardhook::~ckeyboardhook ()
if (Glhhook)
UnhookWindowsHookEx (Glhhook);

Install the hook and set the Receive display window handle
BOOL Ckeyboardhook::starthook ()
BOOL Bresult=false;
Glhhook=setwindowshookex (wh_keyboard,keyboardproc,glhinstance,0);
Hhook SetWindowsHookEx (int idhook,hookproc lpfn, INSTANCE hmod,dword dwthreadid)
The parameter Idhook represents the hook type, which corresponds to the hook function type one by one.
For example, Wh_keyboard indicates that a keyboard hook is installed, Wh_mouse is a mouse hook, and so on.

LPFN is the address of the hook function.

Hmod is the handle to the instance where the hook function resides. For thread hooks, this parameter is NULL, and for system hooks,
This parameter is the DLL handle where the hook function resides.

DWTHREADID Specifies the thread number of the thread that the hook is monitoring. For global hooks, this parameter is null.

SetWindowsHookEx returns the installed hook handle.
It is important to note that the position of the hook function of the thread hook and the system hook is very different.
Thread hooks are typically within the current thread or thread that derives from the
The system hooks must be placed in a separate dynamic link library, which is a bit cumbersome to implement.
if (glhhook!=null)
return bresult;

Uninstalling Hooks
BOOL Ckeyboardhook::stophook ()
BOOL Bresult=false;
if (Glhhook)
bresult= UnhookWindowsHookEx (Glhhook);
if (bresult)
return bresult;

(10) Compile the project to generate KeyboardHook.dll.

2. Create hooks to execute programs
(1) using MFC AppWizard (EXE) to create the project Keyhook;

(2) Select "Based on the Dialogue app" and press "Finish" key;

(3) include "KeyboardHook.h" in KeyHookDlg.h;

(4) Add private data members to KeyHookDlg.h:
Ckeyboardhook m_hook;//joins the Hook class as a data member

(5) Link DLL library, that is, put the. /keyboardhook.lib added to the Project Settings Link tab;

(6) Change the OK button ID to id_hook and write the implementation code:
void Ckeyhookdlg::onhook ()
M_hook. Starthook ();

(7) Close button implementation:
void Ckeyhookdlg::oncancel ()
M_hook. Stophook ();
Cdialog::oncancel ();

(8) Compile the project to generate executable files;

Run the generated KeyHook.exe program, press the hook! button, load the hook and press some keys on the keyboard, you can find the EXE directory automatically generated a key.txt file, which records your key information

A simple keyboard hook program

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.