BatHzw 发表于 2008-8-15 00:07:55

某强人用另类技术修改H3之谈!!!

标 题:给自己喜欢的游戏升级
发信人:咖啡豆
时 间:2004-10-27,17:57
详细信息:

偶有一个非常喜欢的游戏,英雄无敌III,99年出的游戏,现在连她的发行公司都破产了,这样老掉牙的东西当然没人更新乐(虽然现在有一批俄罗斯发烧友在做MOD)。但是能不能自己给她加入新的乐趣呢?
   怎么不行泥~WE ARE CRACKERS !下面是偶给这个游戏做的一个补丁的部分功能的过程。想想当初学CRACK的时候就是看着各位大大的文章长大的,现在有空也写点什么吧,但是水平很屁,纯属抛砖引玉:)
   英雄无敌这个游戏有5个难度,但是作为一个骨灰玩家,这第5个难度已经不能满足偶的被虐待欲了,于是想到为这个做游戏增加难度的补丁。
   加大难度最直接的方法当然就是给电脑更多的钱和资源,和电脑英雄更多的经验。于是制作这个补丁就分为3个步骤:
1,找出程序中加资源和战斗后加经验的地方
2,写自己的增加资源和经验的函数,并做成DLL
3,修改游戏EXE文件,在游戏中调用自己写的在DLL中的函数
   LET’S GO!第一步很简单,运行游戏,在内存中找出存放钱和经验的的地址,然后叫出SOFTICE,在找到的内存地址上设下断点。切换到游戏,度日(游戏中每过一日就会根据你占据的领地加钱和资源),SOFTICE跳出:
:0054ECD7 cmp dword ptr , 00000007
:0054ECDB jge 0054ECFA
:0054ECDD mov edx, dword ptr
:0054ECE0 mov eax, dword ptr
:0054ECE3 mov ecx, dword ptr
:0054ECE6 mov edx, dword ptr
:0054ECE9 mov eax, dword ptr
:0054ECEC add ecx, dword ptr
:0054ECEF mov edx, dword ptr
:0054ECF2 mov eax, dword ptr
:0054ECF5 mov dword ptr , ecx
:0054ECF8 jmp 0054ECCE
:0054ECFA jmp 0054EC79
这里就是加资源和钱的循环,由于有6种资源和钱,所以这个循环要循环7次,每次增加一种资源。可以通过修改这里的代码来让电脑获得更多的资源,但是必须要知道当前写的内存单位是不是代表电脑的资源,如果不管就会导致连自己的资源也增加了,这样起不到增强电脑的效果。
于是必须要找到游戏中数据的绝对寻址(虚拟地址)。资源这种东西在程序中肯定会为它分配一个永久的空间,而不会是在局部栈中分配,也不会在堆中分配。
因此这是一个全局变量。(即使C++中类把它的成员封装了,但是编译时还是会通过NAME-MANGLING生成一个全局唯一的标识符)
:00458098 imul edx, 00000168
:0045809E mov eax, dword ptr
:004580A3 lea ecx, dword ptr
:004580AA mov edx, dword ptr
:004580AD mov eax, dword ptr
:004580B0 mov esi, dword ptr
:004580B3 mov eax, dword ptr
从这里知道资源的寻址:
* 168 + + 20AD0 + 9C + 资源号 * 4
可以看出,这个寻址是在编译后就确定下来的。
然后找出判别是否为电脑的标志:
+ 20AD0 + * 168 + E2
   这里可以看出一点面向对象的影子,这个游戏听说是用VC做的。 + 20AD0 是一个类的所有对象基地址,应该是每一个势力就是这个类一个对象,并且编译器为每个对象分配的数据空间为168H个字节。就是势力的编号。知道了这些之后就可以进入第二步了。
   写一个函数,作用是先判断是不是电脑,如果是,就为它加上额外的资源。
入口参数为当前的势力编号好了:
DLLIMPORT void AddResource(int iPlayerID);
函数中把通过上面两个寻址完成判断和增加资源的任务。同样加经验的函数也是如此。是不是很简单:)
写完所有函数之后,就编译成一个DLL
头文件如下
#ifndef _PACKDll_H_
#define _PACKDll_H_

#if BUILDING_DLL
# define DLLIMPORT __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLIMPORT __declspec (dllimport)
#endif /* Not BUILDING_DLL */


DLLIMPORT void Initialization();
DLLIMPORT int MakeMonster(int );
DLLIMPORT int ChangMntNmbToID(int );
DLLIMPORT void AddResource(int );
DLLIMPORT int AddExp(int );
DLLIMPORT int Remark(int );

#endif /* _DLL_H_ */
可以看出有6个出口函数。
   完成第二步进入第三步,在游戏的EXE文件中加入引用自己写的DLL中函数的代码。首先是修改EXE的引入表,增入自己的DLL,这样程序在运行的开始才会连接偶写的DLL。
   用PE编辑工具LordPE打开HEROES3.EXE,选择引入表,回发现程序所有DLL和引入函数。增加一个DLL,输入DLL中的所有引出函数名,LordPE就帮你把引入表做好了,是不是太简单鸟?糊里糊涂就搞定了?THUNKRVA 是什么?THUNKVAULE又是什么东东?那看看真正的引入表是怎样的吧:
