使用Pymem修改游戏内存遇指针转换及内存读取错误求助
问题排查与修复
核心问题分析
- 指针读取位数不匹配:
read_long仅读取4字节数据,适配32位程序。如果目标游戏是64位,必须用read_ulonglong读取8字节指针,否则会得到截断的无效地址,触发MemoryReadError(299)(ERROR_PARTIAL_COPY,内存地址无效或无访问权限)。 - 函数调用时机错误:在
CTkCheckBox的command参数中直接执行utility.unlimitedHunger(),会导致程序启动时立即进入死循环,而非点击复选框时触发,可能在游戏内存未完全初始化时就尝试读写,引发地址无效问题。 - 指针遍历逻辑漏洞:原
getPtrAdrr函数未处理空指针或无效地址的情况,一旦某一步读取到无效值,后续操作必然失败。
修复后的代码
指针地址获取与内存写入逻辑修复
from pymem import * from pymem.process import * import time import threading pm = pymem.Pymem("xxx.exe") gameModule = module_from_name(pm.process_handle, "xxx").lpBaseOfDll def getPtrAdrr(base, offsets): try: # 根据程序自动适配指针读取方式:64位读8字节,32位读4字节 addr = pm.read_ulonglong(base) if pm.is_64_bit else pm.read_long(base) # 遍历除最后一个偏移外的所有层级指针 for offset in offsets[:-1]: addr = pm.read_ulonglong(addr + offset) if pm.is_64_bit else pm.read_long(addr + offset) return addr + offsets[-1] except Exception as e: print(f"指针解析失败: {e}") return 0 # 返回无效地址避免后续报错 def unlimitedHunger(): def update_hunger_loop(): while True: target_addr = getPtrAdrr(gameModule + 0x08959C68, [0x410, 0xC8, 0X3B0, 0X4C8, 0X158, 0XAF0]) if target_addr != 0: try: pm.write_float(target_addr, 100.00) except Exception as e: print(f"饥饿值写入失败: {e}") time.sleep(0.1) # 降低循环频率,减少资源占用 # 用线程执行循环,避免阻塞UI线程 threading.Thread(target=update_hunger_loop, daemon=True).start()
UI调用逻辑修复
将复选框的command参数改为函数引用(不带括号),避免程序启动时立即执行:
# 原错误代码: # hunger_Checkbox = customtkinter.CTkCheckBox(root, text="Fill Hunger" ,variable=hungerBoxStatus, onvalue="On", offvalue="Off", command=utility.unlimitedHunger()) # 修改后: hunger_Checkbox = customtkinter.CTkCheckBox(root, text="Fill Hunger" ,variable=hungerBoxStatus, onvalue="On", offvalue="Off", command=utility.unlimitedHunger)
额外注意事项
- 确认目标游戏的位数,Pymem的
is_64_bit属性可自动检测,无需手动判断。 - 确保游戏进程完全加载后再执行内存操作,避免读取未初始化的内存地址。
- 循环中加入
time.sleep,既减少CPU占用,也避免频繁读写内存触发游戏反作弊机制。
内容的提问来源于stack exchange,提问作者JustinMalloy8575
相关产品推荐
相关产品推荐

