我正在制作一个 C++11 游戏,其中分数被发送到服务器。我将分数存储为一个简单的浮点数,因此使用作弊引擎等软件的人可以在将分数发送到服务器之前轻松更改分数的值。
如何保护我的游戏免受此类攻击?
您可以做很多选择,但最好的是不要接受来自客户的任何重要价值观。让服务器完成所有计算,然后将值发送给客户端。
如果您必须首先在客户端执行任何操作,请加密您关心的任何数据(或所有数据,如果可能)。
让服务器计算任何重要的东西可能会更好。例如,在《使命召唤》中,您希望服务器决定谁被击中,以便个别玩家的计算机/延迟/等。不参与。
如果您正在做一个仅限本地 PC 的游戏并且只想在最后上传分数,那么服务器计算不是一个选项。在这种情况下,您确实必须首先坚持加密并混淆重要值。你能做的只有这么多;如果它是 100% 客户端计算的,它可能永远不会是防弹的。
您确实无法确保该值未被篡改。你可以做的是向服务器发送足够的信息,它可以确定“这可能吗”——例如,如果你的游戏是“吃豆人”风格的游戏,你还可以提供吃豆人的所有“Blob”——人吃了,或者每个级别的数量以及完成每个级别所花费的时间等。作弊者可以复制所有需要的额外数据并非不可能,但是如果您要发送更多数据,则这样做会变得更加困难.
但是您的软件中随时可用的任何数据都可能会被“调试器”类型的应用程序修改。你对此无能为力。
总会有办法绕过您的保护。不管它有多好。但是,你可以让它变得更难。有一个例子:https ://github.com/jgk2Th/anti-wpm 。
基本上,重点是创建两个具有相同值的变量,并将其中一个变量移动到 RAM 中的不同位置(简单地说),以使其更难找到。然后,比较差异值。
这是该想法的简化代码。
int VariableToProtect = 0;
int pVar[ 1000 ] = { 0 };
int Pos = 0; // 'pseudo-position' of the element (with same value as VariableToProtect) in pVar
while( !GetAsyncKeyState( VK_SPACE ) )
{
if( pVar[ Pos ] != VariableToProtect )
printf( "detected!" );
++VariableToProtect;
Pos = rand( ) % 1000;
pVar[ Pos ] = VariableToProtect;
Sleep( 10 );
}
如果它是大型多人游戏,那么理论上,您可以使用某种算法,让服务器从随机用户组请求特定问题的答案。作弊者将得到不同的答案,而无需重大勾结。
如果在像《使命召唤》这样的游戏中,你可能有 30 名玩家,并且如果发生杀戮,则需要超级多数同意。这样一来,任何一个团队都无法通过勾结的方式作弊。您仍然需要注意用于攀登排行榜的备用帐户。