#include "imgui.h" #include "imgui_impl_dx9.h" #include "imgui_impl_win32.h" #include #include #pragma comment (lib, "d3d9.lib") #pragma comment (lib, "d3dx9.lib") //detours #include "detours.h" #if defined _M_X64 #pragma comment(lib, "detours.X64/detours.lib") #elif defined _M_IX86 #pragma comment(lib, "detours.X86/detours.lib") #endif #include "imgui_internal.h" #include #include #include #include #include #pragma comment( lib, "psapi.lib" ) HWND MainDlg; typedef HRESULT(APIENTRY* SetStreamSource)(IDirect3DDevice9*, UINT, IDirect3DVertexBuffer9*, UINT, UINT); SetStreamSource SetStreamSource_orig; typedef HRESULT(APIENTRY* SetVertexDeclaration)(IDirect3DDevice9*, IDirect3DVertexDeclaration9*); SetVertexDeclaration SetVertexDeclaration_orig; typedef HRESULT(APIENTRY* SetVertexShaderConstantF)(IDirect3DDevice9*, UINT, const float*, UINT); SetVertexShaderConstantF SetVertexShaderConstantF_orig; typedef HRESULT(APIENTRY* SetVertexShader)(IDirect3DDevice9*, IDirect3DVertexShader9*); SetVertexShader SetVertexShader_orig; typedef HRESULT(APIENTRY* SetPixelShader)(IDirect3DDevice9*, IDirect3DPixelShader9*);; SetPixelShader SetPixelShader_orig; typedef HRESULT(APIENTRY* DrawIndexedPrimitive)(IDirect3DDevice9*, D3DPRIMITIVETYPE, INT, UINT, UINT, UINT, UINT); DrawIndexedPrimitive DrawIndexedPrimitive_orig; typedef HRESULT(APIENTRY* DrawPrimitive)(IDirect3DDevice9*, D3DPRIMITIVETYPE, UINT, UINT); DrawPrimitive DrawPrimitive_orig; typedef HRESULT(APIENTRY* SetTexture)(IDirect3DDevice9*, DWORD, IDirect3DBaseTexture9*); SetTexture SetTexture_orig; typedef HRESULT(APIENTRY* Present) (IDirect3DDevice9*, const RECT*, const RECT*, HWND, const RGNDATA*); Present Present_orig; typedef HRESULT(APIENTRY* EndScene) (IDirect3DDevice9*); EndScene EndScene_orig; typedef HRESULT(APIENTRY* Reset)(IDirect3DDevice9*, D3DPRESENT_PARAMETERS*); Reset Reset_orig; //========================================================================================================================== WNDPROC game_wndproc = NULL; extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); LRESULT WINAPI WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)//yaptığım işlem mouse işlevini iyleştirir ve menude bişeyi tıkladığında arkada oyunda bişey tıklanmaz haraket etmez dimi oyunda deneriz sıkıntıya bakar çözeriz şunuda gösteriyim { if (ImGui_ImplWin32_WndProcHandler(hWnd, msg, wParam, lParam)) { ImGui::GetIO().MouseDrawCursor = ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow); return true; } if (ImGui::GetIO().WantCaptureMouse) { if (ImGui::IsWindowHovered(ImGuiHoveredFlags_AnyWindow)) return true; return false; } return CallWindowProc(game_wndproc, hWnd, msg, wParam, lParam); } BOOL CALLBACK find_game_hwnd(HWND hwnd, LPARAM game_pid) { DWORD hwnd_pid = NULL; GetWindowThreadProcessId(hwnd, &hwnd_pid); if (hwnd_pid != game_pid) return TRUE; game_hwnd = hwnd; return FALSE; } auto find_endscene(HWND game_window) -> void* { constexpr auto endscene_index = 42u; auto d3dpp = D3DPRESENT_PARAMETERS{}; auto d3d = Direct3DCreate9(D3D_SDK_VERSION); if (d3d) { d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = game_window; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; d3dpp.BackBufferFormat = D3DFMT_R5G6B5; d3dpp.Windowed = TRUE; IDirect3DDevice9* device{}; if (SUCCEEDED(d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, game_window, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &device))) { return (void*)*(std::intptr_t*)(*(std::intptr_t*)device + (endscene_index * sizeof(std::intptr_t))); } } return nullptr; } #define WINDOW_WIDTH 1920 #define WINDOW_HEIGHT 1080 HRESULT APIENTRY EndScene_hook(IDirect3DDevice9* pDevice) { if (pDevice == nullptr) return EndScene_orig(pDevice); OyunİçiScan(); if (GetAsyncKeyState(VK_F10) & 1) Log("endscene called"); if (!is_imgui_initialised) { //get viewport pDevice->GetViewport(&Viewport); ScreenCX = (float)Viewport.Width / 2.0f; ScreenCY = (float)Viewport.Height / 2.0f; //generate texture GenerateTexture(pDevice, &Red, D3DCOLOR_ARGB(255, 255, 0, 0)); GenerateTexture(pDevice, &Green, D3DCOLOR_RGBA(0, 255, 0, 255)); GenerateTexture(pDevice, &Blue, D3DCOLOR_ARGB(255, 0, 0, 255)); GenerateTexture(pDevice, &Yellow, D3DCOLOR_ARGB(255, 255, 255, 0)); // Setup Dear ImGui context IMGUI_CHECKVERSION(); ImGui::CreateContext(); ImGuiIO& io = ImGui::GetIO(); (void)io; io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls // Find a handle to the first top-level window belonging to the game process. EnumWindows(find_game_hwnd, GetCurrentProcessId()); // Window handle to which focus belongs for this Direct3D device (similar to EnumWindows.. above) D3DDEVICE_CREATION_PARAMETERS d3dcp; pDevice->GetCreationParameters(&d3dcp); game_hwnd = d3dcp.hFocusWindow; if (game_hwnd != NULL) { // Swap out the window message handler for our own, allowing us to intercept input events game_wndproc = (WNDPROC)SetWindowLongPtr(game_hwnd, GWLP_WNDPROC, (LONG_PTR)WndProc); // Perform final ImGui setup tasks and.. ImGui_ImplWin32_Init(game_hwnd); ImGui_ImplDX9_Init(pDevice); ImGui::GetIO().ImeWindowHandle = game_hwnd; is_imgui_initialised = true; } } ImGui_ImplDX9_NewFrame(); ImGui_ImplWin32_NewFrame(); ImGui::NewFrame(); static auto is_down = false; static auto is_clicked = false; if (GetAsyncKeyState(VK_INSERT)) { is_clicked = false; is_down = true; } else if (!GetAsyncKeyState(VK_INSERT) && is_down) { is_clicked = true; is_down = false; } else { is_clicked = false; is_down = false; } if (is_clicked) { ShowMenu = !ShowMenu; } if (ShowMenu) { ImGui::Begin("test", &ShowMenu); { } ImGui::End(); } // Rendering ImGui::EndFrame(); ImGui::Render(); ImGui_ImplDX9_RenderDrawData(ImGui::GetDrawData()); return EndScene_orig(pDevice); } //========================================================================================================================== HRESULT APIENTRY Reset_hook(IDirect3DDevice9* device, D3DPRESENT_PARAMETERS* params) noexcept { ImGui_ImplDX9_InvalidateDeviceObjects(); const auto result = Reset_orig(device, params); ImGui_ImplDX9_CreateDeviceObjects(); return result; } //========================================================================================================================== HRESULT APIENTRY SetStreamSource_hook(LPDIRECT3DDEVICE9 pDevice, UINT StreamNumber, IDirect3DVertexBuffer9* pStreamData, UINT OffsetInBytes, UINT sStride) { if (StreamNumber == 0) Stride = sStride; return SetStreamSource_orig(pDevice, StreamNumber, pStreamData, OffsetInBytes, sStride); } //========================================================================================================================== HRESULT APIENTRY SetVertexDeclaration_hook(LPDIRECT3DDEVICE9 pDevice, IDirect3DVertexDeclaration9* pdecl) { if (pdecl != NULL) { pdecl->GetDeclaration(decl, &numElements); } return SetVertexDeclaration_orig(pDevice, pdecl); } //========================================================================================================================== HRESULT APIENTRY SetVertexShaderConstantF_hook(LPDIRECT3DDEVICE9 pDevice, UINT StartRegister, const float* pConstantData, UINT Vector4fCount) { if (pConstantData != NULL) { mStartregister = StartRegister; mVectorCount = Vector4fCount; } return SetVertexShaderConstantF_orig(pDevice, StartRegister, pConstantData, Vector4fCount); } //========================================================================================================================== HRESULT APIENTRY SetVertexShader_hook(LPDIRECT3DDEVICE9 pDevice, IDirect3DVertexShader9* veShader) { if (veShader != NULL) { vShader = veShader; vShader->GetFunction(NULL, &vSize); } return SetVertexShader_orig(pDevice, veShader); } //========================================================================================================================== HRESULT APIENTRY SetPixelShader_hook(LPDIRECT3DDEVICE9 pDevice, IDirect3DPixelShader9* piShader) { if (piShader != NULL) { pShader = piShader; pShader->GetFunction(NULL, &pSize); } return SetPixelShader_orig(pDevice, piShader); } //========================================================================================================================== HRESULT APIENTRY DrawPrimitive_hook(IDirect3DDevice9* pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) { //in some games hp bars are drawn here return DrawPrimitive_orig(pDevice, PrimitiveType, StartVertex, PrimitiveCount); } //========================================================================================================================== HRESULT APIENTRY SetTexture_hook(LPDIRECT3DDEVICE9 pDevice, DWORD Sampler, IDirect3DBaseTexture9* pTexture) { //get texture/desc size (usually not needed, decreases fps) texture = static_cast(pTexture); if (texture) { if (FAILED(texture->GetLevelDesc(0, &sDesc))) goto out; if (sDesc.Pool == D3DPOOL_MANAGED && texture->GetType() == D3DRTYPE_TEXTURE) { HRESULT hr = texture->LockRect(0, &pLockedRect, NULL, D3DLOCK_DONOTWAIT | D3DLOCK_READONLY | D3DLOCK_NOSYSLOCK); if (SUCCEEDED(hr)) { if (pLockedRect.pBits != NULL) qCRC = QuickChecksum((DWORD*)pLockedRect.pBits, pLockedRect.Pitch); //get crc //qCRC = QuickChecksum((DWORD*)pLockedRect.pBits, 12); } texture->UnlockRect(0); } } out: return SetTexture_orig(pDevice, Sampler, pTexture); } //========================================================================================================================== HRESULT APIENTRY Present_hook(IDirect3DDevice9* pDevice, const RECT* pSourceRect, const RECT* pDestRect, HWND hDestWindowOverride, const RGNDATA* pDirtyRegion) { return Present_orig(pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); } //===================================================================================================================== DWORD WINAPI D3Dimgui(LPVOID lpParameter) { while (!GetModuleHandleA("d3d9.dll")) { Sleep(200); } auto d3dpp = D3DPRESENT_PARAMETERS{}; IDirect3D9* d3d = NULL; IDirect3DDevice9* d3ddev = NULL; HWND tmpWnd = CreateWindowA("BUTTON", "DX", WS_SYSMENU | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT, 300, 300, NULL, NULL, Hand, NULL); if (tmpWnd == NULL) { //Log("[DirectX] Failed to create temp window"); return 0; } d3d = Direct3DCreate9(D3D_SDK_VERSION); if (d3d == NULL) { DestroyWindow(tmpWnd); //Log("[DirectX] Failed to create temp Direct3D interface"); return 0; } ZeroMemory(&d3dpp, sizeof(d3dpp)); d3dpp.BackBufferCount = 1; d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE; d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.hDeviceWindow = tmpWnd; d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT; d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; d3dpp.BackBufferFormat = D3DFMT_R5G6B5; d3dpp.Windowed = TRUE; HRESULT result = d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, tmpWnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &d3ddev); if (result != D3D_OK) { d3d->Release(); DestroyWindow(tmpWnd); MessageBox(game_hwnd, "Run the game first and inject dll later", "Failed to create temp Direct3D device.", MB_OK); //MessageBox(game_hwnd, L"Run the game first and inject dll later", L"Failed to create temp Direct3D device.", MB_OK); //Log("[DirectX] Failed to create temp Direct3D device. Run the game first and inject dll later"); return 0; } // We have the device, so walk the vtable to get the address of all the dx functions in d3d9.dll #if defined _M_X64 DWORD64* dVtable = (DWORD64*)d3ddev; dVtable = (DWORD64*)dVtable[0]; #elif defined _M_IX86 DWORD* dVtable = (DWORD*)d3ddev; dVtable = (DWORD*)dVtable[0]; // == *d3ddev #endif SetStreamSource_orig = (SetStreamSource)dVtable[100]; SetVertexDeclaration_orig = (SetVertexDeclaration)dVtable[87]; SetVertexShaderConstantF_orig = (SetVertexShaderConstantF)dVtable[94]; SetVertexShader_orig = (SetVertexShader)dVtable[92]; SetPixelShader_orig = (SetPixelShader)dVtable[107]; DrawIndexedPrimitive_orig = (DrawIndexedPrimitive)dVtable[82]; DrawPrimitive_orig = (DrawPrimitive)dVtable[81]; SetTexture_orig = (SetTexture)dVtable[65]; Present_orig = (Present)dVtable[17]; EndScene_orig = (EndScene)dVtable[42]; Reset_orig = (Reset)dVtable[16]; DetourTransactionBegin(); DetourUpdateThread(GetCurrentThread()); DetourAttach(&(LPVOID&)SetStreamSource_orig, (PBYTE)SetStreamSource_hook); DetourAttach(&(LPVOID&)SetVertexDeclaration_orig, (PBYTE)SetVertexDeclaration_hook); DetourAttach(&(LPVOID&)SetVertexShaderConstantF_orig, (PBYTE)SetVertexShaderConstantF_hook); DetourAttach(&(LPVOID&)SetVertexShader_orig, (PBYTE)SetVertexShader_hook); DetourAttach(&(LPVOID&)SetPixelShader_orig, (PBYTE)SetPixelShader_hook); DetourAttach(&(LPVOID&)DrawPrimitive_orig, (PBYTE)DrawPrimitive_hook); DetourAttach(&(LPVOID&)SetTexture_orig, (PBYTE)SetTexture_hook); DetourAttach(&(LPVOID&)Present_orig, (PBYTE)Present_hook); DetourAttach(&(LPVOID&)EndScene_orig, (PBYTE)EndScene_hook); DetourAttach(&(LPVOID&)Reset_orig, (PBYTE)Reset_hook); DetourTransactionCommit(); //Log("[Detours] Detours attached\n"); d3ddev->Release(); d3d->Release(); DestroyWindow(tmpWnd); return 1; } //========================================================================================================================== void OpenConsole(std::string Title) { AllocConsole(); freopen("CONIN$", "r", stdin); freopen("CONOUT$", "w", stdout); freopen("CONOUT$", "w", stderr); SetConsoleTitle(Title.c_str()); } BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: Hand = hModule; DisableThreadLibraryCalls(hModule); if (Beep(100, 100)) { CreateThread(0, 0, D3Dimgui, 0, 0, 0); } break; case DLL_PROCESS_DETACH: break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: break; } return TRUE; }