CE寻找基址
这里说的基址,其实是指静态地址,而真正的基址是指模块基址,但大家都在乱叫,所以就随波逐流的跟着叫了。基址也就是每次重启应用后,都不会发生变化的地址。
通过 CE 多次精确数值搜索,最终获取到了当前血量的动态地址 0x2BF89D50
,准备根据这个动态地址去寻找血量基址。
首先右键 - 找出是什么访问了这个地址,或者直接使用快捷键 F5
:
可以得到 [2BF89AC8+00000288]
:
然后十六进制搜索数值 2BF89AC8
,一般会有很多结果,可以挨个 F5 查找访问:
得到新的地址 [[03A615A8+28]+00000288]
:
再继续搜索 03A615A8
得到新的地址 [[[00D11A50+1C]+28]+00000288]
:
再继续搜索 00D11A50
得到新的地址 [[[[0D0DF1C]+1C]+28]+00000288]
:
最后手动添加地址,填入我们找到的静态地址和偏移,验证结果:
当前血量静态地址为 [[[[elementclient.exe+90DF1C]+1C]+28]+00000288]
OD寻找基址
通过 CE 找到了当前血量的动态地址 0x27AEB18
(调试的游戏重新打开过,所以地址和上面的不同),使用 OD 附加进程后,在数据窗口输入命令 dd 27AEB18
跳转到指定地址,然后给输入下一个硬件访问断点,类型为 Dword
。
断点会停在 CPU 代码区域地址 0x00819A00
,这个地址上面一行代码,就是关键代码。我们可以拿到血量访问是 [edi+288]
,然后查找跟着 edi
继续查找。
最终得出 [[[[0D0DF1C]+1C]+28]+288]
,和上面用 CE 找到的基址和偏移一致,并且寻找过程更简单:
调试完成后,点击工具栏的 HBP
图标,在弹出窗口中删除刚才的断点。
OD寻找基址注意点
只有 mov
指令可以构成偏移。
碰到 ebp
,一般 esp
和 ebp
不会相差太大,大概相差 0x10000
内才是偏移,否则不是。
碰到 esp
不能当偏移看,要看成一个整体,比如 esp+1
是一个整体。就 F9
继续运行,会断在下一个访问数据的地方,再继续找。
碰到 ecx
不见了,就 F9
继续运行,会断在下一个访问数据的地方,再继续找。
碰到 eax
和 call
离得很近或者挨着,eax
来源于 call
的返回值。选中 call
后按回车进入子程序继续查找。
碰到 ax
。eax
32位寄存器,ax
低16位,ah
高8位 al
低8位。比如 00005996
低16位是 0000
,高8位是 59
,低8位是 96
。
CE+OD寻找基址
像上面的例子看起来在 OD 里是很容易找到基址的,但有的时候 OD 里并不容易找到,所以需要结合起来查找。
像上面例子,找到一个当前血量的基地址后,在数据窗口切换数据显示格式,可以很容易再找到人物其他属性的偏移,而不需要重头寻找,这种基址可以叫人物基址,是一个人物的结构的地址。
游戏文本编码
在 CE 中搜索文本,游戏常用的文本字符编码:
ASCII:直接去搜
Unicode:勾选Unicode选项
UTF-8:奇技淫巧或工具
BIG5:利用工具,繁体字
搜索文本
1.OD 中用 StrongOD
插件的 Alloc Memory
申请内存,记下申请的内存的地址。
2.在 CE 中手动添加地址,然后修改这个地址中的值为我们想搜索的文字(1个汉字2字节计算长度,最好多加几字节),再更改记录转换类型为字节数值。
3.再拷贝内容去搜索字节数组。
指针扫描
除了上面 CE 寻找基址例子中通过 F5 查找访问去一级一级的查找外,还有一个全自动的方式,也就是内存浏览器窗口里的指针扫描器,这也是大多数新手最喜欢的一种方式。