我正在开发一个小型单人训练器。我不知道为什么 ReadProcessMemory 函数不起作用。通常它会返回 False 或 True,但在这种情况下什么也不会返回。GetlastError() 给我错误代码 6。

#-*- coding: cp1252 -*-

import ctypes, win32ui, win32process ,win32api

PROCESS_ALL_ACCESS = 0x1F0FFF
HWND = win32ui.FindWindow(None,"Solitär").GetSafeHwnd()
print(HWND)
PID = win32process.GetWindowThreadProcessId(HWND)[1]
print(PID)
PROCESS = win32api.OpenProcess(PROCESS_ALL_ACCESS,0,PID).handle

rPM = ctypes.windll.kernel32.ReadProcessMemory
wPM = ctypes.windll.kernel32.WriteProcessMemory

ADDRESS1 = 0x00E97074
ADDRESS2 = ctypes.create_string_buffer(64)
pi = ctypes.pointer(ADDRESS2)
rPM(PROCESS,ADDRESS1,ADDRESS2,64,0)
print(ADDRESS2)
x=ctypes.windll.kernel32.GetLastError()
print(x)
有帮助吗?

解决方案

查看 MSDN 社区评论 读取进程内存 页面,引用(原文如此):

W7不会运行读取进程内存

您可能需要检查当前进程令牌对“SE_DEBUG_NAME”的访问权限。如果没有启用。启用它。当然,这必须以管理员身份完成。

还完全声明返回类型并使用 use_last_error 参数,其中 ctypes 将缓存 GetLastError() 调用后直接在内部赋值。否则,可能会不正确。如果您使用的是 64 位系统,则 SIZE_T 和指针都是 64 位值,因此 ctypes 需要知道类型才能为调用正确设置堆栈。

...
from ctypes import wintypes
...
rPM = ctypes.WinDLL('kernel32',use_last_error=True).ReadProcessMemory
rPM.argtypes = [wintypes.HANDLE,wintypes.LPCVOID,wintypes.LPVOID,ctypes.c_size_t,ctypes.POINTER(ctypes.c_size_t)]
rPM.restype = wintypes.BOOL
wPM = ctypes.WinDLL('kernel32',use_last_error=True).WriteProcessMemory
wPM.argtypes = [wintypes.HANDLE,wintypes.LPVOID,wintypes.LPCVOID,ctypes.c_size_t,ctypes.POINTER(ctypes.c_size_t)]
wPM.restype = wintypes.BOOL

ADDRESS1 = 0x00E97074
ADDRESS2 = ctypes.create_string_buffer(64)
bytes_read = ctypes.c_size_t()
print(rPM(PROCESS,ADDRESS1,ADDRESS2,64,ctypes.byref(bytes_read)))
print(ctypes.get_last_error())

另外,仅供参考,即使进行了所有修复,我也得到了相同的错误值,但我没有经历启用的麻烦 SE_DEBUG_NAME.

解决了

以下行是问题所在:

PROCESS = win32api.OpenProcess(PROCESS_ALL_ACCESS,0,PID).handle

win32api.OpenProcess 返回一个临时的 PyHANDLE 被摧毁的 并关闭手柄 检索句柄后。

解决方案是使用:

PROCESS = win32api.OpenProcess(PROCESS_ALL_ACCESS,0,PID)
...
rPM(PROCESS.handle,ADDRESS1,ADDRESS2,64,0)

PROCESS 然后持有 PyHANDLE 对象和句柄仍然有效。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top