| 2026. 7. 31. 17:21

PUBGChams

#include <Windows.h>
#include <d3d11.h>
#include <Windows.h>
#pragma comment(lib, "d3d11.lib")
 
#include "FW1FontWrapper\FW1FontWrapper.h"
#include <BeaEngine.h>
 
#pragma comment(lib, "BeaEngineCheetah64.lib")
#include <D3D11Shader.h>
#include <D3Dcompiler.h>//generateshader
#pragma comment(lib, "D3dcompiler.lib")
#include "MinHook\include\MinHook.h"

typedef HRESULT (__stdcall *D3D11PresentHook) (IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags); 
typedef void (__stdcall *D3D11DrawIndexedHook) (ID3D11DeviceContext* pContext, UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation);
typedef void (__stdcall *D3D11ClearRenderTargetViewHook) (ID3D11DeviceContext* pContext, ID3D11RenderTargetView *pRenderTargetView, const FLOAT ColorRGBA[4]);
typedef void(__stdcall *D3D11CreateQueryHook) (ID3D11Device* pDevice, const D3D11_QUERY_DESC *pQueryDesc, ID3D11Query **ppQuery);
D3D11CreateQueryHook phookD3D11CreateQuery = NULL;
ID3D11Device *pDevice = NULL;
ID3D11DeviceContext *pContext = NULL;
 
DWORD_PTR* pSwapChainVtable = NULL;
DWORD_PTR* pDeviceContextVTable = NULL;
DWORD_PTR* pDeviceVTable = NULL;

D3D11PresentHook phookD3D11Present = NULL;
D3D11DrawIndexedHook phookD3D11DrawIndexed = NULL;
D3D11ClearRenderTargetViewHook phookD3D11ClearRenderTargetView = NULL;
 
IFW1Factory *pFW1Factory = NULL;
IFW1FontWrapper *pFontWrapper = NULL;
 
bool firstTime = true;
void* detourBuffer[3];
bool acikkapali = false;

HRESULT GenerateShader(ID3D11Device* pD3DDevice, ID3D11PixelShader** pShader, float r, float g, float b)
{
	/*credits raiders*/
	char szCast[] = "struct VS_OUT"
		"{"
		"    float4 Position   : SV_Position;"
		"    float4 Color    : COLOR0;"
		"};"

		"float4 main( VS_OUT input ) : SV_Target"
		"{"
		"    float4 fake;"
		"    fake.a = 1.0;"
		"    fake.r = %f;"
		"    fake.g = %f;"
		"    fake.b = %f;"
		"    return fake;"
		"}";
	ID3D10Blob*    pBlob;
	ID3DBlob* d3dErrorMsgBlob;
	char szPixelShader[1000];

	wsprintf(szPixelShader, szCast, r, g, b);

	HRESULT hr = D3DCompile(szPixelShader, sizeof(szPixelShader), "shader", NULL, NULL, "main", "ps_4_0", NULL, NULL, &pBlob, &d3dErrorMsgBlob);

	if (FAILED(hr))
		return hr;

	hr = pD3DDevice->CreatePixelShader((DWORD*)pBlob->GetBufferPointer(), pBlob->GetBufferSize(), NULL, pShader);

	if (FAILED(hr))
		return hr;

	return S_OK;
}


ID3D11RenderTargetView* RenderTargetView = NULL;
ID3D11Texture2D* RenderTargetTexture;
ID3D11DepthStencilState* g_depthEnabled;
ID3D11DepthStencilState* g_depthDisabled;

ID3D11PixelShader* psRed = NULL;
ID3D11PixelShader* psOrange = NULL;
ID3D11Device* pD3DDevicex = 0;
enum eDepthState
{
	ENABLED,
	DISABLED,
	READ_NO_WRITE,
	NO_READ_NO_WRITE,
	_DEPTH_COUNT
};
ID3D11DepthStencilState* myDepthStencilStates[static_cast<int>(eDepthState::_DEPTH_COUNT)];
void SetDepthStencilState(eDepthState aState)
{
	pContext->OMSetDepthStencilState(myDepthStencilStates[aState], 1);
}
ID3D11Buffer *inBuffer;
DXGI_FORMAT inFormat;
UINT        inOffset;
D3D11_BUFFER_DESC indesc;


