Skip to content

Instantly share code, notes, and snippets.

@ahmetabdi
Created August 11, 2015 11:50
Show Gist options
  • Save ahmetabdi/9431620e473cb2a7c798 to your computer and use it in GitHub Desktop.
Save ahmetabdi/9431620e473cb2a7c798 to your computer and use it in GitHub Desktop.
#include "header.h"
int Counter = 0;
HWND hwnd;
const int Width = 300;
const int Height = 300;
ID3D11DeviceContext* g_DeviceContext;
ID3D11Device* g_Device;
ID3D11RenderTargetView* g_RenderTargetView;
ID3D11Texture2D* g_BackBuffer;
IDXGISwapChain* g_SwapChain;
DXGI_SWAP_CHAIN_DESC scd;
/*Used for DirectWrite */
IDWriteFactory* pDWriteFactory_;
IDWriteTextFormat* pTextFormat_;
ID2D1Factory* pD2DFactory_;
ID2D1HwndRenderTarget* pRT_;
ID2D1SolidColorBrush* pBlackBrush_;
IDWriteTextLayout* p_DWriteTextLayout;
int (__stdcall* originalClearRenderTargetView)(ID3D11DeviceContext* DeviceContext, ID3D10RenderTargetView* TargetView, const FLOAT ColorRGBA[4]);
int (__stdcall* originalPresent)(IDXGISwapChain* SwapChain, UINT _ui1, UINT _ui2);
int (__stdcall* originalDraw)(ID3D11Device* Device, UINT VertextCount, UINT StartVertextLocation);
int (__stdcall* origDrawIndexed)(ID3D11Device* Device, UINT IndexCount,UINT StartIndexLocation,INT BaseVertexLocation);
int (__stdcall* originalEnd)(ID3D11Device* Device, ID3D10Asynchronous* pAsync);
int (__stdcall* originalBegin)(ID3D11Device* Device, ID3D10Asynchronous* pAsync);
void _SetWireframe();
void _SetSolid();
void _DrawText();
void InitalizeDraw();
int WINAPI myClearRenderTargetView(ID3D11DeviceContext* DeviceContext, ID3D10RenderTargetView* TargetView, const FLOAT ColorRGBA[4])
{
g_DeviceContext = DeviceContext;
if (Counter == 0)
{
DeviceContext->GetDevice(&g_Device);
Counter++;
}
return originalClearRenderTargetView(DeviceContext, TargetView, ColorRGBA);
}
int WINAPI myPresent(IDXGISwapChain* SwapChain, UINT _ui1, UINT _ui2)
{
SwapChain->GetBuffer(0, __uuidof(*g_BackBuffer), (void**)&g_BackBuffer);
g_Device->CreateRenderTargetView(g_BackBuffer, NULL, &g_RenderTargetView);
g_DeviceContext->OMSetRenderTargets(1, &g_RenderTargetView, NULL);
return originalPresent(SwapChain, _ui1, _ui2);
}
int WINAPI myDraw(ID3D11Device* Device, UINT VertextCount, UINT StartVertextLocation)
{
return originalDraw(Device, VertextCount, StartVertextLocation);
}
int WINAPI myDrawIndexed(ID3D11Device* Device, UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation)
{
return origDrawIndexed(Device, IndexCount, StartIndexLocation, BaseVertexLocation);
}
int WINAPI myBegin(ID3D11Device* Device, ID3D10Asynchronous* pAsync)
{
return originalBegin(Device, pAsync);
}
int WINAPI myEnd(ID3D11Device* Device, ID3D10Asynchronous* pAsync)
{
return originalEnd(Device, pAsync);
}
int WINAPI DllThread()
{
HMODULE hD3D11 = NULL;
HMODULE hDXGI = NULL;
while (hD3D11 == NULL)
{
hD3D11 = GetModuleHandle("d3d11.dll");
MessageBoxA(0, "Hook success!", 0, 0);
}
while (hDXGI == NULL)
{
hDXGI = GetModuleHandle("dxgi.dll");
}
hwnd = ::FindWindow(NULL, (LPCSTR)"Game Name");
memset(&scd,0,sizeof(scd));
scd.BufferCount = 1;
scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
scd.OutputWindow = hwnd;
scd.SampleDesc.Count = 4;
scd.Windowed = ((GetWindowLong(hwnd, GWL_STYLE) & WS_POPUP) != 0) ? false : true;
scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
scd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, NULL, NULL, NULL, D3D11_SDK_VERSION, &scd, &g_SwapChain, &g_Device, NULL, &g_DeviceContext);
DWORD *vTable = NULL;
memcpy(&vTable, (void*)g_SwapChain,4);
int Addr_Present = vTable[8];
memcpy(&vTable, (void*)&g_DeviceContext, 4);
int Addr_ClearRenderTargetView = vTable[50];
int Addr_Draw = vTable[13];
int Addr_DrawIndexed = vTable[12];
int Addr_End = vTable[28];
int Addr_Begin = vTable[27];
originalClearRenderTargetView = (int (__stdcall*) (ID3D11DeviceContext* DeviceContext, ID3D10RenderTargetView* TargetView, const FLOAT ColorRGBA[4]))Addr_ClearRenderTargetView;
originalPresent = (int (_stdcall*) (IDXGISwapChain* SwapChain, UINT _ui1, UINT _ui2))Addr_Present;
originalDraw = (int (__stdcall*) (ID3D11Device* Device, UINT VertextCount, UINT StartVertextLocation))Addr_Draw;
origDrawIndexed = (int (__stdcall*) (ID3D11Device* Device,UINT IndexCount,UINT StartIndexLocation,INT BaseVertexLocation))Addr_DrawIndexed;
originalEnd = (int (__stdcall*) (ID3D11Device* Device, ID3D10Asynchronous* pAsync))Addr_End;
originalBegin = (int (__stdcall*) (ID3D11Device* Device, ID3D10Asynchronous* pAsync))Addr_Begin;
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach((PVOID*)&originalClearRenderTargetView, myClearRenderTargetView);
DetourAttach((PVOID*)&originalPresent, myPresent);
DetourAttach((PVOID*)&originalDraw, myDraw);
DetourAttach((PVOID*)&origDrawIndexed, myDrawIndexed);
DetourAttach((PVOID*)&originalEnd, myEnd);
DetourAttach((PVOID*)&originalBegin, myBegin);
DetourTransactionCommit();
return 0;
}
bool WINAPI DllMain(HMODULE hDll, DWORD reason, LPVOID reserved)
{
if (reason == DLL_PROCESS_ATTACH)
{
CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)DllThread, NULL, NULL, NULL);
}
return true;
}
void _SetWireframe()
{
ID3D11RasterizerState* rState;
D3D11_RASTERIZER_DESC rDesc;
do
{
g_DeviceContext->RSGetState(&rState);
rState->GetDesc(&rDesc);
//change to wireframe
rDesc.FillMode = D3D11_FILL_WIREFRAME;
g_Device->CreateRasterizerState(&rDesc, &rState);
g_DeviceContext->RSSetState(rState);
Sleep(100);
}
while (true);
}
void _SetSolid()
{
ID3D11RasterizerState* rState;
D3D11_RASTERIZER_DESC rDesc;
g_DeviceContext->RSGetState(&rState);
rState->GetDesc(&rDesc);
rDesc.FillMode = D3D11_FILL_SOLID;
g_Device->CreateRasterizerState(&rDesc, &rState);
g_DeviceContext->RSSetState(rState);
}
void _DrawText()
{
pRT_->BeginDraw();
D2D1_RECT_F layoutRect = D2D1::RectF(100.0f, 100.0f, 150.0f, 150.0f);
const wchar_t* text = L"Hello World!";
UINT32 textLength = (UINT32)wcslen(text);
pRT_->SetTransform(D2D1::IdentityMatrix());
pRT_->Clear(D2D1::ColorF(D2D1::ColorF::Black));
pDWriteFactory_->CreateTextLayout(text, strlen((LPCSTR)text) - 1, pTextFormat_, 250, 250, &p_DWriteTextLayout);
pRT_->DrawTextA(text, textLength, pTextFormat_, layoutRect, pBlackBrush_);
pRT_->EndDraw();
}
void InitalizeDraw()
{
HRESULT hr;
hr = D2D1CreateFactory(D2D1_FACTORY_TYPE_SINGLE_THREADED, &pD2DFactory_);
if (SUCCEEDED(hr))
{
hr = DWriteCreateFactory(DWRITE_FACTORY_TYPE_SHARED, __uuidof(IDWriteFactory), reinterpret_cast<IUnknown**>(&pDWriteFactory_));
}
if (SUCCEEDED(hr))
{
hr = pDWriteFactory_->CreateTextFormat(L"Gabriola", NULL, DWRITE_FONT_WEIGHT_REGULAR, DWRITE_FONT_STYLE_NORMAL, DWRITE_FONT_STRETCH_NORMAL, 24.0f, L"en-us", &pTextFormat_);
}
if (SUCCEEDED(hr))
{
hr = pTextFormat_->SetTextAlignment(DWRITE_TEXT_ALIGNMENT_CENTER);
}
if (SUCCEEDED(hr))
{
hr = pTextFormat_->SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT_CENTER);
}
if (SUCCEEDED(hr))
{
RECT rc;
GetClientRect(hwnd, &rc);
D2D1_SIZE_U size = D2D1::SizeU(rc.right - rc.left, rc.bottom - rc.top);
pD2DFactory_->CreateHwndRenderTarget(D2D1::RenderTargetProperties(), D2D1::HwndRenderTargetProperties(hwnd, size), &pRT_);
}
if (SUCCEEDED(hr))
{
hr = pRT_->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::White), &pBlackBrush_);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment