ReadProcessMemory

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Rednib
User
Beiträge: 4
Registriert: Freitag 29. Juni 2018, 23:57

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?
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

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?
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Rednib
User
Beiträge: 4
Registriert: Freitag 29. Juni 2018, 23:57

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?
Zuletzt geändert von Rednib am Dienstag 3. Juli 2018, 15:36, insgesamt 3-mal geändert.
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Naja, dann bleibt meine zweite Frage. Und vielleicht noch woher Du weisst, dass 0x0008C900 die richtige Adresse ist.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
Rednib
User
Beiträge: 4
Registriert: Freitag 29. Juni 2018, 23:57

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.
Rednib
User
Beiträge: 4
Registriert: Freitag 29. Juni 2018, 23:57

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)
Antworten