标签:
先说一件事情,昨天我在继续OD调试游戏的时候,运行错了版本,然后OD的备注、标签和断点通通没有了。喜大普奔上天关上了一扇门,然后我开了一扇窗户——抛弃之前的枷锁,重新出发,目前来看可能是找到了判断地图触发器的整个过程,待进一步测试;还找到了立即胜利的源头。
让我们书接上回。
如果细心的你在进行上一步的疯狂的掠夺的时候,发现了没人占有的建筑物的pOwner不是NULL,你就可能发现一片新大陆。是谁拥有了这个建筑物,却还能显示没有归属。
前一篇最后一个图,转移所属函数(call [ebx+378])前面有这么备注的一个CALL:玩家ID获取数据基址(其实这个描述不准确),不知是否注意到了?当时调试时,传入ECX=0,EAX返回玩家数据地址,然后粗略的看了看里面的循环,就做了个这样的标签。毕竟能返回玩家数据地址的函数,需要一个参数,那八成就是玩家ID,因为咱就是本地第一个玩家,就是0号位置咯。联网对战时,才会变成其他位置,单机只能在0号。。。
既然有这么一个ID,就来找找ID在哪个偏移处。用CE的分析数据/结构功能,对比分析地图上所有玩家数据(通过电脑建筑的pOwner获得电脑玩家数据地址,我测试时就两个玩家,我用美国,对手是简单的苏联),同时尝试发现一些其他显而易见的数据,只发现偏移+30处比较明显,我是0,电脑是1。基本就确定+30偏移就是玩家ID。然后就是一堆不明显的数据,一大片0。
然而,当我因某些原因又去看了下那个所谓的CALL<玩家ID获取数据基址>,却发现没有一条指令读取了+30偏移,Amazing!然后仔细跟踪发现一个莫名其妙的循环次数,地图上有2个玩家,却循环了4次。尝试3个玩家,结果循环5次。而且和参数ECX比较的是玩家数据+34偏移处的一个地址的+B8偏移处的数据,文字表述比较复杂。C语言描述就是:if (CurrentPlayer.onePointer->oneValue == ECX)。
这个oneValue,它永远和玩家ID相同的吗?冥思苦想一番,这个指针指向的是什么结构?最终从地图编辑器获得灵感,地图上的单位归属可以设置给不同国家,还有平(即无归属)和治安(一个神秘的组织),这就解释了为什么循环次数永远多两次:平和治安在你看不到的地方,作为特殊玩家一直存在。也解释了单位看起来没有归属,实际上还是有个归属者。玩家数据+34偏移是所属势力对象指针,所属势力对象结构的+B8偏移是势力编号。那么这个CALL的准确备注应该是:势力编号获取数据基址。
现在才算进入正题了,来分析下这个函数(004ED760),就能找到枚举全图玩家的必要条件了:地图玩家数(包括平和治安)(game.exe+6322A8),地图玩家数组(game.exe+63229C)。然后你就能知道他们有多少钱,有几个步兵,有几个建筑等等等等,这些偏移比较好找。
号外,好像是在一个苏军任务上发现,玩家ID终于不是0了,因为剧情是强行登陆建立基地,我是侵略者还有最后一关,俘获总统任务地图上有13个玩家(还有两个隐藏的更深的势力叫GDI和Nod)——我眼瞎,玩得时候没看到。。
标签:
原文地址:http://www.cnblogs.com/viewll/p/4773802.html