文章目录

  • 周围遍历分析
  • 定位角色名字偏移
  • 玩家名字偏移
  • NPC名字偏移
  • 数据整理
  • 代码编写

所谓的周围遍历,其实就是人物附近所有的怪物 NPC 和玩家信息,拿到了这些数据,我们就可以实时获得当前人物对象周围有哪些数据。对于编写自动打怪来说,需要的是周围的怪物的数据,ID 名字血量坐标等等。

周围遍历分析

首先从怪物的血量入手

直接搜索血量

然后筛选出唯一的值

对血量下访问断点,断在了我们之前找人物血量的地方

[rax+0x65C]+0x1AC

rax来源于rbx

rbx来源于rcx

rcx来源于rax,再进入call内追rax的来源

rax来源于rbx

rbx来源于rax

rax来源于rbx

rbx来源于rcx

rcx来源于rax

这里rax来源于一个数组,而且马上就能拿到数组的基地址

ecx是数组的长度,但是这个值太大了,可能是加密后的,也可能是预留的数组的长度,所以需要继续追rcx的值

[[07FF70B1E7518]+rcx+8]

ecx来源于[rax+0x1C]

rax来源于[rsp+0x30]

[rsp+0x30]来源于r8

r8来源于rax

[rax+0x1C]

追到这里就是一个标准的二叉树了

[[rcx+0x75C]+0x8]

上面的值是根节点,这里继续追rcx

最后rcx来源于基地址

[[007FF6B1F27050+0x75C]+0x8]

这里我们就追到了二叉树的根节点

最后整理一下数据

[[007FF6B1F27050+0x75C]+0x8] 根节点
+0 左子树
+0x10 右子树
+0x18 对象ID DWORD
+0x1C 数组下标 DWORD[[[07FF70B1E7518]+rcx+8]+0x65C]+0x1AC 怪物当前血量
[[[07FF70B1E7518]+rcx+8]+0x65C]+0x1B0 怪物最大血量

定位角色名字偏移

首先搜索人物自己的名字

接着筛选出唯一的名字数值

在这个位置下断点,打开角色栏,让断点断下

然后返回上一层,并记录每一层的偏移

rdi+0x638

此时,rdi+0x638是角色名字的偏移

rdi来源于rcx,继续返回追rcx

rcx来源于rsi

rsi来源于rax,然后来源于call

rax来源于rbx

rbx来源于rcx

rcx来源于[rcx+0x248]

[rcx+0x248]+0x638

然后再来源于[rcx+0x71C]

[[rcx+0x71C]+0x248]+0x638

rcx又来源于rax

然后在call内出现了基地址

[[0x00007FF77C447050+0x71C]+0x248]+0x638

玩家名字偏移

接着我们来找一下玩家的名字偏移

搜索一下玩家的名字偏移

确定唯一的一个地址后

下访问断点

返回上层,发现玩家名字的偏移也是+0x638

NPC名字偏移

同样的方法可以找到NPC的名字偏移是0xE08

数据整理

[[007FF6B1F27050+0x75C]+0x8] 根节点
+0 左子树
+0x10 右子树
+0x18 对象ID DWORD
+0x1C 数组下标 DWORD[[[07FF70B1E7518]+rcx+8]+0x65C]+0x1AC 怪物当前血量
[[[07FF70B1E7518]+rcx+8]+0x65C]+0x1B0 怪物最大血量
玩家名字偏移: 对象+0x638
NPC和怪物名字偏移: 对象+0xE08
X坐标:对象+0x80
Y坐标:对象+0x84
Z坐标:对象+0x88

代码编写

首先在_stuObj中添加对象相关的属性

 _stuPos m_Obj_Pos;  //坐标DWORD m_Obj_HP;DWORD m_Obj_MaxHP;DWORD m_Obj_MP;DWORD m_ObjType;    //对象类型

新增一个坐标结构体

struct _stuPos
{float x;float y;float z;
};

接着在GameData.h添加三个函数

//周围遍历
_stuObjs GetAroundData();//进入周围遍历二叉树
void EnterAroundDataTree(DWORD dwRoot, _stuObjs& datalist);//获取对象里面的数据
void GetAroundNodeInfo(DWORD dwNode, _stuObjs& datalist);

首先获取周围遍历