ID3D11DepthStencilState *one;
D3D11_DEPTH_STENCIL_DESC oneDesc;
UINT ref;
UINT Stride;
ID3D11Buffer *veBuffer;
UINT veBufferOffset = 0;
HRESULT __stdcall hookD3D11Present(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags)
{
	if (firstTime)
	{
		//get device and context
		if (SUCCEEDED(pSwapChain->GetDevice(__uuidof(ID3D11Device), (void **)&pDevice)))
		{
			pSwapChain->GetDevice(__uuidof(pDevice), (void**)&pDevice);
			pDevice->GetImmediateContext(&pContext);
		}

	
		//create font
		HRESULT hResult = FW1CreateFactory(FW1_VERSION, &pFW1Factory);
		hResult = pFW1Factory->CreateFontWrapper(pDevice, L"Tahoma", &pFontWrapper);
		pFW1Factory->Release();

		// use the back buffer address to create the render target
		//if (SUCCEEDED(pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), reinterpret_cast<LPVOID*>(&RenderTargetTexture))))
		if (SUCCEEDED(pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&RenderTargetTexture)))
		{
			pDevice->CreateRenderTargetView(RenderTargetTexture, NULL, &RenderTargetView);
			RenderTargetTexture->Release();
		}

		firstTime = false;
	}


	if(!psOrange)
	GenerateShader(pDevice, &psOrange, 0.0f, 0.5f, 0.0f);

	if(!psRed)
	GenerateShader(pDevice, &psRed, 0.8f, 0.0f, 0.0f);

	pContext->OMSetRenderTargets(1, &RenderTargetView, NULL);

	//draw
	/*if (pFontWrapper)
		pFontWrapper->DrawString(pContext, L"LeftSpace - First D3D11 Hook x64 - 13.07.2017", 14, 16.0f, 16.0f, 0xffff1414, FW1_RESTORESTATE);*/

	


	return phookD3D11Present(pSwapChain, SyncInterval, Flags);
}


void __stdcall hookD3D11DrawIndexed(ID3D11DeviceContext* pContext, UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation)
{
	
	pContext->IAGetVertexBuffers(0, 1, &veBuffer, &Stride, &veBufferOffset);

	pContext->GetDevice(&pD3DDevicex);
	pContext->IAGetIndexBuffer(&inBuffer, &inFormat, &inOffset);
	if (inBuffer)
		inBuffer->GetDesc(&indesc);

	
	if (acikkapali)
	{
	   if (Stride == 36) {
		pContext->OMGetDepthStencilState(&one, &ref);
		one->GetDesc(&oneDesc);
		oneDesc.DepthEnable = false;
		pD3DDevicex->CreateDepthStencilState(&oneDesc, &one);
		pContext->OMSetDepthStencilState(one, ref);
		pContext->PSSetShader(psRed, NULL, NULL);/// arka
		phookD3D11DrawIndexed(pContext, IndexCount, StartIndexLocation, BaseVertexLocation);
		oneDesc.DepthEnable = true;
		pD3DDevicex->CreateDepthStencilState(&oneDesc, &one);
		pContext->OMSetDepthStencilState(one, ref);
		pContext->PSSetShader(psOrange, NULL, NULL);/// ön
	   }
	}
	
	return phookD3D11DrawIndexed(pContext, IndexCount, StartIndexLocation, BaseVertexLocation);
}
 
