You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何ReadProcessMemory读取的进程数据少于MiniDumpWriteDump?

Python进程内存读取问题:MiniDumpWriteDump 与 ReadProcessMemory 差异分析

测试程序

import time
PMMMEMPF = "KDOABC"

while True:
    print(PMMMEMPF)
    time.sleep(0.1)

注:选择PMMMEMPF和"KDOABC"是为了方便后续定位变量。

问题描述

  • 使用Process Explorer或MiniDumpWriteDump(参数为MiniDumpWithPrivateReadWriteMemory)生成进程完整转储时,能轻松找到PMMMEMPF和"KDOABC"的引用。
  • 但调用Win32 API的ReadProcessMemory(参考常规内存读取代码)时,无法读取运行中进程的PMMMEMPF变量值;用HxD打开进程主内存、Process Explorer的「属性-字符串」功能也找不到相关引用。
  • 疑惑:MiniDumpWriteDump似乎能获取比ReadProcessMemory更多的数据,但不清楚它从何处获取PMMMEMPF的引用,想知道使用ReadProcessMemory时遗漏了什么。

2025年6月10日补充信息

已通过HxD找到变量地址0x1e262366170,但该地址属于PAGE_NOACCESS属性的内存区域(索引11),询问如何访问该区域。

对应的内存区域信息如下:

  • idx : 1, Type:UNKNOWN, State: MEM_FREE, Region Size : 1592459264, BaseAddress: None, Protect : PAGE_NOACCESS
  • idx : 2, Type:MEM_IMAGE, State: MEM_COMMIT, Region Size : 4096, BaseAddress: 0x5eeb0000, Protect : PAGE_READONLY
  • idx : 3, Type:MEM_IMAGE, State: MEM_COMMIT, Region Size : 356352, BaseAddress: 0x5eeb1000, Protect : PAGE_EXECUTE_READ
  • idx : 4, Type:MEM_IMAGE, State: MEM_COMMIT, Region Size : 131072, BaseAddress: 0x5ef08000, Protect : PAGE_READONLY
  • idx : 5, Type:MEM_IMAGE, State: MEM_COMMIT, Region Size : 126976, BaseAddress: 0x5ef28000, Protect : PAGE_READWRITE
  • idx : 6, Type:MEM_IMAGE, State: MEM_COMMIT, Region Size : 24576, BaseAddress: 0x5ef47000, Protect : PAGE_READONLY
  • idx : 7, Type:UNKNOWN, State: MEM_FREE, Region Size : 554250240, BaseAddress: 0x5ef4d000, Protect : PAGE_NOACCESS
  • idx : 8, Type:MEM_PRIVATE, State: MEM_COMMIT, Region Size : 4096, BaseAddress: 0x7ffe0000, Protect : PAGE_READONLY
  • idx : 9, Type:UNKNOWN, State: MEM_FREE, Region Size : 20480, BaseAddress: 0x7ffe1000, Protect : PAGE_NOACCESS
  • idx : 10, Type:MEM_PRIVATE, State: MEM_COMMIT, Region Size : 4096, BaseAddress: 0x7ffe6000, Protect : PAGE_READONLY
  • idx : 11, Type:UNKNOWN, State: MEM_FREE, Region Size : 824078077952, BaseAddress: 0x7ffe7000, Protect : PAGE_NOACCESS
  • idx : 12, Type:UNKNOWN, State: UNKNOWN, Region Size : 0, BaseAddress: None, Protect : UNKNOWN

核心原因与解决方案

1. MiniDumpWriteDump 与 ReadProcessMemory 的本质差异

MiniDumpWriteDump在指定MiniDumpWithPrivateReadWriteMemory参数时,会捕获进程的虚拟内存快照,包括进程地址空间中所有预留但未提交的区域;而ReadProcessMemory默认只能读取当前已提交(MEM_COMMIT)且具备合法访问权限的内存页,未提交或标记为PAGE_NOACCESS的区域无法直接读取。

2. PAGE_NOACCESS 内存区域的访问方法

你找到的地址属于MEM_FREE状态的PAGE_NOACCESS区域,说明该地址当前未映射到物理内存,但Python解释器会预先预留大块虚拟地址空间作为堆内存,按需提交物理内存——MiniDump会捕获这些预留的虚拟地址空间信息,而常规ReadProcessMemory不会处理这类区域。

要访问该地址,需按以下步骤操作:

  1. 调用VirtualProtectEx函数,将目标地址所在页的权限临时修改为PAGE_READWRITE或PAGE_READONLY,并保存原权限。
  2. 调用ReadProcessMemory读取目标地址的内容。
  3. 读取完成后,再次调用VirtualProtectEx恢复原内存页权限,避免破坏进程正常运行。

注意:操作需要足够权限(如管理员身份运行),且可能影响目标进程稳定性,需谨慎执行。

3. ReadProcessMemory 的遗漏点

之前的代码大概率只遍历了MEM_COMMIT状态的内存区域,未处理**预留(MEM_RESERVE)**区域。Python全局变量通常存放在解释器堆中,而堆包含大量预留未提交的地址空间,需要通过VirtualQueryEx遍历进程所有虚拟内存区域,再针对性处理。

具体操作步骤

  1. 使用VirtualQueryEx遍历目标进程的所有虚拟内存区域,记录每个区域的基地址、大小、保护属性和状态。
  2. 定位包含目标地址0x1e262366170的区域(即使是MEM_FREE/PAGE_NOACCESS状态)。
  3. 调用VirtualProtectEx修改该区域权限为可读取,保存原权限。
  4. 调用ReadProcessMemory读取目标地址内容。
  5. 恢复原内存页权限。

内容的提问来源于stack exchange,提问作者Nono RAM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:33:14