You need to create a DLL and add hook functions to the DLL.
I will use the following code in C++ to create the DLL:
#include <windows.h>
#include <iostream>
HINSTANCE hThisDLL;
HHOOK hMsgHook;
BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
hThisDLL = hinstDLL;
return TRUE;
}
LRESULT CALLBACK GetMsgProc(int nCode, WPARAM wParam, LPARAM lParam)
{
//do what you want to do
return CallNextHookEx(NULL, nCode, wParam, lParam);
}
extern "C" __declspec(dllexport) BOOL InstallHook()
{
if (!hMsgHook)
hMsgHook = SetWindowsHookEx(WH_GETMESSAGE, &GetMsgProc, hThisDLL, 0);
return (hMsgHook != NULL);
}
extern "C" __declspec(dllexport) VOID UninstallHook()
{
if (hMsgHook)
{
UnhookWindowsHookEx(hMsgHook);
hMsgHook = NULL;
}
}
After generating the .dll file, you can load the dynamic library through the LoadLibrary function, and use the GetProcAddress function to get the function address in the dynamic library. Then call the hook function.
Here is the code with C++:
#include <iostream>
#include <windows.h>
typedef BOOL(WINAPI* LPInstallHook)();
typedef VOID(WINAPI* LPUninstallHook)();
int main()
{
HMODULE dll_handle;
LPInstallHook installProc;
LPUninstallHook uninstallProc;
HHOOK process_hook;
dll_handle = LoadLibrary(L"test.dll");
if (dll_handle)
{
installProc = (LPInstallHook)GetProcAddress(dll_handle, "InstallHook");
uninstallProc = (LPUninstallHook)GetProcAddress(dll_handle, "UninstallHook");
}
MSG msg;
installProc();
while (GetMessageW(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessageW(&msg);
}
uninstallProc();
if(dll_handle) FreeLibrary(dll_handle);
}
This is part of the code implemented in python, you can refer to it:
import ctypes
import os
from ctypes import *
user32 = ctypes.windll.user32
kernel32 = ctypes.windll.kernel32
if __name__ == '__main__':
dllpath = os.path.join(path,"test.dll")
pDll = ctypes.WinDLL(dllpath)
pDll.InstallHook()
msg = ctypes.wintypes.MSG()
while user32.GetMessageW(ctypes.byref(msg), 0, 0, 0) != 0:
user32.TranslateMessage(msg)
user32.DispatchMessageW(msg)
Of course, according to the documentation, you can set dwThreadId as the identifier of other threads. You can refer to the similar thread.