红色警戒2修改器原理百科(一)

    红色警戒2,一个经典的游戏。我上初中时经常周末回到家就开始玩任务模式,然后半天过不去一关,就开外挂……开外挂虐冷酷的不开超级武器的电脑。

    先说一下版本,原版V1.006。其他版本只是基址不一样,可参考思路,如共和国之辉。当时比较好用一个外挂是胜利之歌的红色警戒2内存修改器,还有就是红警全能王——各种全能,全能的我不怎么喜欢用(功能默认全开,没得选)。

(一)最简单的开始——修改金钱

    当初刚刚接触Cheat Engine,只会改个金钱。快速建造、地图全开、科技全开什么的完全不知道怎么办。现在貌似突然领悟了什么,回头看看,竟然莫名都搞定了。网上找类似的教程或资料,也只有改个金钱的东西。此文的目的,也就是分享些思路,和自己最后的一些成果。

    此处假定读者对基本的CE使用已经了解,得到金钱的地址:[game.exe+635DB4]+24C。目前来看玩家的数据结构大概描述为:

class Player
{
private:
    //…其他变量
    int nMoney;  //金钱
    int nPower;  //电力
    int nLoad;   //负载
    //…
public:
    //各种函数
}

24C即是金钱在此结构中的偏移。程序中现在看来大概有这么一个变量——Player* CurrentPlayer。这个指针存储固定在game.exe+635DB4的位置,那么[game.exe+635DB4]就是很重要的玩家数据区地址。

(二)建造CD基址查找——实现瞬间建造

    如果你把游戏速度调到最慢,然后找一个建造时间很长的建筑,仔细观察,你会发现从刚开始到就绪,所有单位都有54格变化,每格变化的间隔时间不同。这也说明,将CD改成54就是就绪。

    首先,建造一个发电厂,等到CD刚变化了两三格,暂停建造,然后搜索1-10之间的数值。接着仔细观察CD变化了几格,然后搜索数值增加了几格,如此重复2次左右。这时能得到一个地址,将此值改为1,会发现CD又重新开始了。为了继续进行下去,千万别变成就绪状态或取消建造,可以先将此值锁定。查找什么改写了这个值,应该会得到一条指令:004B9367 - mov [esi+24],edx,然后搜索ESI寄存器的值,可以得到一个绿色地址game.exe+433A80,即基址。[game.exe+433A80]+24就是发电厂的CD地址。重复可以得到矿场、兵营……这时聪明的你,应该会想到一种实现秒建的方法了吧——当这个指针有效的时候(即不是0的时候),且数值小于54时,把CD都改成53。基址存放的指针指向的大概可以想象是如下类,+24偏移是CD,里面应该还有些其他信息……一旦建造完成或取消,这个相关的对象可能就要被销毁以创建新的,这就是上面不要等到变成就绪或取消的原因

class SometingAboutConstruction
{
    //…
    int nCD; //+24偏移
    //…
}

    分享我找的几个:盟军电厂CD([game.exe+433A80]+24),以下只给出基址:盟军矿场(game.exe+433AB0),盟军兵营(game.exe+433AE0)。大笑我才没有找全呢,也不会告诉你CD基址相差0x30偏移

=====================

本文补丁,2015/09/01:

1.CD基址并不关联于建造的单位,也就是说不是盟军电厂、盟军矿场之类的,它是对应他所在的位置的——第一格、第二格……

2.以上实际上有两个结构相关,而并非只有一个,这在第七篇有介绍。这里可以先这么简单的理解,为了避免以后理解上的混淆已经对上文进行了简单修改。

