Эксперт
- Статус
- Оффлайн
- Регистрация
- 12 Июн 2014
- Сообщения
- 994
- Реакции
- 1,209
Закрываем все исходники и создаем новый проект.......
Часть обертки, которая работает на основе
Использование:
Часть обертки, которая работает на основе
Пожалуйста, авторизуйтесь для просмотра ссылки.
Код:
#include "MinHook\include\MinHook.h"
template<typename T>
class cDetour
{
public:
explicit cDetour<T>(T target, T detour):m_target(target), m_detour(detour)
{
MH_CreateHook(m_target, m_detour, reinterpret_cast<void**>(&m_trampoline));
}
~cDetour()
{
MH_DisableHook(m_target);
}
T GetTrampoline() const
{
return static_cast<T>(m_trampoline);
}
bool IsApplied() const
{
return m_isEnabled;
}
void Apply()
{
if (!m_isEnabled)
{
m_isEnabled = MH_EnableHook(m_target) == MH_OK;
if (m_isEnabled)
memcpy(m_hookBuffer, m_target, sizeof(m_hookBuffer));
}
}
void Remove()
{
m_isEnabled = !(m_isEnabled && MH_DisableHook(m_target) == MH_OK);
}
void EnsureApply()
{
if (memcmp(m_hookBuffer, m_target, sizeof(m_hookBuffer)) != 0)
{
DWORD oldProtect;
VirtualProtect(m_target, sizeof(m_hookBuffer), PAGE_READWRITE, &oldProtect);
memcpy(m_target, m_hookBuffer, sizeof(m_hookBuffer));
VirtualProtect(m_target, sizeof(T), oldProtect, &oldProtect);
}
}
private:
T m_trampoline;
T m_target;
T m_detour;
bool m_isEnabled = false;
char m_hookBuffer[20];
};
class cContext
{
public:
static cContext& GetInstance();
template<typename T> cDetour<T>* CreateDetour(T target, T detour)
{
auto pDetour = new cDetour<T>(target, detour);
return pDetour;
}
template<typename T> bool ApplyDetour(T target, T detour, cDetour<T>** ppDetour)
{
auto pDetour = CreateDetour(target, detour);
if (pDetour)
{
*ppDetour = pDetour;
pDetour->Apply();
return true;
}
return false;
}
void CloseExit()
{
if(!(MH_Uninitialize() == MH_OK))
TerminateProcess(GetCurrentProcess(), -1);
}
cContext(){}
~cContext(){}
};
bool bInitialized = false;
cContext& cContext::GetInstance()
{
if (!bInitialized)
bInitialized = MH_Initialize() == MH_OK;
static cContext pCtx;
return pCtx;
}
Использование:
Код:
#include <Windows.h>
#include "Detour.h"
#include <d3d9.h>
#include <d3dx9.h>
#include <Shlobj.h>
#pragma comment(lib, "d3d9.lib")
#pragma comment(lib, "d3dx9.lib")
typedef HRESULT(WINAPI* oPresent)(IDirect3DDevice9 *, CONST RECT*, CONST RECT*, HWND, CONST RGNDATA*);
cDetour<oPresent>* pPresent;
HRESULT WINAPI myPresent(IDirect3DDevice9 * m_pDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion)
{
D3DRECT rec{ 10,10,100,100 };
m_pDevice->Clear(1, &rec, D3DCLEAR_TARGET, 0xff00ff00, 0, 0);
auto result = pPresent->GetTrampoline()(m_pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion);
return result;
}
typedef HRESULT(WINAPI* oReset)(IDirect3DDevice9 *, D3DPRESENT_PARAMETERS*);
cDetour<oReset>* pReset;
HRESULT WINAPI myReset(IDirect3DDevice9* m_pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters)
{
auto hRes = pReset->GetTrampoline()(m_pDevice, pPresentationParameters);
return hRes;
}
bool Init()
{
bool bResult = false;
HMODULE hD3d9 = NULL;
if (hD3d9 = GetModuleHandleA("d3d9.dll"))
{
using oDirect3DCreate9Ex = HRESULT(WINAPI*)(UINT, IDirect3D9Ex**);
oDirect3DCreate9Ex pDirect3DCreate9Ex = (oDirect3DCreate9Ex)GetProcAddress(hD3d9, "Direct3DCreate9Ex");
if (pDirect3DCreate9Ex)
{
HRESULT hr = D3D_OK;
LPDIRECT3D9EX d3d9ex = nullptr;
if (SUCCEEDED(hr = pDirect3DCreate9Ex(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;
PVOID* vtbl = *reinterpret_cast<PVOID**>(mDevice);
auto& pContext = cContext::GetInstance();
pContext.ApplyDetour<oPresent>(static_cast<oPresent>(vtbl[17]), reinterpret_cast<oPresent>(myPresent), &pPresent);
pContext.ApplyDetour<oReset>(static_cast<oReset>(vtbl[16]), reinterpret_cast<oReset>(myReset), &pReset);
mDevice->Release();
}
d3d9ex->Release();
}
}
}
return bResult;
}
DWORD WINAPI MyThread(LPVOID lParam)
{
while (!Init())
Sleep(200);
return 0;
}
BOOL WINAPI DllMain(HINSTANCE module, DWORD dwReason, LPVOID reserved)
{
if (dwReason == DLL_PROCESS_ATTACH)
{
DisableThreadLibraryCalls(module);
CloseHandle(CreateThread(NULL, NULL, MyThread, NULL, NULL, NULL));
}
if (dwReason == DLL_PROCESS_DETACH)
{
if (pPresent)
pPresent->Remove();
if (pReset)
pReset->Remove();
}
return TRUE;
}