43 66 50 61 63 6B 2E 64 6C 6C 00 00 00 49 6E 69
74 69 61 6C 69 7A 61 74 69 6F 6E 00 00 01 4D 61
6B 65 4D 6F 6E 73 74 65 72 00 00 02 43 68 61 6E
67 4D 6E 74 4E 6D 62 54 6F 49 44 00 03 00 41 64
64 52 65 73 6F 75 72 63 65 00 04 00 41 64 64 45
78 70 00 05 00 52 65 6D 61 72 6B 00 0B 10 47 00
1C 10 47 00 2A 10 47 00 3C 10 47 00 4A 10 47 00
53 10 47 00
第一行43 66 50 61 63 6B 2E 64 6C 6C是这个DLL的名字,也就是CfPack.dll
然后有一个00,是名字的结束标志。接下来的0000就是标志第一个函数的开始
也是这个函数在DLL中的序号。49 6E 69 74 69 61 6C 69 7A 61 74 69 6F 6E 就是第一个引入函数的名字:Initialization接下来是结束附00,然后又是下一个函数。一共6个函数,到第6行的6B(红色)结束。
下来是什么呢?就是每个函数的THUNKVALUE也就是每个出口函数的符号在引入表中的地址。如6B接下来的0B 10 47,就是第一个函数的符号的地址。也就是第一行中红色的00的地址0047100B,下来00是分隔符,然后是第二个引入函数符号的地址0047101C,指向第二行的红字部分。这样一共6个地址,分别指向6个引入函数的名字。
搞定引入表后,就可以该原代码了。

   首先,在HEROES3.EXE中找到空白的部分,如
:007AB425 int 03
:007AB426 int 03
:007AB427 int 03
:007AB428 int 03
:007AB429 int 03
:007AB42A int 03
:007AB42B int 03
:007AB42C int 03
:007AB42D int 03
:007AB42E int 03
:007AB42F int 03
...
这里有一大段空白的部分
然后跳到加资源的地方:
:0054ECD7 cmp dword ptr , 00000007
:0054ECDB jge 0054ECFA
:0054ECDD mov edx, dword ptr
:0054ECE0 mov eax, dword ptr
:0054ECE3 mov ecx, dword ptr
:0054ECE6 mov edx, dword ptr
:0054ECE9 mov eax, dword ptr
:0054ECEC add ecx, dword ptr
:0054ECEF mov edx, dword ptr
:0054ECF2 mov eax, dword ptr
:0054ECF5 mov dword ptr , ecx
:0054ECF8 jmp 0054ECCE
:0054ECFA jmp 007AB46D
兰色的部分被改了,跳到了空白的地方,然后,呵呵,怎么搞都可以鸟!
把原来的int 03改成以下代码
:007AB46D 8B4DF8                  mov ecx, dword ptr
:007AB470 51                      push ecx

* Reference To: CfPack.AddResource, Ord:0003h

:007AB471 FF1568108700            Call dword ptr
:007AB477 83C404                  add esp, 00000004
:007AB47A E9FA37DAFF            jmp 0054EC79
:007AB47F CC                      int 03
调用CfPack.AddResource后跳会去,神不知,鬼不觉就运行给电脑加资源的过程,呵呵:)
这里的Call dword ptr 调用的CfPack.AddResource地址是怎么知道啊?就是这个函数的地址了,这个地址是由引入表中的THUNKRVA:471068(系统在装入DLL之后填写的该函数接口的具体地址)加上程序装如地址400000H得到的。
同理,其他功能也可以由类似方法完成。
当然了,还要写一个图形界面用来设置新的难度等级,把设置写在一个文件中,然后在DLL中加入读取设置的函数Initialization()放在游戏运行开始的地方运行就OK了。
呵呵,新的难度下又终于可以被电脑虐待了~~-_-!!

暗黑龙守护神 发表于 2008-8-15 08:27:20

为什么只增加难度而不加最终得分呢?

shenbing100 发表于 2008-8-15 21:52:41

最终得分也加了,可以超500.
游家有补丁下载.但只能用于h3,在wog无效.

BatHzw 发表于 2008-8-17 02:25:17

某强人用另类技术修改H3之谈—2!!!

原创:zhoubapi

死亡阴影英雄特长diy
在wog英雄特长是可以通过Erm脚本来更改的,甚至能实现战斗特长和升级特长的并存。
但在英雄无敌中死亡阴影中就没这么灵活了,如果需要改变某个英雄的特长,只能修改
Exe执行文件中的硬编码了
这两天在论坛大虾的提示下,研究了一下英雄特长的修改,有了点小小的心得。
版本号:死亡阴影3.1.0.0
工具:ultraEdit

