Hooking is Simple (Part 3) - Infopulse
image of banner
Back

Hooking is Simple (Part 3)

It happened that on this blog you can find a few of my articles about hooking libraries. The first dealt with the general principles and implementation based on Detours, the second was about a cheaper (but nonetheless efficient) library madCodeHook. Today, I will describe one more option: the Deviare library by Nektra.

“Another identical hooking library?” you would ask. “Identical but different,” I would answer. Deviare has some distinctive features making it different from both Detours and madCodeHook and making it much more useful in some cases.

The library is distributed under the double license: GPL\commercial.

For open source projects, it can be found on GitHub, and those who need support and the right to incorporate the library’s code into a mature product are welcome to the official website. That means, yes, you can simply read the library’s code, take it from GitHub and incorporate it into your open-source project right now without paying a dime to anyone. It is a miracle unavailable with Detours and madCodeHook. It should be mentioned that the project remained closed for a long time, but then Nektra decided to be somehow closer to the people.

The library makes the base for a powerful product SpyStudio

Before writing any code for hooking, you can simply start this utility and see what it is capable of. Detours and madCodeHook have also been used to make many things, but, surprisingly, no similar software has ever been developed by the authors of these libraries.

In their blog, the authors share a bunch of case studies about hooking

There you can find hooking for SQL Server to prevent SQL injections, video recording of games, created with the use of DirectX, cheats and modifying a player’s speed in a browser. When you read it, you quickly understand how hooking should be used.

Apart from the classical С++, COM component is offered that allows hooking from anywhere (C#, Python, VB, Delphi, etc.)

Yes, finally, hooking can be used without understanding the meaning of the reference to a reference to an array of references.

Not only native functions or COM objects but also .NET methods can be hooked.

This feature doesn’t seem such a “killer”, as .NET has never had big problems with metadata and reflection, and that means that those who needed it could do it themselves. Still, why not give zest to your “pie”?

The library has long lived through all “childhood” illnesses

Today, it is used by the Fortune 500, while the partnership with VMware allows, for example, making portable versions of installed applications.

I will not write miles of code (it’s useless for an open source library with examples on GitHub). I’ll just give some overview.

An injection of your library into a foreign process:

#include “NktHookLib.h”
NktHookLibHelpers::InjectDllByPidW(dwPid, L”myDll.dll”);

Hooking a 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);
}

Finally, somehow in this way, Notepad is started from Python where you hook the CreateFileW function:

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 Deviare library!

Next Article

We have a solution to your needs. Just send us a message, and our experts will follow up with you asap.

Thank you!

We have received your request and will contact you back soon.