python中ReadProcessMemory读取64位进程内存时出现问题

2024-05-29 00:21:42 发布

您现在位置:Python中文网/ 问答频道 /正文

当使用ReadProcessMemory读取64位进程(扫雷舰)的内存时,我得到错误代码998(error_NOACCESS)。我在Windows7上使用的是64位的Python3.5。在

奇怪的是,这个错误只发生在更高的地址上,例如0x 0000 0000 FF3E 0000。较低的地址,如0x 0000 0000 0012 AE40,不会抛出错误并返回正确的扫雷艇数据。在

当我在C#.NET中使用几乎相同的代码编写相同的程序并查看相同的地址时,它可以正常工作,而且不会出错!在

我知道我正在查看的地址是正确的,因为我可以通过作弊引擎和VMMap看到它。我不知道它是否相关,但我要查看的更高地址是扫雷舰.exe扫雷艇模块。在

为什么python代码不能工作?在

Python代码(对于较高的地址抛出错误,但对于较低的地址有效):

import ctypes, struct

pid = 3484  # Minesweeper
processHandle = ctypes.windll.kernel32.OpenProcess(0x10, False, pid)

addr = 0x00000000FF3E0000  # Minesweeper.exe module base address
buffer = (ctypes.c_byte * 8)()
bytesRead = ctypes.c_ulonglong(0)
result = ctypes.windll.kernel32.ReadProcessMemory(processHandle, addr, buffer, len(buffer), ctypes.byref(bytesRead))
e = ctypes.windll.kernel32.GetLastError()

print('result: ' + str(result) + ', err code: ' + str(e))
print('data: ' + str(struct.unpack('Q', buffer)[0]))

ctypes.windll.kernel32.CloseHandle(processHandle)

# Output:
# result: 0, err code: 998
# data: 0

C#.NET代码(64位项目,无错误):

^{pr2}$

Tags: 代码net地址buffer错误resultctypesexe
0条回答
网友
1楼 · 发布于 2024-05-29 00:21:42

看到了艾尔克森的评论,它解决了我的问题!在ReadProcessMemory调用中将“addr”更改为“ctypes.c\u void_p(addr)”。在

网友
2楼 · 发布于 2024-05-29 00:21:42

使用ctypes时最好是显式的。适当地设置argtypes和{}将有助于检查参数的数量和类型,就像C中的DllImport语句一样。在

这里有一个迂腐的例子:

import ctypes as c
from ctypes import wintypes as w

pid = 4568  # Minesweeper

k32 = c.windll.kernel32

OpenProcess = k32.OpenProcess
OpenProcess.argtypes = [w.DWORD,w.BOOL,w.DWORD]
OpenProcess.restype = w.HANDLE

ReadProcessMemory = k32.ReadProcessMemory
ReadProcessMemory.argtypes = [w.HANDLE,w.LPCVOID,w.LPVOID,c.c_size_t,c.POINTER(c.c_size_t)]
ReadProcessMemory.restype = w.BOOL

GetLastError = k32.GetLastError
GetLastError.argtypes = None
GetLastError.restype = w.DWORD

CloseHandle = k32.CloseHandle
CloseHandle.argtypes = [w.HANDLE]
CloseHandle.restype = w.BOOL

processHandle = OpenProcess(0x10, False, pid)

addr = 0x00000000FF900000  # Minesweeper.exe module base address
data = c.c_ulonglong()
bytesRead = c.c_ulonglong()
result = ReadProcessMemory(processHandle, addr, c.byref(data), c.sizeof(data), c.byref(bytesRead))
e = GetLastError()

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

CloseHandle(processHandle)

输出:

^{pr2}$

还请注意,您可以传递数据变量的地址,而不是创建缓冲区并用struct模块将其解包。在

相关问题 更多 >

    热门问题