Your mistakes:
The game is written on directX8, not version 9, you are trying to hook version 9, LoadLibraryA("d3d9.dll") , you need LoadLibraryA("d3d8.dll") and in the table virtual methods there, as far as I remember, have a slightly different sequence (to check which version of dx applications only need to open the debugger and view the list of loaded modules or view info on wikipedia).
You are trying (most likely, these are my guesses) to inject code into the generals.exe process, but this is just a child window and it does not perform the functions of rendering the game world \ menu, etc., you need a game.dat process.
In the evening, when I come home, I will try to redo your code in working condition and supplement the answer. If you are interested, you can read an interesting article on your topic .
UPD:
#include <Windows.h> #include <d3d8.h> #include <d3dx8.h> #pragma comment (lib, "d3d8.lib") #pragma comment (lib, "d3dx8.lib") #pragma comment( lib, "LIBCI.lib" ) #include "MessageControll.h" #include "ConsoleControll.h" //"Game.dat"+0056C9A4 // Hook Function HRESULT WINAPI HookedPresent(LPDIRECT3DDEVICE8 pDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion); HRESULT WINAPI HookedReset(LPDIRECT3DDEVICE8 pDevice, D3DPRESENT_PARAMETERS *params); // Orig Function typedef HRESULT(WINAPI* tPresent)(LPDIRECT3DDEVICE8 pDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion); typedef HRESULT(WINAPI *tReset)(LPDIRECT3DDEVICE8 pDevice, D3DPRESENT_PARAMETERS *pp); DWORD origReset = 0, origPresent = 0; tPresent _tPresent = nullptr; tReset _tReset = nullptr; ID3DXFont* pFont = nullptr; void createFont(IDirect3DDevice8* pDevice) { LOGFONT log_font = { 50, //height 0, //width; 0, // lfEscapement; 0, //lfOrientation; FW_BOLD, // lfWeight; FALSE, // lfItalic; FALSE, // lfUnderline; FALSE, // lfStrikeOut; DEFAULT_CHARSET, // lfCharSet; OUT_DEFAULT_PRECIS, //lfOutPrecision; CLIP_DEFAULT_PRECIS, // lfClipPrecision; ANTIALIASED_QUALITY,// lfQuality; DEFAULT_PITCH,// lfPitchAndFamily; "Tahoma"// lfFaceName[LF_FACESIZE]; }; HFONT font = CreateFont(10, 10, 0, 0, FW_NORMAL, false, false, false, DEFAULT_CHARSET, OUT_OUTLINE_PRECIS, 0, ANTIALIASED_QUALITY, DEFAULT_PITCH | FF_DONTCARE, "Arial"); if (D3DXCreateFontIndirect(pDevice, &log_font, &pFont) != D3D_OK) { console("D3DXCreateFontIndirect error!"); } } VOID D3DX_Font(LPDIRECT3DDEVICE8 Device_Interface) { RECT Rect = { 0,0,1000,1000 }; //if (Device_Interface != NULL) //{ // HFONT Logical_Font_Characteristics = CreateFont(16, 0, 0, 0, 400, 0, 0, 0, 0, 0, 0, 2, 0, "Arial"); // if (Logical_Font_Characteristics != NULL) // { // D3DXCreateFont(Device_Interface, Logical_Font_Characteristics, &pFont); // DeleteObject(Logical_Font_Characteristics); // } //} if (pFont != NULL) { pFont->Begin(); pFont->DrawText("StackOverflow.ru!", -1, &Rect, 0, 0xFFFF0000); pFont->End(); } } //========================================================= //if (bDrawText && m_pFont) //{ // PrintTextB(m_pFont, // 250, 20, //x, y // 255, 255, 255, 255, //color values (and then alpha) // "Testing 1234567890!!!"); //} //My custom PrintText Function: //void drawText(const D3DXVECTOR4& area, const DWORD& color, TCHAR *text, ...) //{ // TCHAR buf[1024]{}; // // RECT FontRect = { // // (long)area.x, // (long)area.y, // (long)area.x + (long)area.z, // (long)area.y + (long)area.w // }; // // va_list vaList; // va_start(vaList, text); // //#ifdef UNICODE // vswprintf_s(buf, text, vaList); //#else // vsprintf_s(buf, text, vaList); //#endif // // va_end(vaList); // // pFont->Begin(); // pFont->DrawText(buf, -1, &FontRect, 0, color); // pFont->End(); //} void* DetourCreate(BYTE *src, const BYTE *dst, const int len) { BYTE *jmp; DWORD dwback, dwold; DWORD jumpto, newjump; VirtualProtect(src, len, PAGE_EXECUTE_READWRITE, &dwback); if (src[0] == 0xE9) { jmp = (PBYTE)malloc(10); VirtualProtect(jmp, 10, PAGE_EXECUTE_READWRITE, &dwold); jumpto = (*(DWORD*)(src + 1)) + ((DWORD)src) + 5; newjump = (jumpto - (DWORD)(jmp + 5)); jmp[0] = 0xE9; *(DWORD*)(jmp + 1) = newjump; jmp += 5; jmp[0] = 0xE9; *(DWORD*)(jmp + 1) = (DWORD)(src - jmp); } else { jmp = (PBYTE)malloc(5 + len); VirtualProtect(jmp, 5 + len, PAGE_EXECUTE_READWRITE, &dwold); memcpy(jmp, src, len); jmp += len; jmp[0] = 0xE9; *(DWORD*)(jmp + 1) = (DWORD)(src + len - jmp) - 5; } src[0] = 0xE9; *(DWORD*)(src + 1) = (DWORD)(dst - src) - 5; for (int i = 5; i < len; i++) { src[i] = 0x90; } VirtualProtect(src, len, dwback, &dwback); return (jmp - len); } void GetDevice9Methods() { D3DDISPLAYMODE ds{}; D3DPRESENT_PARAMETERS pp{}; IDirect3DDevice8* dev{}; HMODULE hD3D8Dll = GetModuleHandle("d3d8.dll"); //console("address \"d3d8.dll\" [%#x]", hD3D8Dll); //Инициализируем свой девайс, чтобы узнать адреса функций ресета и презента в виртуальной таблице методов if (hD3D8Dll) { IDirect3D8* d3d8 = Direct3DCreate8(D3D_SDK_VERSION); //console("address \"IDirect3D8\" [%#x]", d3d8); if (d3d8->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &ds) != D3D_OK) { d3d8->Release(); return; } pp.Windowed = 1; pp.SwapEffect = D3DSWAPEFFECT_COPY_VSYNC; pp.BackBufferFormat = ds.Format; if (d3d8->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, GetForegroundWindow(), D3DCREATE_HARDWARE_VERTEXPROCESSING, &pp, &dev) == D3D_OK) { if (dev) { //Копируем адреса виртуальных методов origReset = *((DWORD*)(*(DWORD*)dev) + 14); origPresent = *((DWORD*)(*(DWORD*)dev) + 15); //console("address \"Reset method\" [%#x]", origReset); //console("address \"Present method\" [%#x]", origPresent); dev->Release(); d3d8->Release(); } } else { d3d8->Release(); return; } } } DWORD WINAPI InitThread(HINSTANCE hinstDLL) { //t_con.create(); GetDevice9Methods(); if (origReset && origPresent) { _tPresent = (tPresent)DetourCreate((PBYTE)origPresent, (PBYTE)HookedPresent, 5); _tReset = (tReset)DetourCreate((PBYTE)origReset, (PBYTE)HookedReset, 5); } while (!GetAsyncKeyState(VK_END)) { Sleep(1); } //t_con.del(); FreeLibraryAndExitThread(hinstDLL, 0); return 1; } HRESULT WINAPI HookedPresent(LPDIRECT3DDEVICE8 pDevice, CONST RECT* pSourceRect, CONST RECT* pDestRect, HWND hDestWindowOverride, CONST RGNDATA* pDirtyRegion) { if (!pFont) { createFont(pDevice); } else { D3DX_Font(pDevice); } D3DRECT rec = { 10, 10, 30, 30 }; //pDevice->Clear(1, &rec, D3DCLEAR_TARGET, 0xFFFF0000, 1.0f, 0); return _tPresent(pDevice, pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); } HRESULT WINAPI HookedReset(LPDIRECT3DDEVICE8 pDevice, D3DPRESENT_PARAMETERS *params) { return _tReset(pDevice, params); } BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH://Вызывается первым CreateThread(0, 0, LPTHREAD_START_ROUTINE(InitThread), hinstDLL, 0, 0); return 1; case DLL_PROCESS_DETACH://вызывается после освобождения библиотеки break; case DLL_THREAD_ATTACH://вызывается при создании потока break; case DLL_THREAD_DETACH://вызывается после разрушения потока break; } return TRUE; }
How to fix problems with lack of libci:
- Download the lib itself and upload it to the project;
- Overload additional dependencies, as stated here.
Result: 