贤知有您 发表于 2014-10-17 14:27:38

ERM内存修改和函数调用探讨专题

鄙人不才,专门开这么一个纯技术帖.美其名<ERM内存修改和函数调用探讨专题>.
大家可以在这个主题中探讨"关于ERA平台下使用ERM方式实现的内存修改或内存函数调用"的话题.
当然,并不限制ERM的实现方式,归根结底是关于ERA/WOG内存的问题.


先旨声明,如果在此主题发表灌水或无意义帖子,将被严惩.(为了保持楼层,建议版主们不删帖而用其它惩罚方式.)

计划使用二楼三楼作为一个资源索引帖,内容是关于ERA/WOG内存修改的案例,内容指向于某个楼层(或多个楼层).
二楼主要是UN:C类别的简单修改.
三楼侧重于SN:E的函数调用修改(复杂型).


本人也会不定时发布一些常用的或者最新发现的内存修改应用案例.
同时欢迎各位探讨所有有关内存修改的话题,可以直接跟楼提问或析疑解答.
目前只能在ERA平台下才能采用ERM形式的内存修改,所以基本上测试平台都是ERA2.4以上.

贤知有您 发表于 2014-10-17 14:27:50

占楼备用

贤知有您 发表于 2014-10-17 14:28:08

占楼备用

贤知有您 发表于 2014-10-17 14:32:45

怎样使用ERM进行内存修改
WOG时代,大家对ERM修改游戏的能力肯定是大为赞赏,通过简单的ERM语句语法就能实现很多自定义的游戏功能.
ERA的作者bersy把内存修改引入到ERM语法中,使得用ERM来直接修改内存变成现实,很多原ERM语法无法实现的功能都可能用内存修改来完成.
由于涉及到计算机原理,不明白某些名词的可以忽略,直接应用案例就是了.如果是SN:E的调用内存函数形式,一般都会封装成一个FU函数并通过参数来应用.
2个主要的ERM语句:UN:C和SN:E语法.详细可参考ERM/ERA帮助.
我在这里需要特别提醒的是,修改内容一般会影响全局.特别是涉及到编码命令地址值的修改,在经过UN:C修改后,会一直驻留,除非是重启游戏.也就是说,某个地图你改了某个内存,然后载入了其它地图,这个内存修改可能会保留着.相反,如果你的ERM语句修改内存只是在地图初始化(如!?PI)使用,重启游戏并载入存档时,该内存修改可能会被还原.


因此,我对ERM内存修改的建议是:
1.为了不影响其它地图(不退出游戏时),尽量在适当的时候还原内存设置.比如某些内存修改是在战斗时用,可以在!?BA0时修改,并在!?BA1还原为原貌.
2.某些全局性的内存修改,除了在初始化PI触发器上进行,也应该在 GM0触发器(载入)地图时执行.简单来说,!?PI和!?GM0都使用同一套内存修改语句就行了.
3.UN:C的修改语句分为1/2/4字节,要留意修改地址的长度,也要注意写入数值的长度.
4.内存修改有风险,请做好随时崩溃的准备:).


首先来一个简单说明的例子.
v变量都是固定的内存地址,每个占用4字节.它的起始地址(v1)是 887668h=8943208 (在16进制数结尾会加个h或者前头加0x以便区别10进制数,)
(PS:10进制和16进制的转换,可以直接用WINDOWS的计算器,切换到"科学型"模式即可.)
那么某个v变量的地址可以这样表达
!!VRy1:S10;[索引号为10,v10]
!!VRy2:Sy1*4+8943204;
!!UN:Cy2/4/?y3;
最后一句改为这样
!!UN:Cy2/4/100;
就相当于
!!VRv10:S100;
实际上,ERM命令就是一种修改内存.只不过各种不同的命令可能进行不同的内存处理,包括复杂的函数调用等.


