void WardenWin::HandleData(ByteBuffer& buff) { sLog.outDebug("Handle data"); m_WardenDataSent = false; m_WardenKickTimer = 0; uint16 Length; buff >> Length; uint32 Checksum; buff >> Checksum; if (!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length)) { buff.rpos(buff.wpos()); if (sWorld.getConfig(CONFIG_WARDEN_KICK)) Client->KickPlayer(); return; } bool found = false; //TIMING_CHECK { uint8 result; buff >> result; // @todo test it. if (result == 0x00) { sLog.outWarden("TIMING CHECK FAIL result 0x00"); found = true; } uint32 newClientTicks; buff >> newClientTicks; uint32 ticksNow = getMSTime(); uint32 ourTicks = newClientTicks + (ticksNow - ServerTicks); sLog.outDebug("ServerTicks %u", ticksNow); // now sLog.outDebug("RequestTicks %u", ServerTicks); // at request sLog.outDebug("Ticks %u", newClientTicks); // at response sLog.outDebug("Ticks diff %u", ourTicks - newClientTicks); } WardenDataResult* rs; WardenData* rd; uint8 type; for (std::vector<uint32>::iterator itr = SendDataId.begin(); itr != SendDataId.end(); ++itr) { rd = WardenDataStorage.GetWardenDataById(*itr); rs = WardenDataStorage.GetWardenResultById(*itr); type = rd->Type; switch (type) { case MEM_CHECK: { uint8 Mem_Result; buff >> Mem_Result; if (Mem_Result != 0) { sLog.outWarden("RESULT MEM_CHECK not 0x00, CheckId %u account Id %u", rd->id, Client->GetAccountId()); found = true; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->res.AsByteArray(0, false), rd->Length) != 0) { sLog.outWarden("RESULT MEM_CHECK fail CheckId %u account Id %u", rd->id, Client->GetAccountId()); found = true; buff.rpos(buff.rpos() + rd->Length); continue; } buff.rpos(buff.rpos() + rd->Length); sLog.outDebug("RESULT MEM_CHECK passed CheckId %u account Id %u", rd->id, Client->GetAccountId()); break; } case PAGE_CHECK_A: case PAGE_CHECK_B: case DRIVER_CHECK: case MODULE_CHECK: { const uint8 byte = 0xE9; if (memcmp(buff.contents() + buff.rpos(), &byte, sizeof(uint8)) != 0) { if (type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog.outWarden("RESULT PAGE_CHECK fail, CheckId %u account Id %u", rd->id, Client->GetAccountId()); if (type == MODULE_CHECK) sLog.outWarden("RESULT MODULE_CHECK fail, CheckId %u account Id %u", rd->id, Client->GetAccountId()); if (type == DRIVER_CHECK) sLog.outWarden("RESULT DRIVER_CHECK fail, CheckId %u account Id %u", rd->id, Client->GetAccountId()); found = true; buff.rpos(buff.rpos() + 1); continue; } buff.rpos(buff.rpos() + 1); if (type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog.outDebug("RESULT PAGE_CHECK passed CheckId %u account Id %u", rd->id, Client->GetAccountId()); else if (type == MODULE_CHECK) sLog.outDebug("RESULT MODULE_CHECK passed CheckId %u account Id %u", rd->id, Client->GetAccountId()); else if (type == DRIVER_CHECK) sLog.outDebug("RESULT DRIVER_CHECK passed CheckId %u account Id %u", rd->id, Client->GetAccountId()); break; } case LUA_STR_CHECK: { uint8 Lua_Result; buff >> Lua_Result; if (Lua_Result != 0) { sLog.outWarden("RESULT LUA_STR_CHECK fail, CheckId %u account Id %u", rd->id, Client->GetAccountId()); found = true; continue; } uint8 luaStrLen; buff >> luaStrLen; if (luaStrLen != 0) { char* str = new char[luaStrLen + 1]; memset(str, 0, luaStrLen + 1); memcpy(str, buff.contents() + buff.rpos(), luaStrLen); sLog.outDebug("Lua string: %s", str); delete[] str; } buff.rpos(buff.rpos() + luaStrLen); // skip string sLog.outDebug("RESULT LUA_STR_CHECK passed, CheckId %u account Id %u", rd->id, Client->GetAccountId()); break; } case MPQ_CHECK: { uint8 Mpq_Result; buff >> Mpq_Result; if (Mpq_Result != 0) { sLog.outWarden("RESULT MPQ_CHECK not 0x00 account id %u", Client->GetAccountId()); found = true; continue; } if (memcmp(buff.contents() + buff.rpos(), rs->res.AsByteArray(0), 20) != 0) // SHA1 { sLog.outWarden("RESULT MPQ_CHECK fail, CheckId %u account Id %u", rd->id, Client->GetAccountId()); found = true; buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 continue; } buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 sLog.outDebug("RESULT MPQ_CHECK passed, CheckId %u account Id %u", rd->id, Client->GetAccountId()); break; } default: // should never happens break; } } if (found && sWorld.getConfig(CONFIG_WARDEN_KICK)) Client->KickPlayer(); }
void WardenWin::HandleData(ByteBuffer &buff) { sLog->outStaticDebug("Handle data"); m_WardenDataSent = false; m_WardenKickTimer = 0; bool forceKick = false; uint16 Length; buff >> Length; uint32 Checksum; buff >> Checksum; if(!IsValidCheckSum(Checksum, buff.contents() + buff.rpos(), Length)) { buff.rpos(buff.wpos()); if(sWorld->getBoolConfig(CONFIG_BOOL_WARDEN_KICK)) Client->KickPlayer(); return; } bool found = false; uint8 banDays = 0; //TIMING_CHECK { uint8 result; buff >> result; // TODO: test it. if(result == 0x00) { sLog->outWarden("TIMING CHECK FAIL result 0x00"); found = true; } uint32 newClientTicks; buff >> newClientTicks; uint32 ticksNow = getMSTime(); uint32 ourTicks = newClientTicks + (ticksNow - ServerTicks); sLog->outStaticDebug("ServerTicks %u", ticksNow); // now sLog->outStaticDebug("RequestTicks %u", ServerTicks); // at request sLog->outStaticDebug("Ticks %u", newClientTicks); // at response sLog->outStaticDebug("Ticks diff %u", ourTicks - newClientTicks); } WardenDataResult *rs; WardenData *rd; uint8 type; for(std::vector<uint32>::iterator itr = SendDataId.begin(); itr != SendDataId.end(); ++itr) { if(forceKick) break; rd = WardenDataStorage.GetWardenDataById(*itr); rs = WardenDataStorage.GetWardenResultById(*itr); type = rd->Type; switch(type) { case MEM_CHECK: { uint8 Mem_Result; buff >> Mem_Result; if(Mem_Result != 0) { sLog->outWarden("RESULT MEM_CHECK not 0x00, CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); forceKick = true; banDays = 0; found = true; continue; } if(memcmp(buff.contents() + buff.rpos(), rs->res.AsByteArray(0, false), rd->Length) != 0) { sLog->outWarden("RESULT MEM_CHECK fail CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); found = true; if(rd->banDays > banDays) banDays = rd->banDays; buff.rpos(buff.rpos() + rd->Length); continue; } buff.rpos(buff.rpos() + rd->Length); sLog->outStaticDebug("RESULT MEM_CHECK passed CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); break; } case PAGE_CHECK_A: case PAGE_CHECK_B: case DRIVER_CHECK: case MODULE_CHECK: { const uint8 byte = 0xE9; if(memcmp(buff.contents() + buff.rpos(), &byte, sizeof(uint8)) != 0) { if(type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog->outWarden("RESULT PAGE_CHECK fail, CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); if(type == MODULE_CHECK) sLog->outWarden("RESULT MODULE_CHECK fail, CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); if(type == DRIVER_CHECK) sLog->outWarden("RESULT DRIVER_CHECK fail, CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); found = true; buff.rpos(buff.rpos() + 1); if(rd->banDays > banDays) banDays = rd->banDays; continue; } buff.rpos(buff.rpos() + 1); if(type == PAGE_CHECK_A || type == PAGE_CHECK_B) sLog->outStaticDebug("RESULT PAGE_CHECK passed CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); else if(type == MODULE_CHECK) sLog->outStaticDebug("RESULT MODULE_CHECK passed CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); else if(type == DRIVER_CHECK) sLog->outStaticDebug("RESULT DRIVER_CHECK passed CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); break; } case LUA_STR_CHECK: { uint8 Lua_Result; buff >> Lua_Result; if(Lua_Result != 0) { sLog->outWarden("RESULT LUA_STR_CHECK fail, CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); found = true; if(rd->banDays > banDays) banDays = rd->banDays; continue; } uint8 luaStrLen; buff >> luaStrLen; if(luaStrLen != 0) { char *str = new char[luaStrLen + 1]; memset(str, 0, luaStrLen + 1); memcpy(str, buff.contents() + buff.rpos(), luaStrLen); sLog->outStaticDebug("Lua string: %s", str); delete[] str; } buff.rpos(buff.rpos() + luaStrLen); // skip string sLog->outStaticDebug("RESULT LUA_STR_CHECK passed, CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); break; } case MPQ_CHECK: { uint8 Mpq_Result; buff >> Mpq_Result; if(Mpq_Result != 0) { sLog->outWarden("RESULT MPQ_CHECK not 0x00 account id %u", Client->GetAccountId()); found = true; if(rd->banDays > banDays) banDays = rd->banDays; continue; } if(memcmp(buff.contents() + buff.rpos(), rs->res.AsByteArray(0, false), 20) != 0) // SHA1 { sLog->outWarden("RESULT MPQ_CHECK fail, CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); found = true; buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 if(rd->banDays > banDays) banDays = rd->banDays; continue; } buff.rpos(buff.rpos() + 20); // 20 bytes SHA1 sLog->outStaticDebug("RESULT MPQ_CHECK passed, CheckId: %u, account Id: %u, player: %s", rd->DBid, Client->GetAccountId(), Client->GetPlayerName()); break; } default: // should never happens break; } } if(banDays > 0 && m_previousCheckFailed) banDays = 0; m_previousCheckFailed = false; if(found && banDays > 0) { std::stringstream ssDuration; ssDuration << +banDays << "d"; std::string sDuration; sDuration = ssDuration.str(); std::string sText = ("Player: " + std::string(Client->GetPlayerName()) + " have used Cheating software and have banned for " + sDuration.c_str()); sWorld->SendGMText(LANG_GM_BROADCAST, sText.c_str()); sLog->outWarden("Player %s (account: %u) have used Cheating software and have banned for %s", Client->GetPlayerName(), Client->GetAccountId(), sDuration.c_str()); sWorld->BanAccount(BAN_CHARACTER, Client->GetPlayerName(), sDuration.c_str(), "Cheating software user", "Server guard"); } else if(found && sWorld->getBoolConfig(CONFIG_BOOL_WARDEN_KICK)) Client->KickPlayer(); }