将以游戏攻击立方体为例。以下是从搜索健康值时使用欺骗引擎找到的地址。

我们有0x0050F4F4 (静态本地播放器指针),它指向0x00CA9000 (动态播放器对象地址)。
然后0x00C9A000 + F8 = 0x00C9A0F8将给出健康的动态地址。
这是一堂课:
class CPlayer
{
public:
char __0x0000[0xF7]; //0x0 - 0xF7
__int32 m_nHealth; //0xF8
};#define ADDR_Player 0x0050F4F4
CPlayer* pPlayer = *(CPlayer**) ADDR_Player;
pPlayer->m_nHealth;我不明白的是,为什么他们将ADDR_Player转换为指向CPlayer类型指针的指针?怎么会是双指针?
如果取消引用*ADDR_Player:
0x0050F4F4 -> 0x00C9A000 = 13202112 (随机值)
如果取消引用*ADDR_Player +偏移:
0x0050F4F4 -> 0x00C9A00+F8 = 40 (健康)
我想应该是这样的:CPlayer* pPlayer = *(CPlayer*) ADDR_Player;,但是这是不正确的,我不明白为什么正确的那个被抛到一个双指针:
CPlayer* pPlayer = *(CPlayer**) ADDR_Player;
发布于 2022-06-19 14:26:09
您需要一个指针CPlayer*。取消引用时的指针是指向指针CPlayer**的指针。因此,将数据转换为CPlayer**和取消引用是获得CPlayer*值的好方法。
发布于 2022-06-19 16:09:49
0x0050F4F4是一个内存地址,所以保存该值的变量的类型将是“指向某物的指针”,但它是指向什么的指针?
地址0x0050F4F4的是什么?另一个内存地址:0x00C9A000。因为这是一个内存地址,所以该数据的类型是“指向某物的指针”。这意味着保存0x0050F4F4的原始变量的类型是“指向指向某物的指针”。
最后,您可以查看驻留在address 0x00C9A000上的内容。这是一个CPlayer对象,因此变量holding 0x00C9A000是“指向CPlayer的指针”,这意味着变量holding 0x0050F4F4是“指向CPlayer的指针”。
也就是说,你的记忆中有这样的东西:
Memory ADDR_Player 0x0050F4F4 0x00C9A000
┌─────────────┬──────────┬─────────────┬──────────┬─────────────┬────────────────────────┐
│ │ │ │ │ │ │
│ ... │0x0050F4F4│ ... │0x00C9A000│ ... │ CPlayer Object │
│ │ │ │ │ │ │ │ │
└─────────────┴─────┼────┴─────────────┴─────┼────┴─────────────┴────────────────────────┘
│ ▲ │ ▲
│ │ │ │
└──────────────────┘ └──────────────────┘如您所见,ADDR_Player指向指向CPlayer对象的指针。也就是说,它是一个CPlayer**。
https://stackoverflow.com/questions/72677646
复制相似问题