чтение данных из памяти процесса с помощью Python - PullRequest
0 голосов
/ 26 сентября 2018

Я пытаюсь прочитать данные из памяти процесса, введя имя процесса, а затем найдя PID с помощью psutil.Пока у меня есть это:

import ctypes
from ctypes import *
from ctypes.wintypes import *
import win32ui
import psutil # install, not a default module
import sys

# input process name
nameprocess = "notepad.exe"

# find pid
def getpid():
    for proc in psutil.process_iter():
        if proc.name() == nameprocess:
            return proc.pid

PROCESS_ID = getpid()

if PROCESS_ID == None:
    print "Process was not found"
    sys.exit(1)


# read from addresses
STRLEN = 255

PROCESS_VM_READ = 0x0010
process = windll.kernel32.OpenProcess(PROCESS_VM_READ, 0, PROCESS_ID)
readProcMem = windll.kernel32.ReadProcessMemory
buf = ctypes.create_string_buffer(STRLEN)

for i in range(1,100): 
    if readProcMem(process, hex(i), buf, STRLEN, 0):
        print buf.raw


Последний цикл for должен читать и распечатывать содержимое первых 100 адресов в процессе, если я правильно понял.Единственное, выход выглядит как полный бред.


Здесь у меня есть 2 проблемы: во-первых, действительно ли я так читаю адреса из выбранного процесса?И во-вторых, как я могу определить, как долго я должен идти в цикле, если есть какой-то конечный адрес?

1 Ответ

0 голосов
/ 29 сентября 2018

Я не установил psutil, а просто извлек идентификатор процесса и действительный виртуальный адрес с помощью диспетчера задач и SysInternals VMMap .Числа, конечно, будут различаться.

Хорошей практикой с ctypes является определение типов аргументов и возвращаемого значения через .argtypes и .restype.Получите свой собственный экземпляр библиотеки kernel32, поскольку изменение атрибутов кэшированного экземпляра windll.kernel32 может вызвать проблемы с другими модулями, использующими ctypes и kernel32.

Вам необходим действительный виртуальный адрес.В ответ на вашу вторую проблему, я думаю, VMMap доказывает, что есть способ сделать это.Возьмите копию Windows Internals, чтобы изучить методы.

from ctypes import *
from ctypes.wintypes import *

PROCESS_ID = 9476 # From TaskManager for Notepad.exe
PROCESS_HEADER_ADDR = 0x7ff7b81e0000 # From SysInternals VMMap utility

# read from addresses
STRLEN = 255

PROCESS_VM_READ = 0x0010

k32 = WinDLL('kernel32')
k32.OpenProcess.argtypes = DWORD,BOOL,DWORD
k32.OpenProcess.restype = HANDLE
k32.ReadProcessMemory.argtypes = HANDLE,LPVOID,LPVOID,c_size_t,POINTER(c_size_t)
k32.ReadProcessMemory.restype = BOOL

process = k32.OpenProcess(PROCESS_VM_READ, 0, PROCESS_ID)
buf = create_string_buffer(STRLEN)
s = c_size_t()
if k32.ReadProcessMemory(process, PROCESS_HEADER_ADDR, buf, STRLEN, byref(s)):
    print(s.value,buf.raw)

Вывод (Примечание: «MZ» означает начало заголовка программы):

255 b'MZ\x90\x00\x03\x00\x00\x00\x04\x00\x00\x00\xff\xff\x00\x00\xb8\x00\x00\x00\x00\x00\x00\x00@\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xe8\x00\x00\x00\x0e\x1f\xba\x0e\x00\xb4\t\xcd!\xb8\x01L\xcd!This program cannot be run in DOS mode.\r\r\n$\x00\x00\x00\x00\x00\x00\x00\xd0\x92\xa7\xd1\x94\xf3\xc9\x82\x94\xf3\xc9\x82\x94\xf3\xc9\x82\x9d\x8bZ\x82\x8a\xf3\xc9\x82\xfb\x97\xca\x83\x97\xf3\xc9\x82\xfb\x97\xcd\x83\x83\xf3\xc9\x82\xfb\x97\xcc\x83\x91\xf3\xc9\x82\xfb\x97\xc8\x83\x8f\xf3\xc9\x82\x94\xf3\xc8\x82\x82\xf2\xc9\x82\xfb\x97\xc1\x83\x8d\xf3\xc9\x82\xfb\x976\x82\x95\xf3\xc9\x82\xfb\x97\xcb\x83\x95\xf3\xc9\x82Rich\x94\xf3\xc9\x82\x00\x00\x00\x00\x00\x00\x00\x00PE\x00\x00d\x86\x06\x00^\'\x0f\x84\x00\x00\x00\x00\x00\x00\x00\x00\xf0\x00"'

Вот снимок экрана VMMap с указанием адреса заголовка notepad.exe:

VMMap Screenshot

Вот снимок экрана шестнадцатеричной записи содержимого файла notepad.exe, который соответствует выводу программы:

hedump of the notepad.exe binary file

...