Skip to content

Instantly share code, notes, and snippets.

@ahmetabdi
Created April 23, 2016 00:54
Show Gist options
  • Save ahmetabdi/4efa44cf8be9a8ea31f40d6d37c3272b to your computer and use it in GitHub Desktop.
Save ahmetabdi/4efa44cf8be9a8ea31f40d6d37c3272b to your computer and use it in GitHub Desktop.
#include "Hook.h"
#include <D3DX11.h>
#include <Shlobj.h>
#include "MenuRenderer.h"
#include "Logger.h"
typedef HRESULT(WINAPI*D3D11CREATEPROC)(IDXGIAdapter*, D3D_DRIVER_TYPE, HMODULE, UINT, D3D_FEATURE_LEVEL*, UINT, UINT, DXGI_SWAP_CHAIN_DESC*, IDXGISwapChain**, IUnknown**, D3D_FEATURE_LEVEL*, IUnknown**);
HMODULE hD3D11Dll = NULL;
HookData d3d11SwapPresent;
HookData d3d11ResizeBuffer;
HookData d3d11DrawIndexed;
ID3D11Device* device = NULL;
ID3D11DeviceContext *context = 0;
D3D11Renderer* ren = nullptr;
HRESULT STDMETHODCALLTYPE DXGISwapResizeBuffersHook(IDXGISwapChain *swap, UINT bufferCount, UINT width, UINT height, DXGI_FORMAT giFormat, UINT flags)
{
d3d11ResizeBuffer.Unhook();
if (ren)
delete ren;
HRESULT hRes = swap->ResizeBuffers(bufferCount, width, height, giFormat, flags);
d3d11ResizeBuffer.Rehook();
return hRes;
}
HRESULT STDMETHODCALLTYPE DXGISwapPresentHook(IDXGISwapChain *pSwapChain, UINT syncInterval, UINT flags)
{
d3d11SwapPresent.Unhook();
ID3D11Device* device = NULL;
if (SUCCEEDED(pSwapChain->GetDevice(__uuidof(ID3D11Device), (void **)&device)))
{
device->GetImmediateContext(&context);
if (ren == nullptr)
{
ren = new D3D11Renderer(device);
ren->InitObjects();
}
if (ren->Begin())
{
DoMenu(ren);
ren->End();
}
}
HRESULT hRes = pSwapChain->Present(syncInterval, flags);
d3d11SwapPresent.Rehook();
return hRes;
}
void __stdcall D3D11DrawIndexedhook(ID3D11DeviceContext* context, UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation)
{
Logger::LogMessage("D3D11DrawIndexedhook()\n");
d3d11DrawIndexed.Unhook();
//if(GetAsyncKeyState(VK_F10) & 1 )
//Output("IndexCount == %d", IndexCount);
context->DrawIndexed(IndexCount, StartIndexLocation, BaseVertexLocation);
d3d11DrawIndexed.Rehook();
}
bool InitD3D11Hook()
{
Logger::Initialize("Blast.log");
Logger::LogMessage("InitD3D11Hook()\n");
bool bSuccess = false;
char szD3D11Path[0x110];
SHGetFolderPathA(NULL, CSIDL_SYSTEM, NULL, SHGFP_TYPE_CURRENT, szD3D11Path);
strcat_s(szD3D11Path, "\\d3d11.dll");
if (hD3D11Dll = GetModuleHandleA(szD3D11Path))
{
HRESULT hr = S_OK;
D3D11CREATEPROC d3d11Create = (D3D11CREATEPROC)GetProcAddress(hD3D11Dll, "D3D11CreateDeviceAndSwapChain");
D3D_FEATURE_LEVEL desiredLevels[6] =
{
D3D_FEATURE_LEVEL_11_0,
D3D_FEATURE_LEVEL_10_1,
D3D_FEATURE_LEVEL_10_0,
D3D_FEATURE_LEVEL_9_3,
D3D_FEATURE_LEVEL_9_2,
D3D_FEATURE_LEVEL_9_1,
};
D3D_FEATURE_LEVEL receivedLevel;
DXGI_SWAP_CHAIN_DESC sd;
ZeroMemory(&sd, sizeof(sd));
sd.BufferCount = 1;
sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
sd.OutputWindow = GetForegroundWindow();
sd.SampleDesc.Count = 1;
sd.SampleDesc.Quality = 0;
sd.Windowed = TRUE;
sd.BufferDesc.Width = 2;
sd.BufferDesc.Height = 2;
sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
sd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
IDXGISwapChain *swap = NULL;
IUnknown *device = NULL;
IUnknown *context;
hr = d3d11Create(NULL, D3D_DRIVER_TYPE_NULL, NULL, 0, desiredLevels, 6, D3D11_SDK_VERSION, &sd, &swap, &device, &receivedLevel, &context);
if (SUCCEEDED(hr))
{
context->Release();
device->Release();
bSuccess = true;
UPARAM * vtbl = *(UPARAM**)swap;
UPARAM * vtblcontext = *(UPARAM**)context;
d3d11SwapPresent.Hook((FARPROC)*(vtbl + (32 / 4)), (FARPROC)DXGISwapPresentHook);
d3d11ResizeBuffer.Hook((FARPROC)*(vtbl + (52 / 4)), (FARPROC)DXGISwapResizeBuffersHook);
d3d11DrawIndexed.Hook((FARPROC)*(vtblcontext + (48 / 4)), (FARPROC)D3D11DrawIndexedhook);
swap->Release();
d3d11SwapPresent.Rehook();
d3d11ResizeBuffer.Rehook();
d3d11DrawIndexed.Rehook();
}
}
return bSuccess;
}
void DeleteD3D11Hook()
{
d3d11SwapPresent.Unhook();
d3d11ResizeBuffer.Unhook();
if (ren)
{
delete ren;
ren = nullptr;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment