You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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)

问题原因

  1. 函数返回值错误:getPointerAddr函数最终返回的是数值所在的内存地址,而非地址存储的实际数值,导致打印的是地址而非目标值400。
  2. 指针遍历逻辑冗余:原函数中通过offset != offsets[-1]判断遍历逻辑,写法易出错,且未明确区分指针层级遍历与最终偏移的处理。
  3. 基地址概念混淆:CE显示的"基地址"是模块的相对偏移量(如Game.exe+0x1908中的0x1908),而Pymem的pm.base_address返回的是模块在内存中的绝对起始地址,二者概念不同,数值自然有差异,但计算指针基址时pm.base_address + 偏移量的写法是正确的。
  4. 位数兼容性问题:若目标游戏是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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 09:55:58