Fix gender exploit.

Now check that character has a valid gender (and not an invalid via packet modifications).
This check works when trying to create a character or when building the character list.
If gender is invalid (neither male nor female): can't create the character and can't see in the characters' list (and also can't login with it via packet modding).

Signed-off-by: Anubisss <[email protected]>
This commit is contained in:
Anubisss
2011-04-01 05:05:13 +02:00
parent 5fe6c225e2
commit 1b0843194f
3 changed files with 27 additions and 3 deletions
+24 -2
View File
@@ -895,6 +895,9 @@ void Player::CleanupsBeforeDelete(bool finalCleanup)
bool Player::Create(uint32 guidlow, const std::string& name, uint8 race, uint8 class_, uint8 gender, uint8 skin, uint8 face, uint8 hairStyle, uint8 hairColor, uint8 facialHair, uint8 /*outfitId*/)
{
//FIXME: outfitId not used in player creating
// TODO: need more checks against packet modifications
// should check that skin, face, hair* are valid via DBC per race/class
// also do it in Player::BuildEnumData, Player::LoadFromDB
Object::_Create(guidlow, 0, HIGHGUID_PLAYER);
@@ -928,6 +931,12 @@ bool Player::Create(uint32 guidlow, const std::string& name, uint8 race, uint8 c
setFactionForRace(race);
if (!IsValidGender(gender))
{
sLog->outError("Player has invalid gender (%hu), can't be loaded.", gender);
return false;
}
uint32 RaceClassGender = (race) | (class_ << 8) | (gender << 16);
SetUInt32Value(UNIT_FIELD_BYTES_0, (RaceClassGender | (powertype << 24)));
@@ -1842,6 +1851,7 @@ bool Player::BuildEnumData(QueryResult result, WorldPacket * p_data)
uint32 guid = fields[0].GetUInt32();
uint8 pRace = fields[2].GetUInt8();
uint8 pClass = fields[3].GetUInt8();
uint8 Gender = fields[4].GetUInt8();
PlayerInfo const *info = sObjectMgr->GetPlayerInfo(pRace, pClass);
if (!info)
@@ -1849,12 +1859,17 @@ bool Player::BuildEnumData(QueryResult result, WorldPacket * p_data)
sLog->outError("Player %u has incorrect race/class pair. Don't build enum.", guid);
return false;
}
else if (!IsValidGender(Gender))
{
sLog->outError("Player (%u) has incorrect gender (%hu), don't build enum.", guid, Gender);
return false;
}
*p_data << uint64(MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
*p_data << fields[1].GetString(); // name
*p_data << uint8(pRace); // race
*p_data << uint8(pClass); // class
*p_data << uint8(fields[4].GetUInt8()); // gender
*p_data << uint8(Gender); // gender
uint32 playerBytes = fields[5].GetUInt32();
*p_data << uint8(playerBytes); // skin
@@ -16430,11 +16445,18 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
// overwrite possible wrong/corrupted guid
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_PLAYER));
uint8 Gender = fields[5].GetUInt8();
if (!IsValidGender(Gender))
{
sLog->outError("Player (GUID: %u) has wrong gender (%hu), can't be loaded.", guid, Gender);
return false;
}
// overwrite some data fields
uint32 bytes0 = 0;
bytes0 |= fields[3].GetUInt8(); // race
bytes0 |= fields[4].GetUInt8() << 8; // class
bytes0 |= fields[5].GetUInt8() << 16; // gender
bytes0 |= Gender << 16; // gender
SetUInt32Value(UNIT_FIELD_BYTES_0, bytes0);
SetUInt32Value(UNIT_FIELD_LEVEL, fields[6].GetUInt8());
+2
View File
@@ -1471,6 +1471,8 @@ class Player : public Unit, public GridObject<Player>
static uint32 GetLevelFromDB(uint64 guid);
static bool LoadPositionFromDB(uint32& mapid, float& x,float& y,float& z,float& o, bool& in_flight, uint64 guid);
static bool IsValidGender(uint8 Gender) { return Gender <= GENDER_FEMALE ; }
/*********************************************************/
/*** SAVE SYSTEM ***/
/*********************************************************/
@@ -552,7 +552,7 @@ void WorldSession::HandleCharCreateOpcode(WorldPacket & recv_data)
Player * pNewChar = new Player(this);
if (!pNewChar->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_PLAYER), name, race_, class_, gender, skin, face, hairStyle, hairColor, facialHair, outfitId))
{
// Player not create (race/class problem?)
// Player not create (race/class/etc problem?)
pNewChar->CleanupsBeforeDelete();
delete pNewChar;