我正在使用称为Cheat Engine的内存编辑应用程序。我将Cheat Engine附加到游戏中。在我的游戏中,我有一个32位整数,称为HP。 HP存储在内存地址A.如果我重新启动游戏,HP会存储在新的内存地址B.似乎使用Cheat Engine,我可以执行指针扫描并找到一个静态内存地址C,指向另一个存储器地址及其伴随的偏移量D和偏移量,以便[D + offset]始终在该会话期间存储HP的存储器地址。因此,如果我取消引用[D + offset],我总是得到存储HP的内存地址。
这是一个图表:
A或B - > HP
D +偏移 - > A或B
C - > d
使用抵消有什么好处?为什么C不能直接指向A或B?我很熟悉在使用C语言处理数组时使用偏移是有益的。这是否意味着每当我看到指针的偏移量时,指针指向数组中的第一个元素,而偏移量指的是数组中的一个元素?
答案 0 :(得分:2)
如果您了解C编程语言,应该很容易想象和理解。您在C中编写的任何内容都非常接近编译程序时生成的实际机器代码。
C中对象的抽象通常使用“struct”来完成。
在你的例子中想象一个非常简单的“玩家”结构:
struct Player {
int id;
float xposition;
float yposition;
int health;
int maxhealth;
};
如果你想创建这样的对象,你可以这样做:
struct Player *myPlayer = malloc(sizeof(struct Player));
高语言中结构良好的结构实际上只是编译程序中的一块内存。
要访问例如“health”,你在C中执行myPlayer->health;
但是现在如何在一个编译的程序中查看不了解美丽名称并且只有一块内存可以使用?
它必须使用基指针的偏移量。在上面的例子中(假设Windows操作系统和任何默认配置的理智编译器),某些伪机器代码中的访问将如下所示:
move myHealth, read4bytes[myPlayer + 12]
如果对程序进行逆向工程,则无法从偏移访问中判断出内存块是结构,数组还是类(来自C ++代码)或完全不同的东西。