看流星社区

 找回密码
 注册账号
查看: 5114|回复: 1

大多数游戏都适用的移动加速原理

[复制链接]

该用户从未签到

发表于 2013-8-22 08:42:29 | 显示全部楼层 |阅读模式
对于大多数单机游戏的人物位置,基本都是用xyz坐标确定的,只要这个坐标没有加密,那么就可以轻松的找出这个坐标并做出瞬移,加速等修改器
现在以单机游戏<<双星物语2+>>为例,讲解一下游戏加速的原理和过程:

1)找出决定位置的坐标

首先打开游戏和ce
在任意一个场景中,使用ce搜索未知的浮点值
稍微向左移动,然后搜索减少的数值
向右移动,然后搜索增加的数值
重复搜索20多次应该就能将正确的地址过滤出来
如果发现没有找到的话,就搜索相反的方向(就是左边则数值增加,右边减少,不过这种游戏见过很少)
用ce查看这个地址周围的内存,并将显示模式设为浮点值,将发现有3个浮点值是连在一起的
现在将这三个地址添加到ce的表中,然后锁定
尝试移动人物,如果发现画面抖动并且无法移动就说明这三个就是xyz坐标了
现将3个坐标按顺序命名为x,y,z
通常我喜欢用x表示左右,y表示上下,z就是跳起来的
但这个游戏的xy是斜着的

2)简单瞬移,移动加速的基本原理
将x的坐标增加500,将发现人物向右下移动了一段距离(这个游戏的坐标比较大,通常的游戏来说500就是一个场景的宽了)
通过修改坐标的值,便可简单的达到瞬移的功能
那么如果在每次坐标改变的时候巧妙使用瞬移,就可以达到移动加速的功能了
比如在一次移动中,坐标由(x1,y1,z1),移动为(x2,y1,z1)
那么移动速度就是(x2-x1,0,0)
然后将这个速度乘以一个设定好的值,叫做speed
得到(speed*(x2-x1),speed*0,speed*0)
然后加上移动前的值,得到
(speed*(x2-x1)+x1,speed*0+y1,speed*0+z1)
这个就是加速后的值了

3)实战操作
用ce搜索什么写入了x
进入游戏后,ce马上检测到了一条指令(有的游戏是有移动操作才会出现写坐标的指令)
004C73E8 - 89 41 30  - mov [ecx+30],eax
进入反汇编将这条指令nop掉
在游戏中尝试移动,发现只能从左下到右上斜移了,说明这条指令就是控制移动的

查看指令所在的这个函数,很明显就是将3个参数赋值给3个坐标
也即是esp+4开始的3个浮点数,复制到ecx+30开始的3个浮点数:

004C73E0 - mov eax,[esp+04]
004C73E4 - mov edx,[esp+08]
004C73E8 - mov [ecx+30],eax
004C73EB - mov eax,[esp+0C]
004C73EF - mov [ecx+34],edx
004C73F2 - mov [ecx+38],eax
004C73F5 - ret 0010

在这个函数上注入代码就可以实现加速功能了
但是在这之前还有一些需要解决的问题:
(1)这段代码不止是主角在用,怪物,boss,甚至是花草树木都有可能用到这段代码
(2)遇到场景变化的时候,游戏在其他代码中会先将坐标清零,然后调用这个函数将新的坐标写进去,这样就会发生严重错误:
比如坐标本来是要从(0,0,0)变成(1000,1000,0),这是执行了注入后的代码,结果变成了(2000,2000,0)
好运的话就是起始坐标换了个位置,一般情况下都是直接越界,产生错误

对于第一个问题,在注入的代码中比较一下指针即可
对于第二个问题,首先设定一个值,比如100,在新坐标减去旧坐标后,取绝对值,与这个值比较
如果大于这个值则不执行加速,非场景切换的时候值的改变都是很小的,而场景切换就会发生很大的改变
在一些坐标比较小的游戏中,这个值可能要设定为10

利用ce的自动汇编功能,首先插入一个框架模版,然后在第一条指令上注入代码:
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
globalalloc(spd,4)//这是调节速度的值
globalalloc(dspd,4)//这是用来比较移动速度的
globalalloc(temp,4)
spd:
db 00 00 00 40//设为加速2倍
dspd:
db 00 00 c8 42//100,比较速度

alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(originalcode)
label(exit)
label(for)
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
mov eax,009e81d4
cmp eax,ecx
jne originalcode
//首先比较移动的坐标是不是主角的,不是就跳回原代码

xor eax,eax
//eax是循环用的偏移量

for:
fld [esp+04+eax]//新坐标
fsub [ecx+30+eax]//减去旧坐标
fst [temp]
fld [temp]
fabs//复制一次差值,取绝对值
fcom [dspd]//与设定的100比较
fstp [temp]//平衡浮点寄存器
push eax
fstsw ax
sahf
pop eax//将比较的结果存到标志寄存器中
ja originalcode//如果差是大于100,则认为是场景切换,跳走
fmul [spd]//乘上设定的加速值
fadd [ecx+30+eax]//加上原来的旧坐标
fstp [esp+04+eax]//赋给新坐标

add eax,4
cmp eax,c
jb for//循环3次
jmp originalcode

originalcode:
mov eax,[esp+04]
mov edx,[esp+08]

exit:
jmp returnhere

"ZWEI2P.exe"+C73E0:
jmp newmem
nop
nop
nop
returnhere:

[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
dealloc(spd)
dealloc(dspd)
dealloc(temp)
"ZWEI2P.exe"+C73E0:
mov eax,[esp+04]
mov edx,[esp+08]
//Alt: db 8B 44 24 04 8B 54 24 08

4)跳的更高
对于这个游戏,在设定加速的同时,也会让人物跳得更高
如果需要单独设定跳跃高度,只需将循环中的z坐标提出来,单独处理
但是有的游戏对于跳跃使用其他代码的,那么只要将那段代码找出来,同样处理即可

该用户从未签到

发表于 2015-12-5 10:33:50 | 显示全部楼层
明年...............
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-3-29 21:25

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表