読者です 読者をやめる 読者になる 読者になる

めいくりぷとのブログ

技術的なことやゲームのことやら・・・

D3D9 Hook Project Template

DirectX

特にネタないので、D3D9 Hook (x86/x64)のプロジェクトテンプレート作ったついでに...
IDirect3D9/IDirect3DDevice9/IDirect3DStateBlock9.hpp はtypedefで定義してるだけのラップファイルです
基本的にはIDirect3D9/IDirect3DDevice9しか使わないので、必要になり次第追加していこうかなと。


追記:
静的の関数ポインタに動的で関数ポインタ渡すのを関数外からやってるせいで、普通に取得できてないっていう。
まあ使う時に書き直したらいいや。

#ifndef _DIRECT3D9_HPP
#define _DIRECT3D9_HPP

#include "IDirect3D9.hpp"
#include "IDirect3DDevice9.hpp"
#include "IDirect3DStateBlock9.hpp"

#ifdef _M_X86
typedef DWORD DWORD_XX;
#else 
typedef DWORD64 DWORD_XX;
#endif

class Direct3D9
{
public:
	static Direct3D9 * GetInstance();

	BOOL Initialize();

	_IDirect3D9 *m_pD3Dint;				// IDirect3D9
	_IDirect3DDevice9 *m_pD3Ddev;			// IDirect3DDevice 
	_IDirect3DStateBlock9 *m_pD3Dstate;		// IDirect3DStateBlock9

private:
	DWORD_XX *m_pVtbl;
};

#endif

#include "stdafx.h"
#include "Direct3D9.hpp"

#include <d3d9.h>
#include <d3dx9.h>

Direct3D9 * Direct3D9::GetInstance()
{
	static Direct3D9 *pInstance = new Direct3D9;
	return pInstance;
}

BOOL Direct3D9::Initialize()
{
	IDirect3D9 *pD3Dint = NULL;
	IDirect3DDevice9 *pD3Ddev = NULL;
	D3DPRESENT_PARAMETERS d3dpp;

	HWND hWnd = CreateWindow(_T("BUTTON"), _T("Temp Window"), WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, NULL, NULL);
	if (hWnd == NULL)
		return FALSE;

	pD3Dint = Direct3DCreate9(D3D_SDK_VERSION);
	if (pD3Dint == NULL)
	{
		DestroyWindow(hWnd);
		return FALSE;
	}

	ZeroMemory(&d3dpp, sizeof(D3DPRESENT_PARAMETERS));
	d3dpp.Windowed = TRUE;
	d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
	d3dpp.hDeviceWindow = hWnd;
	d3dpp.BackBufferFormat = D3DFMT_UNKNOWN;

	HRESULT hResult = pD3Dint->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &pD3Ddev);
	if (hResult != D3D_OK)
	{
		pD3Dint->Release();
		DestroyWindow(hWnd);
		return FALSE;
	}

	// IDirect3DDevice9
	m_pVtbl = reinterpret_cast<DWORD_XX*>(pD3Ddev);
	m_pVtbl = reinterpret_cast<DWORD_XX*>(m_pVtbl[0]);
	m_pD3Ddev = reinterpret_cast<_IDirect3DDevice9*>(&m_pVtbl);

	// IDirect3D
	m_pVtbl = reinterpret_cast<DWORD_XX*>(pD3Dint);
	m_pVtbl = reinterpret_cast<DWORD_XX*>(m_pVtbl[0]);
	m_pD3Dint = reinterpret_cast<_IDirect3D9*>(&m_pVtbl);

	DestroyWindow(hWnd);

	return TRUE;
}
#include "stdafx.h"

#include "Hook.hpp"
#include "detour.hpp"
#include "Direct3D9.hpp"

#define D3D_DEVICE Direct3D9::GetInstance()->m_pD3Ddev->vfptr
#define D3D_INTERFACE Direct3D9::GetInstance()->m_pD3Dint->vfptr

static pfnDrawIndexedPrimitive _DrawIndexedPrimitive = reinterpret_cast<pfnDrawIndexedPrimitive>(D3D_DEVICE->DrawIndexedPrimitive);
pfnDrawIndexedPrimitive DrawIndexedPrimitive_Hook = [](
	D3DPRIMITIVETYPE Type, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT StartIndex, UINT PrimitiveCount) -> HRESULT
{
	IDirect3DVertexBuffer9* pvBuffer;
	UINT uOffset, uStride;

	if (D3D_DEVICE->GetStreamSource(0, &pvBuffer, &uOffset, &uStride) == S_OK)
		pvBuffer->Release();

	if (uStride == 32)
	{
		D3D_DEVICE->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE);
		_DrawIndexedPrimitive(Type, BaseVertexIndex, MinVertexIndex, NumVertices, StartIndex, PrimitiveCount);
		D3D_DEVICE->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE);
	}

	return _DrawIndexedPrimitive(Type, BaseVertexIndex, MinVertexIndex, NumVertices, StartIndex, PrimitiveCount);
};

static pfnCreateQuery _CreateQuery = reinterpret_cast<pfnCreateQuery>(D3D_DEVICE->CreateQuery);
pfnCreateQuery CreateQuery_Hook = [](
	D3DQUERYTYPE Type, IDirect3DQuery9 **ppQuery) -> HRESULT
{
	if (Type == D3DQUERYTYPE_OCCLUSION)
		Type = D3DQUERYTYPE_TIMESTAMP;

	return _CreateQuery(Type, ppQuery);
};

static pfnGetDirect3D _GetDirect3D = reinterpret_cast<pfnGetDirect3D>(D3D_DEVICE->GetDirect3D);
pfnGetDirect3D GetDirect3D_Hook = [](
	IDirect3D9 **ppD3D9) -> HRESULT
{
	HRESULT hr = _GetDirect3D(ppD3D9);
	if (SUCCEEDED(hr))
		*ppD3D9 = reinterpret_cast<IDirect3D9*>(D3D_INTERFACE);
	return hr;
};

BOOL Init()
{
	if (!Direct3D9::GetInstance()->Initialize())
		return FALSE;

	DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_DrawIndexedPrimitive), DrawIndexedPrimitive_Hook);
	DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_CreateQuery), CreateQuery_Hook);
	DetourFunction(TRUE, reinterpret_cast<LPVOID*>(&_GetDirect3D), GetDirect3D_Hook);

	return TRUE;
}