//周围遍历
_stuObjs GetAroundData()
{//周围对象数据_stuObjs AroundDataList;//获取二叉树根节点QWORD dwTemp = g_GameAddr + AroundAndBagDataTree;//[007FF6B1F27050+0x75C]dwTemp = ReadQword(dwTemp + 0x75C);//[[007FF6B1F27050+0x75C]+0x8]DWORD dwTreeRoot = ReadDword(dwTemp + 8);//拿到了二叉树的根节点 开始遍历EnterAroundDataTree(dwTreeRoot, AroundDataList);//返回周围对象数据return AroundDataList;
}

这个函数的功能负责读取二叉树根节点,进入二叉树后,返回周围对象数据的列表

//进入周围遍历二叉树
void EnterAroundDataTree(DWORD dwRoot, _stuObjs& datalist)
{//左子树DWORD dwLeftNode = ReadDword(dwRoot + 0);//右子树DWORD dwRightNode = ReadDword(dwRoot + 0x10);//标志位BYTE bFlag = ReadBYTE(dwRoot + 0x21);//标志位为0开始遍历if (bFlag == 0){//获取对象里面的数据GetAroundNodeInfo(dwRoot, datalist);//递归遍历左子树EnterAroundDataTree(dwLeftNode, datalist);//递归遍历右子树EnterAroundDataTree(dwRightNode, datalist);}
}

然后进入二叉树,这个函数负责递归遍历整个二叉树的左子树和右子树,判断标志位,获取对象数据的功能由GetAroundNodeInfo函数处理。

void GetAroundNodeInfo(DWORD dwNode, _stuObjs& datalist)
{//对象的结构体_stuObj _stuData;//数组首地址DWORD dwArray = ReadDword(g_GameAddr + AroundDataArray);//对象类型_stuData.m_StuType = Em_Object;//怪物ID_stuData.m_ID = ReadDword(dwNode + 0x18);//怪物ID(数组的下标)int index= ReadDword(dwNode + 0x1C);//怪物对象=数组首地址+数组下标*8_stuData.m_Obj = ReadDword(dwArray + index * 0x8);//对象类型_stuData.m_ObjType = ReadBYTE(_stuData.m_Obj + 0x5AB);//血量_stuData.m_Obj_HP = ReadDword(_stuData.m_Obj + 0x65C);_stuData.m_Obj_HP = ReadDword(_stuData.m_Obj_HP + 0x1AC);//获取名字//自己名字和其他玩家名字if (_stuData.m_ObjType == 0x2 || _stuData.m_ObjType == 0x3){DWORD nameaddr = ReadDword(_stuData.m_Obj + 0x638);_stuData.m_Name = ReadWChar(nameaddr);}//NPC 怪物 小动物 神兽else if (_stuData.m_ObjType == 0x4 || _stuData.m_ObjType == 0x5 ||_stuData.m_ObjType == 0xC || _stuData.m_ObjType == 0xD){DWORD nameaddr = ReadDword(_stuData.m_Obj + 0xE08);_stuData.m_Name = ReadWChar(nameaddr);}//坐标_stuData.m_Obj_Pos.x = ReadFloat(_stuData.m_Obj + 0x80);_stuData.m_Obj_Pos.y = ReadFloat(_stuData.m_Obj + 0x84);_stuData.m_Obj_Pos.z = ReadFloat(_stuData.m_Obj + 0x88);//保存对象到集合datalist.m_data.push_back(_stuData);
}

最后GetAroundNodeInfo函数取出对象下的所有数据,并保存到集合里。

//输出对象信息case Em_Object:{__OutputDebugStringW(L"对象:%x  ID:%x 类型:%x 血量:%d  名字:%s 坐标:(x %f y %f z %f) 距离:%f", m_Obj, m_ID, m_ObjType, m_Obj_HP, m_Name.c_str(), m_Obj_Pos.x, m_Obj_Pos.y, m_Obj_Pos.z, m_ObjDistance);}break;

然后在OutputDebugInfo中输出对象的信息;然后添加按钮响应事件,调用函数输出信息。实际效果如图:

这样我们就取出了所有的周围对象的数据

Github:https://github.com/TonyChen56/GameReverseNote

完整代码:https://download.csdn.net/download/qq_38474570/79498815

