作者sitos (麦子)
站内WarCraftChat
标题[闲聊] 开图、防开图及反防开图
时间Fri Nov 12 23:58:41 2010
※ [本文转录自 WarCraft 看板 #1CtM8kKq ]
作者: sitos (麦子) 站内: WarCraft
标题: [闲聊] 开图、防开图及反防开图
时间: Fri Nov 12 23:50:04 2010
之前写了一个小的防开图程式,算是长久以来对开图与防开图一些想法的实验,
也发现自己对这些事,累积的一些认识和想法,不如就整理出来和大家分享。
毕竟过去在讨论开图的事上面,也有许多板友零零星星地提过一些想法,
虽然多数人没有程式能力可以自己实作这些想法,但提出想法的时候,
若是对於开图以及防开图这些事,没有基本的了解,很多想法就只是空谈而不可行。
如果能够把相关的背景介绍给一些稍有背景的人了解,也许也能得到一些回馈,
或至少在未来讨论的时候,能够把焦点放在一些可能的方法上面,比较有建设性。
废话就不多说了,首先我们得要从 Warcraft III 的多人游戏运作原理开始讲起,
这会告诉我们为什麽可以开图,以及应该要怎麽样做才能开图。 Warcraft III
基本上是以 peer-to-peer 的方式进行连线,也就是在多人游戏当中,
只有玩家和玩家之间彼此互连,并没有透过伺服器。这代表游戏中的频宽是受限的,
而且游戏的状态必定是以某种分布方式储存在玩家的电脑上。
我想以 Warcraft III 发布时的网路频宽,这样的选择算是合理的选择。
毕竟 Blizzard 的玩家众多,如果所有的游戏都一定要在线上伺服器进行,
让所有的人都连到伺服器,那麽伺服器的维护成本相对就会较高,
恐怕游戏本身就没办法以买断的方式让玩家不断地去玩。反而可能像是 WoW 这样,
是以月费的方式来维持线上服务的进行。这在当时恐怕销售上会有困难。
既然玩家彼此互连,就不可能像伺服器一样可以控制可取得的频宽,
因此在设计的时候就得要先假设频宽可能是很受限的。因此,传递的资料应该精简。
传递的资料可以简单的分为两种选择,一种是直接玩家需要知道的游戏状态,
这样做的优点是,可以只把玩家知道的资讯曝露出来,而玩家不应该知道的,
就根本不传送出去,如此一来就可以避免玩家取得不应该取得的资讯。
然而缺点也很明显,整个游戏正在改变的事物太多,如果每一小段时间,
就必须要把所有改变的事物都传出去,对於网路频宽的需求太高,
以 Warcraft III 当时开发的环境而言,实作上恐怕是有困难的。
另外一种方式,就是只把玩家的动作传送出去。就算是高估一个玩家的动作,
当作每一秒有五个动作,也只不过是每 0.2 有一个简单的描述就够了,
封包里面大概就描述一下是什麽动作,对象或座标等等,传输量不大。
而接收到动作的那一端,再自行计算相应这个动作,游戏状态应该有的改变,
并把计算的结果呈现给玩家就可以了。这样做的优点是传输的量相对较小。
但缺点是,很多将被看见的游戏状态,都是取决於未被看见的部份,
因此必须要让玩家拥有原本看不见的状态,才有可能作出正确的计算。
既然这些资料已经存在在玩家的电脑之中,试着窃取出来就容易多了。
因此,游戏的状态不可能是被切割成很多份存在不同的玩家电脑上,
反而必须要每一个人都存有一份完整的资料。这样做的好处,
除了只传送动作进而自行演算游戏状态可以减少网路频宽的使用以外,
另一个好处是,每一个人都有完整的游戏状态,可以对其它玩家的指令,
进行验证,避免其它玩家直接锁定血量、更改等级等等,
自己却无法验证这样的动作本身是否合法,而造成游戏不公平。
然而,人人都有一份游戏状态的缺点,就是很容易可以取得不应有的资讯。
最着名的例子,当然就是显示阴影中的单位,也就是所谓的开图。
相应着 Warcraft III 本身的写法,开图只需要要求 Warcraft III ,
把原本因为被阴影遮住,而不显示的那些单位,要求它显示就可以了。
由於是否要显示的判断是写在 Warcraft III 的二进位档案当中,
只要能够对这个档案,或者是载入记忆体後的资料作适当的修改。
就可以让 Warcraft III 在游戏当中显示这些原本不应该显示的资讯。
当然,这并不是唯一开图的方法,不过目前常见的开图软体,
基本上都是透过这个方式进行的,因此我们就暂且只讨论这种开图方式。
现在主导游戏资讯显示的二进位档,是 game.dll 这个档案,
因此只要可以修改这个档案,或者是在游戏进行中,
对这个档案在记忆体中相对的位子作修改,就可以达到开图的效果。
例如某个开图软体,要求你输入 Warcraft III 所在资料夹,
并在启用後才能开启 Warcraft III ,就是透过第一种方式。
当你选启用以後,它实际上的动作是修改 game.dll ,
因此当你开启 Warcraft III 後,便是载入了开图版本的 game.dll 。
而当你把这个程式关闭的时候,它会再将 game.dll 还原,
因此像是取消开图一样, Warcraft III 的执行又回归正常。
不过事实上,对档案的修改是永久的,当你选择启用开图以後,
如果直接从工作管理员关闭这个开图程式,它就没有机会改回来。
因此 game.dll 就会永远都在开图状态,即使你不再打开开图程式,
只要 Warcraft III 执行起来,都持续会有开图的效果。
当然,这不是一件好事情,修改二进位执行档也可能有法律问题。
而且这种会带来永久副作用的方式,也让人不太舒服。
另一种方式,也是更为传统的方式,是待这个档案载入记忆体後,
直接修改记忆体的内容,同样也可以达到开图的效果。
优点是,几乎没有副作用,只要程式被关闭,开图的效果就消失了。
再一次打开,又是乾乾净净的 Warcraft III ,也比较没有法律问题。
不过两者的原理其实是相通的,目的就是希望在执行时,
记忆体当中的那一份 game.dll 是要被修改过来取得开图资讯的。
那麽,相应着各式各样的开图机制,防开图又是怎麽做的呢?
基本上可以粗略地方成三类。第一,侦测开图的程式。
第二,阻挡开图的动作。第三,侦测 game.dll 在记忆体中的状态。
第一种侦测开图的程式,也是最早被实际应用的方式。
大致上的方法脱离不了找寻开图程式的视窗或者是特定的特徵,
如果找到已经被开启的开图程式,就认定玩家有开图。
早期的 Garena 也是用类似的作法。
然而,侦测开图程式基本上已经完全无效了。原因很简单,
一旦开图完成,开图程式就可以被关闭,而一旦开图程式关闭了,
就无法透过侦测开图程式来侦测开图。然而即使这样,开图的效果还在。
就形成了实际上有开图,但是侦测不到的死角。
这也就是早期你只要先开启 Warcraft III 开好图,再开 Garena ,
就可以快快乐乐开图的原因。因此後来 Garena 作了一些修改,
让 Garena 一定要先执行,再透过 Garena 执行 Warcraft III ,
才会替 Warcraft III 转送封包,藉此确保执行开图动作时,
Garena 一定是处於启动的状态,以便可以侦测开图。
可惜这样的作法也是徒劳无功,只要用 Process Explorer 之类的工具,
让 Garena 的执行暂停,再进行开图的动作,接着关闭开图程式,
再恢复 Garena 的运作,就一点也没有机会可以侦测到已关闭的开图程式。
那麽,第二种方式如何? 如果我们可以阻挡开图,是否就能禁止开图?
有一段时间这个作法是挺成功的。如果我的印象没有错的话,
大概就是 Garena 跟输入法冲突的时候。由於当时多数的开图程式,
都是透过 WriteProcessMemory 修改记忆体内容,因此只要阻挡这个函式,
就可以避免开图程式修改 Warcraft III 的记忆体进而避免开图。
可惜这个方法也有很大的问题,第一方面就造就了刚刚讲的,
直接修改 game.dll 档案的开图方式。 Garena 不可能阻档修改档案,
因此,只要改过档案再开 Warcraft III 就根本挡不到了。
第二种方式就是把 WriteProcessMemory 的阻挡解开。
一般阻挡的方式就是对 WriteProcessMemory 进行全域的勾载,
把对这个函式的呼叫导到别的地方,让它不起作用。因此,
只要将这个函式呼叫进去的位置还原,让它能有原本的作用,防护就不在了。
既然侦测开图的手段和阻挡开图的手段都没有用,直接侦测记忆体内容,
算得上是最釜底抽薪的作法。只要检查一下记忆体的内容,看看是否正确。
就可以知道 Warcraft III 是否有被窜改过,就知道有没有开图。
我认为这是三种作法里面最好的作法,也是反制上较为困难的作法。
不过依据实作的方式不同,还是有很容易绕过的方式。
但既然目前这个作法似乎还能够运作,破解方式就先不讲了。
--
活着的目的是为主活 然後为主死
死亡的目的是为主死 然後为主活
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 122.116.24.61
1F:推 vivie:快推 不然人家以为我们看不懂 11/12 23:51
2F:推 tlw0709:我承认我电梯向下了 11/12 23:52
3F:推 wen456789:看不懂~囧 11/12 23:53
4F:推 Feather025:不小心按到end了 11/12 23:54
5F:推 jlik12385:好文推 11/12 23:54
6F:推 MITCHLIN:虽然没有很懂 还是推一个认真 11/12 23:56
7F:推 ug945:目前坊间有用最後一种方法的吗 11/12 23:56
8F:推 choosin:COOL 11/12 23:57
9F:推 freezeyp:专业文,推 11/12 23:58
--
我实实在在的告诉你们,一粒麦子不落在地里死了,
仍旧是一粒,若是死了,就结出许多子粒来。
约翰福音 12:24
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 122.116.24.61
10F:→ sitos:发错板了... Orz 11/12 23:59
11F:推 xyzbug:YA 我变头推 11/12 23:59
12F:推 wix3000:WWW 发在主版也可以啊 11/13 00:05
13F:→ sitos:比较喜欢这边的讨论风气 :) 11/13 00:11
14F:推 zebra01:推!! 11/13 00:16
15F:推 sherwinc:所以game.dll 无解.. 11/13 00:18
16F:推 xyzbug:虽然看不太懂 但有没有可能这几种不定时交替侦查? 11/13 00:34
17F:推 datoutwo:其实第三种也有漏洞可钻.... 11/13 00:34
当然有办法,而且办法还有很多种...
18F:→ datoutwo:所以确定是game.dll修改所产生的开图罗?? 11/13 00:35
大多数都是
19F:推 wix3000:我可以请问一下坏模组是如何绕过的吗 11/13 00:44
透过 reverse engineer 还是可以找到显示的位子,再修改程式码仍可以跳过。
不过新地图出来如果方法有换可能就要再找一次。 not sure 要问 kloer
20F:→ datoutwo:被回文了好兴奋 >"< 等我论文弄完也来研究好了..... 11/13 00:46
21F:推 superksh:检查完记忆体在修改记忆体内容? 11/13 01:11
22F:推 Gemani:欢迎回来 11/13 04:08
23F:推 dkyumi:让她爆吧!! 11/13 10:44
24F:推 xxhenryxx:推一个 原PO干嘛把原本PO在主板的文删掉?? 11/13 12:17
就说我贴错板了。我本来就是要发在 WCC ,但是发文前没检查,就发在 WC 。
然後跑到 WCC 看,找不到自己的文章,就想说 SVC 也删得太快了吧...
结果到 allpost 找才发现自己是贴在 WC 。 Orz...
※ 编辑: sitos 来自: 122.116.24.61 (11/13 12:37)
25F:推 leocoolguy:推一个 但看不懂 11/13 12:44
26F:推 Gemani:砍文会留屍呀 <sitos> 11/13 12:54
27F:推 Kujacob:MM起来!!!你是开图专家!!!!!!!!! 11/13 13:44
28F:嘘 phypoem:推认真 11/13 13:58
29F:推 stu110003:推! 11/13 15:54
30F:推 ts01721286:综观以上说法,现在要开图还是算困难的?还是一键就搞定? 11/13 16:13
只要把几个元件包起来,就可以一键搞定了。
31F:→ b2202761:免洗帐号这麽多 不怕你锁 锁了再开 11/13 16:53
32F:推 toolan:快推 不然人家以为我们看不懂 11/13 21:15
33F:推 aringring:有热心又专业的玩家花心思来对抗作弊行为,只能推了! 11/13 23:14
34F:推 KxDashx:其实麦大先发在主板只是想拿P币(误) 11/14 00:25
35F:推 Gemani:砍文会要回p币 再加清洁费 11/14 01:16
36F:推 lomit:噫!好了!我懂了! 11/14 01:50
37F:推 white1003:所以p币 其实亏了.XD 11/14 01:55
p 币对我没啥用。
※ 编辑: sitos 来自: 122.116.24.61 (11/14 02:18)
38F:→ Gemani:2000p可以买sc2试玩序号 11/14 02:46
39F:→ KMSNY:麦大应该有永久帐号了吧 11/14 14:00
40F:推 Irooxker:推~不过有点难QQ 11/14 16:36
41F:推 han2312:P币没有用的话施舍我吧=.= 可以买diablo的装备唷~! 11/14 19:19
42F:推 gozha:专业推 11/14 20:12
43F:推 goodgeorge:推 11/17 19:33
44F:推 jujustine83:好文 推 只是好多字 11/17 20:40
45F:推 tynse71864:推 11/26 20:28