Код:
#ifndef _Hook_H_
#define _Hook_H_
#pragma once
#ifdef _WIN64
typedef unsigned __int64 UPARAM;
#else
typedef unsigned long UPARAM;
#endif
class CreateHook
{
BYTE data[14];
FARPROC func;
FARPROC hookFunc;
bool bHooked;
bool b64bitJump;
DWORD oldProtect;
public:
inline CreateHook() : bHooked(false), func(NULL), hookFunc(NULL), b64bitJump(false), oldProtect(0)
{
}
inline ~CreateHook()
{
if (bHooked)
Unhook();
if (func && oldProtect)
VirtualProtect((LPVOID)func, 14, oldProtect, &oldProtect);
}
inline bool Hook(FARPROC funcIn, FARPROC hookFuncIn)
{
if (bHooked)
{
if (funcIn == func)
{
if (hookFunc != hookFuncIn)
{
hookFunc = hookFuncIn;
Rehook();
return true;
}
}
Unhook();
}
func = funcIn;
hookFunc = hookFuncIn;
if (!VirtualProtect((LPVOID)func, 14, PAGE_EXECUTE_READWRITE, &oldProtect))
return false;
memcpy(data, (const void*)func, 14);
return true;
}
inline void Rehook(bool bForce = false)
{
if ((!bForce && bHooked) || !func)
return;
UPARAM startAddr = UPARAM(func);
UPARAM targetAddr = UPARAM(hookFunc);
UPARAM offset = targetAddr - (startAddr + 5);
#ifdef _WIN64
b64bitJump = (offset > 0x7fff0000);
if (b64bitJump)
{
LPBYTE addrData = (LPBYTE)func;
*(addrData++) = 0xFF;
*(addrData++) = 0x25;
*((LPDWORD)(addrData)) = 0;
*((unsigned __int64*)(addrData + 4)) = targetAddr;
}
else
#endif
{
LPBYTE addrData = (LPBYTE)func;
*addrData = 0xE9;
*(DWORD*)(addrData + 1) = DWORD(offset);
}
bHooked = true;
}
inline void Unhook()
{
if (!bHooked || !func)
return;
UINT count = b64bitJump ? 14 : 5;
memcpy((void*)func, data, count);
bHooked = false;
}
};
#endif
Код:
CreateHook chPresent;
typedef HRESULT(WINAPI*D3D9CREATEEXPROC)(UINT, IDirect3D9Ex**);
HRESULT WINAPI SMPresent(LPDIRECT3DDEVICE9 SMGamepDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion)
{
chPresent.Unhook();
if (!Create)
{
D3DXCreateLine(SMGamepDevice, &pLine);
D3DXCreateFontW(SMGamepDevice, 13, 0, FW_BOLD, 1, 0, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, FF_MODERN, L"Tahoma", &pFont);
Create = true;
}
if (!pFont || !pLine)
{
pLine->OnLostDevice();
pFont->OnLostDevice();
}
else
{
pLine->OnLostDevice();
pLine->OnResetDevice();
pFont->OnLostDevice();
pFont->OnLostDevice();
}
HRESULT r_Present = SMGamepDevice->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
chPresent.Rehook();
return r_Present;
}
bool Interace()
{
HMODULE hD3D9 = NULL;
bool bResult = false;
char szPath[256];
SHGetFolderPathA(NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT, szPath);
strcat_s(szPath, "\\d3d9.dll");
if (hD3D9 = GetModuleHandleA(szPath))
{
D3D9CREATEEXPROC CreateEx = (D3D9CREATEEXPROC)GetProcAddress(hD3D9, "Direct3DCreate9Ex");
if (CreateEx)
{
HRESULT hr = D3D_OK;
LPDIRECT3D9EX d3d9ex = nullptr;
if (SUCCEEDED(hr = CreateEx(D3D_SDK_VERSION, &d3d9ex)))
{
D3DPRESENT_PARAMETERS dp;
ZeroMemory(&dp, sizeof(dp));
dp.Windowed = 1;
dp.SwapEffect = D3DSWAPEFFECT_FLIP;
dp.BackBufferFormat = D3DFMT_A8R8G8B8;
dp.BackBufferCount = 1;
dp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
IDirect3DDevice9Ex *mDevice = nullptr;
if (SUCCEEDED(hr = d3d9ex->CreateDeviceEx(D3DADAPTER_DEFAULT, D3DDEVTYPE_NULLREF, NULL, D3DCREATE_HARDWARE_VERTEXPROCESSING, &dp, NULL, &mDevice)))
{
bResult = true;
UPARAM * vtbl = *(UPARAM**)mDevice;
chPresent.Hook((FARPROC)*(vtbl + 17), (FARPROC)SMPresent);
mDevice->Release();
chPresent.Rehook();
}
d3d9ex->Release();
}
}
}
return bResult;
}