【问题标题】:What is the benefit of offsets to pointers?指针偏移量有什么好处?
【发布时间】:2013-04-16 23:07:34
【问题描述】:

我正在使用称为作弊引擎的内存编辑应用程序。我将作弊引擎附加到游戏中。在我的游戏中,我有一个称为 HP 的 32 位整数。 HP 存储在内存地址 A。如果我重新启动游戏,HP 将存储在新的内存地址 B。似乎使用 Cheat Engine,我可以进行指针扫描并找到指向的静态内存地址 C另一个内存地址及其附带的偏移量 D 和偏移量,因此 [D + offset] 在该会话期间始终存储 HP 的内存地址。所以如果我取消引用[D + offset],我总是得到存储HP的内存地址。

这是一个图表:

A 或 B --> 生命值

D + 偏移量 --> A 或 B

C --> D

使用偏移量有什么好处?为什么 C 不能直接指向 A 或 B?我熟悉在 C 语言中处理数组时使用偏移量是有益的。这是否意味着每当我看到一个指针的偏移量时,指针都指向数组中的第一个元素,而偏移量是指数组中的一个元素?

【问题讨论】:

  • 此级别的答案可能会受到旨在运行代码的芯片(或虚拟机)的架构和指令集的严重影响。一些指令集通过为偏移索引提供快速寻址模式来鼓励这种事情。

标签: windows memory-management reverse-engineering memory-editing


【解决方案1】:

如果您了解 C 编程语言,应该很容易想象和理解。您用 C 编写的任何内容都非常接近编译程序时生成的实际机器代码。

C 中对象的抽象通常使用“结构”来完成。

在你的例子中想象一个非常简单的“玩家”结构:

struct Player {
    int id;
    float xposition;
    float yposition;
    int health;
    int maxhealth;
};

如果你想创建这样的对象,你可以这样做:

struct Player *myPlayer = malloc(sizeof(struct Player));

高级语言中看起来漂亮的结构化事物实际上只是已编译程序中的一块内存。

要访问例如“健康”,您可以在 C 中使用 myPlayer->health;。但是现在,在一个不知道漂亮名称并且只有一块内存可以使用的编译程序中,这看起来如何?

它必须使用基指针的偏移量。在上面的示例中(假设 Windows 操作系统和任何默认配置的健全编译器),一些伪机器代码中的访问将如下所示:

move myHealth, read4bytes[myPlayer + 12]

如果您对程序进行逆向工程,则无法通过偏移访问来判断内存块是结构、数组还是类(来自 C++ 代码)或完全不同的东西。

【讨论】:

  • 完美解释。很棒的答案。 :)
猜你喜欢
  • 2021-12-23
  • 2017-08-26
  • 1970-01-01
  • 1970-01-01
  • 2012-05-22
  • 2018-04-04
  • 1970-01-01
  • 1970-01-01
  • 2016-08-15
相关资源
最近更新 更多