内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

【游戏辅助】人物数组搜索与分析

2018-05-12 16:40 出处:清屏网 人气: 评论(0

前言

学习游戏辅助必备的技能主要包括:游戏数据的查找、功能函数的调用、封包数据的分析、辅助程序的开发几个部分。首先就是游戏数据的查找,接下来我们以一款回合制游戏 《逍遥情缘》(时间:20180512,版本:7.3.0) 为例给大家进行分析和查找人物信息数组。

使用工具

工具如下:

数据搜索工具:CE

游戏调试工具:OD

辅助开发工具:delphi7

数据搜索步骤

当然你可以使用你熟悉的编程工具进行开发,首先用CE加载游戏搜索人物的当前血值(1054)

可以扫描到很多数据

然后通过打怪或者升级使当前血量发生变化

然后再用CE“再次搜索”新的血量,通过改变血量反复搜索直到剩余一个为止

然后记录地址 221310C8

打开OD附加游戏进程后,查看上述地址的数据,使用 “dd 221310C8” 命令查询。

看到数据为“42c”这是一个十六进制的数据,可以将它转化为十进制,正好就是1068。然后在该数据上下断点(硬件访问-Dword)

然后点击任务属性查看血值,OD会断在 00A8325A

向上看代码发现 “mov eax, dword ptr [eax]” 也就是数据来源于eax,继续向上 “call 00A8CE80” eax来源于这个call的返回值,进入这个call查看。

eax来源于ecx+edx*8,多次查看血值,发现这里的edx是不变的是16。返回上一层继续向上看找ecx的来源。

看到ecx来源于[ebp-34]这个局部变量,继续向上找[ebp-34]的来源,发现来源于ecx,然后可以在函数头下F2断点,断下后ctrl+F9向上返回。

返回后,关注ecx的值即可。

可以看到从下往上显示加18,然后是取地址里的值。

到这里先总价一下上面的血值表达式: [[ecx]+18]+16*8 。然后在函数头下断继续ctrl+F9向上返回。

ecx来源于eax+c69c,然后看eax在本函数来源于ecx,然后继续在本函数头下断ctrl+F9向上返回。

ecx来源于eax,eax是上一个call的返回值,进入上一个call查看。

找到基地址028B6208。综上,总结下当前血量地址为: [[028B6208+0000C69C]+18]+16*8

找到血量后,可以在当前血量附近查看任务其它的相关信息,一般游戏会将人物的信息存放在一个数组里面,我们找到的当前血值地址应该也是在这个数组里。

通过附近查看,找到:

[[028B6208+0000C69C]+18]+16*8        当前血值
[[028B6208+0000C69C]+18]+17*8        最大血值
[[028B6208+0000C69C]+18]+1D*8        当前蓝
[[028B6208+0000C69C]+18]+1E*8        最大蓝
[[028B6208+0000C69C]+18]+0F*8        等级

用同样的方法还可以找到任务名字的地址为: [[[028B6208+0000C69C]+18]+1*8]+4

辅助编写

分析完成后,我们就可以用delphi编程实现获取游戏内存中的数据了。

窗口设计如下

代码实现如下:

首先定义游戏窗口、类名和游戏基地址:

GameCaption='逍遥情缘 - 名扬四海';
 GameWndClassName='Platform_Client_Class';
 GameBase =$28B6208;

然后是编写获得人物信息基地址的功能函数,先获取游戏窗体句柄,在获取游戏进程id,打开游戏进程并读取内存信息:

Gameh:=FindWindow(nil,GameCaption);
   if  Gameh=0 then exit;
  GetWindowThreadProcessID(Gameh,GamePid);
  GamehProcess:=OpenProcess(windows.PROCESS_ALL_ACCESS,false,GamePid);
  ReadProcessMemory(GamehProcess,Pointer(GameBase+$C69C),@ptmp,4,readByte);
   ReadProcessMemory(GamehProcess,Pointer(Ptmp+$18),@ptmp,4,readByte);

有了人物信息基地址就可以获得人物相关的信息数据了,比如当前血值:

Function GetCurBlood:integer;
var
 base,ptmp:integer;
 readByte:Dword;
begin
 Result:=0;
  base:=GetRoleBase;
   Gameh:=FindWindow(nil,GameCaption);
   if  Gameh=0 then exit;
  GetWindowThreadProcessID(Gameh,GamePid);
  GamehProcess:=OpenProcess(windows.PROCESS_ALL_ACCESS,false,GamePid);
   ReadProcessMemory(GamehProcess,Pointer(base+$B0),@ptmp,4,readByte);
  Result:=ptmp;
end;

这里的“$B0”就是十六进制的16*8的结果啦。

编译运行得到信息与游戏中一致:


分享给小伙伴们:
本文标签: 电子游戏

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号