A Windows application that uses a hook function to capture keyboard responses

Source: Internet
Author: User

A: Introduction:

You may have been on the screen capture PowerWord the principle of confusion, you may want to put your keyboard, mouse activities timely record down, and even you want to know how the Trojan horse in the Windows operating system is the Trojan DLL loading ... in fact, these are used in the windows of the hook function. So this paper will explain the related knowledge of hook function. Of course, the purpose of this article is not to use this program to allow readers to steal someone else's password, but because the hook function in the Windows system is a very important system interface function, so want to discuss with everyone, of course, this article also on how to establish a dynamic link library (DLL) made some simple description. (The program for this article is the vc6.0 development environment, the language is: C and Win32 API).

Two: Hook Overview:

Microsoft's WINDOWSX operating system is built on an event-driven mechanism, which is implemented through message delivery. In the Windows operating system, hooks are a mechanism for receiving events midway through events (such as messages, mouse activations, keyboard responses) before they reach the application. In addition, the hook function can be modified, discarded and other means to work on the event.
Windows has two hooks, one for a particular thread specific hooks, and one for the global system hook (systemwide hooks). A specific thread hook only monitors the specified thread, while the global system hook can monitor all the threads in the system. Both the specific thread hooks and the global system hooks are set by SetWindowsHookEx (). For a particular thread hook, the function of the hook can be either contained in an. exe or a. dll. But for a global system hook, the hook function must be contained in a separate DLL, so when we want to capture the keyboard response, we have to create a dynamic link library. But when the hook function is given control and the related event is processed, if you want the message to continue passing, you must call another function: CallNextHookEx. Because the system must handle each message, the hook program increases the burden of processing and therefore reduces the performance of the system. In view of this, the hook program is not supported in Windows CE. So when the program finishes and exits, it should release the hook, calling the function: UnhookWindowsHookEx.
Below we will give an example (capture keyboard) to explain in detail the design of the hook function.

Three: The design of the program:

I: Setting Hooks

The set hook is an API function via SetWindowsHookEx ().
Prototype: Hhook SetWindowsHookEx (int idhook,hookproc lpfn,hinstance Hmod,dword dwthreadid)
Idhook: Type of hook to load.
LPFN: The entry address of the hook process
Hmod: Event handle for an application
dwThreadID: Thread Marking for hook loading

Parameters:
Idhook:
This parameter can be the following value:
Wh_callwndproc, Wh_callwndprocret, WH_CBT, Wh_debug, Wh_foregroundidle, Wh_getmessage, WH_JOURNALPLAYBACK, WH_ Journalrecord, Wh_keyboard, Wh_keyboard_ll, Wh_mouse, Wh_mouse_ll, Wh_msgfilter, Wh_shell, WH_SYSMSGFILTER.
For these parameters, I don't want to explain them one after the other because they have detailed annotations on MSDN. I only select a few of them for Chinese explanation.
Wh_keyboard: Once you have a keyboard banging message (keyboard pressed, keyboard bouncing), Windows will call your hook function before the message is placed in the application's message queue. The hook function can change and discard keyboard banging messages.
Wh_mouse: Each mouse message is placed in the application's message queue before Windows will call your hook function. The hook function can change and discard mouse messages.

Wh_getmessage: Every time your application calls a GETMESSAGE () or a peekmessage () in order to request a message from the application's message queue, Windows calls your hook function. The hook function can change and discard this message.

II: Release Hooks

The hook is released using the UnhookWindowsHookEx () function
Prototype: BOOL UnhookWindowsHookEx (Hhook hhk)
The UnhookWindowsHookEx () function will release the hook process that the function SetWindowsHookEx in the hook chain is loading.
HHK: The handle to the hook process that will be released.

III: Hook Process

The hook process uses the function HookProc; in fact, HookProc is just an application-defined symbol. For example, you can write Keyboardhook. But the parameters are constant. WIN32 API provides functions such as: Callwndproc, Getmsgproc, Debugproc, Cbtproc, Mouseproc, Keyboardproc, MessageProc, for their detailed explanation, You can look at MSDN and I'll just explain what keyboardhook means here.
Prototype: LRESULT CALLBACK keyboardhook (int nCode, WPARAM WPARAM, LPARAM LPARAM)
Note: The hook process is some function attached to a hook, so the hook process is only called by Windows and not by the application, they sometimes need to act as a callback function (CALLBACK).

