我正在研究一些小型教练。我不知道为什么功能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 ReadProcessMemory页面的评论,引用(原文如此):

还要完全声明返回类型并使用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())
同样,FYI,即使使用所有修复程序,我也得到相同的错误值,但是我没有遇到启用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对象,并且该句柄保持有效。

关于python - 具有ctypes的ReadProcessMemory,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12712585/

10-13 00:06