void __stdcall hookD3D11ClearRenderTargetView(ID3D11DeviceContext* pContext, ID3D11RenderTargetView *pRenderTargetView, const FLOAT ColorRGBA[4])
{
	return phookD3D11ClearRenderTargetView(pContext, pRenderTargetView, ColorRGBA);
}
void __stdcall hookD3D11CreateQuery(ID3D11Device* pDevice,  D3D11_QUERY_DESC *pQueryDesc, ID3D11Query **ppQuery)
{

	if (acikkapali)
	{
		if (pQueryDesc->Query == D3D11_QUERY_OCCLUSION)
		{
			D3D11_QUERY_DESC oqueryDesc = CD3D11_QUERY_DESC();
			(&oqueryDesc)->MiscFlags = pQueryDesc->MiscFlags;
			(&oqueryDesc)->Query = D3D11_QUERY_TIMESTAMP;
		
			return phookD3D11CreateQuery(pDevice, &oqueryDesc, ppQuery);
		}
	}
	return phookD3D11CreateQuery(pDevice, pQueryDesc, ppQuery);
}

const void* DetourFuncVTable(SIZE_T* src, const BYTE* dest, const DWORD index)
{
	DWORD dwVirtualProtectBackup;
	SIZE_T* const indexPtr = &src[index];
	const void* origFunc = (void*)*indexPtr;
	VirtualProtect(indexPtr, sizeof(SIZE_T), PAGE_EXECUTE_READWRITE, &dwVirtualProtectBackup);
	*indexPtr = (SIZE_T)dest;
	VirtualProtect(indexPtr, sizeof(SIZE_T), dwVirtualProtectBackup, &dwVirtualProtectBackup);
	return origFunc;
}
DWORD_PTR* pContextVTable = NULL;
LRESULT CALLBACK DXGIMsgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return DefWindowProc(hwnd, uMsg, wParam, lParam); }
#ifdef _WIN64
	struct HookContext
	{
		BYTE original_code[64];
		SIZE_T dst_ptr;
		BYTE far_jmp[6];
	};
 
	HookContext* presenthook64;
 
	const unsigned int DisasmLengthCheck(const SIZE_T address, const unsigned int jumplength)
	{
		DISASM disasm;
		memset(&disasm, 0, sizeof(DISASM));
 
		disasm.EIP = (UIntPtr)address;
		disasm.Archi = 0x40;
 
		unsigned int processed = 0;
		while (processed < jumplength)
		{
			const int len = Disasm(&disasm);
			if (len == UNKNOWN_OPCODE)
			{
				++disasm.EIP;
			}
			else
			{
				processed += len;
				disasm.EIP += len;
			}
		}
 
		return processed;
	}
 
	const void* DetourFunc64(BYTE* const src, const BYTE* dest, const unsigned int jumplength)
	{
		// Allocate a memory page that is going to contain executable code.
		MEMORY_BASIC_INFORMATION mbi;
		for (SIZE_T addr = (SIZE_T)src; addr > (SIZE_T)src - 0x80000000; addr = (SIZE_T)mbi.BaseAddress - 1)
		{
			if (!VirtualQuery((LPCVOID)addr, &mbi, sizeof(mbi)))
			{
				break;
			}
 
			if (mbi.State == MEM_FREE)
			{
				if (presenthook64 = (HookContext*)VirtualAlloc(mbi.BaseAddress, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE))
				{
					break;
				}
			}
		}
 
		// If allocating a memory page failed, the function failed.
		if (!presenthook64)
		{
			return NULL;
		}
 
		// Select a pointer slot for the memory page to be freed on unload.
		for (int i = 0; i < sizeof(detourBuffer) / sizeof(void*); ++i)
		{
			if (!detourBuffer[i])
			{
				detourBuffer[i] = presenthook64;
				break;
			}
		}
 
		// Save original code and apply detour. The detour code is:
		// push rax
		// movabs rax, 0xCCCCCCCCCCCCCCCC
		// xchg rax, [rsp]
		// ret
		BYTE detour[] = { 0x50, 0x48, 0xB8, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0x48, 0x87, 0x04, 0x24, 0xC3 };
		const unsigned int length = DisasmLengthCheck((SIZE_T)src, jumplength);
		memcpy(presenthook64->original_code, src, length);
		memcpy(&presenthook64->original_code[length], detour, sizeof(detour));
		*(SIZE_T*)&presenthook64->original_code[length + 3] = (SIZE_T)src + length;
 
		// Build a far jump to the destination function.
		*(WORD*)&presenthook64->far_jmp = 0x25FF;
		*(DWORD*)(presenthook64->far_jmp + 2) = (DWORD)((SIZE_T)presenthook64 - (SIZE_T)src + FIELD_OFFSET(HookContext, dst_ptr) - 6);
		presenthook64->dst_ptr = (SIZE_T)dest;
 
		// Write the hook to the original function.
		DWORD flOld = 0;
		VirtualProtect(src, 6, PAGE_EXECUTE_READWRITE, &flOld);
		memcpy(src, presenthook64->far_jmp, sizeof(presenthook64->far_jmp));
		VirtualProtect(src, 6, flOld, &flOld);
 
		// Return a pointer to the original code.
		return presenthook64->original_code;
	}
