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

使用ReadProcessMemory读取GBA模拟器内存值异常求助

问题描述

尝试用Python调用ReadProcessMemory读取VisualBoyAdvance模拟器的GBA内存,内存查看器显示GBA内存地址0xD273的值应为81,但代码每次返回随机字节值(如15、255、11、195等)。已确认进程ID正确,且必须使用32位Python运行,否则会出现ERROR_PARTIAL_COPY(错误码299)。疑惑未指定基地址是否是问题所在。

示例输出:

result: 1, err code: 0, bytesRead: 1
data: 0000000000000015h
21

原代码:

import ctypes as c
from ctypes import wintypes as w
import psutil

# Must use py -3-32 vba_script.py 

vba_process_id = [p.pid for p in psutil.process_iter() if "visualboyadvance" in p.name()][0]
pid = vba_process_id  # I assume you have this from somewhere.

k32 = c.WinDLL('kernel32', use_last_error=True)

OpenProcess = k32.OpenProcess
ReadProcessMemory = k32.ReadProcessMemory
CloseHandle = k32.CloseHandle

processHandle = OpenProcess(0x10, False, pid)

addr = c.c_void_p(0xD273)
dataLen = 8
data = c.c_byte()
bytesRead = c.c_byte()
result = ReadProcessMemory(processHandle, c.byref(addr), c.byref(data), c.sizeof(data), c.byref(bytesRead))
e = c.get_last_error()

print('result: {}, err code: {}, bytesRead: {}'.format(result,e,bytesRead.value))
print('data: {:016X}h'.format(data.value))
print(data.value)

CloseHandle(processHandle)
问题原因与解决办法

1. 核心错误:地址混淆

你直接使用的0xD273是GBA模拟器内部的游戏内存地址,而非Windows系统中VBA进程的虚拟内存地址。VBA会将GBA的内存映射到自身进程的虚拟内存空间中,你需要先找到这个映射区域的基地址,再加上0xD273的偏移量,才是要读取的正确虚拟内存地址。

可以用Cheat Engine这类工具查找VBA进程中对应GBA内存的基地址:

  • 打开Cheat Engine,附加到VBA进程
  • 在游戏中找到一个已知值(比如生命值),搜索该值找到对应的内存地址,查看该地址的基地址与偏移,最终得到GBA内存区域的基地址。

2. ReadProcessMemory参数错误

你调用ReadProcessMemory时,第二个参数传递了c.byref(addr),这是错误的。该参数需要的是目标内存的地址值,而不是addr变量自身的地址。你之前的写法导致读取的是Python进程中addr变量所在的内存区域,自然得到随机值。

修正后的代码示例

import ctypes as c
import psutil

# 必须使用32位Python运行
vba_process_id = [p.pid for p in psutil.process_iter() if "visualboyadvance" in p.name().lower()][0]

k32 = c.WinDLL('kernel32', use_last_error=True)
OpenProcess = k32.OpenProcess
ReadProcessMemory = k32.ReadProcessMemory
CloseHandle = k32.CloseHandle

# 打开进程,使用PROCESS_VM_READ权限
PROCESS_VM_READ = 0x0010
processHandle = OpenProcess(PROCESS_VM_READ, False, vba_process_id)

# ===== 替换为你实际找到的GBA内存基地址 =====
gba_memory_base = 0x00400000  # 示例值,需自行查找
# 计算目标地址:基地址 + GBA内存偏移0xD273
target_addr = c.c_void_p(gba_memory_base + 0xD273)

data = c.c_byte()
bytes_read = c.c_size_t()

# 修正第二个参数,直接传递target_addr(目标内存地址)
result = ReadProcessMemory(
    processHandle,
    target_addr,
    c.byref(data),
    c.sizeof(data),
    c.byref(bytes_read)
)

err_code = c.get_last_error()
print(f'result: {result}, err code: {err_code}, bytesRead: {bytes_read.value}')
print(f'data: {data.value:#018X}')
print(f'decimal value: {data.value}')

CloseHandle(processHandle)

关键修正点:

  • 替换gba_memory_base为你通过工具找到的实际基地址
  • 调用ReadProcessMemory时,第二个参数直接传递target_addr,而非c.byref(addr)
  • 使用c.c_size_t()存储bytes_read,符合Windows API的参数类型要求

内容的提问来源于stack exchange,提问作者Jérémie Talbot-Pâquet

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 14:40:39