[转]防外挂和防木马的通用解决方案

外挂、木马和私服一直网络游戏的三大死敌。一个不小心被任意一个家伙打倒,一款好好的网络游戏就全毁了。
在这里我要讲一下防外挂和防木马的一个通用解决方案,希望能解决大多数的外挂和木马问题。从原理上看,也可以用于防私服,具体是否可行,请大家斟酌。这个方案受到了传奇的反外挂方案的启发,在这里对盛大表达感谢。

该方案包括“两点一线”。其中一个“点”是侦测代码,检查外挂和木马是否存在,有点象个“侦察员”。另一个“点”是攻击代码,可以抓玩家进监狱,也可以通知玩家修改密码,有点象个“狙击手”。一条“线”是指发现外挂或木马的信息要安全的从侦察员传到狙击手那里,有点象“电话线”。下面我分别介绍这“两点一线”的设计要点。

一、“侦察员”。
侦察员要有什么特点呢?
第一要会隐蔽。
培养侦察员不容易,写一个侦测代码也不容易,一但被敌人发现了,很容易被缴械或者被击毙。下次又写一段,又被发现搞定,一直这样打拉锯战,也不是克敌制胜之法。
如果我们在客户端放一段侦测代码,一定要注意尽量不要被黑客用动态分析法(例如SoftIce),或反编译法(例如MASM)等很容易的查到。例如不要在代码段中包含任何可供识别的字符串,如出错信息文字串,用于查找外挂的关键字字符串,包括外挂程序名,外挂进程名……。总之,尽量不要包含字符串就对了,如果要用也要加密后存放,并且解密字符串的过程中用到的临时字符串变量要放在栈上,在用过之后最好全部置0。
在侦测代码中,不要进行任何I/O操作,所有的通讯、界面消息、读盘写盘、显示、接收键盘鼠标输入等操作,都容易被黑客顺藤摸瓜找到你的代码段。也不要读写任何很容易被黑客监控的内存,包括全局变量和堆变量。因为黑客很容易通过监控内存的修改来找出你的代码段。
侦测代码也不要嵌放在容易动态跟踪的“程序初始化”部分,或者任何固定时间或固定条件下会运行的部分。最好是比较随机的触发侦测代码,增加黑客追踪你的难度。
还有一点,就是侦测代码建议不要写成一个独立的函数,而是做成个内嵌宏的代码,这样杂在功能代码中间,更不容易被黑客找到。

第二要多样化。
通过多样化能解决正确性的问题。大家都知道抓错人、杀错人是什么后果。一但你把一个没有用外挂的玩家抓进外挂监狱,或者把没有被木马盗号的帐号强行锁定,那会比你少抓10个甚至少抓100个更严重的伤害到玩家。
除了在发布前认真测试之外,一个比较好的方法就是多做几个“侦察员”,狙击手根据多个侦察员汇报的情况进行加权判断,宁可放过、不可枉杀。必竟“人”命关天啊。
多做几个侦察员的好处还在于,万一有个别的侦察员被黑客“杀掉”,狙击手也不会变成“瞎子”。同时狙击手还可以根据有问题的侦察员的情况,报告总部该侦察员已死亡,让总部重新增派侦察员过来。
所以在程序中可以按时间长短设计3种侦测代码。一种是启动之后就尽快检测并报告给狙击手。这种代码比较容易被黑客查出,也可以让此代码成为一个陷阱,以了解黑客破解我们的情况。
另一种是过几分钟之或几十分钟后再进行检测,这种代码的破解难度会很大,因为黑客破解一段代码,通常要尝试许多次,延迟了检测时间,无疑会增加破解的时间成本。可以用这一类检测的报告,作为判断是否被攻击的主要依据。
第三种检测最好1小时以后再启动,甚至是启动数次才会检测一次。这段代码报告的情况,可以检查出之前的其它检测代码是否被黑客全部破解,以提醒程序员是否需要重建防御体系,或者改用其它方案。这一类检测方法不是必须的,可做可不做。
另外要注意的是,各段检测代码一定不要用完全相同的代码(即程序二进制码相同),或者各段代码都检测唯一的一个外挂特征或木马特征。如果想同一段检测代码放到不同的位置,在不同的时间段进行检测,也要在不影响功能的前提下,调整一些代码行的前后顺序,以防黑客利用相同的代码串,查找另一个检测点的代码。总之,各个检测代码要尽可能的不同,检测的外挂特征或木马特征也要多样化。

