超级玩家
 
- 贡献度
- 94
- 金元
- 5510
- 积分
- 937
- 精华
- 1
- 注册时间
- 2009-4-24
|
本帖最后由 gsky1986 于 2011-4-12 00:48 编辑
在系列2中,我们来研究如何找出Elona的SpellStock(魔法存量)的地址公式以及游戏的基址。
系列1传送门http://3dm.178.com/thread-1927561-1-2.html
ElonaExe微调补丁包http://3dm.178.com/thread-1912689-1-1.html
>>前言
任何在计算机上运行的软件都必须借助内存达到快速存取数据并交给CPU运算的目的,为什么是这样?问冯诺依曼去...............
内存有很多单元,每个单元各自不同,如何区分呢?你懂的,是地址(Memory Address),找到了这个地址,我们就找到了我们要的数据。
是不是很想做个自己的内存修改器?或是EXE补丁?无论哪个,你都必须理解并熟悉你要修改的游戏的内存布局............
这次我们拿Elona的SpellStock开刀,看看能不能发现点啥?
>>基础知识
装入内存的很多数据地址都是动态变化的,我们可以利用Cheat Engine或者金山游侠找到某个数据的临时地址,但当你重启游戏时,地址都有可能变化,所以我们要
找的不是具体的那个地址,而是一个公式。
->基地址(Base Address)
这个一般游戏版本不变就不变化,含义就像它名字一样。
->偏移量(Offset)
这个一般游戏版本不变也不发生变化,指的是某个地址离它的父级地址有多远。
-> N级偏移
如果拿数轴上的自然数1所在的位置所谓基地址,那我们要找到数字5,有多少种找法?(被喷了吧.......)
其实不用管有多少种找法,我们可以这样找。
GetAddressOf(1) + Offset(1,5)= AddressOf(5) - - - - (1)
GetAddressOf(1) + Offset(1,n1) + Offset(n1,n2) + ... + Offset(n,5) = AddressOf(5) - - - - (2)
第一种就是一级偏移,下面的就是N级偏移。
在内存中,我们的公式会稍微有点变化,为什么呢?看下面:
Level_1 = GetValueOf(BaseAddr + OffsetToLevel_1);
Level_2 = GetValueOf(Level_1 + OffsetToLevel_2);
........
Level_N = GetValueOf(Level_N-1 + OffsetToLevel_N).
其中GetValueOf(X)代表取Address = X 处的值。(如果你要的地址是32位就按32位来取)
>>思路
现在我们要找的重点就是基地址和偏移,我们一般采用回溯法去找。
所谓回溯法,以SpellStock为例,我们先找到某时刻SpellStock的数值所在地址,然后在OllyDBG中通过回溯程序逻辑来找到从基地址到它的偏移公式。
>>操作
首先我们要得到某个SpellStock的地址,怎么找?
打开Elona,打开Cheat Engine(CE)->附加至Elona的进程。
然后在搜索框内填入一个你想找的魔法存量的数值,比如肉体复活:
好,我们在CE中输入192,并点击搜索,然后按下图选择:
接着,回到游戏,使用一下肉体复活,迅速切换至CE点重新搜索(如上图),如果不行就多试几次,这样我们就得到 肉体复活 魔法存量的一个地址。
找到地址后,按下图操作:
很好,我们看看这个地址附近的内存都有什么?
嗯,发现:
对比我们其它的魔法存量来看,这块区域就是我们SpellStock数据存储的区域了。OK,打开OllyDBG附加Elona进程,再把这个内存地址在OD中输入查看,得到:
嗯,然后下内存访问断点:
为什么是内存访问断点?因为我们接下来要按V键打开魔法窗口,你觉得要画这个窗口并且显示数据的话,会不会访问这个区域呢?
在Elona中,按V打开魔法窗口,发现OD断在这里:
嗯,注意看图,一定要注意看哦,这段代码是干什么用的,我们先不关心,我们只要知道我们的地址是怎么来的就好了:
看看寄存器的值:
嗯EDX = 0x00DE11F4,这个就是我们肉体复活的地址嘛~
好,EDX的值又是从ESP+0x10(十进制的16)来的,我们看看有没有操作堆栈(Stack)的指令,喔,下面有2个POP,那么向上看:
发现了2个Push,我们知道,PUSH一个寄存器值会使得ESP+4,2个就是ESP+8,那么我们要找的那个堆栈值应该在什么位置呢?
ESP+0x10-0x08 = ESP+0x08 = ESP + 8
有趣么?呵呵,我们找找调用这段代码的时候,倒数第二个PUSH。在OD中按Ctrl+F9执行到返回,接着F8:
嗯,看来就是这个ESI拉,不废话,往上跟:
这幅图比较复杂,所以大家一定要集中精力看清楚,看看是怎么向上回溯的。
在上图中每个红色框处,我们下断点并重新F9,会发现ESI的值决定于ECX,向上看看:
发现了什么?发现了0x424D8C?你不熟悉?你没用过Elona_Me?呵呵,这个就是我们游戏的基地址,当然要确定它是不是,我们要做一些测试,如果各种情况(除非更新了你的游戏版本)它都不变,我们就当它是个基地址吧!还有那个2C就是著名的Elona_Me中的p1->p2的偏移量,这里我们略过不提,如果你做了足够多的测试,发现很多数据都起始于这里。。。。。
我们完成了第一个目标,找到了游戏的基地址,但我们还没有找出完全的公式,回到这幅图来:
请注意第一个红框标记的那个Call, 它有什么作用呢?F7跟进去:
注意看图,嗯EAX的值在这里改变,并且来自于ESP+4,老办法,找离它最近的那个PUSH,来到:
才会发现最近的那个PUSH就是ESI,这才有了我们上面找基地址那么顺利,哈哈。
看来又要跟跟EAX了,上:
继续上:
嗯,发现EAX来自内存0x424D88处,很抱歉,这个地址的数据是变化的,怎么办呢?跟这个数据的变化情况?God,我们看看放宽条件行不行,假设在处理有关我们的SpellStock数据时,0x424D88处有个值,我们看看每次我们打开
魔法窗口和使用魔法时,它是不是一个特殊而固定的值呢?
经测试,是的,如下:
这个问题就是我在ElonaEXE微调补丁中的旧版本中,缩减SpellStock有时失效的原因了:)
嗯,改成常量,在任意分辨率都没问题了。不是么?
>>结论
现在,根据我们的发现整理一下这个公式:
代码:
<
代码执行到EAX时,它的地址就是我们的SpellStock地址
公式:
BaseAddr = 0x400000+0x24D8C = 0x424D8C
P2 = GetValueOf(BaseAddr +0x2C)
P3 = GetValueOf([P2+0x4E30+0x1C])
FirstAddrOfSpellStock = P3 + 0x0 = (((0x400000+0x24D8C)+0x2C)+0x4E4C) + 0x0
LastAddrOfSpellStock = P3+0x31C = (((0x400000+0x24D8C)+0x2C)+0x4E4C) + 0x31C
测试图如下:
|
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有帐号?注册
x
评分
-
2
查看全部评分
-
|