D3D11Hook.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. // Check windows
  2. #if _WIN32 || _WIN64
  3. #if _WIN64
  4. #define ENV64BIT
  5. #else
  6. #define ENV32BIT
  7. #endif
  8. #endif
  9. // Detours imports
  10. #include "../../il2cpp/detours.h"
  11. // DX11 imports
  12. #include <D3D11.h>
  13. #pragma comment(lib, "d3d11.lib")
  14. #pragma comment(lib, "winmm.lib")
  15. #pragma comment(lib, "detours.lib")
  16. #include <Windows.h>
  17. #include "../../includes.h"
  18. #include "../imgui/ImGui/imgui_internal.h"
  19. #include "../../gui/InitGui.h"
  20. // D3X HOOK DEFINITIONS
  21. typedef HRESULT(__fastcall* IDXGISwapChainPresent)(IDXGISwapChain* pSwapChain, UINT SyncInterval, UINT Flags);
  22. typedef void(__stdcall* ID3D11DrawIndexed)(ID3D11DeviceContext* pContext, UINT IndexCount, UINT StartIndexLocation, INT BaseVertexLocation);
  23. typedef HRESULT(__stdcall* ResizeBuffers)(IDXGISwapChain* pSwapChain, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags);
  24. // Definition of WndProc Hook. Its here to avoid dragging dependencies on <windows.h> types.
  25. extern LRESULT ImGui_ImplWin32_WndProcHandler(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
  26. // Main D3D11 Objects
  27. ResizeBuffers oResizeBuffers;
  28. ID3D11DeviceContext* pContext = NULL;
  29. namespace { ID3D11Device* pDevice = NULL; }
  30. ID3D11RenderTargetView* mainRenderTargetView;
  31. static IDXGISwapChain* pSwapChain = NULL;
  32. static WNDPROC OriginalWndProcHandler = nullptr;
  33. HWND window = nullptr;
  34. IDXGISwapChainPresent fnIDXGISwapChainPresent;
  35. bool LoadTextureFromResources(LPCTSTR resource_name, LPCTSTR resource_type, ID3D11Device* pDevice, ID3D11ShaderResourceView** out_srv, int* out_width, int* out_height) {
  36. if (pDevice == nullptr)
  37. return false;
  38. HMODULE hModuleF = GetModuleHandleA("minty.dll");
  39. //HMODULE hModuleF;
  40. // Find the resource handle within the DLL
  41. HRSRC hResource = FindResource(hModuleF, resource_name, resource_type);
  42. if (!hResource) {
  43. // Resource not found
  44. return false;
  45. }
  46. // Load the resource data
  47. HGLOBAL hMemory = LoadResource(hModuleF, hResource);
  48. if (!hMemory) {
  49. // Failed to load resource
  50. return false;
  51. }
  52. // Get the resource data pointer and size
  53. LPVOID pData = LockResource(hMemory);
  54. DWORD dataSize = SizeofResource(hModuleF, hResource);
  55. // Create texture
  56. D3D11_TEXTURE2D_DESC desc;
  57. ZeroMemory(&desc, sizeof(desc));
  58. desc.Width = *out_width;
  59. desc.Height = *out_height;
  60. desc.MipLevels = 1;
  61. desc.ArraySize = 1;
  62. desc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  63. desc.SampleDesc.Count = 1;
  64. desc.Usage = D3D11_USAGE_DEFAULT;
  65. desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
  66. desc.CPUAccessFlags = 0;
  67. D3D11_SUBRESOURCE_DATA subResource;
  68. ZeroMemory(&subResource, sizeof(subResource));
  69. subResource.pSysMem = pData;
  70. subResource.SysMemPitch = desc.Width * 4;
  71. subResource.SysMemSlicePitch = 0;
  72. ID3D11Texture2D* pTexture = nullptr;
  73. pDevice->CreateTexture2D(&desc, &subResource, &pTexture);
  74. if (pTexture == nullptr)
  75. return false;
  76. // Create texture view
  77. D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc;
  78. ZeroMemory(&srvDesc, sizeof(srvDesc));
  79. srvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  80. srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
  81. srvDesc.Texture2D.MipLevels = desc.MipLevels;
  82. srvDesc.Texture2D.MostDetailedMip = 0;
  83. pDevice->CreateShaderResourceView(pTexture, &srvDesc, out_srv);
  84. pTexture->Release();
  85. *out_width = desc.Width;
  86. *out_height = desc.Height;
  87. return true;
  88. }
  89. // Boolean
  90. BOOL g_bInitialised = false;
  91. bool g_PresentHooked = false;
  92. bool m_IsPrevCursorActive = true;
  93. LRESULT CALLBACK hWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
  94. ImGuiIO& io = ImGui::GetIO();
  95. POINT mPos;
  96. GetCursorPos(&mPos);
  97. ScreenToClient(hWnd, &mPos);
  98. ImGui::GetIO().MousePos.x = static_cast<float>(mPos.x);
  99. ImGui::GetIO().MousePos.y = static_cast<float>(mPos.y);
  100. ImGui_ImplWin32_WndProcHandler(hWnd, uMsg, wParam, lParam);
  101. auto& settings = cheat::Settings::getInstance();
  102. if (settings.f_ShowMenu.getValue()) {
  103. m_IsPrevCursorActive = app::Cursor_get_visible(nullptr);
  104. if (!m_IsPrevCursorActive) {
  105. app::Cursor_set_visible(true);
  106. app::Cursor_set_lockState(app::CursorLockMode__Enum::None);
  107. }
  108. return true;
  109. }
  110. else if (!m_IsPrevCursorActive) {
  111. app::Cursor_set_visible(false);
  112. app::Cursor_set_lockState(app::CursorLockMode__Enum::Locked);
  113. }
  114. return CallWindowProc(OriginalWndProcHandler, hWnd, uMsg, wParam, lParam);
  115. }
  116. HRESULT GetDeviceAndCtxFromSwapchain(IDXGISwapChain* pSwapChain, ID3D11Device** ppDevice, ID3D11DeviceContext** ppContext) {
  117. HRESULT ret = pSwapChain->GetDevice(__uuidof(ID3D11Device), (PVOID*)ppDevice);
  118. if (SUCCEEDED(ret))
  119. (*ppDevice)->GetImmediateContext(ppContext);
  120. return ret;
  121. }
  122. HRESULT hkResizeBuffers(IDXGISwapChain* pSwapChain, UINT BufferCount, UINT Width, UINT Height, DXGI_FORMAT NewFormat, UINT SwapChainFlags) {
  123. if (mainRenderTargetView) {
  124. pContext->OMSetRenderTargets(0, 0, 0);
  125. mainRenderTargetView->Release();
  126. }
  127. HRESULT hr = oResizeBuffers(pSwapChain, BufferCount, Width, Height, DXGI_FORMAT_R8G8B8A8_UNORM, SwapChainFlags);
  128. ID3D11Texture2D* pBuffer;
  129. pSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (void**)&pBuffer);
  130. // Perform error handling here!
  131. pDevice->CreateRenderTargetView(pBuffer, NULL, &mainRenderTargetView);
  132. // Perform error handling here!
  133. pBuffer->Release();
  134. pContext->OMSetRenderTargets(1, &mainRenderTargetView, NULL);
  135. // Set up the viewport.
  136. D3D11_VIEWPORT vp;
  137. vp.Width = Width;
  138. vp.Height = Height;
  139. vp.MinDepth = 0.0f;
  140. vp.MaxDepth = 1.0f;
  141. vp.TopLeftX = 0;
  142. vp.TopLeftY = 0;
  143. pContext->RSSetViewports(1, &vp);
  144. return hr;
  145. }
  146. HRESULT __fastcall hkPresent(IDXGISwapChain* pChain, UINT SyncInterval, UINT Flags) {
  147. if (!g_bInitialised) {
  148. g_PresentHooked = true;
  149. //LOG_DEBUG("DirectX Present Hook called by first time");
  150. if (FAILED(GetDeviceAndCtxFromSwapchain(pChain, &pDevice, &pContext)))
  151. return fnIDXGISwapChainPresent(pChain, SyncInterval, Flags);
  152. pSwapChain = pChain;
  153. DXGI_SWAP_CHAIN_DESC sd;
  154. pChain->GetDesc(&sd);
  155. window = sd.OutputWindow;
  156. gui::InitImGui(window, pDevice, pContext);
  157. //Set OriginalWndProcHandler to the Address of the Original WndProc function
  158. OriginalWndProcHandler = (WNDPROC)SetWindowLongPtr(window, GWLP_WNDPROC, (LONG_PTR)hWndProc);
  159. ID3D11Texture2D* pBackBuffer;
  160. D3D11_RENDER_TARGET_VIEW_DESC rtvDesc = {};
  161. rtvDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM; // Use the UNORM format to specify RGB88 color space
  162. rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
  163. rtvDesc.Texture2D.MipSlice = 0;
  164. pChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&pBackBuffer);
  165. pDevice->CreateRenderTargetView(pBackBuffer, &rtvDesc, &mainRenderTargetView);
  166. pBackBuffer->Release();
  167. g_bInitialised = true;
  168. }
  169. gui::Render();
  170. //// Load texture from resources
  171. //int imageWidth = 512; // Specify the desired image width
  172. //int imageHeight = 512; // Specify the desired image height
  173. //ID3D11ShaderResourceView* textureSRV = nullptr;
  174. //if (LoadTextureFromResources(MAKEINTRESOURCE(103), LPCSTR("PNG"), pDevice, &textureSRV, &imageWidth, &imageHeight)) {
  175. // // Draw the texture
  176. // ImGuiWindowFlags flags = ImGuiWindowFlags_NoDecoration | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBringToFrontOnFocus | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoBackground;
  177. // //ImGui::SetNextWindowPos(ImVec2(about.width / 2, about.height * 0.063f), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
  178. // if (ImGui::Begin("Gato", nullptr, flags)) {
  179. // ImGui::Image(textureSRV, ImVec2(static_cast<float>(imageWidth), static_cast<float>(imageHeight)));
  180. // ImGui::End();
  181. // }
  182. // textureSRV->Release();
  183. //}
  184. //else {
  185. // util::log(2, "loadtex err");
  186. //}
  187. pContext->OMSetRenderTargets(1, &mainRenderTargetView, NULL);
  188. ImGui_ImplDX11_RenderDrawData(ImGui::GetDrawData());
  189. return fnIDXGISwapChainPresent(pChain, SyncInterval, Flags);
  190. }
  191. void DetourDirectXPresent() {
  192. //LOG_DEBUG("Calling fnIDXGISwapChainPresent Detour");
  193. DetourTransactionBegin();
  194. //LOG_DEBUG("Detour Begin Transaction");
  195. DetourUpdateThread(GetCurrentThread());
  196. //LOG_DEBUG("Detour Update Thread");
  197. // Detours the original fnIDXGISwapChainPresent with our Present
  198. //LOG_DEBUG("DX11 Present Address: %s", util::get_ptr(fnIDXGISwapChainPresent));
  199. //LOG_DEBUG("HookBuf Address: %s", util::get_ptr(oResizeBuffers));
  200. DetourAttach(&(LPVOID&)fnIDXGISwapChainPresent, (PBYTE)hkPresent);
  201. DetourAttach(&(LPVOID&)oResizeBuffers, (PBYTE)hkResizeBuffers);
  202. //LOG_DEBUG("DX11 Detour Attach");
  203. DetourTransactionCommit();
  204. }
  205. void PrintValues() {
  206. LOG_DEBUG("Present Address: %s", util::get_ptr(fnIDXGISwapChainPresent));
  207. LOG_DEBUG("ID3D11DeviceContext Address: %s", util::get_ptr(pContext));
  208. LOG_DEBUG("ID3D11Device Address: %s", util::get_ptr(pDevice));
  209. LOG_DEBUG("ID3D11RenderTargetView Address: %s", util::get_ptr(mainRenderTargetView));
  210. LOG_DEBUG("IDXGISwapChain Address: %s", util::get_ptr(pSwapChain));
  211. }
  212. LRESULT CALLBACK DXGIMsgProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { return DefWindowProc(hwnd, uMsg, wParam, lParam); }
  213. void GetPresent() {
  214. WNDCLASSEXA wc = { sizeof(WNDCLASSEX), CS_CLASSDC, DXGIMsgProc, 0L, 0L, GetModuleHandleA(NULL), NULL, NULL, NULL, NULL, "DX", NULL };
  215. RegisterClassExA(&wc);
  216. HWND hWnd = CreateWindowA("DX", NULL, WS_OVERLAPPEDWINDOW, 100, 100, 300, 300, NULL, NULL, wc.hInstance, NULL);
  217. DXGI_SWAP_CHAIN_DESC sd;
  218. ZeroMemory(&sd, sizeof(sd));
  219. sd.BufferCount = 1;
  220. sd.BufferDesc.Width = 2;
  221. sd.BufferDesc.Height = 2;
  222. sd.BufferDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
  223. sd.BufferDesc.RefreshRate.Numerator = 60;
  224. sd.BufferDesc.RefreshRate.Denominator = 1;
  225. sd.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT;
  226. sd.OutputWindow = hWnd;
  227. sd.SampleDesc.Count = 1;
  228. sd.SampleDesc.Quality = 0;
  229. sd.Windowed = TRUE;
  230. sd.Flags = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
  231. D3D_FEATURE_LEVEL FeatureLevelsRequested = D3D_FEATURE_LEVEL_11_0;
  232. UINT numFeatureLevelsRequested = 1;
  233. D3D_FEATURE_LEVEL FeatureLevelsSupported;
  234. HRESULT hr;
  235. IDXGISwapChain* swapchain = 0;
  236. ID3D11Device* dev = 0;
  237. ID3D11DeviceContext* devcon = 0;
  238. if (FAILED(hr = D3D11CreateDeviceAndSwapChain(NULL,
  239. D3D_DRIVER_TYPE_HARDWARE,
  240. NULL,
  241. 0,
  242. &FeatureLevelsRequested,
  243. numFeatureLevelsRequested,
  244. D3D11_SDK_VERSION,
  245. &sd,
  246. &swapchain,
  247. &dev,
  248. &FeatureLevelsSupported,
  249. &devcon))) {
  250. //util::log(M_Error, "Failed to hook Present with VT method.");
  251. return;
  252. }
  253. DWORD_PTR* pSwapChainVtable = NULL;
  254. pSwapChainVtable = (DWORD_PTR*)swapchain;
  255. pSwapChainVtable = (DWORD_PTR*)pSwapChainVtable[0];
  256. fnIDXGISwapChainPresent = (IDXGISwapChainPresent)(DWORD_PTR)pSwapChainVtable[8];
  257. oResizeBuffers = (ResizeBuffers)(DWORD_PTR)pSwapChainVtable[13];
  258. g_PresentHooked = true;
  259. Sleep(2000);
  260. }
  261. void* SwapChain[18];
  262. void* Device[40];
  263. void* Context[108];