- 积分
- 34677
- 威望
- 499
- 魅力
- 507
- 经验
- 20326
- 热心度
- 9
- 注册时间
- 2006-3-13
- 最后登录
- 2024-9-30
- 主题
- 134
- 回帖
- 4949
- 精华
- 35
- 阅读权限
- 150
TA的每日心情 | 郁闷 2015-6-6 16:12 |
---|
签到天数: 52 天 连续签到: 1 天 [LV.5]女巫
超级版主
- 积分
- 34677
|
楼主 |
发表于 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;[v10的内存地址]
!!UN:Cy2/4/?y3;[y3获得v10的值]
最后一句改为这样
!!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^;[Y1=-1]
[255在内存1字节上表达是FF,而1字节FF用于区分正负时的表达式-1,因此 y1=-1]
[或者说 !!UN:C8943208/1/255; 和 !!UN:C8943208/1/-1; 是一样效果的]
!!UN:C8943208/1/257;
!!UN:C8943208/1/?y1;
!!IF:M^%Y1^;
[257超出1字节最大范围255,但如果用2字节表达则是0101h,因此系统自动取低位1字节,所以Y1=1.而且,第一句的设置并不会影响都下一个字节,属于内部转换]
并不是所有内存地址都能修改(访问)的.其它在内存执行的程序,比如某些DLL,访问或修改它们都可能失败并造成游戏崩溃.
ERA下之所以能随意修改游戏程序内存,估计是因为去掉了EXE的保护,BeforeWoG下有这么一个插件 remove exe protection.bin,估计是这个的作用.
另外关乎程序执行的指令内存,不能随便改,会造成指令混乱和崩溃的.(执行指令或普通数据在内存上都是字节排列的形式,都能用UN:C来修改)
看ERA帮助有这么一段关于让游戏崩溃的语句,原因是不允许访问(修改)0地址的.
!?FU77008; [保存游戏之后的触发器]
!!IF:M^游戏已保存,建议你关闭电脑并稍作休息^;
!!UN:C0/4/0; [引导游戏崩溃]
|
|