// dllmain.cpp : Définit le point d'entrée pour l'application DLL. #include "stdafx.h" #include #include /* Function to patch .text:00403B70 ; void *__thiscall Class1::LogMessageWrapper(Class1 *this, void *message, size_t messageLength) .text:00403B70 Class1__LogMessageWrapper proc near ; CODE XREF: CGbxGame__DestroyApp+58 .text:00403B70 ; CGbxGame__DestroyApp+5F ... .text:00403B70 .text:00403B70 message = dword ptr 4 .text:00403B70 messageLength = dword ptr 8 .text:00403B70 .text:00403B70 56 push esi .text:00403B71 FF 74 24 0C push [esp+4+messageLength] .text:00403B75 8B F1 mov esi, ecx .text:00403B77 FF 74 24 0C push [esp+8+message] ; message .text:00403B7B E8 D0 01 00 00 call Class1__LogMessage .text:00403B80 8B C6 mov eax, esi .text:00403B82 5E pop esi .text:00403B83 C2 08 00 retn 8 */ void __stdcall LogMessageWrapperHook() { std::cout << "[OK] Message wrapped called :D :D :D" << std::endl; } __declspec(naked) void TrampolineLogMessageWrapperHook() { __asm { // Save registers PUSHAD // Call our hook CALL LogMessageWrapperHook // Restore registers POPAD // Overwrited instructions by the patch PUSH esi PUSH[esp + 0xC] // push [esp + 4 + messageLength] // Jump back to the function... PUSH 0x403b75 RET } } void initDll() { AllocConsole(); SetConsoleTitleA("Maniaplanet Observer"); FILE* console; freopen_s(&console, "CONIN$", "r", stdin); freopen_s(&console, "CONOUT$", "w", stdout); freopen_s(&console, "CONOUT$", "w", stderr); std::cout << "[OK] Observer.dll was successfully injected, time to patch now..." << std::endl; unsigned char* addressToPatch = (unsigned char *)0x403b70; DWORD oldProtection = 0; if (*addressToPatch != 0x56 || *(addressToPatch + 1) != 0xff) { std::cout << "[ERR] Did not found 0x56 0xff which are the searched opcodes..." << std::endl; return; } else { std::cout << "[OK] Found the searched opcodes 0x56 0xff" << std::endl; } // Enable writing in memory if (!VirtualProtect(addressToPatch, 5, PAGE_EXECUTE_READWRITE, &oldProtection)) { std::cout << "[ERR] Failed to change VirtualProtect BEFORE writing memory" << std::endl; return; } else { std::cout << "[OK] Successfully changed VirtualProtect BEFORE writing memory" << std::endl; } // Change the instruction by JMP Trampoline *addressToPatch = 0xE9; // JMP INT32 --- char = 1 octet *(unsigned int*) (addressToPatch + 1) = (unsigned int) TrampolineLogMessageWrapperHook - ((unsigned int) addressToPatch + 5); std::cout << "[OK] Memory written." << std::endl; std::cout << "[INF] Patched function: 0x" << std::hex << (int)addressToPatch << std::endl; std::cout << "[INF] Trampoline function: 0x" << std::hex << ((int)TrampolineLogMessageWrapperHook) << std::endl; std::cout << "[INF] Relative jump: 0x" << std::hex << *(unsigned int*)(addressToPatch + 1) << std::endl; // Reprotect memory if (!VirtualProtect(addressToPatch, 5, oldProtection, &oldProtection)) { std::cout << "[ERR] Failed to change VirtualProtect AFTER writing memory" << std::endl; return; } else { std::cout << "[OK] Successfully changed VirtualProtect AFTER writing memory" << std::endl; } } BOOL APIENTRY DllMain( HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch (ul_reason_for_call) { case DLL_PROCESS_ATTACH: initDll(); break; case DLL_THREAD_ATTACH: case DLL_THREAD_DETACH: case DLL_PROCESS_DETACH: break; } return TRUE; }