Somehow it happened that I had already written several articles about hook libraries on Habré.
The first was about the general principles and implementation based on Detours, the
second about the cheaper (but no less functional) madCodeHook library. Today I will talk about another option -
Deviare library from Nektra. “Another exactly the same library for hooks?” You ask. "The same, but not so" - I will answer. Deviare has several features that distinguish it from both Detours and madCodeHook and make it in some cases much more useful.
The library is distributed under a double license - GPL \ commercial .
For open source projects, she lives on
GitHub , and for those who need support and the right to embed library code in closed products, welcome to the official website. That is, yes, you can directly take and read the library code, pick it up from GitHub and embed it in your open-source project right now without paying a penny to anyone. Miracle not available for Detours and madCodeHook. I must say that the project was closed for a long time, but then Nektra decided that it was necessary to be somehow closer to the people.
On the basis of the library made a powerful product SpyStudio
Before writing any code for hooks, you can simply run this utility and see what it is capable of. On the basis of Detours and madCodeHook, too, of course, much has been done, but there is somehow no similar software from the authors of the libraries themselves.
')
The authors put a bunch of practical examples of using hooks in their blog.
Here you and
SQL Server hooks to prevent SQL injection, and
video recording from games drawn via DirectX, and
cheats , and
changes in the speed of the player in the browser . You read - and it becomes immediately clear why you can use hooks.
In addition to classic C ++, a COM component is offered that allows you to install hooks from anywhere (C #, Python, VB, Delphi, etc.)
Yes, you can finally start using hooks without understanding what a pointer to a pointer to an array of pointers is.
Hooks can be hung not only on native functions or methods of COM objects, but also on .NET methods
This feature seems to me not so lethal, because in .NET it seems to be quite good with meta-information and reflection, which means that it was necessary for anyone - he knew how to do it himself. But so, as a cherry on the cake - why not.
The library has long gone through all the "childhood" disease
Today, it is used by companies from the Fortune 500, and partnership with VmWare allows you to make,
for example , portable versions of installed applications.
I’m not going to paint kilometers of code here (it’s silly to do it for an open source library with
examples on GitHub). Well, purely so, well.
Injection of your library into someone else's process:
#include "NktHookLib.h" NktHookLibHelpers::InjectDllByPidW(dwPid, L"myDll.dll");
Setting the hook to the function:
#include "NktHookLib.h" typedef int (WINAPI *lpfnMessageBoxW)(__in_opt HWND hWnd, __in_opt LPCWSTR lpText, __in_opt LPCWSTR lpCaption, __in UINT uType); static int WINAPI Hooked_MessageBoxW(__in_opt HWND hWnd, __in_opt LPCWSTR lpText, __in_opt LPCWSTR lpCaption, __in UINT uType); static struct { SIZE_T nHookId; lpfnMessageBoxW fnMessageBoxW; } sMessageBoxW_Hook = { 0, NULL }; int WinMainCRTStartup() { CNktHookLib cHookMgr; HINSTANCE hUser32Dll; LPVOID fnOrigMessageBoxW; DWORD dwOsErr; hUser32Dll = NktHookLibHelpers::GetModuleBaseAddress(L"user32.dll"); if (hUser32Dll == NULL) { ::MessageBoxW(0, L"Error: Cannot get handle of user32.dll", L"HookTest", MB_OK|MB_ICONERROR); return 0; } fnOrigMessageBoxW = NktHookLibHelpers::GetProcedureAddress(hUser32Dll, "MessageBoxW"); if (fnOrigMessageBoxW == NULL) { ::MessageBoxW(0, L"Error: Cannot get address of MessageBoxW", L"HookTest", MB_OK|MB_ICONERROR); return 0; } dwOsErr = cHookMgr.Hook(&(sMessageBoxW_Hook.nHookId), (LPVOID*)&(sMessageBoxW_Hook.fnMessageBoxW), fnOrigMessageBoxW, Hooked_MessageBoxW, NKTHOOKLIB_DisallowReentrancy); ::MessageBoxW(0, L"This should be hooked", L"HookTest", MB_OK); dwOsErr = cHookMgr.Unhook(sMessageBoxW_Hook.nHookId); ::MessageBoxW(0, L"This should NOT be hooked", L"HookTest", MB_OK); return 0; } static int WINAPI Hooked_MessageBoxW(__in_opt HWND hWnd, __in_opt LPCWSTR lpText, __in_opt LPCWSTR lpCaption, __in UINT uType) { return ::MessageBoxW(hWnd, lpText, L"HOOKED!!!", uType); }
But somehow Notepad is launched from Python, in which the hook to the CreateFileW function is hung:
import win32com.client import ctypes, sys from EventHandlers import NktSpyMgrEvents from AuxFunctions import * if sys.version_info.major < 3: warnings.warn("Need Python 3.0 for this program to run", RuntimeWarning) sys.exit(0) win32com.client.pythoncom.CoInitialize() spyManager = win32com.client.DispatchWithEvents("DeviareCOM.NktSpyMgr", NktSpyMgrEvents) result = spyManager.Initialize() if not result == 0: print ("ERROR: Could not initialize the SpyManager. Error code: %d" % (result)) sys.exit(0) notepad = StartNotepadAndHook(spyManager) MessageBox = ctypes.windll.user32.MessageBoxW MessageBox(None, "Press OK to end the demo.", "Deviare Python Demo", 0) notepad.Terminate(0)
Good luck with the library!