修改效果:
1,一般的特长生物有效
2,第二技能特长有效(英雄需要有对应的技能)
3,特殊的生物特长有效(如科尔格的比蒙特长,1级就有攻击力+5防御力+5伤害力+10)
4,生物升级特长有效(德肯和格鲁可以复制了)
5,增加资源特长/魔法特长尚有待研究
6,有效修改后显示特长的图片还是原来那个,这个还不知道怎么改图片;但是可以修改HEROSPEC.TTT或HEROSPEC.TXT修改特技说明

修改方法:
用ultraEdit打开Heroes3.exe(事先记得备份),十六进制编辑模式下找到
00408000h
从此行开始,每40个字节,也就是两行半记录一个英雄的特长,英雄排列顺序
看宝典吧,宝典上英雄头像下有序号如 005kn 排行老六,战役特殊英雄排在最后
每个英雄数据的前4个字节记录特长种类,后面数据记录特长的具体信息
种类有
(1) 00 00 00 00------ 第二技能特长,接下来四个字节就是技能的序号了
如欧灵同学是 00 00 00 00 01 00 00 00    技能中排行老二的是箭术,所以就是箭术特长
如果改为 00 00 00 00 02 00 00 00就是后勤特长了,当然你得带有后勤技能或者是升级后升出了后勤技能才是有用的
如果改为 00 00 00 00 16 00 00 00就是进攻特长了,16换算成十进制就是22
顺便说一句,技能编号,英雄编号,魔法编号,生物编号等的数据可以在Erm的帮助中找
(2) 01 00 00 00 -------- 一般生物特长,接下来的四个字节就是生物的序号
如威尔斯凯 是 01 00 00 00 02 00 00 00特长射手,改成01 00 00 00 0C 00 00 00 就是特长天使了
(3) 02 00 00 00 -------- 应该是资源特长,俺鄙视不劳而获,没有研究
(4) 03 00 00 00 ---------魔法特长,后面接下来四个字节是魔法序号
如阿德拉mm是03 00 00 00 29 00 00 00 特长41号魔法祝福,改成
03 00 00 00 30 00 00 00 就去抢老罗的饭碗了
(老罗:小姑娘,你开始没有自带祈祷魔法,祝你一辈子学不到祈祷魔法)
(5) 04 00 00 00 ---------特殊生物特长,就是猛兵特长,一级就给生物加一大堆攻防的那种,数据结构如下
04 00 00 00 XX 00 00 00
AA 00 00 00 BB 00 00 00 CC 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
XX是生物序号,AA加攻指数,BB加防指数,CC加伤害指数
如果嫌塔丽丝mm不够猛,那就把她改成
04 00 00 00 0A 00 00 00
FF 00 00 00 FF 00 00 00 FF 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
于是一个在一级时就给骑士加255攻,255防,255伤害的骑神诞生了.......
(5) 05 00 00 00 ---------- 速度特长,姆拉克同学是
05 00 00 00 02 00 00 00
(6) 06 00 00 00 ---------升级特长,原来gelu同学的特长现在滥用了,数据结构如下:
06 00 00 00 XX 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 YY 00 00 00
ZZ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
XX是第一种生物,YY是第二种生物,ZZ是升级后的生物。觉得天使太少么,那就改成
06 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00
0D 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
如果你有足够的资源,就可以使劲的往枪兵和射手背上插翅膀了,有话说得好:会飞的不一定是天使,也有可能是鸟人。
(7)07 00 00 00 ---------- 龙特长,对所有龙都有效。数据结构如下:
07 00 00 00 00 00 00 00
AA 00 00 00 BB 00 00 00 CC 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
AA加攻指数,BB加防指数,CC加伤害指数. 巨龙摩丽尔算得了啥,你才是龙的传人
最后提醒一句:修改不要太BT,注意备份。

修改用到的生物编号技能编号等文件见附件

yunings 发表于 2008-8-17 12:01:59

支持技术类文章。

yunings 发表于 2008-8-17 12:03:49

呃,土地公的FTP上也提供了这个补丁下载,但一直躺在我的硬盘里,未曾使用过……

alovelycat 发表于 2008-8-21 10:20:11

长期不完原版的人飘过

BatHzw 发表于 2008-8-22 12:28:27

某强人用另类技术修改H3之谈—3!!!

一劳永逸的解决瘟疫之月,已验证成功。
作者:mhtkjkj
1、用winhex等十六位编辑器打开主程序(如hero3.exe),并备份该程序
2、查找十六进制数EB35837DF409
3、替换为EB35837DF40A
4、保存
效果:
1、瘟疫之月永不出现
2、原本发生瘟疫的月份成为生物月-- 蝇 49等
3、不影响游戏其他环节
4、联机.....影响未知,应该对host有作用

其他方法 提前buy 兵,跑位,建筑....效果要看rp(能否改变随机数)。
瘟疫之月无法通过编辑地图改变

songfx 发表于 2012-11-9 14:23:29

Mark一下,执行合并操作
页: [1]
查看完整版本: 某强人用另类技术修改H3之谈!!!

捐赠