0

After trying to break down code from GitHub and find any youtube videos that talk about this I'm starting to give up, so I'm hoping one of you can please help me. All I want to be able to do is monitor a games memory addresses value. For example, let's say in the game Minecraft the health value and the memory address is:

Address: 001F6498

Value: 20

How do I turn this value into a variable in Python?

Code Thought Process:

import pywin32

pid = 5601
address = 001F6498 

ReadProcessMemory(pid, address):
    print(Value)

#In this example i would like it to print 20
martineau
  • 119,623
  • 25
  • 170
  • 301
  • @martineau the link you directed me towards doesn't answer my question at all could you explain how they are the same? – lavarockman Jan 14 '19 at 06:43
  • Your question sounds like you're basically wanting to deference pointers, which Python doesn't support—although it's possible do something similar with Python object id's (which happen to memory addresses in cPython). That said, it would also be possible to write your own custom Python C extension that did it. – martineau Jan 14 '19 at 07:43
  • You could do it via *ctypes* (as *pywin32* doesn't expose that function - and possibly others that you might need). But, it would be easier to do it directly in *C*. – CristiFati Jan 15 '19 at 16:09

1 Answers1

1

You need to get a handle to the process first. Here is some code that does so using OpenProcess() FindWindow() and GetWindowThreadProcessId() to get the handle to the process. Also included is a little function to properly read the correct size variable and store it correctly. This method can be used to read pointers, utilizing "i" to denote an integer type.

import win32api
import win32gui
import win32process

from ctypes import *
from pymem import *

PROCESS_ALL_ACCESS = 0x1F0FFF
ReadProcessMemory = windll.kernel32.ReadProcessMemory

def read_memory(procId, address, type):
    buffer = (ctypes.c_byte * getlenght(type))()
    bytesRead = ctypes.c_ulonglong(0)
    readlenght = getlenght(type)
    ReadProcessMemory(procId, address, buffer, readlenght, byref(bytesRead))
    return struct.unpack(type, buffer)[0]


hWnd = win32gui.FindWindow(0, ("WINDOW NAME HERE"))

pid=win32process.GetWindowThreadProcessId(hWnd)
handle = pymem.Pymem()
handle.open_process_from_id(pid[1])
procBaseAddress = handle.process_base

hProc = windll.kernel32.OpenProcess(PROCESS_ALL_ACCESS, 0, pid[1])

value = ReadProcessMemory(hProc, ADDRESS_OF_VARIABLE_TO_READ, "i")

print(value)

Credits to a friend, puppetmaster, who taught me how to do this

GuidedHacking
  • 3,628
  • 1
  • 9
  • 59
  • You are using `windll.kernel32.ReadProcessMemory` from ctypes in this code which does not work like this. Instead use `win32process.ReadProcessMemory` and the above code will work. – Tim Woocker Aug 10 '21 at 13:20