2017-07-04 74 views
1

我想讓Python從諸如0x101BFFDC這樣的地址獲取值/數據,這是我通過使用遊戲的作弊引擎找到的。我做了很多研究,並且認爲我需要使用ReadProcessMemory。但是,我嘗試了幾個例子,但沒有成功。Python - 如何獲取內存地址的值?

例如,我發現下面的代碼:

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

嘗試這樣做:https://stackoverflow.com/questi ons/8250625/access-memory-address-in-python? – sharath

+0

@sharath不適用於從另一個進程讀取內存,只能用於Python進程。 –

回答

2

這是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