Jump to content
Nytro

ExtendedHook Functions c++

Recommended Posts

Posted

[h=1]ExtendedHook Functions c++[/h]By RosDevil

[intro]

I decided to give away one of my master sources, a bauch of functions that are really useful to hook APIs (or any address) on x86 machines.

(i'm writing a x64 version, will be published as soon as possible)

txt.gif ExtendedHook.h 1.46K 17 downloads

txt.gif ExtendedHook.cpp 3.21K 9 downloads

[index]

This page is divided so:

- Function Documentation

- EHOOKSTRUCT structure

- Usage

- Compiler settings and notes to remember

- Example 1# - hooking MessageBox

- Example 2# - hooking DirectX (version 9 in this case)

- Example 3# - hooking WSASend

[Functions Documentation]

There are 3 main functions (InstallEHook, InstallEHookEx, CustomEHook) and 1 to unhook (UnistallEHook).

//InstallEHook
bool InstallEHook(
LPCSTR API,
LPCTSTR lib,
PEHOOKSTRUCT EHookA,
void * redit
);

PARAMETERS

LPCSTR API: the name of the API

LPCTSTR lib: module name or path

PEHOOKSTRUCT EHookA: pointer to an EHOOKSTRUCT

void * redit: address of the function that will receive the parameters of the call. When the API is called, it will be redirected there.

RETURN VALUE

If the function succeeds it returns true, otherwise false.

REMARKS

This function first tries to get the module through GetModuleHandle of the given dll name or path, if it fails, it tries a LoadLibrary.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//InstallEHookEx
bool InstallEHookEx(
void * TargetAddress,
PEHOOKSTRUCT EHookA,
void * redit
);

PARAMETERS

void * TargetAddress: in this case function you give the address of the function to hook. This function is needed especially when you try to hook a function which you don't have the definition but only the address. (See Example 2# to understand better)

PEHOOKSTRUCT EHookA: pointer to an EHOOKSTRUCT

void * redit: address of the function that will receive the parameters of the call. When the API is called, it will be redirected there.

RETURN VALUE

If the function succeeds it returns true, otherwise false.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//CustomEHook
bool CustomEHook(
void * TargetAddress,
PEHOOKSTRUCT EHookA,
void * redit,
unsigned int bytes_jmp
);

PARAMETERS

void * TargetAddress: in this case function you give the address of the function to hook. This function is needed especially when you try to hook a function which you don't have the definition but only the address. (See Example 2# to understand better)

PEHOOKSTRUCT EHookA: pointer to an EHOOKSTRUCT

void * redit: address of the function that will receive the parameters of the call. When the API is called, it will be redirected there.

unsigned int bytes_jmp: integer that cointains the number of bytes that must be copied to hook. This function is specific for the address of strange APIs that might have a particular beginning signature that the above functions don't recognize, mostly you will use this when trying to hook an address in the middle of an API, not at the beginning.

RETURN VALUE

If the function succeeds it returns true, otherwise false.

REMARKS

This function is can easily crash if you are not careful, it does not check anything and the given bytes don't corrispond to the end of a specific instruction you won't be able to call the original API, if you do it, it will crash.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//UnistallEHook
void * UninstallEHook(
PEHOOKSTRUCT EHookA
);

PARAMETER

PEHOOKSTRUCT EHookA: pointer to an EHOOKSTRUCT to unistall the hook.

RETURN VALUE

If the function succeeds it returns the original address of the API, otherwise NULL.

[EHOOKSTRUCT structure]

This structure is the core of these functions.

typedef struct _EHOOKSTRUCT{
DWORD * adr_init;
DWORD * adr_redirect;
DWORD * adr_new_api;
DWORD bytes_size;
}EHOOKSTRUCT, *PEHOOKSTRUCT;

MEMBERS

DWORD * adr_init: Stores the original address

DWORD * adr_redirect: Stores the address of the hook function

DWORD * adr_new_api: Stores the address of the NEW API

DWORD bytes_size: Number of bytes copied to perform the hook

[usage]

This is a general summary how to use these functions. It's easier if you look at the examples.

#include "ExtendedHook.h"

typedef -type- ( -Api Prototype- ) ( -parameters- );
EHOOKSTRUCT api_tohook;

//define a function exately the same of the prototype
-type- Api_function_hook ( -parameters- );


-type- Api_function_hook ( -parameters- ){
//here you can manage the paramters

return ((-Api Prototype-)api_hook.adr_new_api) (- parameters -); //perform the call with any paramters you want, right parameters or changed
}

int main(){

if (InstallEHook("-Api name-", "-Api module-", &api_tohook, &Api_function_hook) == false){
printf("Error hooking");
return 1;
}

return 0;
}

[Compiler settings and notes to remember]

This hooking method requires one change in the compiler settings.

- Disable intrinsic functions

[VC++]

Project -> Properties -> Configuration Property -> C/C++ -> Optimization -> Enable Intrinsic Functions -> [No]

Notes

- When you define the function protoype and its function hook, it must be the same of the orginal API, no changes in the parameters count, moreover remember to put WINAPI (__stdcall) in the definition when is needed, otherwise it won't work.

- There are some APIs that are necessary for any other api, like GetModuleHandle, GetProcAddress, LoadLibrary... if you want to hook these APIs remember not to call any other API inside the hook function that requires them, otherwise you will obtain an infinite loop.

[Example 1# - hooking MessageBox]

#include "stdafx.h"
#include "windows.h"
#include <iostream>
#include "ExtendedHook.h"

using namespace std;

typedef int (WINAPI * pMessageBox)(HWND myhandle, LPCWSTR text, LPCWSTR caption, UINT types); //function prototype
int WINAPI MessageBoxWHooker(HWND myhandle, LPCTSTR text, LPCTSTR caption, UINT types); //function hook
EHOOKSTRUCT myApi; //essential structure

pMessageBox myMessageBox = NULL; //optional, but i think it is useful


int _tmain(int argc, _TCHAR* argv[])
{
if (InstallEHook("MessageBoxW", L"User32.dll", &myApi, &MessageBoxWHooker) == false){
wcout<<"Error hooking"<<endl;
return 1;
}

myMessageBox = (pMessageBox)myApi.adr_new_api; //[optional] this will be a MessageBox without hook
myMessageBox(0, L"Hooking is my speciality!", L"ROSDEVIL", MB_OK | MB_ICONWARNING);

if (MessageBox(0, L"Hi, did you understand?", L"ehi", MB_YESNO) == IDYES) {//this will be hooked!
wcout<<"You have pressed yes"<<endl;
}else{
wcout<<"You have pressed no"<<endl;
}

UninstallEHook(&myApi);
cin.get();
return 0;
}

int WINAPI MessageBoxWHooker(HWND myhandle, LPCWSTR text, LPCWSTR caption, UINT types){
wcout<<"-- MessageBoxW hooked!"<<endl;
wcout<<"HWND: "<<myhandle<<endl;
wcout<<"Text: "<<text<<endl;
wcout<<"Caption: "<<caption<<endl;
wcout<<"Buttons/Icon: "<<types<<endl;

return ((pMessageBox)myApi.adr_new_api)(myhandle, text, caption, types);
}

[Example 2# - hooking DirectX (version 9 in this case)]

This is an cool example, a dll that must be injected from the very beginning of the game. If you delve into DirectX hooking you will know what i'm talking about.

It has been tested on Age of Empires 3 (x86).

//AgeOfEmpireHook.dll

#include "stdafx.h"
#include "windows.h"
#include "d3dx9.h"
#include "ExtendedHook.h"

#pragma comment(lib, "d3dx9.lib")


void start_hooking();
void WriteText(IDirect3DDevice9 * d3ddev, LPCTSTR text, long x, long y, long width, long height);
int times_load = 0;

typedef DWORD D3DCOLOR;

IDirect3DDevice9 * DeviceInterface;

//hook Direct3DCreate9
typedef IDirect3D9 *(WINAPI * pDirect3DCreate9) (UINT SDKVersion);
EHOOKSTRUCT api_Direct3DCreate9;
IDirect3D9 * WINAPI Direct3DCreate9_Hook(UINT SDKVersion);

//hook CreateDevice
typedef HRESULT (APIENTRY * pCreateDevice)(
IDirect3D9 * pDev,
UINT Adapter,
D3DDEVTYPE DeviceType,
HWND hFocusWindow,
DWORD BehaviorFlags,
D3DPRESENT_PARAMETERS* pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInterface
);
EHOOKSTRUCT api_CreateDevice;
HRESULT APIENTRY CreateDevice_hook(IDirect3D9 * pDev, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInterface);

//Hook EndScene
typedef HRESULT (WINAPI * pEndScene)(IDirect3DDevice9 * pDevInter);
EHOOKSTRUCT api_EndScene;
HRESULT WINAPI EndScene_hook(IDirect3DDevice9 * pDevInter);

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
start_hooking();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

void start_hooking(){


if (InstallEHook("Direct3DCreate9", L"d3d9.dll", &api_Direct3DCreate9, &Direct3DCreate9_Hook)==false){
MessageBox(0, L"Error while hooking Direct3DCreate9", L"Hooker", MB_OK | MB_ICONWARNING);
}
return;
}



IDirect3D9 * WINAPI Direct3DCreate9_Hook(UINT SDKVersion){
IDirect3D9 * pDev = ((pDirect3DCreate9)api_Direct3DCreate9.adr_new_api)(SDKVersion);

_asm pushad
DWORD * vtable = (DWORD*)*((DWORD*)pDev); //VTABLE
if (times_load == 1){ //the first time d3d9.dll is used, isn't for the game making, we need the second
InstallEHookEx((void*)vtable[16], &api_CreateDevice, &CreateDevice_hook);
}
times_load += 1;
_asm popad

return pDev;
}

HRESULT APIENTRY CreateDevice_hook(IDirect3D9 * pDev, UINT Adapter, D3DDEVTYPE DeviceType, HWND hFocusWindow,
DWORD BehaviorFlags, D3DPRESENT_PARAMETERS* pPresentationParameters,
IDirect3DDevice9** ppReturnedDeviceInterface){

HRESULT final = ((pCreateDevice)api_CreateDevice.adr_new_api)(pDev, Adapter, DeviceType, hFocusWindow,
BehaviorFlags, pPresentationParameters, ppReturnedDeviceInterface);

_asm pushad
DWORD * DevInterface = (DWORD*)*((DWORD*)*ppReturnedDeviceInterface); //VTABLE
InstallEHookEx((void*)DevInterface[42], &api_EndScene, &EndScene_hook); //EndScene
_asm popad

return final;
}

HRESULT WINAPI EndScene_hook(IDirect3DDevice9 * pDevInter){
_asm pushad
WriteText(pDevInter, L"AGE OF EMPIRES EXTENDED HOOK BY ROSDEVIL", 20, 20, 300, 50);
if (GetAsyncKeyState(VK_F1))WriteText(pDevInter, L"Hooked functions:\n - CreateDevice\n - EndScene\n", 20, 50, 150, 100);
_asm popad

return ((pEndScene)api_EndScene.adr_new_api)(pDevInter);
}


void WriteText(IDirect3DDevice9 * d3ddev, LPCTSTR text, long x, long y, long width, long height){
ID3DXFont *m_font;

D3DXCreateFont(d3ddev, 15, 0, FW_BOLD, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH | FF_DONTCARE, TEXT("Arial"), &m_font );
D3DCOLOR fontColor1 = D3DCOLOR_XRGB(255, 0, 0);

RECT space;
space.top = y;
space.left = x;
space.right = width + x;
space.bottom = height + y;

m_font->DrawText(NULL, text, -1, &space, 0, fontColor1);
m_font->Release();
}

[Example 3# - hooking WSASend]

This example is again a dll, but doesn't require to be injected at the very beginning since the function that we are going to hook doesn't belong to a any class.

It has been tested on Chrome to create a FormGrabber.

//ChromeHook.dll

#include "stdafx.h"
#include "windows.h"
#include "ExtendedHook.h"

bool first = true;
void start_hooking();

//I don't want to include all winsock.h so let's declare want we need:
//(you can include winsock.h, it's quicker)
typedef unsigned int SOCKET;
typedef void* LPWSAOVERLAPPED_COMPLETION_ROUTINE;

typedef struct __WSABUF {
unsigned long len;
char FAR *buf;
} WSABUF, *LPWSABUF;

typedef struct _WSAOVERLAPPED {
ULONG_PTR Internal;
ULONG_PTR InternalHigh;
union {
struct {
DWORD Offset;
DWORD OffsetHigh;
};
PVOID Pointer;
};
HANDLE hEvent;
} WSAOVERLAPPED, *LPWSAOVERLAPPED;



//hook WSASend
typedef int (WINAPI * pWSASend)(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
EHOOKSTRUCT api_WSASend;
int WINAPI WSASend_hook(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
start_hooking();
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}

void start_hooking(){

if (InstallEHook("WSASend", L"Ws2_32.dll", &api_WSASend, &WSASend_hook)==false){
MessageBox(0, L"Error while hooking WSASend", L"Hooker", MB_OK | MB_ICONWARNING);
}

}

int WINAPI WSASend_hook(
SOCKET s,
LPWSABUF lpBuffers,
DWORD dwBufferCount,
LPDWORD lpNumberOfBytesSent,
DWORD dwFlags,
LPWSAOVERLAPPED lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
){

_asm pushad
if (first == true){ //only show the first time a call is intercepted
MessageBox(0, L"WSASEND FIRST INTERCEPTED!", L"CHROME HOOK", MB_OK);
first = false;
}


//NOW WE CAN HANDLE, CRACK, COPY, ALTER, SMASH, ABORT all it's parameters!

//... your code man ...



_asm popad


return ((pWSASend)api_WSASend.adr_new_api)(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent,
dwFlags, lpOverlapped, lpCompletionRoutine);

}

Well, we're done!

PUT LIKE IF YOU APPRECIATE

I've updated my ExtendedHook.cpp, there were a little bug about the bytes to copy. [see attachment]

RosDevil

Sursa: ExtendedHook Functions c++ - rohitab.com - Forums

Posted

Da, se pot modifica datele. Cel mai practic e sa aloci memorie in procesul repsectiv (VirtualAllocEx) si sa pui in acel buffer datele modificate, iar la apelul functiei sa folosesti noile date (pointerul alocat de tine).

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...