本帖最后由 我是谁004 于 2016-5-28 16:20 编辑
前 言
以前大家也知道,许多特性属于“硬编码”,比如破坏者自爆、市场买卖功能等。
这些之所以叫“硬编码”,是因为它们不是在DAT中所设置的,而直接由EXE进行调控,故只有且一定是对应ID的单位具有该特性。过去,我们可以在这些ID上头改单位。但是,随着MOD发展,其中的单位越来越多,总不能轮流替班硬编码单位吧?有没有什么好的解决方法呢?
曾经在国外的论坛中提到为所有建筑都增设翻页按钮的方法,cyc也叙述过的,便是直接修改EXE文件的特定数据。我想,既然可以修改EXE文件,把船坞的按钮给予所有建筑,那其他的硬编码也应有它的解决方案。
就在昨天,我尝试了直接使用UltraEdit查看并修改EXE数据。在我之前所知道的船坞第二页地址,0x0012830C处,看见了一个字节数据:2D;而这个2D正是船坞的编号(十进制是45)。2D是船坞75改66,那么我就试着改其他值,改成2D,果然箭头跑兵营去了。有了初步的了解,但显然不能这么进行下去,毕竟是盲人摸象,无法进展。
幸亏我知道,编译完成的EXE文件中存在的是机器语言,而机器语言是可以反汇编的。于是,经过了解,认识了OllyDbg工具,它可以将十六进制信息转变为汇编语言。又受一位不愿透露名字的网友所帮助,使用Cheat Engine来对程序内存进行查看。经过大量的实验,用上控制变量法,得到了结论。
现在已知的,可以修改破坏者自爆、死亡爆炸、狂战士回复生命值、市场交易的特性。
原 理
我们用OllyDbg打开age2_x1.exe,寻找地址0x004C2CE6,这是葡萄牙MOD作者在源代码中指明的对破坏者的调节的地址。可以看到它的上下文如下:
OllyDbg中显示的地址是内存中的,实际上对应EXE文件数据的地址应减去0x00400000。
从0x004C2CD0起始,是对单位进行判断,判断其是否要实现自杀式攻击。我来简单解释一下代码:
将EDI+0x10的双字数据放进AX寄存器中,前者即为EDI(此时为单位地址)指向的单位的ID在内存中的地址;
让AX与0x020F进行比较,如果相等则跳转至0x004C2CEC。0x020F是爆破船的ID;
没跳转则让AX与0x0210进行比较,如果相等则跳转至0x004C2CEC。0x0210是重型爆破船的ID;
还没跳转则让AX先后与0x02C2、0x01B8进行比较,如果相等则还跳转,否则跳转至0x004C2D1F。这两个是破坏者、英雄破坏者的ID。
其中跳转至0x004C2CEC即越过对其他ID的判断直接执行后面的语句;而跳转至0x004C2D1F,便跳过了自爆属性。
于是乎,我们可以修改汇编代码, 让程序进行另一种形式的判断,来让更多单位拥有爆炸能力。
如果把整个原理再描述一遍的话,篇幅可能不够用。下面仅仅对我所给出的部分方案进行描述:
判断EDI+0x16(对应为单位类别)的双字值是否为0x0023(破坏者类),是的话执行自爆属性,否则跳过。NOP为空指令,不执行任何事情。
判断EDI+0x00000099(对应为单位攻击模式)的双字值是否为0x0005,是的话执行自爆属性,否则跳过。
同时,自行修改的指令也是有长度限制的,其字节数不能大于原有的指令长度。除非你有超强的能力,可以连带着扶正整个程序。也正是因为这个,我没有使用属性来控制市场功能,而只是用单位的类别。
具体方法
破坏者、爆破船的自爆功能实际上是两个方面:单位攻击时自爆、单位死亡时爆炸。这两个方面可以分别使用,故实际上可以做出排雷时不会爆炸的地雷,以及不可攻击但可以打爆的油桶。
以下请使用十六进制编辑器进行修改,我用的是UltraEdit。
0x000C2CD0
这里在进行“攻击时自爆”的单位的筛选。
原始数据为:
66 8B 47 10, 66 3D 0F 02, 74 12 66 3D, 10 02 74 0C,
66 3D C2 02, 74 06 66 3D, B8 01 75 33, ?? ?? ?? ??, 方案1:
66 8B 47 16, 66 3D 23 00, 74 12 75 43, 90 ?? ?? ??, (90与后续的数据可以不改,但建议一同改为90,这样在反编译工具中也能够正确显示,下同)。结果是类别为35(破坏者类)的单位自爆。修改其中的23为对应类别(注意,是十六进制)也是可以的。
方案2:8A 87 A4 00, 00 00 24 04, 3C 04 74 10, EB 41 90 ??, 这可以让单位标志(Unit Attributes)那一部分,第三位成为自爆属性。在AGE中,为第三个复选框,标注为“SW: Stealth Unit”。修改两个04为其他的值(01、02、08、10、20、40、80)可以对应其他的位。
方案3:
8A 87 99 00, 00 00 3C 05, 74 12 EB 43, 90 ?? ?? ??,
这样可以让攻击模式(Attack Mode)为5时,单位自爆。将05修改为其他值也可以对应。
0x000C167F
这里在进行“死亡时爆炸”的单位的筛选,可以令单位在死亡时原地释放攻击,即使单位没有攻击能力。
原始数据为:
66 8B 40 10, 66 3D 0F 02, 74 12 66 3D, 10 02 74 0C, 66 3D C2 02, 74 06 66 3D, B8 01 75 1B, ?? ?? ?? ??, 方案1:
8A 80 A4 00, 00 00 24 04, 3C 04 74 10, EB 29 90 ??, 这样可以让单位标志第三位成为死亡时爆炸的属性。
新加的爆破单位是可以伤及友军的,可以制造出连环爆炸效果来。并且爆炸后的伤害时机取决于帧延迟。
0x000C1791
这里在进行“狂战士式的生命回复”的单位的筛选,如果单位还是英雄,还可以叠加。
原始数据为:
66 8B 42 10, 66 3D B4 02, 74 0A 66 3D, B6 02 0F 85, E6 00 00 00, ?? ?? ?? ??, ?? ?? ?? ??, ?? ?? ?? ??, 方案1:
8A 82 A4 00, 00 00 24 08, 3C 08 74 08, E9 E9 00 00, 00 90 90 90, ?? ?? ?? ??, ?? ?? ?? ??, ?? ?? ?? ??, 这样可以让单位标志第四位成为生命回复的属性。
0x00121FBA
这里在进行“市场价格初始化”的单位的筛选,只有在游戏中选择了这种单位,市场买卖才能够显示价格,否则会为0。
原始数据为:
66 83 78 10 54 方案1:
66 83 78 16 65 这样可以让类别为101的单位能够初始化市场价格。将65改为其他数值,也可以指定其他类别。实际上,当类型为建筑时,大多数类别都是没有区别的。
0x00128580
这里进行的是“可买卖”的单位的筛选,只有这种单位且类型为80-建筑时才能买卖。
原始数据为:
66 83 79 10 54 方案1:
66 83 79 16 65 这样可以让类别为101的单位能够进行买卖。其他同上。
效果图
帐篷市场。
|