1

Update 1:

I've tried the solution given below using buffer.value.decode(). This resulted in getting back just (#, which is a step in the right direction, but I want to get this to 9000. When I use Cheat Engine to change the address value to 2000, this same method runs into the error UnicodeDecodeError: 'utf-8' can't decode byte 0xd0 in position 0: invalid continuation byte. So I'm guessing I have the wrong encoding. Any suggestion on what I should do with that?

Original Question:

I'm trying to use ReadProcessMemory from ctypes to get the value from an address in a process. I seem to acquiring the byte data without a problem, but I'm running into difficult converting it into the appropriate form. I'm using Cheat Engine to inspect the data via a third party method, and using it to change the data in the address I'm sure I have the correct address output from my script. The value I'm expecting to have returned is 9000. The complete code I'm using is below, but I'm reading the memory into a buffer of the type c_char_p (from ctypes). I've tried a couple ways of converting the value to a string and printing it. using just str(buffer), as expected I get back the byte representation as c_char_p(b'(#'). When I try to convert the data using str(int.from_bytes(buffer, sys.byteorder)) I get back 43586512. I have seen elsewhere the ability to convert from bytes using buffer.decode() but it appears this is not for the ctypes version as c_char_p has no decode method (which might suggest I should be taking a different approach to get the process address value other than ctypes?). Can anyone point out what I need to do to correctly get the value of this address in the form I'm looking for? Thank you much!

Code:

from ctypes import *
from ctypes.wintypes import *

OpenProcess = windll.kernel32.OpenProcess
ReadProcessMemory = windll.kernel32.ReadProcessMemory
CloseHandle = windll.kernel32.CloseHandle

PROCESS_ALL_ACCESS = 0x1F0FFF #I'll try to do minimum permissions later.

pid = 3112 #Don't worry about this, I know it's right.
address = 0x2411918 #This too.

buffer = c_char_p(b"The data goes here") #Maybe I should be using something else?
bufferSize = len(buffer.value)
bytesRead = c_ulong(0)

processHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
if ReadProcessMemory(processHandle, address, buffer, bufferSize, byref(bytesRead)):
    print("Success:" + str(int.from_bytes(buffer, "little"))) #Here's the problem print line.
else:
    print("Failed.")

CloseHandle(processHandle)
4

2 回答 2

2

It turns out my problem had to do with the ctypes representation. If I use memmove to move to move the c_char_p to a c_int, then I end up with the correct results printing out. This can be seen done in the completed code below.

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 = 3112
address = 0x2411918

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)
于 2013-10-30T21:22:33.130 回答
0

c_char_p(b"test").value.decode()

于 2013-10-30T14:25:04.777 回答