我是谁004 发表于 2016-5-25 17:48:37

把硬编码进行“软化”

本帖最后由 我是谁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的单位能够进行买卖。其他同上。


效果图


帐篷市场。



troytroytroy 发表于 2016-5-25 18:15:43

對exe檔感到苦手,以前使用UltraEdit時只會改引用dat名稱。
我覺得我們需要更多像004這樣的人才來破解其中的訊息。

Boston30 发表于 2016-5-25 21:21:16

非常非常有用!感谢!

这只话唠菜鹰是路人 发表于 2016-5-25 21:59:35

004一发教程就看不懂……但是感觉对做mod的人很有用

cycbobby 发表于 2016-5-25 23:46:47

本帖最后由 cycbobby 于 2016-5-26 01:07 编辑

天際已經突破了~~~~~~~~
另外建議把數據另起一行書寫,以方便新舊數據對齊以便參考

Howerds 发表于 2016-5-26 10:55:44

支持!虽不明,但觉厉!

qweytr_1 发表于 2016-5-31 18:11:32

……传说中是有一个办法保证几乎任意长度的指令的……
据传可以在某个代码区域新增一大段你想要执行的命令,然后使用jmp命令(或者更长的?我不太清楚用哪个……但肯定有那种一跳跳好远的汇编指令)进行无条件跳转,这样可以节省大量空间……似乎是这个道理……我不是专业学汇编的……不太清楚,但可以用这个原理进行更大程度上的修改

我是谁004 发表于 2016-5-31 18:33:48

qweytr_1 发表于 2016-5-31 18:11
……传说中是有一个办法保证几乎任意长度的指令的……
据传可以在某个代码区域新增一大段你想要执行的命令 ...

您说的没错,我在第二次研究https://www.hawkaoe.net/bbs/thread-137060-1-1.html中就用到了这种方式。
不过缺点在于,这样的话我就要找exe中的空白部分了。上面这个帖子中我找的是文末有很长一串0x00的部分,不知道能不能在更远的地方写新的语句。或者用DLL,但DLL我这里没有编译的环境……

timclyde 发表于 2016-7-4 09:01:43

支持楼主的工作,希望以后楼主能够发更多硬编码软化的教程。

timclyde 发表于 2016-7-4 09:38:57

本帖最后由 timclyde 于 2016-7-4 21:07 编辑

还有,楼主你所说的“标志第四位成为生命恢复单位”中的第四位是不是指的是SW:侦测单位?

我是谁004 发表于 2016-7-4 10:24:43

timclyde 发表于 2016-7-4 09:38
还有,楼主你所说的“标志第四位成为生命恢复单位”中的第四位是不是指的是SW:侦测单位?

对呀,从左往右数可不就是第四个

leo0691 发表于 2018-2-2 23:11:15

可以去52pojie学习关于反汇编的一些知识。CE是游戏修改工具,相对于OD各有所长。总体来说OD更好用,CE偏向于修改游戏,更容易上手。
7L的意思应该是代码注入。。。
在比较大的内存地址注册一小段空间,利用JMP进行跳转,执行完返回。
......
我不是专业学编程的,但是通过外挂dll的方式拓展代码是绝对可行的。只可惜帝国毕竟是少数人的执念。。。
页: [1]
查看完整版本: 把硬编码进行“软化”