【CE】Mac下的CE教程Tutorial:基础篇(第6关:指针)

▒ 目录 ▒

    • 导读
      • 开发环境
    • 1️⃣ 第6关:指针
      • 翻译
      • 操作步骤
    • 2️⃣ 指针相关概念
      • 一级指针
      • 多级指针
      • 指针在游戏中的应用
    • 文章小结
    • 参考资料

导读

开发环境

版本号 描述
文章日期 2023-03-
操作系统 MacOS Big Sur 11.5
Cheat Engine 7.4.3

1️⃣ 第6关:指针

【CE】Mac下的CE教程Tutorial:基础篇(第6关:指针)_第1张图片

翻译

第6步:指针:(PW=098712)

在上一步中,我解释了如何使用Code Finder来处理位置的变化。但仅使用该方法会使查找要设置的值的地址变得困难。

这就是为什么有指针存在的原因:

在底部,你会发现两个按钮。其中一个会更改值,另一个会更改值以及该值的位置。

对于这一步,你不需要真正了解汇编语言,但如果你了解的话,会有很大帮助。

首先找到该值的地址。当你找到它后,使用函数找出是什么访问了这个地址。再次更改该值,列表中会显示一个新的项。双击该项(或者选择并单击more info),将会打开一个新窗口,其中包含有关指令运行时发生的详细信息。

如果汇编指令在“[”和“]”之间没有任何东西,那么使用列表中的另一个项。

如果汇编指令中有“[”和“]”之间的内容,它将告诉你你需要的指针的值。然后回到主Cheat Engine窗口(如果你想保留这个额外的信息窗口,可以保留它,但是如果你关闭它,请记住“[”和“]”之间的内容),用十六进制的4个字节扫描额外信息中告诉你的值。

扫描完成后,它可能会返回1个或几百个地址。大多数时候,你需要的地址将是最小的地址。现在点击手动添加并选择指针复选框。

窗口将更改并允许你输入指针地址和偏移量。在地址中填入你刚才找到的地址。如果汇编指令的末尾有一个计算(例如:[esi+12]),则在末尾输入该值。否则,将其保留为0。如果它是一个更复杂的指令,请查看计算。

下面是更复杂指令的一个例子:

[EAX * 2 + EDX + 00000310] eax=4C and edx=00801234.

在这种情况下,EDX将是指针的值,EAX * 2 + 00000310将是偏移量,所以你需要填写的偏移量将是2 * 4C + 00000310 = 3A8。 (这都是十六进制的,可以使用windows中的calc.exe在科学模式下计算)

回到教程,点击“确定”按钮,地址将被添加。如果一切顺利,地址将显示为P->xxxxxxx,其中xxxxxxx是您找到的值的地址。如果不是这样,那么您可能做错了什么。
现在,使用您添加的指针在5000中更改该值并冻结它。然后点击“更改指针”,如果一切顺利,下一个按钮将变为可见。

额外信息:
您还可以使用指针扫描器查找到该地址的指针。

操作步骤

  1. 找到需要更改的值的地址。
    【CE】Mac下的CE教程Tutorial:基础篇(第6关:指针)_第2张图片
  1. 使用函数查看访问该地址的指令。
    【CE】Mac下的CE教程Tutorial:基础篇(第6关:指针)_第3张图片
    【CE】Mac下的CE教程Tutorial:基础篇(第6关:指针)_第4张图片
    上图中的指令中有“[”和“]”之间的内容(RAX=0000000106738BE0),这将告诉我们,需要的是指针的值。
  1. 使用十六进制扫描该地址值(RAX=0000000106738BE0)。
    很幸运,只有一个值,而且地址为“基址”(地址以模块+偏移的形式出现就表示该地址是基于模块的某个偏移,该值是固定的,我们一般称其为基址)。
    【CE】Mac下的CE教程Tutorial:基础篇(第6关:指针)_第5张图片
  1. 添加地址:
  • 点击手动添加地址按钮
  • 弹出对话框中选择指针复选框。
  • 在地址中填写第3步中找到的地址
  • 在偏移量中填写0,这是因为第2步中,我们找到的汇编地址指令为mov [rax], edx,写入地址rax没有偏移(指令可以理解为mov [rax+0], edx)。这个地方需要好好想想!!!
    点击“确定”按钮,地址将被添加。
    【CE】Mac下的CE教程Tutorial:基础篇(第6关:指针)_第6张图片
  1. 使用添加的指针在5000中更改该值并冻结它。
    点击“更改指针”按钮,下一个按钮将变为可见。
    【CE】Mac下的CE教程Tutorial:基础篇(第6关:指针)_第7张图片

