我正在使用称为Cheat Engine的内存编辑应用程序。 我把作弊引擎附加到游戏中。 在我的游戏中,我有一个称为HP的32位整数。 惠普存储在一个内存地址A.如果我重新启动我的游戏,惠普存储在一个新的内存地址B.似乎使用作弊引擎,我可以做一个指针扫描,并find一个静态内存地址,C,指向另一个内存地址及其相应的偏移量D和偏移量,使得在该会话期间[D +偏移量]总是存储HP的内存地址。 所以如果我解引用[D +偏移],我总是得到存储HP的内存地址。
这是一张图表:
A或B – > HP
D +偏移量 – > A或B
C – > D
使用偏移有什么好处? 为什么C不能直接指向A或B? 我很熟悉使用偏移量在处理C语言中的数组时是有益的。 这是否意味着每当我看到一个指针的偏移量,指针指向数组中的第一个元素,偏移量是指数组中的一个元素?
如果你知道C语言,应该很容易想象和理解。 用C写的任何内容都与编译程序时生成的实际机器代码非常接近。
C中抽象一个对象通常是用“struct”来完成的。
在你的例子中想象一个非常简单的“玩家”结构:
struct Player { int id; float xposition; float yposition; int health; int maxhealth; };
如果你想创建一个像这样的对象,你可以这样做:
struct Player *myPlayer = malloc(sizeof(struct Player));
在高级语言中,一个漂亮的结构化的东西实际上只是编译程序中的一块内存。
要访问例如“健康”,您可以使用myPlayer->health;
但是现在怎么看这个编译的程序,不知道这个美丽的名字,只是有一块内存可以工作?
它必须使用基址指针的偏移量。 在上面的例子中(假设windows操作系统和任何默认配置的健全的编译器),在某些伪代码中的访问将如下所示:
move myHealth, read4bytes[myPlayer + 12]
如果你反编译一个程序,你不能通过偏移量访问来判断内存块是一个结构体,一个数组还是一个类(来自C ++代码)或者完全不同的类。