=====================

    但是这么多个种类,都要找是很麻烦的。我们换个思路……熟悉游戏的你,应该都习以为常了:每种类型的单位只能同时建造一个——建筑,武器,步兵,战车,战船等等。程序中为了实现这个功能,可以枚举每种类型的所有单位,看是否有一种正在建造中,然后拒绝同时建造其他的同种单位。当然这是一种方案,但总觉得每当CD变化一次就要枚举这工作好累恼怒。有点技巧的方法是为每种类型设置一个标志变量,有正在建造的此类型单位就设置一个标志值。

    红警2每种类型设置了一个指针,指向正在建造的单位的上述结构,+24偏移就是CD。怎么发现这个指针?上面你已经获得了不同建筑的CD地址,当你造一座电厂,暂停,这个指针应该指向电厂的上述相关对象,造矿场时指向矿场的,造兵营时指向兵营的。要精确搜索的内容就是CD地址减去偏移24——即SomethingAboutConstuction对象的起始地址。如此查找3次,最后我找到两个地址都符合,造什么时指向什么的描述对象,到底是哪一个!!突然想到,我什么都不造,应该是NULL,果断只剩下一个了。然后找什么改写,得到一条指令:004E607A - mov [edi+000052E8],esi,然后精确查找EDI的值,得到game.exe+635DB4——这个值熟悉不,和金钱起始基址一样,这更说明了,这个地址存放的是与玩家有关的数据,也就是CurrentPlayer对象的地址。

    这样就把上面找每种建造单位的CD基址,变成了找每种类型的CD基址,只有建筑、武器、步兵、飞行器、战车和船只六种了。分享我找的结果:建筑CD([[game.exe+635DB4]+52E8]+24),以下只给出一级偏移:武器CD(52F8),步兵CD(52DC),飞机CD(52D8),战车CD(52E0),船只CD(52E4)。

(三)更优雅的方式——快速建造

    上面实现了瞬间建造,有不少修改器是这样实现的。我不怎么喜欢这种方式,编程要用Timer,还有就是造步兵的时候,只有一两个兵营,点了十多下由于动画速度跟不上,只出来一两个,还要造好多好多兵营来配合这瞬间建造的速度。悲伤

    游戏中一个设定就是,当你存在的兵营多的时候,步兵建造速度加快,军工厂多的时候,坦克就建造的快,基地多的时候,各种建筑就快。这必然有一个计数值。

    当你有一个兵营的时候搜索1,两个兵营搜索2,三个搜索3,这时就剩5个地址了,再建造第四个,都变成4了。哪个是?一个个尝试是一种方法。可是如果弄清楚点,可以得到更多信息哦。换点不同操作,卖掉一个兵营!有三个变成3,两个还是4。再建造一个兵营——5个地址都增加了1。你建造一个兵营,取消,会发现有一个已经增加1了,再建造,取消,它又增加1,这个地址大概就是你曾经试图建造的所有兵营数。剩下4个地址,3个为4,一个为5。继续建造一个兵营,暂停,发现有一个增加了1,取消会再减少1,这个地址就是包含正在建造的所有兵营数。还有一个地址是随着你成功建造的兵营数,只增加不减少,这个地址就是该局游戏总共建造的兵营数。现在剩下两个地址,都是对应地图上实际的兵营数。正常游戏,我是没发现怎么让他两个不同。这两个地址一个就是与加速建造有关的,一个就是仅仅保存地图上兵营数的,两个地址修改一个看效果就区分完毕。

    下图是我测试的时候的地址截图,在你电脑上肯定不一样,不过图中第一个和最后一个的相对偏移以及中间3个的相对偏移应该是相同的,可以参考。

add

    然后就是找到基址,直接找什么改写了与加速有关的那个地址,会得到:004EACF4 - inc [eax],然而直接内存中搜索EAX,即上面找到的地址09F96EA4,你不会找到什么。此时一般有两条路可选:1.OD调试,跟踪EAX从哪里来。2.聪明人直接就知道了

    我反正直接知道了马上回来,我没夸我自己,我没夸我自己,你一定要相信——快速建造-步兵([game.exe+635DB4]+52BC)。这显然是与玩家有关的数据,而这个地址又与上面提到的玩家数据地址不算远也不算近(这么一大块都存了些什么转动眼睛,地图迷雾肯定也在),直接相减,就是偏移了。

    惯例,因为这是百科,分享我找到的结果:快速建造-步兵([game.exe+635DB4]+52BC),以下只给出偏移:快速建造-建筑(52C4),快速建造-船坞(52C8),快速建造-战车(52C0),快速建造-飞机(52B8)。其实也不用找,肯定都在附近,尝试+4,-4就OK了。因为程序员肯定不会把相似变量定义在相距太远的位置,除非是传说中吃饱撑的。

    说到这,如果还不知道如何快速建造,我是服了,提示下,把这个值适当加大,15是个不错的数热烈的笑脸,这个数来源于胜利之歌的内存修改器,这个优雅的方式也是受其启发。

To be continued…

署名许可转载请注明来源,http://www.cnblogs.com/viewll/p/4768880.html

posted @ 2015-08-29 15:47  vIewll  阅读(5230)  评论(7编辑  收藏  举报