2️⃣ 指针相关概念

一级指针

指针(Pointer)在编程中是一种非常重要的概念,指向内存中的某个位置。可以将指针理解为一种变量类型,它存储的是另一个变量的地址,而不是实际的值。

指针可以用来传递函数参数、动态分配内存、数组操作和数据结构等方面。通过指针,我们可以直接访问和操作内存中的数据,从而实现高效的编程。

指针通常是以一个特定的数据类型为基础定义的,这个数据类型定义了指针可以指向的数据类型。例如,如果要定义一个指向整数类型的指针,可以使用以下语法:

int *ptr;
上述语句定义了一个名为ptr的指针,它可以指向一个整数类型的变量。在使用指针时,可以通过取地址运算符&来获取变量的地址,例如:

int num = 10;
int *ptr = # // ptr指向变量num的地址

现在,ptr指向了变量num的地址,可以使用解引用运算符*来访问该地址中存储的值,例如:

*ptr = 20; // 将num的值改为20

上述语句将内存地址中存储的值改为了20,也就是将num的值改为了20。

总之,指针是编程中的一个非常重要的概念,它可以让我们更加高效地访问和操作内存中的数据。在使用指针时,需要特别注意指针的数据类型和指针的解引用运算符。

多级指针

多级指针是指指向指针的指针,也称为“指向指针的指针”或“间接指针”。简单来说,它是一个指针变量的指针。

例如,一个指针变量可以指向一个整数,而一个指向指针变量的指针可以指向该指针变量,进而指向该整数。这种多级指针的使用通常涉及到复杂的数据结构或者动态内存分配。

在C语言中,可以使用星号(*)来声明指针变量,而多级指针则需要在变量名前面添加额外的星号。例如,一个指向整数类型的指针可以这样声明:

int *ptr;

而一个指向指针类型的指针可以这样声明:

int **ptr;

指针的级别可以随着需要而增加,例如:

int ***ptr;

这是一个指向指向指针的指针的指针,可以依此类推。在实际编程中,使用多级指针可以方便地访问复杂的数据结构,例如链表和树。同时,也需要注意指针的有效性和正确性,以避免出现错误和内存泄漏等问题。

指针在游戏中的应用

我们模仿游戏中编写一个人物及背包的类。当访问gRole中第二个背包的容量时,就需要使用gRole->bag2->count进行访问。
gRole本身就是个指针,该值为全局变量,对于C++应用,将被编译到PE文件的data节中,也就是上面提到的基址,一旦编译好的软件,该值无论重启应用还是重启电脑,都是相对于该模块的固定偏移。对于本节,该值就是我们要找的目标指针。count就是我们最终要找的血量了。
ps: 下面示例代码是三级指针,而CE教程中的是二级指针。

// 背包
class Bag
{
int type;  // 背包类型
int index; // 索引,第几个背包
int count; // 容量
}

class Role
{
Bag *bag1;
Bag *bag2;
Bag *bag3;
}

Role *gRole = new Role();
int count = gRole->bag2->count;

文章小结

除了上述讲述的方案,一级一级的搜索指针外,还有很多方案可以定位多级指针(而且,如果通过本方案在实际应用中,会搜到很多地址,这些地址很可能不是正确的,最终淹没在无尽的多级指针中,迷失方向)。

  • 分析汇编代码,根据堆栈,向上回溯定位基址。
  • 可以使用CE提供的指针扫描器查找到地址的指针,这个以后专门进行讲解。

参考资料

  • 【CE】Mac下的CE教程Tutorial:基础篇(1-4关)https://blog.csdn.net/kinghzking/article/details/129776334
  • Cheat Engine 教程( 1 - 9 通关 ) https://blog.csdn.net/freeking101/article/details/101107489

**ps:**文章中内容仅用于技术交流,请勿用于违规违法行为。

你可能感兴趣的:(#,CheatEngine,macos,cheat,engine,ce,游戏安全)