Поиск базового адреса запущенного процесса

У меня есть следующий код:

import subprocess
from ctypes import *

#-Part where I get the PID and declare all variables-#

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

processHandle = OpenProcess(PROCESS_ALL_ACCESS, False, PID)

ReadProcessMemory(processHandle, address, buffer, bufferSize, byref(bytesRead))

Все это работает безупречно, но поскольку некоторые процессы используют так называемые BaseAddress или StartAddress. И в моем случае размер этого BaseAddress время от времени является случайным. Как было предложено здесь, я попытался использовать следующий код:

BaseAddress = win32api.GetModuleHandle(None)

Все, что он делает, это дает одно и то же шестнадцатеричное значение снова и снова, хотя я точно знаю, что мой BaseAddress изменился.

Снимок экрана из связанной ветки, показывающий, что я ищу (где левая часть — это базовый адрес): CE BaseAddress


person Willy    schedule 25.12.2012    source источник
comment
Вы когда-нибудь находили ответ на свой вопрос? Сам ищу ответ.   -  person Dream Lane    schedule 13.03.2013
comment
@DreamLane Нет, до сих пор ничего не нашел. Вместо этого решил пойти с С#. Такой позор, так как я люблю python.   -  person Willy    schedule 14.03.2013
comment
Я также обсуждал переход на C++ или C#. Python отлично подходит для прототипирования....   -  person Dream Lane    schedule 14.03.2013


Ответы (2)


Мне удалось найти решение для 32-битной и 64-битной версии Python 3.5.

Для 32-битной версии я использовал psutil и pymem (как уже предлагалось по этому вопросу).:

import psutil
import pymem

my_pid = None
pids = psutil.pids()
for pid in pids:
    ps = psutil.Process(pid)
    # find process by .exe name, but note that there might be more instances of solitaire.exe
    if "solitaire.exe" in ps.name():
        my_pid = ps.pid
        print( "%s running with pid: %d" % (ps.name(), ps.pid) )

base_address = pymem.process.base_address(pid)

Для 64-битного pymem не работал. Я нашел предложения, используя win32api.GetModuleHandle(fileName), но для этого требуется win32api.LoadLibrary(fileName), который не использует уже запущенный процесс.

Поэтому я нашел это неоптимальное решение, поскольку оно возвращает целый список возможностей:

import win32process
import win32api

# first get pid, see the 32-bit solution

PROCESS_ALL_ACCESS = 0x1F0FFF
processHandle = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, my_pid)
modules = win32process.EnumProcessModules(processHandle)
processHandle.close()
base_addr = modules[0] # for me it worked to select the first item in list...
person Robin Manoli    schedule 10.03.2018
comment
Откуда берутся pid в первом фрагменте? - person Rehan; 25.07.2020

См. Как перечислить модули в python 64bit, чтобы получить хороший код для использования. . Вы ищете «modBaseAddr».

Дополнительные сведения о tagMODULEENTRY32 см. в разделе http://msdn.microsoft.com/en-us/library/windows/desktop/ms684225(v=vs.85).aspx

Вы также можете использовать pymem ("устаревший" проект, но все еще работает) со следующим кодом (вы хотите, чтобы modBaseAddr ):

  for m in self.listModules():
    if m.szModule==szModule:
      print m.szModule, m.szExePath, m.modBaseAddr
person Pierre-Francoys Brousseau    schedule 29.07.2013
comment
С pymem работает base_address = pymem.process.base_address(pid), но класс MODULEENTRY32, на который вы ссылаетесь, не работает - он возвращает другой modeBaseAddr каждый раз, когда вы его запускаете, и это неправильно. - person Robin Manoli; 10.03.2018