我正在尝试让Python从诸如0x101BFFDC之类的地址获取值/数据,我通过使用作弊引擎来找到游戏。我做了很多研究,并认为我需要使用ReadProcessMemory
。但是,我尝试了几个例子没有成功。
例如,我找到了以下代码:
from ctypes import *
from ctypes.wintypes import *
import struct
OpenProcess = windll.kernel32.OpenProcess
ReadProcessMemory = windll.kernel32.ReadProcessMemory
CloseHandle = windll.kernel32.CloseHandle
PROCESS_ALL_ACCESS = 0x1F0FFF
pid = 10684 # pid of the game
address = 0x101BFFDC # I put the address here
buffer = c_char_p(b"The data goes here")
val = c_int()
bufferSize = len(buffer.value)
bytesRead = c_ulong(0)
processHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
if ReadProcessMemory(processHandle, address, buffer, bufferSize, byref(bytesRead)):
memmove(ctypes.byref(val), buffer, ctypes.sizeof(val))
print("Success:" + str(val.value))
else:
print("Failed.")
CloseHandle(processHandle)
我希望它能给我56值,这就是我从作弊引擎中获得的值。但是,它只是打印“失败”。每一次。
我如何才能获得正确的价值?
答案 0 :(得分:3)
这是WinAPI ReadProcessMemory
的ctypes包装器。它需要读取进程ID,基址和大小(以字节为单位)。它返回从目标进程读取的字节字符串。
如果allow_partial
为false,则整个地址范围必须是可读的,否则会因Windows错误代码ERROR_PARTIAL_COPY
而失败。如果allow_partial
为真,则返回的字节字符串可能少于请求的字节数。
ctypes定义
import ctypes
from ctypes import wintypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
ERROR_PARTIAL_COPY = 0x012B
PROCESS_VM_READ = 0x0010
SIZE_T = ctypes.c_size_t
PSIZE_T = ctypes.POINTER(SIZE_T)
def _check_zero(result, func, args):
if not result:
raise ctypes.WinError(ctypes.get_last_error())
return args
kernel32.OpenProcess.errcheck = _check_zero
kernel32.OpenProcess.restype = wintypes.HANDLE
kernel32.OpenProcess.argtypes = (
wintypes.DWORD, # _In_ dwDesiredAccess
wintypes.BOOL, # _In_ bInheritHandle
wintypes.DWORD) # _In_ dwProcessId
kernel32.ReadProcessMemory.errcheck = _check_zero
kernel32.ReadProcessMemory.argtypes = (
wintypes.HANDLE, # _In_ hProcess
wintypes.LPCVOID, # _In_ lpBaseAddress
wintypes.LPVOID, # _Out_ lpBuffer
SIZE_T, # _In_ nSize
PSIZE_T) # _Out_ lpNumberOfBytesRead
kernel32.CloseHandle.argtypes = (wintypes.HANDLE,)
<强>功能强>
def read_process_memory(pid, address, size, allow_partial=False):
buf = (ctypes.c_char * size)()
nread = SIZE_T()
hProcess = kernel32.OpenProcess(PROCESS_VM_READ, False, pid)
try:
kernel32.ReadProcessMemory(hProcess, address, buf, size,
ctypes.byref(nread))
except WindowsError as e:
if not allow_partial or e.winerror != ERROR_PARTIAL_COPY:
raise
finally:
kernel32.CloseHandle(hProcess)
return buf[:nread.value]
示例强>
if __name__ == '__main__':
import os
buf = ctypes.create_string_buffer(b'eggs and spam')
pid = os.getpid()
address = ctypes.addressof(buf)
size = len(buf.value)
value = read_process_memory(pid, address, size)
assert value == buf.value