maniackplanet/Observer/dllmain.cpp

169 lines
5.0 KiB
C++

// dllmain.cpp : Définit le point d'entrée pour l'application DLL.
#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>
/*
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(char* message, size_t message_length) {
std::string content(message, message_length);
std::cout << content;
}
__declspec(naked) void TrampolineLogJump()
{
__asm
{
// Save registers
PUSHAD
PUSH [esp + 32 + 8 ] // PUSHAD + shift of 8
PUSH [esp + 32 + 4 + 4 ] // PUSHAD + prev. PUSH + shift of 4
// 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
}
}
__declspec(naked) void TrampolineLogCall()
{
__asm
{
// Save registers
PUSHAD
PUSH[esp + 4 + 32 + 8] // Ret address + PUSHAD + shift of 8
PUSH[esp + 4 + 32 + 4 + 4] // Ret address + PUSHAD + prev. PUSH + shift of 4
// 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 (8 as 4 + 4 for the 2 previous PUSH)
RET
}
}
void patchJump(unsigned char* addressToPatch) {
// JMP INT32 --- char = 1 octet
*addressToPatch = 0xE9;
*(unsigned int*)(addressToPatch + 1) = (unsigned int)TrampolineLogJump - ((unsigned int)addressToPatch + 5);
std::cout << "[OK] Jump patch written." << std::endl;
std::cout << "[INF] Patched function: 0x" << std::hex << (int)addressToPatch << std::endl;
std::cout << "[INF] Trampoline function: 0x" << std::hex << ((int)TrampolineLogJump) << std::endl;
std::cout << "[INF] Relative jump: 0x" << std::hex << *(unsigned int*)(addressToPatch + 1) << std::endl;
}
// DOES NOT WORK CURRENTLY
void patchCall(unsigned char* addressToPatch) {
*addressToPatch = 0xE8;
*(unsigned int*)(addressToPatch + 1) = (unsigned int)TrampolineLogCall - ((unsigned int)addressToPatch + 5);
std::cout << "[OK] Call patch written." << std::endl;
std::cout << "[INF] Patched function: 0x" << std::hex << (int)addressToPatch << std::endl;
std::cout << "[INF] Trampoline function: 0x" << std::hex << ((int)TrampolineLogCall) << std::endl;
std::cout << "[INF] Relative jump: 0x" << std::hex << *(unsigned int*)(addressToPatch + 1) << std::endl;
}
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
patchJump(addressToPatch);
// 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;
}