【发布时间】:2015-09-21 17:07:40
【问题描述】:
我正在尝试查找进程process.exe 中使用的render.dll 的基地址。我修改了代码in this question,可以得到render.dll基地址的结果。
from ctypes import *
from ctypes.wintypes import *
import psutil
class MODULEENTRY32(Structure):
_fields_ = [( 'dwSize', DWORD),
( 'th32ModuleID', DWORD),
( 'th32ProcessID', DWORD),
( 'GlblcntUsage', DWORD),
( 'ProccntUsage', DWORD),
( 'modBaseAddr', POINTER(BYTE)),
( 'modBaseSize', DWORD),
( 'hModule', HMODULE),
( 'szModule', c_char * 256),
( 'szExePath', c_char * 260)]
CreateToolhelp32Snapshot = windll.kernel32.CreateToolhelp32Snapshot
Module32First = windll.kernel32.Module32First
Module32Next = windll.kernel32.Module32Next
CloseHandle = windll.kernel32.CloseHandle
TH32CS_SNAPMODULE = 0x00000008
TH32CS_SNAPMODULE32 = 0x00000010
def getpid(processname):
for proc in psutil.process_iter():
if str(processname) in str(proc.name):
return proc.pid
def GetModuleByName(name):
snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE32 | TH32CS_SNAPMODULE, getpid('process.exe'))
entry = MODULEENTRY32()
entry.dwSize = sizeof(MODULEENTRY32)
if Module32First(snapshot, pointer(entry)):
while Module32Next(snapshot, entry):
if entry.szModule == name:
CloseHandle(snapshot)
return entry.modBaseAddr
CloseHandle(snapshot)
return None
baseAddr = GetModuleByName('render.dll')
print baseAddr
结果为@987654327@。我知道这与结果是 POINTER(BYTE) 类型有关,但我不确定如何从这种类型获取正常的十六进制内存地址,我可以使用它来读取该位置的进程内存。
【问题讨论】:
-
id(object)将返回一个对象的内存地址......不知道为什么你想要它作为十六进制,因为我确定任何期望一个整数...... -
我试图找到
render.dll的内存地址,而不是LP_c_byte对象。我正在寻找的内存地址应该包含在 LP_c_byte 对象中,我只是不确定如何从该对象中检索它。我希望将十六进制值与 Process Hacker 2 中显示的render.dll的十六进制值进行比较,但是在十六进制和整数之间进行转换很容易,所以对我来说两者都很好。 -
你可以用
byref(entry)代替pointer(entry);即您不需要分配实际的 ctypes 指针对象;只需传递地址。Module32Next调用有错误;缺少byref或pointer来传递entry的地址。 -
仅传递
entry是按值传递结构,但您可以在Module32Next文档中清楚地看到它需要一个指针。这恰好在 x64 ABI 中起作用,因为大型结构是通过引用隐式传递的。但在 32 位 x86 中,该结构被复制到调用堆栈,因此 Windows 将dwSize字段解释为指针参数,这是访问冲突。 -
您还跳过了第一个模块,它应该是进程映像(例如“process.exe”)。匹配名称也应该不区分大小写。
标签: python ctypes memory-address