2017-07-04 129 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がtrueの場合、返されるバイト文字列は要求されたバイト数より少なくなることがあります。

の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 
関連する問題