예제 #1
0
// Sending this packet to initialize engine functions warden uses
void WardenMgr::SendWardenData(WorldSession* const session)
{
    sLog->outStaticDebug("WardenMgr::SendWardenData");
    WorldPacket data( SMSG_WARDEN_DATA, 1 + 2+4+20 + 1 + 2+4+8 + 1 +2+4+8); // 42 // 57 // 3.3.5a init packet
    data << uint8(WARDS_DATA);
    {
        data << uint16(20);
        uint8 buff[20] =
        {
            0x01, 0x00, 0x02, 0x00,
            0x80, 0x4F, 0x02, 0x00,     // 0x00400000 + 0x00024F80 SFileOpenFile
            0xC0, 0x18, 0x02, 0x00,     // 0x00400000 + 0x000218C0 SFileGetFileSize
            0x30, 0x25, 0x02, 0x00,     // 0x00400000 + 0x00022530 SFileReadFile
            0x10, 0x29, 0x02, 0x00      // 0x00400000 + 0x00022910 SFileCloseFile
        };
        data << uint32(BuildChecksum(buff, 20));
        data.append(buff, 20);
    }
    data << uint8(WARDS_DATA);
    {
        data << uint16(8);
        uint8 buff[8] =
        {
           0x04, 0x00, 0x00,
           0x40, 0x9D, 0x41, 0x00,      // 0x00400000 + 0x00419D40 FrameScript__GetText
           0x01
        };
        data << uint32(BuildChecksum(buff, 8));
        data.append(buff, 8);
    }
    // Computed part for timing checks (did not exist on Offy 3.3.5a)
    data << uint8(WARDS_DATA);
    {
        data << uint16(8);
        uint8 buff[8] =
        {
           0x01, 0x01, 0x00,
           0x20, 0xAE, 0x46, 0x00,      // 0x00400000 + 0x0046AE20 PerformanceCounter
           0x01
        };
        data << uint32(BuildChecksum(buff, 8));
        data.append(buff, 8);
    }

    data.hexlike();
    data.crypt(&session->m_rc4ServerKey[0], &rc4_crypt);
    session->SendPacket(&data);
}
예제 #2
0
void WardenWin::InitializeModule()
{
#if defined(ENABLE_EXTRAS) && defined(ENABLE_EXTRA_LOGS)
    sLog->outDebug(LOG_FILTER_WARDEN, "Initialize module");
#endif

    // Create packet structure
    WardenInitModuleRequest Request;
    Request.Command1 = WARDEN_SMSG_MODULE_INITIALIZE;
    Request.Size1 = 20;
    Request.Unk1 = 1;
    Request.Unk2 = 0;
    Request.Type = 1;
    Request.String_library1 = 0;
    Request.Function1[0] = 0x00024F80;                      // 0x00400000 + 0x00024F80 SFileOpenFile
    Request.Function1[1] = 0x000218C0;                      // 0x00400000 + 0x000218C0 SFileGetFileSize
    Request.Function1[2] = 0x00022530;                      // 0x00400000 + 0x00022530 SFileReadFile
    Request.Function1[3] = 0x00022910;                      // 0x00400000 + 0x00022910 SFileCloseFile
    Request.CheckSumm1 = BuildChecksum(&Request.Unk1, 20);

    Request.Command2 = WARDEN_SMSG_MODULE_INITIALIZE;
    Request.Size2 = 8;
    Request.Unk3 = 4;
    Request.Unk4 = 0;
    Request.String_library2 = 0;
    Request.Function2 = 0x00419D40;                         // 0x00400000 + 0x00419D40 FrameScript::GetText
    Request.Function2_set = 1;
    Request.CheckSumm2 = BuildChecksum(&Request.Unk2, 8);

    Request.Command3 = WARDEN_SMSG_MODULE_INITIALIZE;
    Request.Size3 = 8;
    Request.Unk5 = 1;
    Request.Unk6 = 1;
    Request.String_library3 = 0;
    Request.Function3 = 0x0046AE20;                         // 0x00400000 + 0x0046AE20 PerformanceCounter
    Request.Function3_set = 1;
    Request.CheckSumm3 = BuildChecksum(&Request.Unk5, 8);

    // Encrypt with warden RC4 key.
    EncryptData((uint8*)&Request, sizeof(WardenInitModuleRequest));

    WorldPacket pkt(SMSG_WARDEN_DATA, sizeof(WardenInitModuleRequest));
    pkt.append((uint8*)&Request, sizeof(WardenInitModuleRequest));
    _session->SendPacket(&pkt);
}
예제 #3
0
bool Warden::IsValidCheckSum(uint32 checksum, const uint8* data, const uint16 length)
{
    uint32 newChecksum = BuildChecksum(data, length);

    if (checksum != newChecksum)
    {
        sLog->outDebug(LOG_FILTER_WARDEN, "CHECKSUM IS NOT VALID");
        return false;
    }
    else
    {
        sLog->outDebug(LOG_FILTER_WARDEN, "CHECKSUM IS VALID");
        return true;
    }
}
예제 #4
0
bool Warden::IsValidCheckSum(uint32 checksum, const uint8* data, const uint16 length)
{
    uint32 newChecksum = BuildChecksum(data, length);

    if (checksum != newChecksum)
    {
        TC_LOG_DEBUG("warden", "CHECKSUM IS NOT VALID");
        return false;
    }
    else
    {
        TC_LOG_DEBUG("warden", "CHECKSUM IS VALID");
        return true;
    }
}
예제 #5
0
bool WardenBase::IsValidCheckSum(uint32 checksum, const uint8 *Data, const uint16 Length)
{
    uint32 newchecksum = BuildChecksum(Data, Length);

    if (checksum != newchecksum)
    {
        sLog->outWarden("CHECKSUM IS NOT VALID");
        return false;
    }
    else
    {
        sLog->outStaticDebug("CHECKSUM IS VALID");
        return true;
    }
}
예제 #6
0
bool WardenMgr::ValidateCheatCheckResult(WorldSession* const session, WorldPacket& clientPacket)
{
    uint32 accountId = session->GetAccountId();
    sLog->outStaticDebug("Wardend::ValidateCheatCheckResult(%u, *pkt)", accountId);
    bool valid = true;

    uint16 pktLen;
    uint32 checksum;
    clientPacket >> pktLen;
    clientPacket >> checksum;
    if (checksum != BuildChecksum(clientPacket.contents() + clientPacket.rpos(), clientPacket.size() - clientPacket.rpos()))
    {
        if (session->GetPlayer())
        {
            sLog->outWarden("Warden Cheat-check: Kicking player %s for failed check, Packet Checksum 0x%08X is invalid!", session->GetPlayerName(), checksum);
        }
        else
        {
            sLog->outWarden("Warden Cheat-check: Kicking account %u for failed check, Packet Checksum 0x%08X is invalid!", session->GetAccountId(), checksum);
        }
        ReactToCheatCheckResult(session, false);
        return false;
    }

    if (pktLen == 0)
        return false;

    // parse the timing check always sent
    sLog->outStaticDebug("TimeCheck");
    uint8 res;
    uint32 ticks;
    clientPacket >> res; // should be 1
    clientPacket >> ticks;
    // Need to compare ticks based on last one using server ticks diff since
    sLog->outStaticDebug("Warden: Time unk 0x%08X", ticks);
    pktLen = pktLen - 5;

    WardenClientCheckList* checkList = (WardenClientCheckList*)session->m_WardenClientChecks;
    if (!checkList)
        return false;

    for (uint8 i=0; i<checkList->size(); ++i)
    {
        switch ((*checkList)[i].check)
        {
            case WARD_CHECK_TIMING:
            {
                sLog->outStaticDebug("Warden: TimeCheck");
                uint8 res;
                uint32 ticks;
                clientPacket >> res; // should be 1
                clientPacket >> ticks;
                // Need to compare ticks based on last one using server ticks diff since
                sLog->outStaticDebug("Warden: Time unk 0x%08X", ticks);
                pktLen = pktLen - 5;
                break;
            }
            case WARD_CHECK_MEMORY:
            {
                sLog->outStaticDebug("Warden: MemCheck");
                uint8 res;
                clientPacket >> res; // should be 0
                if (res)
                {
                    valid = false;
                    if (session->GetPlayer())
                    {
                        sLog->outWarden("Warden: player %s failed check, MEM at Offset 0x%04X, lentgh %u could not be read by client", session->GetPlayerName(), (*checkList)[i].mem->Offset, (*checkList)[i].mem->Length);
                    }
                    else
                    {
                        sLog->outWarden("Warden: account %u failed check, MEM at Offset 0x%04X, lentgh %u could not be read by client", session->GetAccountId(), (*checkList)[i].mem->Offset, (*checkList)[i].mem->Length);
                    }                    
                }
                else
                {
                    uint8 memContent[20];
                    bool memcheck_failed = false;

                    for (uint8 pos=0; pos<(*checkList)[i].mem->Length; ++pos)
                    {
                        clientPacket >> memContent[pos];                        

                        if (memContent[pos]!=(*checkList)[i].mem->Result[pos])
                        {
                            valid = false;
                            memcheck_failed = true;
                        }
                    }
                    pktLen = pktLen - (1 + (*checkList)[i].mem->Length);

                    if (memcheck_failed)
                    {
                        std::string strContent, strContent2;
                        hexEncodeByteArray(memContent, (*checkList)[i].mem->Length, strContent);
                        hexEncodeByteArray((*checkList)[i].mem->Result, (*checkList)[i].mem->Length, strContent2); 

                        if (session->GetPlayer())
                        {
                            sLog->outWarden("Warden: player %s failed check, MEM Offset 0x%04X length %u has content '%s' instead of '%s'",
                                session->GetPlayerName(), (*checkList)[i].mem->Offset, (*checkList)[i].mem->Length, strContent.c_str(), strContent2.c_str());
                        }
                        else
                        {
                            sLog->outWarden("Warden: account %u failed check, MEM Offset 0x%04X length %u has content '%s' instead of '%s'",
                                session->GetAccountId(), (*checkList)[i].mem->Offset, (*checkList)[i].mem->Length, strContent.c_str(), strContent2.c_str());
                        } 
                        
                    }
                }
                sLog->outStaticDebug("Warden: Mem %s", valid ? "Ok" : "Failed");
                break;
            }
            case WARD_CHECK_FILE:
            {
                sLog->outStaticDebug("Warden: MPQCheck");
                uint8 res;
                uint8 resSHA1[20];
                clientPacket >> res; // should be 0
                if (res)
                {
                    valid = false;
                    if (session->GetPlayer())
                    {
                        sLog->outWarden("Warden: player %s failed check, MPQ '%s' not found by client", session->GetPlayerName(), (*checkList)[i].file->String.c_str());
                    }
                    else
                    {
                        sLog->outWarden("Warden: account %u failed check, MPQ '%s' not found by client", session->GetAccountId(), (*checkList)[i].file->String.c_str());
                    }
                    
                    pktLen = pktLen - 1;
                }
                else
                {
                    for (uint8 pos=0; pos<20; ++pos)
                        clientPacket >> resSHA1[pos];
                    if (res || memcmp(resSHA1, (*checkList)[i].file->SHA, 20))
                    {
                        valid = false;
                        std::string strResSHA1, strReqSHA1;
                        hexEncodeByteArray(resSHA1, 20, strResSHA1);
                        hexEncodeByteArray((*checkList)[i].file->SHA, 20, strReqSHA1);

                        if (session->GetPlayer())
                        {
                            sLog->outWarden("Warden: player %s failed check, MPQ '%s' SHA1 is '%s' instead of '%s'", session->GetPlayerName(), (*checkList)[i].file->String.c_str(), strResSHA1.c_str(), strReqSHA1.c_str());
                        }
                        else
                        {
                            sLog->outWarden("Warden: account %u failed check, MPQ '%s' SHA1 is '%s' instead of '%s'", session->GetAccountId(), (*checkList)[i].file->String.c_str(), strResSHA1.c_str(), strReqSHA1.c_str());
                        }
                        
                    }
                    pktLen = pktLen - 21;
                }
                sLog->outStaticDebug("Warden: MPQ %s", valid ? "Ok" : "Failed");
                break;
            }
            case WARD_CHECK_LUA:
            {
                sLog->outStaticDebug("Warden: LUACheck");
                uint8 res;
                uint8 foundLuaLen;
                clientPacket >> res; // should be 0
                clientPacket >> foundLuaLen; // should be 0
                uint8 *luaStr;
                if (foundLuaLen > 0)
                {
                    luaStr = (uint8*)malloc(foundLuaLen+1);
                    for (uint8 pos=0; pos<foundLuaLen; ++pos)
                    {
                        clientPacket >> luaStr[pos];
                    }
                    luaStr[foundLuaLen] = 0;

                    if (session->GetPlayer())
                    {
                        sLog->outWarden("Warden: player %s failed lua check, Lua '%s' found as '%s'", session->GetPlayerName(), (*checkList)[i].lua->String.c_str(), (char*)luaStr);
                    }
                    else
                    {
                        sLog->outWarden("Warden: account %u failed lua check, Lua '%s' found as '%s'", session->GetAccountId(), (*checkList)[i].lua->String.c_str(), (char*)luaStr);
                    }

                    valid = false;
                    free(luaStr);
                }
                sLog->outStaticDebug("Lua %s", valid ? "Ok" : "Failed");
                pktLen = pktLen - 2;
                break;
            }
            case WARD_CHECK_PAGE1:
            case WARD_CHECK_PAGE2:
            case WARD_CHECK_DRIVER:
            {
                sLog->outStaticDebug("PageCheck or DriverCheck");
                uint8 res;
                clientPacket >> res; // should be 0xE9
                if (res != 0xE9)
                {
                    if ((*checkList)[i].check == WARD_CHECK_DRIVER)
                    {
                        if (session->GetPlayer())
                        {
                            sLog->outWarden("Warden: player %s failed driver check '%s'", session->GetPlayerName(), (*checkList)[i].driver->String.c_str());
                        }
                        else
                        {
                            sLog->outWarden("Warden: account %u failed driver check '%s'", session->GetAccountId(), (*checkList)[i].driver->String.c_str());
                        }                        
                    }
                    else
                    {
                        if (session->GetPlayer())
                        {
                            sLog->outWarden("Warden: player %s failed page check Offset 0x%08X, length %u", session->GetPlayerName(), (*checkList)[i].page->Offset, (*checkList)[i].page->Length);
                        }
                        else
                        {
                            sLog->outWarden("Warden: account %u failed page check Offset 0x%08X, length %u", session->GetAccountId(), (*checkList)[i].page->Offset, (*checkList)[i].page->Length);
                        }                        
                    }
                    valid = false;
                }
                sLog->outStaticDebug("Page or Driver %s",valid?"Ok":"Failed");
                pktLen = pktLen - 1;
                break;
            }
            default:
                sLog->outStaticDebug("Warden: Other!!");
                // Finish skiping the rest of the packet and return failed checks

                if (session->GetPlayer())
                {
                    sLog->outWarden("Wrong packet for player %s or problem to parse it, I had to clean %u bytes", session->GetPlayerName(), clientPacket.size() - clientPacket.rpos());
                }
                else
                {
                    sLog->outWarden("Wrong packet for account %u or problem to parse it, I had to clean %u bytes", session->GetAccountId(), clientPacket.size() - clientPacket.rpos());
                } 

                clientPacket.read_skip(clientPacket.size() - clientPacket.rpos());
                return false;
        }
    }