了解记忆-游戏黑客

问题描述 投票:2回答:1

我正在尝试开始学习如何使用C ++编写游戏秘籍。但是此刻,我想了解内存的布局等-我有几个问题要问,将使用游戏Assault Cube作为参考。请帮助我,并以简单的形式解释任何内容。我是新来的。

1]假设ac_client.exe的图像基址位于0x4000000-这是否仅表示该过程的开始已分配在该内存地址?

2)接下来是图像基数+偏移(&ac_client.exe + 0x10F4F4)-偏移是否表示它从起点将您带到过程中的某个位置或功能?

3)在Cheat Engine中,我加载了Assault Cube。我搜索了我的健康价值。我找到了健康的动态地址。现在,我将需要找到静态地址,因为没有直接指向健康的指针,因此单击“查找访问此地址的内容”选项-这是否意味着我正在尝试查找正在使用或传递我的动态健康状况的函数变量?

4)找到健康值的静态地址后。我发现偏移量是0xF8。还有ac_client.exe + 0x10F4F4-> 0x50F4F4-人们说0x50F4F4是本地玩家基础类,但是如果不告诉我,我怎么知道呢?这是否也意味着所有游戏变量都在类中?

仍然有点困惑,有人可以从视觉上解释这一切。

reverse-engineering cheat-engine
1个回答
0
投票

1]假设ac_client.exe的映像基址为0x4000000-这是否仅表示该进程的开始已分配在该内存地址?

是,但是更具体地说,它是映射到内存中的PE(便携式可执行文件)的基地址。因此,在地址基础上,您具有PE标头,然后有很多结构,然后是可执行文件的各个部分,等等。

2)接下来是图像库+偏移量(ac_client.exe + 0x10F4F4)-偏移量是否表示它从起点将您带到过程中的某个位置或功能?

从技术上讲,这称为RVA(Relative Virtual Address;它相对于模块的基地址):偏移量(适用于磁盘上的平面文件)和RVA(适用于文件)之间存在差异一旦映射到内存中)。一旦可执行文件映射到内存中(尽管称为OS加载程序),它就具有与磁盘上不同的“形状”,因此偏移量与RVA并不相同。

要回答您的问题,是的,它指向名为ac_client.exe的模块中的某个位置。

3)在作弊引擎中,我加载了Assault Cube。我搜索了我的健康价值。我找到了健康的动态地址。现在,我将需要找到静态地址,因为没有直接指向健康的指针,因此单击“查找访问此地址的内容”选项-这是否意味着我正在尝试查找正在使用或传递我的动态健康状况的函数变量?

正好。

我不熟悉作弊引擎,但是可以通过多种方式完成:

  1. 静态:通过分解代码并搜索指向感兴趣位置的任何交叉引用。基本上,当代码访问您要搜索的值时,它会通过一些指令来执行此指令,这些指令的内存操作数直接(或不太远)指向有趣的位置。

  2. 内存扫描:引擎直接在进程地址空间中搜索指向(或不太远)指向感兴趣位置的任何内容。如果碰巧在代码部分中,则您有一个匹配项。否则(例如,在数据部分或堆中的其他地方)尝试找到指向该新位置的任何代码位置。洗净然后重复直到找到东西。

  3. 以上混合。

4)找到健康值的静态地址后。我发现偏移量是0xF8。也是ac_client.exe + 0x10F4F4-> 0x50F4F4-人们说0x50F4F4是本地播放器的基类,但是如果不告诉我,我怎么知道呢?这是否也意味着所有游戏变量都在类中?

如果游戏是封闭源代码,则必须对其进行反向工程以了解游戏的来龙去脉。这会花费很多时间,很困难,而且您永远不会拥有原始程序员想要的“名称”。 “名称”(类名称,函数名称,变量名称等)不包含在最终的二进制文件中:您失去了查看类名称及其位置的能力。

[在少数情况下,至少在C ++中,您可以恢复这些名称(例如,当您有名为RTTI的名称时),或者如果有符号信息可用(游戏开发人员在少数情况下从不提供调试信息)。

就您而言(据我所见,游戏是开源的,并且使用C ++),您可以通过调试支持自行编译游戏(从技术上讲,对于Windows,这意味着在链接可执行文件时会产生一个PDB来提供符号支持) )。然后将游戏放入符号调试器(例如Windbg)或反汇编程序中,然后询问工具在此精确偏移量/ RVA处的功能/类是什么。确实如此简单,当您拥有符号信息时。

可以对某些语言(例如C#,Java)进行反编译(!=反汇编),并且您可以直接检索所有名称(类,函数,变量等),除非最终的二进制文件受到保护以防反编译。

这是否也意味着所有游戏变量都在类中?

这是一个相当棘手的问题,有很多分支:首先,它取决于所使用的语言。如果它是OO语言,则可能是,除了全局,静态和局部变量。有些语言没有类的概念,因此在C游戏和C ++游戏之间,由游戏操纵的对象的内存布局可能完全不同。

另一个重要的一点是,您可能还没有类中的内容[[直接,而是由类的成员指向的。

假设您的游戏中玩家拥有一个存货(因此,“玩家”类具有名为“存货”的变量成员),这可能由某种复杂的结构(例如associative container或甚至更复杂的东西)。由于这些复杂的结构是由游戏动态分配的(例如new in c++),因此清单中的所有对象最终都位于heap上,而不是直接在类本身中。该分配由“清单”成员指向(不一定直接指向),但是清单中的对象位于内存中的其他位置。
© www.soinside.com 2019 - 2024. All rights reserved.