Code:
#define CGUnit_C__SendMovementPacket 0x007413F0
void* g_PlayerPtr = nullptr;
BYTE* trampoline = nullptr;
void* lastThis = nullptr;
int lastA2, lastA6, lastA7, lastA9;
char lastA4;
float lastA5, lastA8;
int lastOpcode;
typedef int(__thiscall* tSendMovementPacket)(void* _this, int a2, int opcode, char a4, float a5, int a6, int a7, float a8, int a9);
tSendMovementPacket oSendMovementPacket = (tSendMovementPacket)CGUnit_C__SendMovementPacket;
int _fastcall hkSendMovementPacket(void* _this, void* edx, int a2, int opcode, char a4, float a5, int a6, int a7, float a8, int a9) {
lastThis = _this;
lastA2 = a2;
lastA4 = a4;
lastA5 = a5;
lastA6 = a6;
lastA7 = a7;
lastA8 = a8;
lastA9 = a9;
lastOpcode = opcode;
int result = oSendMovementPacket(_this, a2, opcode, a4, a5, a6, a7, a8, a9);
return result;
}
DWORD WINAPI ResendThread(LPVOID lpModule) {
while (true) {
if (lastThis != nullptr) {
try {
oSendMovementPacket(lastThis, lastA2, lastOpcode, lastA4, lastA5, lastA6, lastA7, lastA8, lastA9);
}
catch (const std::exception& e) {
MessageBoxA(NULL, e.what(), "Error", MB_OK | MB_ICONERROR);
lastThis = nullptr; // Reset lastThis to avoid repeated errors
}
}
else {
Sleep(100); // Sleep if no data is available
}
Sleep(100); // Adjust sleep time as needed
}
return 0;
}
void CreateTrampoline() {
trampoline = (BYTE*)VirtualAlloc(NULL, 12, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
if (!trampoline) return;
memcpy(trampoline, (void*)CGUnit_C__SendMovementPacket, 7);
intptr_t jmpBackAddr = CGUnit_C__SendMovementPacket + 7;
intptr_t relAddrBack = (intptr_t)jmpBackAddr - ((intptr_t)trampoline+7)-5;
trampoline[7] = 0xE9; // JMP
*((int32_t*)(trampoline + 8)) = (int32_t)relAddrBack;
}
void InstallHook()
{
DWORD oldProtect;
VirtualProtect((void*)CGUnit_C__SendMovementPacket, 7, PAGE_EXECUTE_READWRITE, &oldProtect);
CreateTrampoline();
intptr_t relAddr = (intptr_t)hkSendMovementPacket - (intptr_t)CGUnit_C__SendMovementPacket - 5;
BYTE patch[7] = { 0xE9 }; // JMP instruction
*((int32_t*)(patch + 1)) = (int32_t)relAddr; // Relative address for the jump
for (int i = 5; i < 7; i++)
patch[i] = 0x90;
try {
memcpy((void*)CGUnit_C__SendMovementPacket, patch, 7);
}
catch (const std::exception& e) {
MessageBoxA(NULL, e.what(), "Error", MB_OK | MB_ICONERROR);
VirtualProtect((void*)CGUnit_C__SendMovementPacket, 7, oldProtect, &oldProtect);
return;
}
VirtualProtect((void*)CGUnit_C__SendMovementPacket, 7, oldProtect, &oldProtect);
try {
oSendMovementPacket = (tSendMovementPacket)trampoline;
}
catch (const std::exception& e) {
MessageBoxA(NULL, e.what(), "Error", MB_OK | MB_ICONERROR);
VirtualProtect((void*)CGUnit_C__SendMovementPacket, 7, oldProtect, &oldProtect);
return;
}
}