Parameter description:
NCode: Hook code, hook process using the hook code to decide whether to execute. The value of the hook code depends on the type of hook. Each type of hook has its own code of characteristics. For example, for Wh_keyboard, the parameters of the hook code are: Hc_action,hc_noremove. Hc_action Significance: Parameters wparam and lparam contain information about the keyboard banging message, hc_noremove meaning: The parameters wparam and lparam contain information about the keyboard banging message, and the keyboard banging message has not been removed from the message queue. (The application calls the PeekMessage function and sets the PM_NOREMOVE flag). This means that when ncode equals hc_action, the hook process must process the message. In the case of Hc_noremove, the hook process must pass the message to the CALLNEXTHOOKEX function without further processing, and must have the return value of the CallNextHookEx function.
WParam: Keyboard keystrokes generated by keyboard messages, keyboard keys for virtual code.
LParam: Contains the message details.

Note: If NCode is less than 0 in the hook process, the hook process must return (return) CallNextHookEx (Ncode,wparam,lparam), while the NCode in the hook process is greater than 0, but the hook process does not process the message. The author recommends that you call CallNextHookEx and return the function's return value. Otherwise, if another application also loads the Wh_keyboard hook, the hook will not accept the hook notification and return an incorrect value. If the hook process processes the message, it may return a non-0 value to prevent the system from passing that information to other remaining hooks or Windows processes. So it is best to return the return value of CallNextHookEx at the end of the hook process.

IV: Call the next hook function

Use the Callnexhookex function when calling the next hook function.
Prototype: LRESULT CallNextHookEx (hhook hhk, int nCode, WPARAM WPARAM, LPARAM LPARAM)
The Callnexhookex () function is used to pass the hook information to the next hook process in the current hook chain, and a hook process can call the function either before the hook is processed or after the hook is processed. Why this function is used in the "attention" in the III hook process is described in detail.
HHK: Handle to the current hook
NCode: The hook code that is sent to the hook process.
WParam: The value to be transferred to the hook process.
LParam: The value to be transferred to the hook process.
Parameters:
HHK: The handle of the current hook. The application accepts this handle as a result of a previous call to the Setwindowshooke function
NCode: Hook code to the hook process, the next hook process uses this code to decide how to handle the hook information
WParam: The value of the WParam parameter that is passed to the hook process, and the specific meaning of the parameter value is related to the hook type hooked up to the current hook chain
LParam: The value of the wparam parameter that is passed to the hook process, and the specific meaning of the parameter value is related to the hook type hooked up to the current hook chain
Return value: The return value is the value returned by the next hook process in the chain, the current hook process must return this value, the specific meaning of the return value is related to the hook type hooks, for more information, see the specific hook process description.

V Create a Dynamic Connection library (DLL)

Now that we are familiar with each of these functions, we begin to write a dynamic connection library (DLL). Here I'm using the WIN32 DLL, not the MFC DLL. And all of the following programs are written in C language. This is mainly because using the WIN32 API can be more detailed, more comprehensive control of how the implementation of the program, and using MFC, some low-level control is impossible to achieve (of course, only for the program, but also can use MFC).

1: Build A. cpp file for the dynamic Connection library. For example, we now create a file called Hookdll.cpp. In the Hookdll.cpp file, add the following:
#include <windows.h>
#include "string.h"
#include "stdio.h"

HINSTANCE HInst;

#pragma data_seg ("Hookdata")
Hhook oldkeyhook=0;
#pragma data_seg ()

#pragma COMMENT (linker, "/SECTION:HOOKDATA,RWS")

#define DllExport extern "C" __declspec (DllExport)

DllExport LRESULT CALLBACK keyboardproc (int ncode,wparam WPARAM, LPARAM LPARAM);
DllExport void Installhook (int nCode);
DllExport void Endhook (void);

BOOL WINAPI DllMain (hinstance hinstance,ulong what,lpvoid notused)
{
Switch (what)
{
Case Dll_process_attach:
HInst = hinstance;
Break
Case Dll_process_detach:
Break
Case Dll_thread_attach:
Break
Case Dll_thread_detach:
Break

}
return 1;
}

void Installhook (int nCode)
{
Oldkeyhook = SetWindowsHookEx (Wh_keyboard, (HOOKPROC) keyboardproc,hinst,0);
}

