Python3 从 PID 获取进程基地址
Python3 get process base-address from PID
我正在尝试获取 Windows(64 位)进程的基址,使用 Python3,假设知道 PID。
我查看了堆栈上的所有问题,但解决方案 old/not 有效。
我假设在名为 pid 的变量中包含进程的 PID。
我尝试过的众多代码之一是
PROCESS_ALL_ACCESS = 0x1F0FFF
processHandle = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
modules = win32process.EnumProcessModules(processHandle)
fileName = win32process.GetModuleFileNameEx(processHandle, modules[0])
base_address = win32api.GetModuleHandle(fileName)
processHandle.close()
但是我在 GetModuleHandle 上遇到错误:'Impossible to find the specified module'。
感谢您的帮助。
根据[MS.Docs]: GetModuleHandleW function(重点是我的):
Retrieves a module handle for the specified module. The module must have been loaded by the calling process.
这意味着它对当前进程可以正常工作,但对于任何其他进程你会得到 未定义的行为,因为你尝试检索:
- 来自其他进程的.dll(或.exe)名称(GetModuleFileNameEx呼叫)
- 名称在上一步(GetModuleHandle 调用)的句柄但在当前进程中(如果加载),这使得没有意义
虽然没有关于这个主题的明确文档(或者至少我找不到任何文档),句柄 是 的基础地址。这是你也依赖的一个原则(调用GetModuleHandle),但是你可以直接使用EnumProcessModules返回的值(看下面的例子, 值相同)。
如果要严谨,可以用[MS.Docs]: GetModuleInformation function. Unfortunately, that's not exported by PyWin32, and an alternative is using [Python 3.Docs]: ctypes - A foreign function library for Python。
code00.py:
#!/usr/bin/env python3
import sys
import win32api as wapi
import win32process as wproc
import win32con as wcon
import ctypes as ct
from ctypes import wintypes as wt
import traceback as tb
class MODULEINFO(ct.Structure):
_fields_ = [
("lpBaseOfDll", ct.c_void_p),
("SizeOfImage", wt.DWORD),
("EntryPoint", ct.c_void_p),
]
get_module_information_func_name = "GetModuleInformation"
GetModuleInformation = getattr(ct.WinDLL("kernel32"), get_module_information_func_name, getattr(ct.WinDLL("psapi"), get_module_information_func_name))
GetModuleInformation.argtypes = [wt.HANDLE, wt.HMODULE, ct.POINTER(MODULEINFO)]
GetModuleInformation.restype = wt.BOOL
def get_base_address_original(process_handle, module_handle):
module_file_name = wproc.GetModuleFileNameEx(process_handle, module_handle)
print(" File for module {0:d}: {1:s}".format(module_handle, module_file_name))
module_base_address = wapi.GetModuleHandle(module_file_name)
return module_base_address
def get_base_address_new(process_handle, module_handle):
module_info = MODULEINFO()
res = GetModuleInformation(process_handle.handle, module_handle, ct.byref(module_info))
print(" Result: {0:}, Base: {1:d}, Size: {2:d}".format(res, module_info.lpBaseOfDll, module_info.SizeOfImage))
if not res:
print(" {0:s} failed: {1:d}".format(get_module_information_func_name, getattr(ct.WinDLL("kernel32"), "GetLastError")()))
return module_info.lpBaseOfDll
def main(*argv):
pid = int(argv[0]) if argv and argv[0].isdecimal() else wapi.GetCurrentProcessId()
print("Working on pid {0:d}".format(pid))
process_handle = wapi.OpenProcess(wcon.PROCESS_ALL_ACCESS, False, pid)
print("Process handle: {0:d}".format(process_handle.handle))
module_handles = wproc.EnumProcessModules(process_handle)
print("Loaded modules: {0:}".format(module_handles))
module_index = 0 # 0 - the executable itself
module_handle = module_handles[module_index]
get_base_address_funcs = [
#get_base_address_original, # Original behavior moved in a function
get_base_address_new,
]
for get_base_address in get_base_address_funcs:
print("\nAttempting {0:s}".format(get_base_address.__name__))
try:
module_base_address = get_base_address(process_handle, module_handle)
print(" Base address: 0x{0:016X} ({1:d})".format(module_base_address, module_base_address))
except:
tb.print_exc()
process_handle.close()
#input("\nPress ENTER to exit> ")
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main(*sys.argv[1:])
print("\nDone.")
输出:
e:\Work\Dev\Whosebug\q059610466>"e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32
Working on pid 59608
Process handle: 452
Loaded modules: (140696816713728, 140714582343680, 140714572513280, 140714535354368, 140714547544064, 140713592946688, 140714443341824, 140714557898752, 140714556325888, 140714550362112, 140714414964736, 140714562486272, 140714532798464, 140714555473920, 140714548592640, 140714533322752, 140714531946496, 140714553769984, 140714555670528, 140714558750720, 140714581426176, 140714556129280, 140714546036736, 140714518052864, 140714532601856, 140714524737536, 140714210361344, 1797128192, 140714574151680, 140714535026688, 140714557046784, 140714538172416, 140714531291136, 140714530963456, 140714530766848, 140714530832384, 1796931584, 140714561044480, 140714573299712, 140714215014400, 140714529849344, 1798438912, 140714559995904, 140714167042048)
Attempting get_base_address_new
Result: 1, Base: 140696816713728, Size: 110592
Base address: 0x00007FF687C80000 (140696816713728)
Done.
e:\Work\Dev\Whosebug\q059610466>:: Attempting to run with Task Manager pid
e:\Work\Dev\Whosebug\q059610466>"e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py 22784
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32
Working on pid 22784
Process handle: 480
Loaded modules: (140699900903424, 140714582343680, 140714572513280, 140714535354368, 140714547544064, 140714573299712, 140714531946496, 140714550362112, 140714562486272, 140714532798464, 140714530963456, 140714530766848, 140714556981248, 140714557898752, 140714556325888, 140714555473920, 140714365222912, 140714548592640, 140714496753664, 140714533322752, 140714553769984, 140714574151680, 140714535026688, 140714557046784, 140714538172416, 140714581426176, 140714558750720, 140714531291136, 140714530832384, 140714546036736, 140714444521472, 140714567467008, 140714532601856, 140714468966400, 140714452385792, 140714267115520, 140714510843904, 140714478731264, 140713698263040, 140714510254080, 140714556129280, 140714565435392, 140714110091264, 140714491379712, 140714455007232, 140714514382848, 140714459529216, 140714281140224, 140714370859008, 140714471260160, 140714566746112, 140713839362048, 140714555670528, 140714171695104, 140714508615680, 140714514841600, 140714029154304, 140714036625408, 140714329636864, 140714447011840, 140714434691072, 140714470866944, 140714561044480, 140714520870912, 140714469883904, 140714494787584, 140714293592064, 140713999335424, 140714400743424, 140714497605632, 140714502193152, 140714197254144, 140714415030272, 140714035576832, 140714065854464, 140714513006592, 140714529652736, 140714512809984, 140714495049728, 140714038657024, 140714371448832, 140714421911552, 140714325966848, 140714196074496, 140714057924608, 140714058317824, 140714064281600, 140714058121216, 140714519756800, 140714327539712, 140714311614464, 140714501079040, 140714546167808, 140714531422208, 140714531553280, 140714557767680, 140714518052864, 140714524737536, 140714167631872, 140714528669696, 140714331865088, 140714310369280, 140714310238208, 140714520018944, 140714458939392, 2018133999616, 140714401988608, 2018141863936, 140714514644992, 140714454810624, 140714294640640)
Attempting get_base_address_new
Result: 1, Base: 140699900903424, Size: 1105920
Base address: 0x00007FF73F9D0000 (140699900903424)
Done.
更新#0
根据[MS.Docs]: MODULEINFO structure(备注部分,强调仍然是我的):
The load address of a module is the same as the HMODULE value.
所以,事情似乎很简单。
code01.py:
#!/usr/bin/env python3
import sys
import win32api as wapi
import win32process as wproc
import win32con as wcon
def main(*argv):
pid = int(argv[0]) if argv and argv[0].isdecimal() else wapi.GetCurrentProcessId()
print("Working on pid {0:d}".format(pid))
process_handle = wapi.OpenProcess(wcon.PROCESS_ALL_ACCESS, False, pid)
print(" Process handle: {0:d}".format(process_handle.handle))
module_handles = wproc.EnumProcessModules(process_handle)
module_handles_count = len(module_handles)
print(" Loaded modules count: {0:d}".format(module_handles_count))
module_index = 0 # 0 - the executable itself
if module_index > module_handles_count:
module_index = 0
module_handle = module_handles[module_index]
module_file_name = wproc.GetModuleFileNameEx(process_handle, module_handle)
print(" File [{0:s}] (index {1:d}) is loaded at address 0x{2:016X} ({3:d})".format(module_file_name, module_index, module_handle, module_handle))
process_handle.close()
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main(*sys.argv[1:])
print("\nDone.")
输出:
e:\Work\Dev\Whosebug\q059610466>"e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code01.py
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32
Working on pid 7184
Process handle: 456
Loaded modules count: 43
File [e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe] (index 0) is loaded at address 0x00007FF687C80000 (140696816713728)
Done.
e:\Work\Dev\Whosebug\q059610466>:: Attempting to run with Task Manager pid
e:\Work\Dev\Whosebug\q059610466>"e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code01.py 22784
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32
Working on pid 22784
Process handle: 624
Loaded modules count: 111
File [C:\WINDOWS\system32\taskmgr.exe] (index 0) is loaded at address 0x00007FF73F9D0000 (140699900903424)
Done.
我正在尝试获取 Windows(64 位)进程的基址,使用 Python3,假设知道 PID。 我查看了堆栈上的所有问题,但解决方案 old/not 有效。
我假设在名为 pid 的变量中包含进程的 PID。
我尝试过的众多代码之一是
PROCESS_ALL_ACCESS = 0x1F0FFF
processHandle = win32api.OpenProcess(PROCESS_ALL_ACCESS, False, pid)
modules = win32process.EnumProcessModules(processHandle)
fileName = win32process.GetModuleFileNameEx(processHandle, modules[0])
base_address = win32api.GetModuleHandle(fileName)
processHandle.close()
但是我在 GetModuleHandle 上遇到错误:'Impossible to find the specified module'。
感谢您的帮助。
根据[MS.Docs]: GetModuleHandleW function(重点是我的):
Retrieves a module handle for the specified module. The module must have been loaded by the calling process.
这意味着它对当前进程可以正常工作,但对于任何其他进程你会得到 未定义的行为,因为你尝试检索:
- 来自其他进程的.dll(或.exe)名称(GetModuleFileNameEx呼叫)
- 名称在上一步(GetModuleHandle 调用)的句柄但在当前进程中(如果加载),这使得没有意义
虽然没有关于这个主题的明确文档(或者至少我找不到任何文档),句柄 是 的基础地址。这是你也依赖的一个原则(调用GetModuleHandle),但是你可以直接使用EnumProcessModules返回的值(看下面的例子, 值相同)。
如果要严谨,可以用[MS.Docs]: GetModuleInformation function. Unfortunately, that's not exported by PyWin32, and an alternative is using [Python 3.Docs]: ctypes - A foreign function library for Python。
code00.py:
#!/usr/bin/env python3
import sys
import win32api as wapi
import win32process as wproc
import win32con as wcon
import ctypes as ct
from ctypes import wintypes as wt
import traceback as tb
class MODULEINFO(ct.Structure):
_fields_ = [
("lpBaseOfDll", ct.c_void_p),
("SizeOfImage", wt.DWORD),
("EntryPoint", ct.c_void_p),
]
get_module_information_func_name = "GetModuleInformation"
GetModuleInformation = getattr(ct.WinDLL("kernel32"), get_module_information_func_name, getattr(ct.WinDLL("psapi"), get_module_information_func_name))
GetModuleInformation.argtypes = [wt.HANDLE, wt.HMODULE, ct.POINTER(MODULEINFO)]
GetModuleInformation.restype = wt.BOOL
def get_base_address_original(process_handle, module_handle):
module_file_name = wproc.GetModuleFileNameEx(process_handle, module_handle)
print(" File for module {0:d}: {1:s}".format(module_handle, module_file_name))
module_base_address = wapi.GetModuleHandle(module_file_name)
return module_base_address
def get_base_address_new(process_handle, module_handle):
module_info = MODULEINFO()
res = GetModuleInformation(process_handle.handle, module_handle, ct.byref(module_info))
print(" Result: {0:}, Base: {1:d}, Size: {2:d}".format(res, module_info.lpBaseOfDll, module_info.SizeOfImage))
if not res:
print(" {0:s} failed: {1:d}".format(get_module_information_func_name, getattr(ct.WinDLL("kernel32"), "GetLastError")()))
return module_info.lpBaseOfDll
def main(*argv):
pid = int(argv[0]) if argv and argv[0].isdecimal() else wapi.GetCurrentProcessId()
print("Working on pid {0:d}".format(pid))
process_handle = wapi.OpenProcess(wcon.PROCESS_ALL_ACCESS, False, pid)
print("Process handle: {0:d}".format(process_handle.handle))
module_handles = wproc.EnumProcessModules(process_handle)
print("Loaded modules: {0:}".format(module_handles))
module_index = 0 # 0 - the executable itself
module_handle = module_handles[module_index]
get_base_address_funcs = [
#get_base_address_original, # Original behavior moved in a function
get_base_address_new,
]
for get_base_address in get_base_address_funcs:
print("\nAttempting {0:s}".format(get_base_address.__name__))
try:
module_base_address = get_base_address(process_handle, module_handle)
print(" Base address: 0x{0:016X} ({1:d})".format(module_base_address, module_base_address))
except:
tb.print_exc()
process_handle.close()
#input("\nPress ENTER to exit> ")
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main(*sys.argv[1:])
print("\nDone.")
输出:
e:\Work\Dev\Whosebug\q059610466>"e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Working on pid 59608 Process handle: 452 Loaded modules: (140696816713728, 140714582343680, 140714572513280, 140714535354368, 140714547544064, 140713592946688, 140714443341824, 140714557898752, 140714556325888, 140714550362112, 140714414964736, 140714562486272, 140714532798464, 140714555473920, 140714548592640, 140714533322752, 140714531946496, 140714553769984, 140714555670528, 140714558750720, 140714581426176, 140714556129280, 140714546036736, 140714518052864, 140714532601856, 140714524737536, 140714210361344, 1797128192, 140714574151680, 140714535026688, 140714557046784, 140714538172416, 140714531291136, 140714530963456, 140714530766848, 140714530832384, 1796931584, 140714561044480, 140714573299712, 140714215014400, 140714529849344, 1798438912, 140714559995904, 140714167042048) Attempting get_base_address_new Result: 1, Base: 140696816713728, Size: 110592 Base address: 0x00007FF687C80000 (140696816713728) Done. e:\Work\Dev\Whosebug\q059610466>:: Attempting to run with Task Manager pid e:\Work\Dev\Whosebug\q059610466>"e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code00.py 22784 Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Working on pid 22784 Process handle: 480 Loaded modules: (140699900903424, 140714582343680, 140714572513280, 140714535354368, 140714547544064, 140714573299712, 140714531946496, 140714550362112, 140714562486272, 140714532798464, 140714530963456, 140714530766848, 140714556981248, 140714557898752, 140714556325888, 140714555473920, 140714365222912, 140714548592640, 140714496753664, 140714533322752, 140714553769984, 140714574151680, 140714535026688, 140714557046784, 140714538172416, 140714581426176, 140714558750720, 140714531291136, 140714530832384, 140714546036736, 140714444521472, 140714567467008, 140714532601856, 140714468966400, 140714452385792, 140714267115520, 140714510843904, 140714478731264, 140713698263040, 140714510254080, 140714556129280, 140714565435392, 140714110091264, 140714491379712, 140714455007232, 140714514382848, 140714459529216, 140714281140224, 140714370859008, 140714471260160, 140714566746112, 140713839362048, 140714555670528, 140714171695104, 140714508615680, 140714514841600, 140714029154304, 140714036625408, 140714329636864, 140714447011840, 140714434691072, 140714470866944, 140714561044480, 140714520870912, 140714469883904, 140714494787584, 140714293592064, 140713999335424, 140714400743424, 140714497605632, 140714502193152, 140714197254144, 140714415030272, 140714035576832, 140714065854464, 140714513006592, 140714529652736, 140714512809984, 140714495049728, 140714038657024, 140714371448832, 140714421911552, 140714325966848, 140714196074496, 140714057924608, 140714058317824, 140714064281600, 140714058121216, 140714519756800, 140714327539712, 140714311614464, 140714501079040, 140714546167808, 140714531422208, 140714531553280, 140714557767680, 140714518052864, 140714524737536, 140714167631872, 140714528669696, 140714331865088, 140714310369280, 140714310238208, 140714520018944, 140714458939392, 2018133999616, 140714401988608, 2018141863936, 140714514644992, 140714454810624, 140714294640640) Attempting get_base_address_new Result: 1, Base: 140699900903424, Size: 1105920 Base address: 0x00007FF73F9D0000 (140699900903424) Done.
更新#0
根据[MS.Docs]: MODULEINFO structure(备注部分,强调仍然是我的):
The load address of a module is the same as the HMODULE value.
所以,事情似乎很简单。
code01.py:
#!/usr/bin/env python3
import sys
import win32api as wapi
import win32process as wproc
import win32con as wcon
def main(*argv):
pid = int(argv[0]) if argv and argv[0].isdecimal() else wapi.GetCurrentProcessId()
print("Working on pid {0:d}".format(pid))
process_handle = wapi.OpenProcess(wcon.PROCESS_ALL_ACCESS, False, pid)
print(" Process handle: {0:d}".format(process_handle.handle))
module_handles = wproc.EnumProcessModules(process_handle)
module_handles_count = len(module_handles)
print(" Loaded modules count: {0:d}".format(module_handles_count))
module_index = 0 # 0 - the executable itself
if module_index > module_handles_count:
module_index = 0
module_handle = module_handles[module_index]
module_file_name = wproc.GetModuleFileNameEx(process_handle, module_handle)
print(" File [{0:s}] (index {1:d}) is loaded at address 0x{2:016X} ({3:d})".format(module_file_name, module_index, module_handle, module_handle))
process_handle.close()
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}\n".format(" ".join(item.strip() for item in sys.version.split("\n")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main(*sys.argv[1:])
print("\nDone.")
输出:
e:\Work\Dev\Whosebug\q059610466>"e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code01.py Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Working on pid 7184 Process handle: 456 Loaded modules count: 43 File [e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe] (index 0) is loaded at address 0x00007FF687C80000 (140696816713728) Done. e:\Work\Dev\Whosebug\q059610466>:: Attempting to run with Task Manager pid e:\Work\Dev\Whosebug\q059610466>"e:\Work\Dev\VEnvs\py_pc064_03.07.06_test0\Scripts\python.exe" code01.py 22784 Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32 Working on pid 22784 Process handle: 624 Loaded modules count: 111 File [C:\WINDOWS\system32\taskmgr.exe] (index 0) is loaded at address 0x00007FF73F9D0000 (140699900903424) Done.