From 2ab82c92718169f09cc6c9128ec9a058f6d1b21c Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Fri, 14 Jan 2011 23:51:15 +0000 Subject: [PATCH] - added some basic protection against memory hacking tools --- source/glest_game/type_instances/resource.cpp | 34 ------ source/glest_game/type_instances/resource.h | 18 +-- source/glest_game/type_instances/unit.cpp | 79 ++++++++++--- source/glest_game/type_instances/unit.h | 3 +- source/glest_game/types/unit_type.cpp | 106 ++++++++++++++---- source/glest_game/types/unit_type.h | 10 +- .../include/platform/common/platform_common.h | 18 +++ .../platform/common/platform_common.cpp | 35 ++++++ 8 files changed, 212 insertions(+), 91 deletions(-) diff --git a/source/glest_game/type_instances/resource.cpp b/source/glest_game/type_instances/resource.cpp index b9bb84ff0..2b4b740c7 100644 --- a/source/glest_game/type_instances/resource.cpp +++ b/source/glest_game/type_instances/resource.cpp @@ -23,40 +23,6 @@ using namespace Shared::Util; namespace Glest{ namespace Game{ -void ValueCheckerVault::addItemToVault(const void *ptr,int value) { - Checksum checksum; - checksum.addString(intToStr(value)); - vaultList[ptr] = intToStr(checksum.getSum()); - - if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] add vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value); -} - -void ValueCheckerVault::checkItemInVault(const void *ptr,int value) const { - map::const_iterator iterFind = vaultList.find(ptr); - if(iterFind == vaultList.end()) { - if(SystemFlags::VERBOSE_MODE_ENABLED) { - printf("In [%s::%s Line: %d] check vault key [%p] value [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,value); - for(map::const_iterator iterFind = vaultList.begin(); - iterFind != vaultList.end(); iterFind++) { - printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str()); - } - } - throw std::runtime_error("memory value has been unexpectedly modified (not found)!"); - } - Checksum checksum; - checksum.addString(intToStr(value)); - if(iterFind->second != intToStr(checksum.getSum())) { - if(SystemFlags::VERBOSE_MODE_ENABLED) { - printf("In [%s::%s Line: %d] check vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value); - for(map::const_iterator iterFind = vaultList.begin(); - iterFind != vaultList.end(); iterFind++) { - printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str()); - } - } - throw std::runtime_error("memory value has been unexpectedly modified (changed)!"); - } -} - // ===================================================== // class Resource // ===================================================== diff --git a/source/glest_game/type_instances/resource.h b/source/glest_game/type_instances/resource.h index 9e9230cbb..427ba7644 100644 --- a/source/glest_game/type_instances/resource.h +++ b/source/glest_game/type_instances/resource.h @@ -13,7 +13,7 @@ #include #include "vec.h" -#include +#include "platform_common.h" #include "leak_dumper.h" using std::string; @@ -22,6 +22,7 @@ using std::map; namespace Glest{ namespace Game{ using Shared::Graphics::Vec2i; +using Shared::PlatformCommon::ValueCheckerVault; class ResourceType; @@ -31,21 +32,6 @@ class ResourceType; /// Amount of a given ResourceType // ===================================================== -class ValueCheckerVault { - -protected: - map vaultList; - - void addItemToVault(const void *ptr,int value); - void checkItemInVault(const void *ptr,int value) const; - -public: - - ValueCheckerVault() { - vaultList.clear(); - } -}; - class Resource : public ValueCheckerVault { private: int amount; diff --git a/source/glest_game/type_instances/unit.cpp b/source/glest_game/type_instances/unit.cpp index df5784988..634776aff 100644 --- a/source/glest_game/type_instances/unit.cpp +++ b/source/glest_game/type_instances/unit.cpp @@ -163,7 +163,6 @@ set Unit::livingUnitsp; Game *Unit::game = NULL; Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType *type, Faction *faction, Map *map, CardinalDir placeFacing):id(id) { - SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); modelFacing = CardinalDir::NORTH; @@ -242,6 +241,9 @@ Unit::Unit(int id, UnitPathInterface *unitpath, const Vec2i &pos, const UnitType livingUnits.insert(id); livingUnitsp.insert(this); + addItemToVault(&this->hp,this->hp); + addItemToVault(&this->ep,this->ep); + logSynchData(__FILE__,__LINE__); SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); } @@ -909,7 +911,11 @@ void Unit::born() { faction->applyStaticProduction(type); setCurrSkill(scStop); + checkItemInVault(&this->hp,this->hp); + hp= type->getMaxHp(); + + addItemToVault(&this->hp,this->hp); } void Unit::kill() { @@ -1115,10 +1121,15 @@ void Unit::tick() { //regenerate hp if(type->getHpRegeneration() >= 0) { + checkItemInVault(&this->hp,this->hp); + hp+= type->getHpRegeneration(); - if(hp>type->getTotalMaxHp(&totalUpgrade)){ - hp= type->getTotalMaxHp(&totalUpgrade); + + if(hp > type->getTotalMaxHp(&totalUpgrade)) { + hp = type->getTotalMaxHp(&totalUpgrade); } + + addItemToVault(&this->hp,this->hp); } // If we have negative regeneration then check if the unit should die else { @@ -1138,11 +1149,16 @@ void Unit::tick() { stopDamageParticles(); } + checkItemInVault(&this->ep,this->ep); + //regenerate ep ep += type->getEpRegeneration(); + if(ep>type->getTotalMaxEp(&totalUpgrade)){ ep= type->getTotalMaxEp(&totalUpgrade); } + + addItemToVault(&this->ep,this->ep); } } @@ -1160,12 +1176,16 @@ bool Unit::computeEp() { } //if not enough ep - if(ep-currSkill->getEpCost() < 0) { + if(ep - currSkill->getEpCost() < 0) { return true; } + checkItemInVault(&this->ep,this->ep); + //decrease ep - ep-= currSkill->getEpCost(); + ep -= currSkill->getEpCost(); + + addItemToVault(&this->ep,this->ep); if(getType() == NULL) { char szBuf[4096]=""; @@ -1173,10 +1193,12 @@ bool Unit::computeEp() { throw runtime_error(szBuf); } - if(ep>getType()->getTotalMaxEp(&totalUpgrade)){ - ep= getType()->getTotalMaxEp(&totalUpgrade); + if(ep > getType()->getTotalMaxEp(&totalUpgrade)){ + ep = getType()->getTotalMaxEp(&totalUpgrade); } + addItemToVault(&this->ep,this->ep); + return false; } @@ -1189,14 +1211,20 @@ bool Unit::repair(){ } //increase hp - hp+= getType()->getMaxHp()/type->getProductionTime() + 1; - if(hp>(getType()->getTotalMaxHp(&totalUpgrade))){ - hp= getType()->getTotalMaxHp(&totalUpgrade); + checkItemInVault(&this->hp,this->hp); + + hp += getType()->getMaxHp()/type->getProductionTime() + 1; + if(hp > (getType()->getTotalMaxHp(&totalUpgrade))) { + hp = getType()->getTotalMaxHp(&totalUpgrade); + + addItemToVault(&this->hp,this->hp); + return true; } + addItemToVault(&this->hp,this->hp); //stop DamageParticles - if(hp>type->getTotalMaxHp(&totalUpgrade)/2 ){ + if(hp > type->getTotalMaxHp(&totalUpgrade)/2 ) { stopDamageParticles(); } return false; @@ -1208,8 +1236,12 @@ bool Unit::decHp(int i) { return false; } + checkItemInVault(&this->hp,this->hp); + hp -= i; + addItemToVault(&this->hp,this->hp); + if(type == NULL) { char szBuf[4096]=""; sprintf(szBuf,"In [%s::%s Line: %d] ERROR: type == NULL, Unit = [%s]\n",__FILE__,__FUNCTION__,__LINE__,this->toString().c_str()); @@ -1225,6 +1257,9 @@ bool Unit::decHp(int i) { if(hp <= 0) { alive= false; hp=0; + + addItemToVault(&this->hp,this->hp); + stopDamageParticles(); return true; } @@ -1328,7 +1363,12 @@ void Unit::applyUpgrade(const UpgradeType *upgradeType){ if(upgradeType->isAffected(type)){ totalUpgrade.sum(upgradeType); - hp+= upgradeType->getMaxHp(); + + checkItemInVault(&this->hp,this->hp); + + hp += upgradeType->getMaxHp(); + + addItemToVault(&this->hp,this->hp); } } @@ -1344,7 +1384,12 @@ void Unit::incKills(){ level= nextLevel; int maxHp= totalUpgrade.getMaxHp(); totalUpgrade.incLevel(type); - hp+= totalUpgrade.getMaxHp()-maxHp; + + checkItemInVault(&this->hp,this->hp); + + hp += totalUpgrade.getMaxHp()-maxHp; + + addItemToVault(&this->hp,this->hp); } } @@ -1370,7 +1415,13 @@ bool Unit::morph(const MorphCommandType *mct){ if(map->isFreeCellsOrHasUnit(pos, morphUnitType->getSize(), morphUnitField, this)){ map->clearUnitCells(this, pos); faction->deApplyStaticCosts(type); - hp+= morphUnitType->getMaxHp() - type->getMaxHp(); + + checkItemInVault(&this->hp,this->hp); + + hp += morphUnitType->getMaxHp() - type->getMaxHp(); + + addItemToVault(&this->hp,this->hp); + type= morphUnitType; level= NULL; currField=morphUnitField; diff --git a/source/glest_game/type_instances/unit.h b/source/glest_game/type_instances/unit.h index 060c121a9..89282b6b5 100644 --- a/source/glest_game/type_instances/unit.h +++ b/source/glest_game/type_instances/unit.h @@ -31,6 +31,7 @@ using Shared::Graphics::Vec3f; using Shared::Graphics::Vec2i; using Shared::Graphics::Model; using Shared::PlatformCommon::Chrono; +using Shared::PlatformCommon::ValueCheckerVault; using std::set; @@ -216,7 +217,7 @@ public: /// A game unit or building // =============================== -class Unit { +class Unit : public ValueCheckerVault { private: typedef list Commands; typedef list Observers; diff --git a/source/glest_game/types/unit_type.cpp b/source/glest_game/types/unit_type.cpp index 687464bfc..7f6960c43 100644 --- a/source/glest_game/types/unit_type.cpp +++ b/source/glest_game/types/unit_type.cpp @@ -52,7 +52,7 @@ const char *UnitType::propertyNames[]= {"burnable", "rotated_climb"}; // ==================== creation and loading ==================== -UnitType::UnitType(){ +UnitType::UnitType() : ProducibleType() { meetingPointImage = NULL; lightColor= Vec3f(0.f); @@ -82,6 +82,22 @@ UnitType::UnitType(){ hpRegeneration= 0; epRegeneration= 0; maxUnitCount= 0; + maxHp=0; + maxEp=0; + armor=0; + sight=0; + size=0; + height=0; + + addItemToVault(&(this->maxHp),this->maxHp); + addItemToVault(&(this->hpRegeneration),this->hpRegeneration); + addItemToVault(&(this->maxEp),this->maxEp); + addItemToVault(&(this->epRegeneration),this->epRegeneration); + addItemToVault(&(this->maxUnitCount),this->maxUnitCount); + addItemToVault(&(this->armor),this->armor); + addItemToVault(&(this->sight),this->sight); + addItemToVault(&(this->size),this->size); + addItemToVault(&(this->height),this->height); } UnitType::~UnitType(){ @@ -124,39 +140,69 @@ void UnitType::load(int id,const string &dir, const TechTree *techTree, const Fa const XmlNode *parametersNode= unitNode->getChild("parameters"); //size + //checkItemInVault(&(this->size),this->size); + size= parametersNode->getChild("size")->getAttribute("value")->getIntValue(); + addItemToVault(&(this->size),this->size); + //height + //checkItemInVault(&(this->height),this->height); + height= parametersNode->getChild("height")->getAttribute("value")->getIntValue(); + addItemToVault(&(this->height),this->height); + //maxHp - maxHp= parametersNode->getChild("max-hp")->getAttribute("value")->getIntValue(); + //checkItemInVault(&(this->maxHp),this->maxHp); + + maxHp = parametersNode->getChild("max-hp")->getAttribute("value")->getIntValue(); + + addItemToVault(&(this->maxHp),this->maxHp); //hpRegeneration + //checkItemInVault(&(this->hpRegeneration),this->hpRegeneration); + hpRegeneration= parametersNode->getChild("max-hp")->getAttribute("regeneration")->getIntValue(); + addItemToVault(&(this->hpRegeneration),this->hpRegeneration); + //maxEp + //checkItemInVault(&(this->maxEp),this->maxEp); + maxEp= parametersNode->getChild("max-ep")->getAttribute("value")->getIntValue(); - if(maxEp!=0){ - //wpRegeneration + addItemToVault(&(this->maxEp),this->maxEp); + + if(maxEp != 0) { + //epRegeneration + //checkItemInVault(&(this->epRegeneration),this->epRegeneration); + epRegeneration= parametersNode->getChild("max-ep")->getAttribute("regeneration")->getIntValue(); } + addItemToVault(&(this->epRegeneration),this->epRegeneration); //maxUnitCount - if(parametersNode->hasChild("max-unit-count")){ + if(parametersNode->hasChild("max-unit-count")) { + //checkItemInVault(&(this->maxUnitCount),this->maxUnitCount); + maxUnitCount= parametersNode->getChild("max-unit-count")->getAttribute("value")->getIntValue(); } + addItemToVault(&(this->maxUnitCount),this->maxUnitCount); //armor + //checkItemInVault(&(this->armor),this->armor); armor= parametersNode->getChild("armor")->getAttribute("value")->getIntValue(); + addItemToVault(&(this->armor),this->armor); //armor type string string armorTypeName= parametersNode->getChild("armor-type")->getAttribute("value")->getRestrictedValue(); armorType= techTree->getArmorType(armorTypeName); //sight + //checkItemInVault(&(this->sight),this->sight); sight= parametersNode->getChild("sight")->getAttribute("value")->getIntValue(); + addItemToVault(&(this->sight),this->sight); //prod time productionTime= parametersNode->getChild("time")->getAttribute("value")->getIntValue(); @@ -486,6 +532,8 @@ const RepairCommandType *UnitType::getFirstRepairCommand(const UnitType *repaire } bool UnitType::hasEmptyCellMap() const { + checkItemInVault(&(this->size),this->size); + bool result = (size > 0); for(int i = 0; result == true && i < size; ++i) { @@ -505,6 +553,9 @@ bool UnitType::getCellMapCell(int x, int y, CardinalDir facing) const { if(cellMap == NULL) { throw runtime_error("cellMap == NULL"); } + + checkItemInVault(&(this->size),this->size); + int tmp=0; switch (facing) { case CardinalDir::EAST: @@ -553,45 +604,53 @@ const SkillType *UnitType::getSkillType(const string &skillName, SkillClass skil // ==================== totals ==================== int UnitType::getTotalMaxHp(const TotalUpgrade *totalUpgrade) const{ + checkItemInVault(&(this->maxHp),this->maxHp); + return maxHp + totalUpgrade->getMaxHp(); } int UnitType::getTotalMaxEp(const TotalUpgrade *totalUpgrade) const{ + checkItemInVault(&(this->maxEp),this->maxEp); + return maxEp + totalUpgrade->getMaxEp(); } -int UnitType::getTotalArmor(const TotalUpgrade *totalUpgrade) const{ +int UnitType::getTotalArmor(const TotalUpgrade *totalUpgrade) const { + checkItemInVault(&(this->armor),this->armor); + return armor + totalUpgrade->getArmor(); } int UnitType::getTotalSight(const TotalUpgrade *totalUpgrade) const{ + checkItemInVault(&(this->sight),this->sight); + return sight + totalUpgrade->getSight(); } // ==================== has ==================== -bool UnitType::hasSkillClass(SkillClass skillClass) const{ +bool UnitType::hasSkillClass(SkillClass skillClass) const { return firstSkillTypeOfClass[skillClass]!=NULL; } -bool UnitType::hasCommandType(const CommandType *commandType) const{ +bool UnitType::hasCommandType(const CommandType *commandType) const { assert(commandType!=NULL); - for(int i=0; igetClass()== SkillClass(j)){ + for(int i= 0; i < skillTypes.size(); ++i) { + if(skillTypes[i]->getClass()== SkillClass(j)) { firstSkillTypeOfClass[j]= skillTypes[i]; break; } @@ -629,10 +688,10 @@ void UnitType::computeFirstStOfClass(){ void UnitType::computeFirstCtOfClass(){ SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] \n",__FILE__,__FUNCTION__,__LINE__); - for(int j=0; jgetClass()== CommandClass(j)){ + for(int i=0; i < commandTypes.size(); ++i) { + if(commandTypes[i]->getClass()== CommandClass(j)) { firstCommandTypeOfClass[j]= commandTypes[i]; break; } @@ -673,7 +732,10 @@ string UnitType::getReqDesc() const{ Lang &lang= Lang::getInstance(); string desc = "Limits: "; string resultTxt=""; - if(getMaxUnitCount()>0){ + + checkItemInVault(&(this->maxUnitCount),this->maxUnitCount); + + if(getMaxUnitCount() > 0) { resultTxt+="\n"+lang.get("MaxUnitCount")+" "+intToStr(getMaxUnitCount()); } if(resultTxt=="") diff --git a/source/glest_game/types/unit_type.h b/source/glest_game/types/unit_type.h index 92a8f56d1..42809d65f 100644 --- a/source/glest_game/types/unit_type.h +++ b/source/glest_game/types/unit_type.h @@ -18,12 +18,14 @@ #include "sound_container.h" #include "checksum.h" #include "game_constants.h" +#include "platform_common.h" #include "leak_dumper.h" namespace Glest{ namespace Game{ using Shared::Sound::StaticSound; using Shared::Util::Checksum; +using Shared::PlatformCommon::ValueCheckerVault; class UpgradeType; class UnitType; @@ -38,7 +40,7 @@ class Faction; // class Level // =============================== -class Level{ +class Level { private: string name; int kills; @@ -56,7 +58,7 @@ public: /// A unit or building type // =============================== -enum UnitClass{ +enum UnitClass { ucWarrior, ucWorker, ucBuilding @@ -64,9 +66,9 @@ enum UnitClass{ typedef list DamageParticleSystemTypes; -class UnitType: public ProducibleType{ +class UnitType: public ProducibleType, public ValueCheckerVault { public: - enum Property{ + enum Property { pBurnable, pRotatedClimb, diff --git a/source/shared_lib/include/platform/common/platform_common.h b/source/shared_lib/include/platform/common/platform_common.h index e97fc18b2..62794f398 100644 --- a/source/shared_lib/include/platform/common/platform_common.h +++ b/source/shared_lib/include/platform/common/platform_common.h @@ -26,6 +26,7 @@ #include "checksum.h" #include #include +#include #include "leak_dumper.h" using std::string; @@ -164,6 +165,23 @@ inline string trim (const string & s, const string & t = SPACES) { return trim_left (trim_right (d, t), t) ; } // end of trim + +class ValueCheckerVault { + +protected: + std::map vaultList; + + void addItemToVault(const void *ptr,int value); + void checkItemInVault(const void *ptr,int value) const; + +public: + + ValueCheckerVault() { + vaultList.clear(); + } +}; + + }}//end namespace #endif diff --git a/source/shared_lib/sources/platform/common/platform_common.cpp b/source/shared_lib/sources/platform/common/platform_common.cpp index dc8a814dc..215481166 100644 --- a/source/shared_lib/sources/platform/common/platform_common.cpp +++ b/source/shared_lib/sources/platform/common/platform_common.cpp @@ -990,4 +990,39 @@ string ModeInfo::getString() const{ return intToStr(width)+"x"+intToStr(height)+"-"+intToStr(depth); } +void ValueCheckerVault::addItemToVault(const void *ptr,int value) { + Checksum checksum; + checksum.addString(intToStr(value)); + vaultList[ptr] = intToStr(checksum.getSum()); + +// if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] add vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value); +} + +void ValueCheckerVault::checkItemInVault(const void *ptr,int value) const { + map::const_iterator iterFind = vaultList.find(ptr); + if(iterFind == vaultList.end()) { + if(SystemFlags::VERBOSE_MODE_ENABLED) { +// printf("In [%s::%s Line: %d] check vault key [%p] value [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,value); +// for(map::const_iterator iterFind = vaultList.begin(); +// iterFind != vaultList.end(); iterFind++) { +// printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str()); +// } + } + throw std::runtime_error("memory value has been unexpectedly modified (not found)!"); + } + Checksum checksum; + checksum.addString(intToStr(value)); + if(iterFind->second != intToStr(checksum.getSum())) { +// if(SystemFlags::VERBOSE_MODE_ENABLED) { +// printf("In [%s::%s Line: %d] check vault key [%p] value [%s] [%d]\n",__FILE__,__FUNCTION__,__LINE__,ptr,intToStr(checksum.getSum()).c_str(),value); +// for(map::const_iterator iterFind = vaultList.begin(); +// iterFind != vaultList.end(); iterFind++) { +// printf("In [%s::%s Line: %d] LIST-- check vault key [%p] value [%s]\n",__FILE__,__FUNCTION__,__LINE__,iterFind->first,iterFind->second.c_str()); +// } +// } + throw std::runtime_error("memory value has been unexpectedly modified (changed)!"); + } +} + + }}//end namespace