DllExport LRESULT CALLBACK keyboardproc (int ncode,wparam WPARAM, LPARAM LPARAM)
{
WPARAM J;
FILE *FP;
if (lparam&0x80000000)
{
j = WParam;
Fp=fopen ("C://hook//key.txt", "a");
fprintf (FP, "%4d", j);
Fclose (FP);
}
return CallNextHookEx (Oldkeyhook,ncode,wparam,lparam);
}
void Endhook (void)
{
UnhookWindowsHookEx (Oldkeyhook);
}
This dynamic connection library source code Hookdll.cpp contains the keyboard processing functions, sets the hooks, exits the hook function. And the key that the keyboard knocks down is saved in the format of the value to the C:/hook/key.txt file. The following is a detailed explanation of the document.
Using a function contained in a DLL, you must import it. When the import operation is done through DllImport, both dllexport and DllImport are keywords supported by the VC (Visual C + +) and BC (Borland C + +). However, the dllexport and DllImport keywords cannot be used by themselves, so it must be preceded by another extended keyword, __declspec. The general format is as follows: __declspec (specifier) where specifier is the storage class identifier. For Dll,specifier will be dllexport and DllImport. And in order to simplify the statements that describe importing and exporting functions, use a macro name instead of __declspec. In this program, you are using dllexport. If the user's DLL is compiled into a C + + program, and you want the C program to be able to use it, you need to add a "C" connection description. #define DllExport extern "C" __declspec (DllExport), which avoids the standard C + + naming corruption. (Of course, if the reader is compiling a C program, do not add the extern "C" because it is not needed and the compiler does not accept it). With a macro definition, you can now export functions with a simple statement, such as: DllExport LRESULT CALLBACK keyboardproc (int ncode,wparam WPARAM, LPARAM LPARAM) ; DllExport void Installhook (int nCode);D llexport void Endhook (void);
The first #pragma statement creates a data segment, which is named Hookdata. In fact, you can also name any of the names you like. All initialized variables after the #pragma statement enter the Hookdata segment. The second #pragma statement is the end flag for a data segment. It is important to initialize variables specifically, otherwise the compiler will place them in a normal uninitialized segment instead of Hookdata.
However, the linker must wait until there is a hookdata segment. We can select the link option in the Project Setting (vc6.0) dialog box, when Hookdll is selected in the Project Options field (both in the release and Debug configurations), with the following connection statement:/section: The Hookdata,rws letter RWs is an indication that the segment has read, write, and shared attributes. Of course, you can also specify the linker directly with the DLL source code, just like hookdll.c: #pragma comment (linker, "/SECTION:HOOKDATA,RWS").
Because some DLLs require special startup and termination code. To do this, all DLLs have a function named DllMain () that is called when the DLL is initialized or terminated. This function is typically defined in the resource file of the dynamic Nexus Library. However, if it is not defined, the compiler automatically provides the default form.
Prototype: BOOL WINAPI DllMain (hinstance hinstance,ulong what,lpvoid notused)
Parameters:
Hinstance:dll instance Handle
What: Specifies the action that occurred
notused: Reserved parameters
The value of what can be the following value:
Dll_process_attach: Process starts using DLL
Dll_process_detach: process is releasing DLL
Dll_thread_attach: The process has created a new thread
Dll_thread_detach: The process has discarded a thread
In general, whenever you call the DllMain () function, you must take the appropriate action based on what you have. This appropriate action can do nothing, but not return a value other than 0.
DllMain () The next step is setting up hooks, keyboard handling, and releasing hooks.

2: Build the header file
As with any other library function used by the application, the program must also contain the prototype of the function within the DLL. All Windows programs must contain windows.h reasons. So we now build a header file Hookdll.h as follows:
#define DllImport extern "C" __declspec (DllImport)
DllImport void Installhook (int nCode);
DllImport LRESULT CALLBACK keyboardproc (int ncode,wparam WPARAM, LPARAM LPARAM);
DllImport void Endhook (void);
Using DllImport is primarily intended to make your code more efficient, so it is recommended. However, you need to dllimport the data when you import it. When completed the above program, build a project, it may be hookdll, and then hookdll.c inserted into the project project, compile, you can generate Hookdll.dll and hookdll.lib.

3: Build program Master file
All the work we have done above is based on the current main program. In fact, when we have finished the DLL file, the rest is to call the set hook function:installhook . If you are familiar with Windows programming, you can call Installhook whenever you need it. But you have to remember that when you exit the program you need to tune Endhook to release the hook function you've loaded. Now I am building a hookspy.cpp and will generate good hookdll.dll and hookdll.lib copy to the project from a directory and build a hookspy. Insert the hookspy.cpp,hookdll.dll,hookdll.lib,hookdll.h into the project engineering. The hook is then set when the Windows window is established and exits the hook function when exiting the program. For example:
Case wm_create:
Installhook (TRUE);
Break
Case wm_destroy: //terminate the program
Endhook ();
PostQuitMessage (0);
Break;

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.