二、“狙击手”。
狙击手要有什么特点呢?
第一还是要会隐蔽。
为什么要隐蔽?要是不隐蔽,你还有机会开第二枪么?人家知道你在哪里了,还不会躲么?
外挂和木马比较好的隐蔽方法,是把狙击手放在服务端。黑客无法修改服务端,服务端可以任意抓玩家进外挂监狱或者通知玩家修改密码,外挂和木马无法阻止我。
对于私服要麻烦一些,因为狙击手必须藏在黑客手中的服务端内。攻击时不仅要注意随机性触发,还可以采用乱写内存等比较隐藏的手段。触发蓝屏也是个办法,但要防止黑客“钩住”触发蓝屏的路径,否则就会暴露自己。

第二是要延时。
千万不要在侦察员刚上报敌情时就立即开枪。这无疑是直接告诉黑客侦察员在什么山头上,好让对方轻松的剿灭我们的侦察员。好的狙击手问题会等待最佳的射击时机。
一定要做足够的延时,让敌人多过几个山头之后,再开枪杀敌。这样黑客就不知道侦察员在到底在哪个山头上,也就能很好的保护我们可爱的侦察员了。
比如我们客户端有一段检测代码会在打开仓库时检查是否存在外挂。如果玩家刚一打开仓库,你就立即将他抓进外挂监狱。那么黑客就能猜出有一段检测代码嵌入在打开仓库的代码中。只要跟踪一下或者读一下代码,就能很容易找出我们的侦察员。要杀要剐还不由他说了算?
但如果我们有做延时,等玩家又开始用外挂练功、用外挂捡钱、用外挂走路之后。狙击手再一枪搞定,送玩家进外挂监狱。这样黑客就有得忙了,练功的地方、捡钱的地方、走路的地方,都要去查是不是有检测代码,而且可能查了N久都查不出来,还以为自己的水平太臭。狙击手在一旁就可以偷笑了。

第三要保护。
因为延时出击的原故,敌人可能在延时的时间里大开杀戒,造成重大损失。这时一定要对可能造成的伤害进行必要的保护。以保证在出击之前,减少无辜玩家的损失。
例如客户端发现了木马并上报给了服务端。这时如果狙击手立即出手,告诉玩家密码已经被盗的事实,无疑违反了第二条“要延时”的原则,极容易暴露我们侦察员的位置。
比较好的解决办法是,发现木马后,立即采用“锁定玩家帐号”之类的办法,保护玩家在延时期间不被黑客盗号,再延时之后通知玩家及时更换密码。
要注意的一点,就是保护要悄悄的进行。如果黑客能探测出你什么时候开始保护的,就能知道侦察员发现他的时机,这就违反了狙击手的第二条守则“延时”。所以在保护玩家利益的同时,也要保护好侦察员。
比如发现木马后,立即锁定的仓库锁,以保护玩家的重要资产。这时就给黑客一个探测侦察员什么时候发现木马的方法,只要频繁的扔一件极品武器,看服务端是否自动锁定了仓库锁,就能探测到什么时候木马被侦察员发现了。其实保护当前已登录的玩家资产并无意义,通常这个玩家的身份是正确的。只有下次登录时,才有可能是黑客在登录。所以只需要下次登录时再锁定仓库锁,就能很好的保护玩家资产了。

三、“电话线”。
电话要怎么打才安全呢?
第一不要直接连线。
如果侦察员和狙击手之间拉了一条电话线,只要找到一个,就能很容易的找到另一个。而后顺藤摸瓜,所有成员都会全军覆没。
如果检测代码和攻击代码,都放在客户端(以防私服为例),千万不要在检测代码中直接调用攻击代码。否则找到了一个,就两个都完蛋了。比较安全的做法是,把检测结果合并到一个经常会被大量代码使用的变量中(例如给这个整数变量增加1000000),然后在正常代码中将此变量计算变化后再写到更多的其它变量中,而攻击代码只在“其它位置”去读出并分析侦察员发来的信号。
对于外挂和木马就相对好一些,因为狙击手在服务端,不存在会暴露的问题。

第二通讯要保密。
如果侦察员一发现敌人,就用明语在步话机上大叫“我看到敌人啦!我看到敌人啦!”,无疑这个侦察员一定很短命。
正确的做法是在一大堆正常的上传消息中,隐蔽的夹杂着敌情信息。例如在上传走路消息或战斗消息时,上传一个“不合理”的特殊数据。比如走路方向为9,或者被攻击怪物的ID是一个非法的固定值98372472。在大量的走路消息或攻击消息中,偶尔出现一个这样的非法值,很难引起黑客的注意,况且他又不知道我什么时候会上传这个“带隐语的消息”,怎么可能发现我们的通讯机密呢?

有了以上的“两点一线”(其实是多点多线啦),整个防御体系就建立起来了。不管外挂、木马和私服多么猖獗,我们也能“One shot, one kill!”。

原文地址:https://www.cnblogs.com/wxxweb/p/2326245.html