The core principle of reverse engineering -- message hooking

Posted by dhope on Tue, 07 Dec 2021 23:21:05 +0100

HOOK

The English word Hook, translated into Chinese, means "Hook" and "fish Hook", which generally refers to all tools used to catch what you need. The basic meaning of "Hook" extends to "the means or tools used to peek or intercept information". Here are some examples to further illustrate the concept of "Hook".

Message hook

The Windows operating system provides users with a GUI (graphical user interface), which works in an Event Driven manner. In the operating system, with the help of the keyboard and mouse, selecting menus and buttons, moving the mouse, changing the size and position of the window are all events. When such an Event occurs, the OS will send the pre-defined message to the corresponding application program, and the application program will perform the corresponding action after analyzing the received information. That is, when you hit the keyboard, the message moves from the OS to the application. The so-called "message hook"

 

Hook through Windows messages

HHOOK SetWindowsHookEx(
    int idHook,                        // hook type
    HOOKpROC lpfn,                // hook procedure
    HINSTANCE hMod,                //DLL handle to which hook procedure belongs
    DWORD dwThreadId            //The thread ID that needs to be hooked. When it is 0, it is represented as a Global Hook
);

Hook procedure is a callback function called by the operating system. When installing a message hook, the hook process needs to exist inside a DLL, and the sample handle of the DLL is hMod.

After using SetWindowsHookEx() to set up the hook, when the specified message is generated in a process, OS will force the corresponding DLL file into injection, and then call the registered hook procedure.

We use a HookMain.exe to control the dll to be injected.

//HookMain.cpp
 
#include <stdio.h>
#include <conio.h>
#include <windows.h>
 
#define DEF_DLL_NAME "KeyHook.dll"
#define DEF_HOOKSTART "HookStart"
#define DEF_HOOKSTOP "HookStop"
 
typedef void (*PFN_HOOKSTART)();
typedef void (*PFN_HOOKSTOP)();
 
int main()
{
    HMODULE hDll=NULL;
    PFN_HOOKSTART HookStart=NULL;
    PFN_HOOKSTOP HookStop=NULL;
    char ch=0;
 
    //Load KeyHook.dll
    hDll=LoadLibraryA(DEF_DLL_NAME);
 
    //Get the address of the exported function
    HookStart=(PFN_HOOKSTART)GetProcAddress(hDll,DEF_HOOKSTART);
    HookStop=(PFN_HOOKSTART)GetProcAddress(hDll,DEF_HOOKSTOP);
 
    //Start hooking
    HookStart();
 
    //Wait until the user enters "q"
    printf("press 'q' to quit!\n");
    while(_getch()!='q');
 
    //End hook
    HookStop();
 
    //Uninstall KeyHook.dll
    FreeLibrary(hDll);
    return 0;
}

#define DEF_DLL_NAME "D: \ \ attack defense confrontation \ \ Dll2\Debug\Dll2.dll"  

The path of dll should be replaced with its own path, fill in its own, and use escape characters.

  dll code, establish dynamic library

#include "main.h"
#include <winnt.h>
#include <windef.h>
 
// a sample exported function
#define DEF_PROCESS_NAME "notepad.exe"
HINSTANCE g_hInstance=NULL;
HHOOK g_hHook=NULL;
HWND g_hWnd=NULL;
 
// a sample exported function
//Lrresult is a data type, which refers to the 32-bit value returned from the window program or callback function
//lParam wParam is a macro definition. It usually carries two types of parameters in the message function. It is usually used to store the parameters of window messages. WParam is used to store small pieces of messages, such as flags. lParam is usually used to store the objects required by messages.
LRESULT CALLBACK KeyboardProc(int nCode,WPARAM wParam,LPARAM lParam)
{
    char szPath[MAX_PATH]={0,};
    char *p=NULL;
 
    if (nCode>=0)
    {
        //0=key press,1=key release
        if (!(lParam&0x80000000))//When the keyboard key is released
        {
            GetModuleFileNameA(NULL,szPath,MAX_PATH);
            p=strrchr(szPath,'\\');//Finds the position of the last occurrence of a character in a specified string starting from the left
 
            //Compare the current process name. If it is notepad.exe, the message will not be delivered to the application (or the next "hook")
            if (!_stricmp(p+1,DEF_PROCESS_NAME))
                return 1;
        }
 
    }
 
    //If it is not notepad.exe, call the CallNextHookEx() function to pass the message to the application (or the next "hook").
    return CallNextHookEx(g_hHook,nCode,wParam,lParam);
 
}
 
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
        case DLL_PROCESS_ATTACH:
            // attach to process
            // return FALSE to fail DLL load
            g_hInstance=hinstDLL;
            break;
 
        case DLL_PROCESS_DETACH:
            // detach from process
            break;
 
        case DLL_THREAD_ATTACH:
            // attach to thread
            break;
 
        case DLL_THREAD_DETACH:
            // detach from thread
            break;
    }
    return TRUE; // succesful
}
#ifdef __cplusplus
extern "C"
{
#endif
 
 
    __declspec(dllexport) void HookStart()
    {
        //Hook type, callback function address, instance handle, thread ID
        g_hHook=SetWindowsHookEx(WH_KEYBOARD,KeyboardProc,g_hInstance,0);
    }
 
    __declspec(dllexport) void HookStop()
    {
        if(g_hHook)
        {
            UnhookWindowsHookEx(g_hHook);
            g_hHook=NULL;
        }
    }
 
#ifdef __cplusplus
}
#endif

 

Open notebook

Debug, start DLL and EXE (must debug and run DLL first, and then debug and run EXE)

A pop-up window appears

If you input into Notepad first, you will find that the keyboard is locked. No matter what you input, there will be no output

However, there is no problem inputting to the browser or WSP

Enter "q" in the window to exit

Topics: C++ Cyber Security