这里顺带说一下修改1/2/4字节的问题.
我们知道v1的内存是887668h=8943208,它占用了4字节.
看一下句子:
!!VRv1:S0; [先清零]
!!UN:C8943208/1/1;
!!UN:C8943209/1/2;
!!UN:C8943210/1/3;
!!UN:C8943211/1/4;[逐个字节修改]
!!IF:M^%V1^;
结果是67305985 = 0x04030201,大家需要记住的是,内存存放的字节顺序,需要反过来排列才是我们通常意义的16进制.(我们通常书写的10进制/16进制都是高位在左端,低位在右端,而内存排列刚好相反,另外有一点要注意到,16进制需要2个数位来表达1个字节 256=16^2)
此时
!!UN:C8943210/2/?y1;
那么y1的值是 0x0403 = 1027. (ERA会自动把2字节的内存值转换成4字节的y变量)


另外需要留意字节数的最大可存储数值.
比如一个字节能区别256个数值,可以表达(0~255)或(-128~127).
由于ERM的变量类型都是分正负的,因为一个字节正常的表达范围是 -128~+127.
看下面句子:
!!UN:C8943208/1/255;
!!UN:C8943208/1/?y1;
!!IF:M^%Y1^;

[或者说 !!UN:C8943208/1/255; 和 !!UN:C8943208/1/-1; 是一样效果的]


!!UN:C8943208/1/257;
!!UN:C8943208/1/?y1;
!!IF:M^%Y1^;



并不是所有内存地址都能修改(访问)的.其它在内存执行的程序,比如某些DLL,访问或修改它们都可能失败并造成游戏崩溃.
ERA下之所以能随意修改游戏程序内存,估计是因为去掉了EXE的保护,BeforeWoG下有这么一个插件 remove exe protection.bin,估计是这个的作用.
另外关乎程序执行的指令内存,不能随便改,会造成指令混乱和崩溃的.(执行指令或普通数据在内存上都是字节排列的形式,都能用UN:C来修改)
看ERA帮助有这么一段关于让游戏崩溃的语句,原因是不允许访问(修改)0地址的.


!?FU77008; [保存游戏之后的触发器]
!!IF:M^游戏已保存,建议你关闭电脑并稍作休息^;
!!UN:C0/4/0; [引导游戏崩溃]

贤知有您 发表于 2014-10-17 14:54:33

以下是本人在学习内存修改初期收集和研究时的一些记录,仅供参考.注意只有1字节可改时,如果是生物编号,那么只能改为0-127之间,高于这个会自动变成负数而没有意义(相当于取消).

部分生物特技内存地址

      内容16进制地址10进制地址字节原数值
