Hook api technology in Windows

Source: Internet
Author: User
What is hook api? The so-called hook means the hook, and the API means that Windows is open Program The operator's programming interface allows users to control the operating system, that is, the general application process needs to call the API to complete some functions, the hook api means that these applications can be intercepted before calling the real system API, so as to perform some processing before calling the real API to complete the function. Before talking about the hook api, let's take a look at how to hook messages, such as hook global keyboard messages, to know which keys the user presses. The following functions can be used to hook messages, this function adds a new hook to the original hook chain. When a message arrives, it passes through its hook chain and then delivers it to the application.

Hhook setwindowshookex (
Int Idhook , // Hook type, such Wh_keyboard,Wh_mouse
Hookproc Lpfn , // Address of the hook processing function
Hinstance Hmod , // Contains the DLL handle of the hook processing process function (if this process can be null)
DWORD Dwthreadid , // The ID of the thread to hook. If it is 0, it indicates that all
); Here we need to mention that if the hook is global rather than a specific process, we need to compile the hook process as a DLL, so that any program can load it to obtain the hook procedure function. For hook api, Microsoft does not provide direct interface functions. Maybe it does not want us to do this, but there are two ways to do this. First, modify the IAT table (that is, the input table) of the executable file, because the table records all the function addresses that call the API, you only need to change these addresses to the address of your function, but there is a limitation, because some programs will shell, so that the real IAT table will be hidden, so that this method fails. The second method is to directly jump, change the first few bytes of the API function, so that the program jumps to its own function, and then restore the first few bytes of the API, after the AP function is called, it can be switched back and hook again. However, there is also a problem with this method, that is, synchronous questions. Of course this can be overcome, this method is not restricted by program shelling. The following describes in detail how to hook an API by using an example of the send function of the hook specified program to monitor each packet sent by the program. The second method is used to compile a DLL. First, some global declarations, // the handle of the DLL
Handle g_hinstance = NULL;
// Modify the API entry to mov eax, 00400000; JMP eax is the function that the program can jump.
Byte g_btnewbytes [8] = {0xb8, 0x0, 0x0, 0x40, 0x0, 0xff, 0xe0, 0x0 };
// Save the 8 bytes of the original API entry
DWORD g_dwoldbytes [2] [2] = {0x0, 0x0, 0x0, 0x0 };
// Hook handle
Hhook g_holdhook = NULL;
// The address of the send function in the API
DWORD g_psend = 0;
// Transaction to solve the synchronization problem
Handle g_hsendevent = NULL; // your own send function address. The parameter must be the same as the send function address of the API: int _ stdcall hook_send (socket S, const char * Buf, int Len, int flags); // process to be hooked and master thread ID: DWORD g_dwprocessid = 0;
DWORD g_dwthreadid = 0; from the Declaration, we can see that we will change the first eight bytes of the API function to mov eax, 00400000; JMP eax, enabling the program to jump, you only need to get our own function address and fill out 00400000 to achieve the jump. G_dwoldbytes is used to save the original 8 bytes starting with the API, and needs to be written back when the API function is actually executed. Another point is that when declaring a new function, hook_send is used in this example. In addition to the consistency between the positive parameter and the API, it also needs to be declared as the _ stdcall type, indicates that the function clears the stack by itself before exiting. Because the stack is directly redirected to the new function, you must clear the stack by yourself. The following describes the main function, bool apientry dllmain (handle hmodule,
DWORD ul_reason_for_call,
Lpvoid lpreserved
)
{
If (ul_reason_for_call = dll_process_attach)
{// Obtain the DLL handle
G_hinstance = hmodule; // create a transaction
G_hsendevent = createevent (null, false, true, null );

// Rewrite the 8 bytes starting with the API
Hmodule hwsock = loadlibrary ("wsock32.dll ");
G_psend = (DWORD) getprocaddress (hwsock, "send"); // Save the original byte readprocessmemory (invalid_handle_value, (void *) g_psend,
(Void *) g_dwoldbytes [0], sizeof (DWORD) * 2, null); // rewrite 00400000 to the address of our function
* (DWORD *) (g_btnewbytes + 1) = (DWORD) hook_send;
Writeprocessmemory (invalid_handle_value, (void *) g_psend,
(Void *) g_btnewbytes, sizeof (DWORD) * 2, null );
}
Return true;
} The above is the main function of the DLL. When the specified program is loaded, the main function of the DLL is automatically run to complete initialization. Here, the first address of the API is rewritten to complete the jump. Of course, this program is used to hook a specified program. If you want to perform a global Hook, you can use the getmodulefilename function in the main function to obtain the complete path of the EXE file and determine whether the previous process is the process you want to hook. The Write function uses invalid_handle_value to write the current process. Int _ stdcall hook_send (socket S, const char * Buf, int Len, int flags)
{
Int nret; waitforsingleobject (g_hsendevent, infinite); // restore the first eight bytes of the API
Writeprocessmemory (invalid_handle_value, (void *) g_psend,
(Void *) g_dwoldbytes [0], sizeof (DWORD) * 2, null);/* Here you can add the desired processing process * // actually execute the API Function
Nret = Send (S, Buf, Len, flags); // write the jump statement to continue the hook
Writeprocessmemory (invalid_handle_value, (void *) g_psend,
(Void *) g_btnewbytes, sizeof (DWORD) * 2, null); setevent (g_hsendevent); Return nret;
} Hook_api bool starthook (hwnd)
{// Obtain the thread handle through the input window handle
G_dwthreadid = getwindowthreadprocessid (hwnd, & g_dwprocessid); // hook of the wh_callwndproc type
G_holdhook = setwindowshookex (wh_callwndproc, hookproc, (hinstance) g_hinstance, g_dwthreadid); If (g_holdhook = NULL)
Return false; return true;
} Static lresult winapi hookproc (INT ncode, wparam, lparam)
{Return callnexthookex (g_holdhook, ncode, wparam, lparam );
} Hook_api void stophook (void)
{
If (g_holdhook! = NULL)
{
Waitforsingleobject (g_hsendevent, infinite); handle hprocess = NULL;
Hprocess = OpenProcess (process_all_access, false, g_dwprocessid); DWORD dwoldproc;
DWORD dwnewproc; // modify the page attribute to read/write
Virtualprotectex (hprocess, (void *) g_psend, 8, page_readwrite, & dwoldproc); // restore the first 8 bytes of the API
Writeprocessmemory (hprocess, (void *) g_psend,
(Void *) g_dwoldbytes [0], sizeof (DWORD) * 2, null); // restore the properties of the page file
Virtualprotectex (hprocess, (void *) g_psend, 8, dwoldproc, & dwnewproc );

Closehandle (g_hsendevent );

Unhookwindowshookex (g_holdhook );
}
} We can see that the hook type we created is the wh_callwndproc type. This type of hook will be loaded to the process space when the process and system communicate with each other, in this way, the main function of the DLL is called to complete the real hook. The hookproc function specified in the setwindowshookex function will not be processed, but callnexthookex is called to send the message to the next link in the hook chain for processing, the only role of setwindowshookex here is to let the process load our DLL. The above is an example of the simplest hook api, which can complete many functions. For example, this method can be used to intercept sent and received packets during the online game plug-in production process, or you can add the trojan function after hook to the API, reverse connection to the specified host or listen to a port. Many shells also use this principle to hide the IAT table and fill in the function address.
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.