Seite 1 von 1

ReadProcessMemory

Verfasst: Samstag 30. Juni 2018, 00:03
von Rednib
Hallo Community,

ich habe folgendes Problem, ich möchte mit Python den Speicher eines anderen Prozesses auslesen, nur leider schlägt es immer fehl.

Code: Alles auswählen

import psutil

from ctypes import *
from ctypes.wintypes import *


def listProcesses():
    for proc in psutil.process_iter():
        try:
            pinfo = proc.as_dict(attrs=['pid', 'name'])
        except psutil.NoSuchProcess:
            pass
        else:
            print(pinfo)

listProcesses()

# Get dll functions
OpenProcess = windll.kernel32.OpenProcess
ReadProcessMemory = windll.kernel32.ReadProcessMemory
CloseHandle = windll.kernel32.CloseHandle

# flags
PROCESS_ALL_ACCESS = 0x1F0FFF
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_VM_READ = 0x0010

pid = 6040   # the pid to read
address = 0x0008C900 # the address to read

bufferSize = 255 # buffer size of 255 bytes
buffer = ctypes.create_string_buffer(bufferSize) # buffer of size bufferSize


processHandle = OpenProcess(PROCESS_VM_READ, False, pid)
if processHandle:
    if ReadProcessMemory(processHandle, address, buffer, bufferSize, 0):
        print("Success:", buffer)
    else:
        print("Failed.")
else:
    print("Unable to open process")

CloseHandle(processHandle)
Leider gibt er eben immer "Failed" aus. (pid und address sind definitiv richtig)

Auslesen möchte ich einen 4 byte integer zum testen.

In C# funktioniert es, in Python irgendwie nicht.

Kann mir da jemand weiterhelfen?

Re: ReadProcessMemory

Verfasst: Samstag 30. Juni 2018, 01:27
von __blackjack__
Was bekommst Du wenn Du mit `GetLastError()` weiterforschst? Wenn Du nur 4 Bytes lesen willst, warum liest Du dann 255? Darfst Du ab der angegebenen Adresse überhaupt so viel lesen?

Re: ReadProcessMemory

Verfasst: Dienstag 3. Juli 2018, 15:19
von Rednib
Hallo __blackjack__,

ich hatte leider viel um die Ohren - also der Errorcode von GetLastError den ich bekomme ist 998 - also "Invalid access to memory location". Ich denke mal dazu brauche ich das "SeDebugPrivilege" um von diesem Speicherbereich lesen zu können. Was mich aber wundert ist, dass ich den Prozess nicht einmal öffnen könnte mit "OpenProcess" ohne diese Rechte, wenn der security descriptor dementsprechend so gesetzt ist von dem Prozess. Da OpenProcess jedoch funktioniert, bin ich da jetzt überfragt.
Kennt sich damit jemand aus und könnte mir da helfen? Evtl. ein kleiner CodeSnippet?

Re: ReadProcessMemory

Verfasst: Dienstag 3. Juli 2018, 15:25
von __blackjack__
Naja, dann bleibt meine zweite Frage. Und vielleicht noch woher Du weisst, dass 0x0008C900 die richtige Adresse ist.

Re: ReadProcessMemory

Verfasst: Dienstag 3. Juli 2018, 15:29
von Rednib
Ich habe an dieser Stelle mit einem Tool den Speicher ausgelesen und weis daher, dass es die richtige Adresse ist. Auch, dass es ein 4 Byte Wert ist.
Und habe es auf 4 Byte geändert, aber leider nach wie vor das selbe Problem.

Re: ReadProcessMemory

Verfasst: Dienstag 3. Juli 2018, 22:03
von Rednib
Ok, ich habe den Fehler gefunden - es waren die falschen c_types.

Der richtige Code wenn es wen interessiert:

Code: Alles auswählen

import psutil

import ctypes as c
from ctypes import wintypes as w


def listProcesses():
    for proc in psutil.process_iter():
        try:
            pinfo = proc.as_dict(attrs=['pid', 'name'])
        except psutil.NoSuchProcess:
            pass
        else:
            print(pinfo)

listProcesses()

k32 = c.windll.kernel32

# Get dll functions
OpenProcess = k32.OpenProcess
OpenProcess.argtypes = [w.DWORD, w.BOOL, w.DWORD]
OpenProcess.restype = w.HANDLE

ReadProcessMemory = k32.ReadProcessMemory
ReadProcessMemory.argtypes = [w.HANDLE, w.LPCVOID, w.LPVOID, c.c_size_t, c.POINTER(c.c_size_t)]
ReadProcessMemory.restype = w.BOOL

CloseHandle = k32.CloseHandle
CloseHandle.argtypes = [w.HANDLE]
CloseHandle.restype = w.BOOL

GetLastError = k32.GetLastError
GetLastError.argtypes = None
GetLastError.restype = w.DWORD

# flags
PROCESS_ALL_ACCESS = 0x1F0FFF
PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_VM_READ = 0x0010

pid = 8128   # the pid to read
address = 0x31CE6590 # the address to read (HEALTH: 0x31CE6590)

bufferSize = 4 # buffer size of 4 bytes
buffer = c.c_ulonglong(bufferSize) # buffer of size bufferSize
bytesRead = c.c_ulonglong()


processHandle = OpenProcess(PROCESS_ALL_ACCESS, False, pid)
if processHandle:
    if ReadProcessMemory(processHandle, address, c.byref(buffer), bufferSize, None):
        print('buffer: {}'.format(buffer.value))
    else:
        print("Failed.")
        print(GetLastError())
else:
    print("Unable to open process")

CloseHandle(processHandle)