- PVSM.RU - https://www.pvsm.ru -

Хуки — это просто (часть 3)

image

Как-то так получилось, что я написал на Хабре уже несколько статей о библиотеках для хуков. Первая [1] была об общих принципах и реализации на базе Detours, вторая [2] — о более дешевой (но не менее функциональной) библиотеке madCodeHook. Сегодня я расскажу об ещё одном варианте — библиотеке Deviare [3] от компании Nektra. «Ещё одна точно такая же библиотека для хуков?» — спросите вы. «Такая же, да не такая» — отвечу я. У Deviare есть несколько особенностей, отличающих её и от Detours и от madCodeHook и делающей её в некоторых случаях намного более полезной.

Библиотека распространяется по двойной лицензии — GPLкоммерческая.

Для опенсорсных проектов она живёт на GitHub [4], а для тех, кому нужна поддержка и право внедрять код библиотеки в закрытые продукты — добро пожаловать на официальный сайт.То есть да, вы можете прямо взять и почитать код библиотеки, забрать её с GitHub и внедрить в своём опенсорс-проекте прямо сейчас не заплатив никому ни копейки. Чудо, не доступное для Detours и madCodeHook. Нужно сказать, что проект долгое время был закрытым, но потом Nektra решили, что надо быть как-то ближе к людям.

На базе библиотеки сделан мощный продукт SpyStudio [5]

Перед тем, как писать какой-то код для хуков, можно просто запустить данную утилиту и посмотреть, на что она способна. На базе Detours и madCodeHook тоже, конечно, много всякого сделано, но вот аналогичного ПО от авторов самих библиотек как-то нет.

Авторы накидали в своём блоге кучу практических примеров использования хуков

Тут вам и хуки на SQL Server [6] для предотвращения SQL-инъекций, и запись видео из игр [7], рисуемых через DirectX, и читы [8], и изменения скорости работы плеера в браузере [9]. Читаешь — и сразу становится ясно, для чего можно использовать хуки.

Кроме классического С++ предлагается COM-компонент, который позволяет ставить хуки откуда угодно (C#, Python, VB, Delphi и т.д.)

Да, наконец-то можно начать использовать хуки, не разбираясь в том, что такое указатель на указатель на массив указателей.

Хуки можно вешать не только на нативные функции или методы COM-объектов, но и на .NET-методы

Данная фича кажется мне не такой уж убойной, поскольку в .NET и так вроде бы неплохо с метаинформацией и рефлексией, а значит кому надо было — умел это делать и сам. Но так, в качестве вишенки на пироге — почему бы и нет.

Библиотека давно пережила все «детские» болезни

Сегодня её используют компании из Fortune 500, а партнёрство с VmWare позволяет делать, например [10], портабельные версии установленных приложений.

Я не буду тут расписывать километры кода (глупо это делать для опенсорсной библиотеки с примерами [11] на GitHub). Ну чисто так, обзорно.

Инъекция своей библиотеки в чужой процесс:

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

Установка хука на функцию:

#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);
}

А вот как-то так из Python запускается Notepad, в котором вешается хук на функцию CreateFileW:

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)

Удачи с библиотекой!

Автор: Инфопульс Украина

Источник [12]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/python/113460

Ссылки в тексте:

[1] Первая: https://habrahabr.ru/company/infopulse/blog/140456/

[2] вторая: https://habrahabr.ru/company/infopulse/blog/213309/

[3] Deviare: http://www.nektra.com/products/deviare-api-hook-windows/

[4] GitHub: https://github.com/nektra/Deviare-InProc/

[5] SpyStudio: http://nektra.com/products/spystudio-api-monitor/

[6] хуки на SQL Server: http://blog.nektra.com/main/2013/06/26/sql-server-interception-and-sql-injection-attacks-prevention/

[7] запись видео из игр: http://blog.nektra.com/main/2013/07/23/instrumenting-direct3d-applications-to-capture-video-and-calculate-frames-per-second/

[8] читы: https://github.com/nektra/Direct3D-Invisible-Walls

[9] изменения скорости работы плеера в браузере: http://blog.nektra.com/main/2012/06/13/controlling-the-speed-of-youtube-flash-html5-and-desktop-videos-with-deviare-hooks/

[10] например: http://blog.nektra.com/main/2013/11/05/nektra-and-vmware-are-collaborating-to-simplify-application-virtualization-packaging/

[11] примерами: https://github.com/nektra/Deviare-InProc/tree/master/Samples

[12] Источник: https://habrahabr.ru/post/277995/