雷鸟的施法几率440EC44460228120
毒龙的毒液伤害几率4411DE4461022120
鬼龙的衰老几率4402644457060120
僵尸的瘟疫几率4402D94457177120
独角兽的失明几率44033E4457278120
诅咒几率4404334457523125
美杜莎和蜥蜴的石化几率4404A74457639120
飞龙王的中毒几率4405604457824130
蝎狮的麻痹几率4405D14457937120
死亡凝视几率440C074459527110
黑骑的会心一击4436E04470496120
血龙的衰老几率756D6E7695726140
圣侏儒的守卫(判断生物)75D0F577212054173
暗黑龙的使人恐惧特性(判断生物)76050377345314155
暗黑龙的黑暗遮幕(判断生物)75464776857034155
暗黑龙的黑暗遮幕(判断生物)75474976859614155
变狼人的使敌人变狼特性(判断生物)7673DC77629084194
变狼人的狂暴(判断生物)7674B277631224194
地狱男爵的使人恐惧特性(判断生物)7604FB77345234153
地狱男爵的盗取灵魂特性79FD63799472315 (改为9可去掉)
邪神召唤长角恶鬼5A776B5928811148 (30h)
邪神召唤长角恶鬼的生命值基数4470CF44853274
苏丹的火盾4225D94335065153
苏丹的火盾442E644468324153
地狱九头龙回复(判断生物类型)75DE8477246764157 (9Dh)
地狱九头龙回复(回复几率)75DF277724839140
地狱九头龙回复(回复量)75DE5C7724636450
144恶鬼重生(判断生物类型)75DE7977246654144 (90h)
60鬼魂再生(判断生物类型)75DE687724648160 (3Ch)
61鬼魂再生(判断生物类型)75DE717724657161 (3Dh)
72鹰身女妖攻返(判断生物类型)75E05B7725147172 (48h)
73鹰身女巫攻返(判断生物类型)75E0607725152173 (49h)
155暗黑龙攻返(判断生物类型)75E06477251564155 (9Bh)
凤凰重生(判断生物类型)75E10B77253234131 (83h)
神圣凤凰重生(判断生物类型)75E11477253324158 (9Eh)
64尸巫云攻击(判断生物)767BA17764897164 (40h)
65尸巫云攻击(判断生物)767BA67764902165 (41h)
196尸巫云攻击(判断生物)767BAA77649064196 (C4)
149箭塔无视距离(判断生物)75DD5177243694149 (95h)
137幻影无视距离(判断生物)75DD5877243764137 (89h)
170幻影无视距离(判断生物)75DD5F77243834170 (AAh)
171幻影无视距离(判断生物)75DD6677243904170 (ABh)
34法师无视障碍(判断生物)76059277346741
35大法师无视障碍(判断生物)76059B77346831
136魔幻法师无视障碍(判断生物)7605A377346914
149箭塔无视障碍(判断生物)7605B177347054
137幻影无视障碍(判断生物)7605AA77346984
170幻影无视障碍判断生物)7605B877347124
171幻影无视障碍(判断生物)7605BF77347194
10骑兵冲锋奖励(判断生物)75D82977230491
11骑士冲锋奖励(判断生物)75D83E77230701
61阴魂吸收2点魔法(判断生物)4650D246082101
43小怪物吸收魔法(判断生物)5A24E25907682143 (2Bh)
67死亡骑士会心一击(判断生物)766DBB7761339167 (43H)
67死亡骑士会心一击(判断几率)4436E04470496120 (14H)
34法师减少施法消耗(判断生物)766BFD7760893134 (22H)
35法师减少施法消耗(判断生物)766C037760899135 (23H)
34,35法师减少魔法消耗值766C09776090542
4皇家狮鹫的无限反击(判断生物)战场开始43D6A2444585814
4皇家狮鹫的无限反击(反击数量)战场开始43D6c7444589545000 (1388h)
4皇家狮鹫的无限反击(判断生物)每回合446E67448471114
4皇家狮鹫的无限反击(反击数量)每回合446E98448476045000 (1388h)
143盗贼的技能(检测生物)4E605D51364774143 (8F)
142游牧的技能(检测生物)4b177c49212124142 (8E)
20飞马让对方英雄多施法2点(检测生物)4E554D5133645120 (14H)
21银飞马让对方英雄多施法2点(检测生物)4E555A5133658121 (15H)
20,21飞马让对方英雄多施法2点(数值)4E5568513367212
96比蒙降低目标防御(检测生物)75d4a37722147196 (60h)
97比蒙巨兽降低目标防御(检测生物)75d4a97722153197 (61h)
156幽灵比蒙降低目标防御(检测生物)75d55477223244156 (9Ch)
196龙巫妖的格挡(检测生物)766A9077605284196 (C4H)
196龙巫妖的格挡(检测几率)766A9A7760538120 (14H)
196龙巫妖的抗魔(检测生物)75D9FF77235194196 (C4H)
196龙巫妖的抗魔(检测几率)75DA0D7723533120 (14H)
78牛头的士气向上(检测生物)战场7671367762230178 (4Eh)
79牛头王的士气向上(检测生物)战场76713c7762236179 (4Fh)
78牛头的士气向上(检测生物)生物槽44AEF94501241178 (4Eh)
79牛头王的士气向上(检测生物)生物槽44AEFE4501246179 (4Fh)
24独角兽的魔法结界(检测生物)17672477762503124 (18H)
25独角兽的魔法结界(检测生物)17672507762512425 (19H)
24独角兽的魔法结界(检测生物)27672A27762594124 (18H)
25独角兽的魔法结界(检测生物)27672AB7762603425 (19H)
12天使+1士气(检测生物)44BA484504136112 (Ch)
12天使+1士气(检测文本)44BA694504169412 (Ch)
13大天使+1士气(检测生物)760A177735831113 (Dh)
150至高天使+2士气(检测生物)760A1C77358364150 (96h)
13大天使+1士气(检测生物)文本字眼760A3B7735867113 (Dh)
150至高天使+2士气(检测生物)文本字眼760A4077358724150 (96h)
55大恶魔-1运气(检测生物)7609BE7735742155 (37h_
153大恶魔-1运气(检测生物)7609C377357474153 (99h)
55大恶魔-1运气(检测生物)文本字眼7609F87735800155 (37h_
153大恶魔-1运气(检测生物)文本字眼7609FD77358054153 (99h)
194狂狼人变狼特技(检测自身生物)7673DC77629084194 (C2h)
194狂狼人变狼特技(检测目标生物)7674B277631224194 (C2h)
194狂狼人变狼特技(触发几率)7675667763302120 (14h)
194狂狼人变狼特技(月圆时增加几率)7675637763299120 (14h)
194狂狼人变狼特技(变成什么生物)76771F77637434194 (C2h)
194狂狼人变狼特技(限定的生命值,除法用)7D64C48217796435 (23h)
45哥革射击时的火球攻击(判断生物)43F72E4454190145 (2Dh)



贤知有您 发表于 2014-10-17 15:48:28

英雄辅助技能效果值的内存地址

       技能编号名字地址DEC地址HEX数据类型[+0][+4][+8][+12]说明
9幸运术654786463E998整型4字节0123
6领导术654788063E9A8整型4字节0123
12招魂术654789663E9B8浮点4字节010%20%30%
8神秘术654791263E9C8整型4字节0234
3侦察术654792863E9D8整型4字节0123
1箭术654794463E9E8浮点4字节010%25%50%
22进攻术654796063E9F8浮点4字节010%20%30%
23防御术654797663EA08浮点4字节05%10%15%(WOG改为10-15-20)
13理财术654799263EA18整型4字节0125250500
11鹰眼术654800863EA28浮点4字节040%50%60%
4外交术654802463EA38浮点4字节020%40%60%
26抵抗力654804063EA48浮点4字节05%10%20%(WOG改为10-20-30)
21学习能力654805663EA58浮点4字节05%10%15%
2后勤术654807263EA68浮点4字节010%20%30%
25魔力654808863EA78浮点4字节05%10%15%(WOG改为10-20-30)
24智力654810463EA88浮点4字节025%25%100%
27急救术654812063EA98浮点4字节0123


浮点数一般就是指带小数的数值,由于存储算法不同,它在内存上的表达形式很复杂.
ERM中的e变量是4字节浮点数,我们可以来这么一段来考察,浮点数和整数在内存上的区别.
已知e1的内存地址是A48F18h ->10784536


!!VRe1:S1:2;
!!UN:C10784536/4/?y1;[看看0.5的浮点数,在内存表达上,如果转成4字节整型时是多少]
!!IF:M^E1=%E1
Y1=%Y1^;
结果
差别不是一般的大.如果你想获得4字节浮点和整数的转换,可以用这样的UN:C的形式演算一下.
因为UN:C是不能直接代入浮点数的.(浮点数会被自动内部转换成整数再代入,舍去所有小数部分)


顺便解答一下,官方脚本中一段超神奇的脚本.
<30 wog - enhanced secondary skills.erm>下有这么一段修改辅助技能的语句:
!?FU7026;   x1=herox2=set/rese
!!HEx1:S23/?y1;                              
!!HEx1&y1=1/x2=0/v7199=1:S23/22;            修改后低级防御术效果为 10%
!!HEx1&y1=2/x2=0/v7199=1:S23/23;            修改后低级防御术效果为 15%
!!HEx1&y1=3/x2=0/v7199=1:S23/19;            修改后低级防御术效果为 20%


!!HEx1&y1=22/x2=1/v7199=1:S23/1;            还原
!!HEx1&y1=23/x2=1/v7199=1:S23/2;            还原
!!HEx1&y1=19/x2=1/v7199=1:S23/3;            还原


有人曾经研究过把原来的等级1-3改成其他数值而带来的效果.
估计毫无规律可言.那这段代码为什么可以这么写呢?
通过上面的辅助技能内存地址和数据,你就能洞悉其意义所在.
上述这些辅助技能的效果都通过4个4字节的地址来存储,分别代表英雄拥有该技能的级别(0-3)所能达到的效果值.


首先我们要了解一下系统处理防御术效果的过程.
在计算防御术能减免多少伤害百分比时,系统会通过当前英雄的防御术技能查找对应的内存值(该内存是一个浮点数,也就是一个小数).
防御术是0-3级,那么对应地址分别是 63EA08/63EA0C/63EA10/63EA14,其对应的内存值就是防御术效果.这里0-3就是 HE:S23/?y1;的值.


我们先考虑等级和内存地址的关系:
!!VRy1:S0; [等级]
!!VRy2:Sy1*4+6547976;[等级对应的地址63EA08h=6547976]
把HE:S23/1 改成 HE:S23/22 后,意味着什么呢?
22*4+6547976=6548064 ->63EA60h 这刚好是二级(21学习能力)对应的地址,该地址的浮点数代表的是10%.
相信你现在明白为什么可以通过改变等级来获得特殊值了吧.
可以看出这种改法是不科学的,如果玩家修改了(21学习能力)的值,这种防御术的效果也跟着改变.


抛开官方这种脚本,我们怎样改写辅助技能的数值呢?看看TE怎样改防御术:
!!UN:C6547980/4/1028443341; basic Armored   5
!!UN:C6547984/4/1036831949; Advance Armored   10
!!UN:C6547988/4/1045220556; Expert Armored    20
这样够直接了当了.只要找到浮点值内存对应整数形式就行了.
当然,结合一下e变量+UN:C来切换成v/y变量再赋值,也是个不错的选择.
(PS:HC论坛上有人写过一个大函数来专门更改辅助技能的.我这里只是论述一下内存修改的方式.)

爱的燃火 发表于 2014-10-17 19:04:33

本帖最后由 爱的燃火 于 2014-10-17 19:11 编辑

这贴子不错,可惜不是3.1的,要不然我倒是可以提供一些地址。另外3.1里通用特技可以扩展为全生物适用,不知道era里行不行。
另外关于生物特技还有部分没有列出来啊,是没找到还是没更新?比如牛眼的瞪死数量就没有,圣龙恐惧好像也没有发现。恐惧对应的标志属性什么的也没有。

wuxiangjinxing 发表于 2014-10-18 07:28:36

画一条线1美元,知道在哪里画线,9999美元。内存修改命令很简单,最大的问题是——007是怎么找到这些功能对应地址的?

顺便问一些我一直希望能通过内存修改来实现的功能吧(因为用模拟实在太麻烦了)

(1)指挥官的死亡凝视是如何做到一次瞪死超过一个敌人的?
(2)能否解除收魂使者重生对象的等级限制?

谢谢~

贤知有您 发表于 2014-10-18 10:39:25

wuxiangjinxing 发表于 2014-10-18 07:28
画一条线1美元,知道在哪里画线,9999美元。内存修改命令很简单,最大的问题是——007是怎么找到这些功能对 ...
还记得很久很久以前的 金山游侠修改器吗?
通过不断改变数值来定位地址.
不过这种方法在WOG下没啥用途.

我是通过多种手段来查找地址的,要我说怎么找地址,也不知道从何说起.
至少我花了一个月的时间来自学汇编语言,它是看懂内存汇编码的基础.
我使用的是CE修改器来查看程序汇编码和修改内存设置的,这是一个非常好用的修改器.
找地址和改内存这个纯属是苦差事,沧海一粟见证了我的成长过程,没有沧海一粟的鼓励和不断提出新挑战,估计我也不会研究得这么深入.
爱的燃火找地址应该很有一套经验,希望他能分享一下.
我的经验是通过一些C语言的源码大概定位的.定位的函数或地址越多,后面就越来越顺利了.
有一个IDA的静态反编译软件非常好用,但同样要去实践和学习.
我建议是,如果想去找内存地址,首先要去学习计算机原理和汇编.

(1)指挥官的死亡凝视是如何做到一次瞪死超过一个敌人的?
WOG把死亡凝视的汇编码HOOK(拦截)到另外一处慢慢处理.
要修改死亡凝视的比例甚至最终个数都不难,但有一个ERM无法逾越的问题,主动攻击和反击无法完全划分.
也就是说,假设你BG0攻击前修改了内存码,主动攻击的那个生物有效,反击的那个生物也有效(带死亡凝视的话).
说到底就是没有一个合适的时机来还原内存.当然,如果限定对方不能反击倒是可以用这种修改.
而WOG是硬编码编写的,它就不用担心这个问题.


(2)能否解除收魂使者重生对象的等级限制?
这个问题我曾经到俄罗斯论坛上咨询过Bersy.
后来也发现是硬编码限定了聚灵奇术施放时,每个生物能聚灵50HP,所以1个指挥官只能聚灵50HP以下的生物堆栈.
正如大天使施放重生时限定是每个生物100HP,跟聚灵同属一段编码.只不过原SOD没有施放聚灵奇术的生物罢了.
看一下汇编码,你会发现50HP并不是一个直接的地址.

005A87AD - e8 ab eb 1b 00 - call 0076735d #SOD这里检测大天使,WOG这里拦截起来让圣天使检测时也有效
005A87B2 - 90 - nop
005A87B3 - 83 f8 0d - cmp eax,0d #13=大天使
005A87B6 - 8d 34 b6 - lea esi, # esi这里指的是生物的个数,这里是 个数*5
005A87B9 - 8d 34 b6 - lea esi, # 再来一次*5=25
005A87BC - 75 05 - jne 005a87c3 #不是天使时跳转
005A87BE - c1 e6 02 - shl esi,02 #是天使的话, esi*4=100 (即生物个数*100)
005A87C1 - eb 4f - jmp 005a8812
005A87C3 - d1 e6 - shl esi,1 #不是天使的话,直接 esi*2 (即生物个数*50) 这里适用于聚灵奇术
005A87C5 - eb 4b - jmp 005a8812

需要说明的是,收魂使者的施法力量,又是经过WOG拦截再处理的.所以无法预知能重生最多多少HP.直接改50HP也没有意义.
假如改成一个很大的数,比如原来esi*2改到esi*1024.只要目标单体HP不大于1024就能应用施法.
尝试后你会发现,收魂使者准备施法时,鼠标指向目标确实都有施法指针.但施法时你可能就收到崩溃报告了.
原因就是,聚灵奇术施法力量太低,计算出来可复活HP低于目标单体.

不过Bersy出了个超级插件(erm_hooker.era)可以解决这个问题.
使用它拦截005A87C3的汇编到ERM的FU函数上,就能通过ERM的语句来处理了.

我这里只是粗略说明一下,为什么很多内存修改都很麻烦.
原因有3点:
1.要修改的数值并不是一个单纯直接数,它可能在汇编上转了几个弯.
2.要修改的地址编码太紧凑,无法修改(除非HOOK出去其它地方,完成后再返回来)
3.修改汇编码,又转为ERM的UN:C码很累,除非修改很有意义,否则我自己也不想做.

贤知有您 发表于 2014-10-18 11:22:04

爱的燃火 发表于 2014-10-17 19:04
这贴子不错,可惜不是3.1的,要不然我倒是可以提供一些地址。另外3.1里通用特技可以扩展为全生物适用,不知 ...

燃火兄弟
确实没把恐惧几率写上.因为当时我已经转型去学习编写汇编码了.
ERA下恐惧的几率地址:4649D8 4字节 原值是 10.
由于ERM可以处理很多修改,有些内存地址显得没啥意义了.
比如ERM可以给生物附加使人恐惧或者不受恐惧的经验特技.

通用特技可以扩充为全生物使用时啥意思?
因为WOG/ERA下有些特技判断生物编号时,是1字节的内存.改成大于127的话,变成负数就应用不了.

爱的燃火 发表于 2014-10-18 13:03:30

贤知有您 发表于 2014-10-18 11:22
燃火兄弟
确实没把恐惧几率写上.因为当时我已经转型去学习编写汇编码了.
ERA下恐惧的几率地址:4649D8 4 ...

这个几率是怎么找到的?我找了好久都没找到。。。。
比如特长2是从吸血鬼开始的,扩展后可以从枪兵开始,sod里也是单字节的,我是通过转跳代码实现扩展的。era里要实现我想应该也不难吧。

爱的燃火 发表于 2014-10-18 13:06:56

wuxiangjinxing 发表于 2014-10-18 07:28
画一条线1美元,知道在哪里画线,9999美元。内存修改命令很简单,最大的问题是——007是怎么找到这些功能对 ...

如贤知说的,用ce查找汇编是很方便的。我的做法很简单,先追踪到改变特定数值的汇编代码,然后通过断点追踪找到原始数值所在。如果感兴趣,可以下载ce6。0版,这个版本的汇编码都有翻译,对于初学者来说是很友好的。

爱的燃火 发表于 2014-10-18 13:33:38

wuxiangjinxing 发表于 2014-10-18 07:28
画一条线1美元,知道在哪里画线,9999美元。内存修改命令很简单,最大的问题是——007是怎么找到这些功能对 ...

这里先来一个最简单的汇编应用教程吧。
将经验值公式由 数量x生命值改为 数量x战斗值。
首先找到英雄的经验值地址(会用金山游侠的都知道怎么找吧,只要注意ce里字节不对的话有时候是搜索不到数据的,比如小于127的应该用单字节搜索,小于32767的用双字节搜索,以上的就用4字节吧)。添加到代码列表里后,对着这台代码右键选择“是什么改变了这个数值“,然后就去打一仗吧。胜利后就会发现已经有一条汇编代码了(有时候会有好几条,这时候就要靠自己识别或用窗口模式盯着了,这里就是最后一条)。与在汇编模式里打开这条代码,我记得应该是 im?? ecx,(只是大概而已,你看着差不多就是这条了)这里的im??是乘法的意思,ecx是数量,ebx是记录生物属性的内存开始地址,esi就是偏移到该生物的内存值,4c是改生物偏移的生命值的内存值。把4c改为3c就是偏移到战斗值了。整条代码就变成 数量x战斗值了。这时在游戏里打怪会发现经验值来的太多了,太bt了怎么办?很简单,在汇编往下拉,找到有好多行int 3的代码的地方,记住第一行的地址(对着代码右键选择转跳地址出来了,这里假设地址是456789)然后回到原来的代码那里,记住下一条代码的地址(假设是456700)双击代码打开汇编窗口,先把这条汇编记下来,然后修改为jmp 456789 ,这条汇编的意思是无条件转跳到以下地址。然后在地址456789里写入汇编代码
im?? ecx,
sar ecx,3
jmp 456700
第一句这么写是因为刚才的转跳删除了原来的语句,所以这里要写回来。第二句的意思是将ecx里的数值/2 3次(也就是100/2/2/2的意思)。到这里已经将经验值减少了,于是再来个转跳回到原来的代码里继续执行下一条代码。
以上就是一例简单的汇编修改应用了,至于在erm里要怎样实现我就不知道了。

爱的燃火 发表于 2014-10-18 13:36:44

最后再来个3.1的修改经验值公式用于参考。




004B7A08 - 0FAF54083C        - imul edx,       //EDX乘以,将结果写入EDX里(EDX为数量,为该生物的战斗值地址。由原来读取生命值偏移地址4C地址改为战斗值偏移地址3C)
004B7A0D - EB33         - jmp 004B7A42         //无条件跳到地址04B7A42(跳到修改的汇编代码处)
004B7A0F - 90                - nop                  //多余指令改为无操作指令nop
004B7A10 - 01c1        - add ecx,eax            //将ECX和EAX相加,结果写入ECX里(将本对生物经验加上队生物经验)

004B7A42 - 8B5C0804        - mov ebx,   //将写入EBX里(读取生物等级)
004B7A46 - 8BC2         - mov eax,edx            //将EDX写入EAX里(除法要用EAX除以ECX,所有需要将数值转到EAX里)
004B7A48 - 99           - cdq                  //除法准备
004B7A49 - B90A000000        - mov ecx,0000000A       //将十进制10写入ECX里
004B7A4E - 01D9                - add ecx,ebx            //将ECX和EBX相加,结果写入ECX里(生物等级加10)
004B7A50 - F7F9        - idiv ecx               //将EAX除以ECX,结果写入EAX里
004B7A52 - 8B4DF8        - mov ecx,       //将的数值写入ECX里(上一队生物的经验值临时保存地址)
004B7A55 - EBB9                - jmp 004B7A10         //无条件跳到地址004B7A10(跳回原来的汇编代码继续执行)


贤知有您 发表于 2014-10-18 15:46:21

爱的燃火 发表于 2014-10-18 13:36
最后再来个3.1的修改经验值公式用于参考。




直接把汇编跳转确实非常方便.
不过在ERA下需要考虑其它方面的问题,因为各种脚本都能改就无法控制好了.(容易冲突)
另外先前引导我们应用UN:C语法的那位高手说过, 跳转需要一块"空白"内存空间,无法申请这样的空间,都是自己定义一个相对空白的位置.但难保证其它脚本或插件会借用这个地址.他的做法倒是新颖,使用了WOG的z变量位置来存储,只要限制避开这个Z变量就行了.

最后问燃火一句,你改汇编是直接在CE上写吗?
我们用ERM脚本,最后还需要把汇编码转成ERM的脚本码,这点比较烦.

贤知有您 发表于 2014-10-18 15:57:29

本帖最后由 贤知有您 于 2014-10-18 16:01 编辑

爱的燃火 发表于 2014-10-18 13:03
这个几率是怎么找到的?我找了好久都没找到。。。。
比如特长2是从吸血鬼开始的,扩展后可以从枪兵开始 ...
从吸血鬼开始的那种特技,是基于一份列表的.之所以有列表出现是汇编处理类似 case XX的需要.
新生物插件也是这样改的,把列表地址转移了,并且把寻址改成从0#生物开始.

这个恐惧地址,我是通过反推算的.我说了我一般通过WOG的C源码推演的.
WOG的源码中找到抵御恐惧的代码.
void Fear1(void)//抵御恐惧的函数

然后查找WOG是怎样把原版圣龙恐惧跳转的
{0x464944,0,DP(Fear1)}

那么0x464944 的前后就是恐惧产生的位置了.
入口函数地址:00464920

爱的燃火 发表于 2014-10-18 16:21:04

贤知有您 发表于 2014-10-18 15:46
直接把汇编跳转确实非常方便.
不过在ERA下需要考虑其它方面的问题,因为各种脚本都能改就无法控制好了.( ...

也是,各种引用什么的太多了,一不小心就出错了。
我都是写在int 3里的,反正也不太可能会溢出,实在溢出了也没办法。。。。
先在ce里写好测试,没问题了就复制机器码到修改器里使用。
有源代码就是方便啊。。。。那独角兽这货有是怎么回事呢?

贤知有您 发表于 2014-10-18 16:34:24

爱的燃火 发表于 2014-10-18 16:21
也是,各种引用什么的太多了,一不小心就出错了。
我都是写在int 3里的,反正也不太可能会溢出,实在溢 ...

我只是知道独角兽魔法结界切入函数是 0043E790.
但代码实在是看不下去,不过有点可以肯定的是.
独角兽和周边生物都挂了很多状态的值(存于堆栈结构上).
但是我看来看去,还是没找到抗魔时增加20%这种有用的信息.
实在没心情一句一句看汇编,所以放弃了.

对了想起个事情.
比如特长防御和特长进攻的每级 0.05 效果.
在汇编上都用同一个 浮点数地址.
计算进攻的函数里
004E4567 - d8 0d e4 ea 63 00 - fmul dword ptr #0063eae4 =>0.05
计算防御的函数里
004E45C7 - d8 0d e4 ea 63 00 - fmul dword ptr #0063eae4 =>0.05

也就是说,一个浮点数的地址可能被多个地方应用.
在ERA中要改这种模式,需要另行找一个4字节的空间存放一个浮点数并把原汇编指向这个地址.
燃火你们的做法是怎样呢?

爱的燃火 发表于 2014-10-18 17:38:09

贤知有您 发表于 2014-10-18 16:34
我只是知道独角兽魔法结界切入函数是 0043E790.
但代码实在是看不下去,不过有点可以肯定的是.
独角兽和 ...

对于这种只能逐句看了吧,当初我追战术的时候就花了好几个小时才找到的。
一样的,这时最方便的方法了,反正int 3多的是,随便找一个地方使用就行,还不用担心被占用。不过也有一些是使用经过搜索没有被使用的空白内存地址,不过这对era来说基本找不到吧,不像个。1里有大量的空白地址。

贤知有您 发表于 2014-10-20 12:26:57

ERA的插件下有个 dismiss last stack.bin
可以让英雄解散最后的部队实现裸奔.不过裸奔的英雄仍然无法从城里出来.
以下简单内存修改即可解除这个限制:

!?PI;
!!UN:C6117225/1/235;[修改]
!?GM0;
!!UN:C6117225/1/235;[修改]
页: [1] 2 3 4
查看完整版本: ERM内存修改和函数调用探讨专题

捐赠