#else
	const void* DetourFunc(BYTE* const src, const BYTE* dest, const DWORD length)
	{
		BYTE* jump = new BYTE[length + 5];
		for (int i = 0; i < sizeof(detourBuffer) / sizeof(void*); ++i)
		{
			if (!detourBuffer[i])
			{
				detourBuffer[i] = jump;
				break;
			}
		}
 
		DWORD dwVirtualProtectBackup;
		VirtualProtect(src, length, PAGE_READWRITE, &dwVirtualProtectBackup);
 
		memcpy(jump, src, length);
		jump += length;
 
		jump[0] = 0xE9;
		*(DWORD*)(jump + 1) = (DWORD)(src + length - jump) - 5;
 
		src[0] = 0xE9;
		*(DWORD*)(src + 1) = (DWORD)(dest - src) - 5;
 
		VirtualProtect(src, length, dwVirtualProtectBackup, &dwVirtualProtectBackup);
 
		return jump - length;
	}
#endif
	DWORD __stdcall InitializeHook(LPVOID)
	{

		HMODULE hDXGIDLL = 0;
		do
		{
			hDXGIDLL = GetModuleHandle("dxgi.dll");
			Sleep(8000);
		} while (!hDXGIDLL);
		Sleep(100);


		IDXGISwapChain* pSwapChain;

		WNDCLASSEXA wc = { sizeof(WNDCLASSEX), CS_CLASSDC, DXGIMsgProc, 0L, 0L, GetModuleHandleA(NULL), NULL, NULL, NULL, NULL, "DX", NULL };
		RegisterClassExA(&wc);
		HWND hWnd = CreateWindowA("DX", NULL, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, wc.hInstance, NULL);

		D3D_FEATURE_LEVEL requestedLevels[] = { D3D_FEATURE_LEVEL_11_0, D3D_FEATURE_LEVEL_10_1 };
		D3D_FEATURE_LEVEL obtainedLevel;
		ID3D11Device* d3dDevice = nullptr;
		ID3D11DeviceContext* d3dContext = nullptr;

		DXGI_SWAP_CHAIN_DESC scd;
		ZeroMemory(&scd, sizeof(scd));
		scd.BufferCount = 1;
		scd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
		scd.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED;
		scd.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;
		scd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;

		scd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
		scd.OutputWindow = hWnd;
		scd.SampleDesc.Count = 1;
		scd.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
		scd.Windowed = ((GetWindowLongPtr(hWnd, GWL_STYLE) & WS_POPUP) != 0) ? false : true;

		// LibOVR 0.4.3 requires that the width and height for the backbuffer is set even if
		// you use windowed mode, despite being optional according to the D3D11 documentation.
		scd.BufferDesc.Width = 1;
		scd.BufferDesc.Height = 1;
		scd.BufferDesc.RefreshRate.Numerator = 0;
		scd.BufferDesc.RefreshRate.Denominator = 1;

		UINT createFlags = 0;
#ifdef _DEBUG
		// This flag gives you some quite wonderful debug text. Not wonderful for performance, though!
		createFlags |= D3D11_CREATE_DEVICE_DEBUG;
#endif

		IDXGISwapChain* d3dSwapChain = 0;

		if (FAILED(D3D11CreateDeviceAndSwapChain(
			nullptr,
			D3D_DRIVER_TYPE_HARDWARE,
			nullptr,
			createFlags,
			requestedLevels,
			sizeof(requestedLevels) / sizeof(D3D_FEATURE_LEVEL),
			D3D11_SDK_VERSION,
			&scd,
			&pSwapChain,
			&pDevice,
			&obtainedLevel,
			&pContext)))
		{
			MessageBox(hWnd, "Failed to create directX device and swapchain!", "Error", MB_ICONERROR);
			return NULL;
		}


		pSwapChainVtable = (DWORD_PTR*)pSwapChain;
		pSwapChainVtable = (DWORD_PTR*)pSwapChainVtable[0];

		pContextVTable = (DWORD_PTR*)pContext;
		pContextVTable = (DWORD_PTR*)pContextVTable[0];

		pDeviceVTable = (DWORD_PTR*)pDevice;
		pDeviceVTable = (DWORD_PTR*)pDeviceVTable[0];

		if (MH_Initialize() != MH_OK) { return 1; }
		if (MH_CreateHook((DWORD_PTR*)pSwapChainVtable[8], hookD3D11Present, reinterpret_cast<void**>(&phookD3D11Present)) != MH_OK) { return 1; }
		if (MH_EnableHook((DWORD_PTR*)pSwapChainVtable[8]) != MH_OK) { return 1; }
		if (MH_CreateHook((DWORD_PTR*)pContextVTable[12], hookD3D11DrawIndexed, reinterpret_cast<void**>(&phookD3D11DrawIndexed)) != MH_OK) { return 1; }
		if (MH_EnableHook((DWORD_PTR*)pContextVTable[12]) != MH_OK) { return 1; }
		if (MH_CreateHook((DWORD_PTR*)pDeviceVTable[24], hookD3D11CreateQuery, reinterpret_cast<void**>(&phookD3D11CreateQuery)) != MH_OK) { return 1;}
		if (MH_EnableHook((DWORD_PTR*)pDeviceVTable[24]) != MH_OK) { return 1; }

		pDevice->Release();
		pContext->Release();
		pSwapChain->Release();

		return NULL;
	}
	DWORD __stdcall KeyHandler(LPVOID)
	{
		while (true)
		{
			if (GetAsyncKeyState(VK_INSERT)) {
				acikkapali = !acikkapali;
			}

			Sleep(100);
		}
		return 0;
	}

BOOL __stdcall DllMain(HINSTANCE hModule, DWORD dwReason, LPVOID lpReserved)
{ 
    if (dwReason == DLL_PROCESS_ATTACH)
    {
		memset(detourBuffer, 0, sizeof(detourBuffer) * sizeof(void*));
        CreateThread(NULL, 0, InitializeHook, NULL, 0, NULL);
		CreateThread(NULL, 0, KeyHandler, NULL, 0, NULL);
		
    }
    else if (dwReason == DLL_PROCESS_DETACH)
    {
		if (pFontWrapper)
		{
			pFontWrapper->Release();
		}
		
		for (int i = 0; i < sizeof(detourBuffer) / sizeof(void*); ++i)
		{
			if (detourBuffer[i])
			{
#ifdef _WIN64
				VirtualFree(detourBuffer[i], 0, MEM_RELEASE);
#else
				delete[] detourBuffer[i];
#endif
			}
		}
    }
	
    return TRUE; 
}

엄청 오래전꺼라 기록용으로..

보관용

FrostK

FrostK

Writer

기록용