Pymem读取指针值与Cheat Engine不符的问题求助
问题:Cheat Engine指针在Pymem中读取结果异常
问题现象
- 通过Cheat Engine找到的两个指向同一数值(示例中为400)的指针,在CE中运行正常,但使用Pymem读取时结果完全错误。
- Pymem返回的
pm.base_address为4259840,而CE显示同一进程的基地址为1908,二者数值差异明显。 - 已排查操作码地址访问情况,所有汇编函数的地址访问标记为(0)或(1),无多地址存储异常。
用户代码
from pymem import Pymem import time target = "Game.exe" try : pm = Pymem(target) except : print("ivalid exe file") quit() data = [["scraps", 0x4C549C, [0x20, 0x0, 0x4, 0x4D4]], ["scraps2", 0x4C54A0, [0x170, 0xFC, 0xB0, 0x9C, 0x4D4]]] def getPointerAddr(base, offsets): addr = pm.read_int(base) for offset in offsets: if offset != offsets[-1]: addr = pm.read_int(addr + offset) addr = addr + offsets[-1] return addr print(pm.base_address) while True : temp = "" for i in range(len(data)) : temp += data[i][0]+" : "+str(getPointerAddr(pm.base_address + data[i][1], offsets=data[i][2]))+", " print(temp) time.sleep(1.5)
问题原因
- 函数返回值错误:
getPointerAddr函数最终返回的是数值所在的内存地址,而非地址存储的实际数值,导致打印的是地址而非目标值400。 - 指针遍历逻辑冗余:原函数中通过
offset != offsets[-1]判断遍历逻辑,写法易出错,且未明确区分指针层级遍历与最终偏移的处理。 - 基地址概念混淆:CE显示的"基地址"是模块的相对偏移量(如
Game.exe+0x1908中的0x1908),而Pymem的pm.base_address返回的是模块在内存中的绝对起始地址,二者概念不同,数值自然有差异,但计算指针基址时pm.base_address + 偏移量的写法是正确的。 - 位数兼容性问题:若目标游戏是64位程序,使用
read_int(仅读取4字节)会导致指针值读取不全,进而引发后续地址计算错误。
解决方案
1. 修正指针读取函数
修改函数逻辑,使其返回最终地址存储的数值,并简化遍历逻辑:
def getPointerValue(base, offsets): addr = pm.read_int(base) # 遍历除最后一个偏移外的所有层级 for offset in offsets[:-1]: addr = pm.read_int(addr + offset) # 计算最终数值地址并读取数值 final_addr = addr + offsets[-1] return pm.read_int(final_addr)
2. 适配64位程序(若需要)
如果目标游戏是64位,将所有read_int替换为read_longlong,因为64位指针长度为8字节:
def getPointerValue(base, offsets): addr = pm.read_longlong(base) for offset in offsets[:-1]: addr = pm.read_longlong(addr + offset) final_addr = addr + offsets[-1] return pm.read_longlong(final_addr)
3. 修改主循环调用
将主循环中调用getPointerAddr改为调用修正后的getPointerValue:
while True : temp = "" for i in range(len(data)) : temp += data[i][0]+" : "+str(getPointerValue(pm.base_address + data[i][1], offsets=data[i][2]))+", " print(temp) time.sleep(1.5)
4. 确认基地址计算正确性
CE中指针的基址格式为模块名+偏移,例如Game.exe+0x4C549C,代码中pm.base_address + 0x4C549C的计算方式是正确的,无需修改。
内容的提问来源于stack exchange,提问作者the shadow
相关产品推荐
相关产品推荐

