在Python中使用静态地址和偏移量从进程读取内存地址
我试图用Python读取另一个进程的内存,我有程序的静态地址和所有偏移量。我正在使用在Python中使用静态地址和偏移量从进程读取内存地址,python,memory,process,Python,Memory,Process,我试图用Python读取另一个进程的内存,我有程序的静态地址和所有偏移量。我正在使用win32api来实现这一点。我已经可以用没有偏移量的地址读取进程内存,但我不知道如何使用偏移量 我已经在中尝试了该脚本,但它返回-1。我已将PROCESS\u ALL\u ACCESS更改为win32con.PROCESS\u VM\u READ,然后返回-1 如何在ReadProcessMemory中使用偏移量 以下是我正在使用的代码: 导入win32api 导入Win32进程 导入win32con 导入ct
win32api
来实现这一点。我已经可以用没有偏移量的地址读取进程内存,但我不知道如何使用偏移量
我已经在中尝试了该脚本,但它返回-1。我已将PROCESS\u ALL\u ACCESS
更改为win32con.PROCESS\u VM\u READ
,然后返回-1
如何在ReadProcessMemory
中使用偏移量
以下是我正在使用的代码:
导入win32api
导入Win32进程
导入win32con
导入ctypes
将ctypes.wintypes导入为wintypes
def按进程名称获取进程(进程名称):
“”“查找给定进程的进程id。”
进程名称并返回进程id。“”
process_name=process_name.lower()
#列举所有进程
processs=win32process.enumprocess()
对于进程中的进程id:
#如果进程id与此程序相同,请跳过它
如果进程id==-1:
持续
#尝试读取进程内存
尝试:
p_handle=win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ,True,PROCESS_id)
#尝试阅读流程的模块
尝试:
modules=win32process.EnumProcessModules(p_句柄)
对于模块中的模块id:
name=str(win32process.GetModuleFileNameEx(p_句柄,模块id))
if name.lower().find(进程名称)!=-1:
返回进程id
最后:
win32api.CloseHandle(p_句柄)
除:
通过
def read_process_内存(进程id、地址、偏移量、数据大小=4):
p_handle=ctypes.windl.kernel32.OpenProcess(win32con.PROCESS\u VM\u READ,False,p\u id)
数据=ctypes.c单元(数据的大小)
bytesRead=ctypes.c单元(数据的大小)
当前地址=地址
如果偏移:
#做点什么来弥补这些不足
ctypes.windell.kernel32.ReadProcessMemory(p_句柄、当前_地址、ctypes.byref(数据)、ctypes.sizeof(数据)、ctypes.byref(ByteRead))
其他:
ctypes.windell.kernel32.ReadProcessMemory(p_句柄、当前_地址、ctypes.byref(数据)、ctypes.sizeof(数据)、ctypes.byref(ByteRead))
#关闭进程的句柄
ctypes.windell.kernel32.CloseHandle(p_handle)
返回数据.value
p_id=get_process_by_name(“program.exe”)
#如果没有补偿,效果很好
地址=0x2ADB1818
val=读取进程内存(p\U id,地址,无)
打印(val)
#没有指向正确的地址
地址=0x00571160
偏移量=[0xD84、0x1B8、0x38、0x5C、0x24、0xF4、0x1D08]
对于偏移中的偏移:
地址+=偏移量
val=读取处理内存(p\U id、地址、偏移量)
打印(val)
我已经找到了我所缺少的东西。我把地址翻译错了。它们是指向地址的指针,因此,当使用偏移量时,我需要读取它们,并将它们相互添加以访问我想要读取的值。另外,我需要使用程序的基址,我只需要返回模块的值
下面是上面的脚本,其中包含读取带有偏移量的进程内存所需的更改:
import win32api
import win32process
import win32con
import ctypes
def get_process_by_name(process_name):
"""Finds the process id of the given
process name and returns the process id and its base address."""
process_name = process_name.lower()
# Enumerate all processes
processes = win32process.EnumProcesses()
for process_id in processes:
# If process_id is the same as this program, skip it
if process_id == -1:
continue
# Try to read the process memory
try:
h_process = win32api.OpenProcess(win32con.PROCESS_QUERY_INFORMATION | win32con.PROCESS_VM_READ, True, process_id)
# Try to read the modules of the process
try:
# modules is an array of base addresses of each module
modules = win32process.EnumProcessModules(h_process)
for base_address in modules:
# Get the name of the module
name = str(win32process.GetModuleFileNameEx(h_process, base_address))
# Compare it to the name of your program
if name.lower().find(process_name) != -1:
return process_id, base_address
finally:
win32api.CloseHandle(h_process)
except:
pass
def read_process_memory(process_id, address, offsets=[]):
"""Read a process' memory based on its process id, address and offsets.
Returns the address without offsets and the value."""
# The handle to the program's process
# This will allow to use ReadProcessMemory
h_process = ctypes.windll.kernel32.OpenProcess(win32con.PROCESS_VM_READ, False, p_id)
# This is a pointer to the data you want to read
# Use `data.value` to get the value at this pointer
# In this case, this value is an Integer with 4 bytes
data = ctypes.c_uint(0)
# Size of the variable, it usually is 4 bytes
bytesRead = ctypes.c_uint(0)
# Starting address
current_address = address
if offsets:
# Append a new element to the offsets array
# This will allow you to get the value at the last offset
offsets.append(None)
for offset in offsets:
# Read the memory of current address using ReadProcessMemory
ctypes.windll.kernel32.ReadProcessMemory(h_process, current_address, ctypes.byref(data), ctypes.sizeof(data), ctypes.byref(bytesRead))
# If current offset is `None`, return the value of the last offset
if not offset:
return current_address, data.value
else:
# Replace the address with the new data address
current_address = data.value + offset
else:
# Just read the single memory address
ctypes.windll.kernel32.ReadProcessMemory(h_process, current_address, ctypes.byref(data), ctypes.sizeof(data), ctypes.byref(bytesRead))
# Close the handle to the process
ctypes.windll.kernel32.CloseHandle(h_process)
# Return a pointer to the value and the value
# The pointer will be used to write to the memory
return current_address, data.value
# Open the process
p_id, base_address = get_process_by_name("program.exe")
# The static address needs the program base_address
address = base_address + 0x00571160
offsets = [0xD84, 0x1B8, 0x38, 0x5C, 0x24, 0xF4, 0x1D08]
pointer_value, value = read_process_memory(p_id, address, offsets)
print(f"(Static Address) Value: {value}")
# Re-reading the memory with the last pointer
pointer_value, value = read_process_memory(p_id, pointer_value, None)
print(f"(Dynamic Address) Value: {value}")
您可以使用
ReadWriteMemory
模块,它更简单,并且您可以获得带有偏移量的指针