005 周围遍历二叉树分析和代码编写相关推荐

  1. 012 背包二叉树遍历分析和代码编写

    文章目录 背包属性遍历 物品名字库遍历 数据整理 代码编写 背包属性遍历 从物品数量入手,搜索2字节 筛选出唯一的值 下两字节的访问断点,鼠标移动到物品上面,断点断下 物品数量=r14+0x10 这里 ...

  2. 006 技能数组分析和代码编写

    文章目录 技能遍历 技能名字 数据整理 代码编写 现在我们已经有了人物的数据和周围对象的数据,还差一个技能数据和释放技能call,就可以完成自动打怪的功能. 接着我们来找技能遍历的数据 技能遍历 以技 ...

  3. 【手把手 脑把脑】教会你使用idea基于MapReduce的统计数据分析(从问题分析到代码编写)

    目录 1 编程前总分析 1.1 数据源 1.2 需要掌握的知识 1.2.1 Hadoop对比java的数据类型 1.2.2 MapReduce流程简介 1.3.3 MapReduce流程细分 2 编码 ...

  4. 【LeetCode题解】BFS层序遍历二叉树

    102.二叉树的层序遍历 分析: 层序遍历,顾名思义,就是按一层一层的顺序来对二叉树进行遍历,遍历顺序如下图所示 那么如何对二叉树进行遍历呢,我们首先将上面二叉树各层按照遍历次序放在同一直线上 现在我 ...

  5. 数据结构之遍历二叉树

    遍历二叉树 在二叉树的一些应用中,常常要求在树中查找具有某种特征的结点.这就提出遍历二叉树的问题,即如何按某条搜索路径巡访树中每个结点,使得每个结点均被访问一次,而且仅被访问一次.遍历对线性结构来说, ...

  6. C语言二叉树实验报告流程图,二叉树的建立与遍历实验报告(c语言编写,附源代码).doc...

    二叉树的建立与遍历实验报告(c语言编写,附源代码).doc 第 1 页,共 9 页二叉树的建立与遍历实验报告级 班 年 月 日 姓名 学号_ 1实验题目建立一棵二叉树,并对其进行遍历(先序.中序.后序 ...

  7. 二叉树的前,中,后序遍历(思路分析) [Java][数据结构]

    二叉树的前,中,后序遍历(思路分析) 前序遍历: 先输出父节点, 再遍历左子树和右子树 中序遍历: 先遍历左子树, 再输出父节点,再遍历右子树 后序遍历: 先遍历左子树,再遍历右子树,最后输出父节点 ...

  8. LeetCode——1104. 二叉树寻路(Path In Zigzag Labelled Binary Tree)[中等]——分析及代码(Java)

    LeetCode--1104. 二叉树寻路[Path In Zigzag Labelled Binary Tree][中等]--分析及代码[Java] 一.题目 二.分析及代码 1. 按位置求解 (1 ...

  9. 层次分析法步骤及代码编写

    层次分析法步骤及代码编写 笔记大部分由观看[强烈推荐]清风:数学建模算法.编程和写作培训的视频课程整理出: 视频链接:https://www.bilibili.com/video/BV1DW411s7 ...

最新文章

  1. SignalR的另类实现技巧
  2. XenServer安全重启xapi的方法
  3. python中导入包中的__init__文件夹的一个重要作用(去年对文件名的导入)
  4. OOD之问题空间到解空间—附FP的建模
  5. python input函数无法输入字符串_Python手把手教程之用户输入input函数
  6. Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转......
  7. [C++基础]037_编写不可被继承的类
  8. Python 圈精选文章
  9. 2018 ACM/ICPC 沈阳站小结
  10. win7服务器如何还原系统教程视频,windows7系统还愿怎么操作_win7系统还原重置方法...
  11. pdf 编辑器 linux
  12. JVM - 【字符串常量池】-XX:StringTableSize
  13. 视频打包为MP4格式并存储到TF卡的实现
  14. 小水智能-智慧工地与传统工地相比,数字科技赋予了以下三大优势
  15. android自定义素材拼图,美图秀秀Android新版 拼图排版秀北爱
  16. Linux中nvme驱动详解
  17. Photoshop如何使用图像调色之实例演示?
  18. 如何在PCB中放置禁止触摸标志
  19. 51单片机学习笔记(清翔版)(25)——LCD1602和指针
  20. html中text函数,Excel中text函数的使用方法

热门文章

  1. LinuxProbe学习笔记(十二)
  2. ai前世识别_ai人脸扫描前世身份
  3. 小程序腾讯地图绘制大头针,以及还原位置
  4. 用python还原《三体》中的二向箔——地球表面的二维投影
  5. web服务器缓存(二)
  6. 终止线程 4 种方式
  7. BarManager控件介绍
  8. [Windows系统]任务管理器中的内存参数
  9. python中sigmoid函数_python实现并绘制 sigmoid函数,tanh函数,ReLU函数,PReLU函数
  10. docker实现mysql 主从复制