必须拥有带PROCESS_VM_READ权限的目标进程句柄,且需满足完整性级别匹配、SE_DEBUG_NAME特权提权、架构一致等条件;读取前应调用VirtualQueryEx验证地址是否为MEM_COMMIT且可读,否则易返回全0或失败。

Windows下用ReadProcessMemory读取目标进程内存需要哪些前提?
必须拥有目标进程的句柄,且该句柄需带有PROCESS_VM_READ访问权限。多数情况下,直接调用OpenProcess会失败——系统默认禁止跨进程内存读取,尤其对高完整性进程(如以管理员身份运行的程序)或受保护进程(如Edge、Chrome沙箱内核、杀软守护进程)。常见错误是返回NULL句柄,GetLastError()常报ERROR_ACCESS_DENIED。
- 目标进程不能处于“低完整性级别”而当前进程是中/高完整性——需匹配或更高完整性
- 若目标进程启用
SE_DEBUG_NAME特权(如被调试器附加),普通用户权限无法打开,必须先用AdjustTokenPrivileges提权 - 64位进程无法读取32位进程的某些高地址(反之亦然),需注意指针宽度和
SIZE_T类型匹配
为什么ReadProcessMemory返回成功但读到全是0?
这不是API失败,而是读取位置无效或未映射。典型原因:
- 传入的地址不是目标进程中有效的已提交内存页(比如是未分配地址、堆栈未触及区域、或已被释放的
VirtualAlloc内存) - 地址属于只读/不可访问页(如代码段有
PAGE_EXECUTE_READ属性,但ReadProcessMemory要求至少PAGE_READABLE) - 没有先调用
VirtualQueryEx验证内存状态:应检查MEM_COMMIT+PAGE_READABLE标志组合
示例判断逻辑:
MEMORY_BASIC_INFORMATION mbi = {};
if (VirtualQueryEx(hProc, (LPCVOID)addr, &mbi, sizeof(mbi)) == sizeof(mbi)
&& mbi.State == MEM_COMMIT && (mbi.Protect & PAGE_READONLY || mbi.Protect & PAGE_READWRITE))
{
// 此时才适合ReadProcessMemory
}Linux下没有ReadProcessMemory等价API,怎么办?
Linux不提供直接跨进程读内存的系统调用。主流做法是通过/proc/[pid]/mem伪文件访问,但限制极严:
立即学习“C++免费学习笔记(深入)”;
- 调用进程必须与目标进程同属一个用户,且具有
ptrace权限(通常需父进程或已attach) - 内核启用
ptrace_scope(默认为1)时,仅允许调试子进程;需临时设为0:echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope - 即使满足条件,
open("/proc/1234/mem", O_RDONLY)仍可能返回EPERM,因目标进程可能设置了PR_SET_DUMPABLE为0(如用prctl(PR_SET_DUMPABLE, 0))
实际操作链:
- 先
ptrace(PTRACE_ATTACH, pid, nullptr, nullptr)获取控制权 - 再
open("/proc/[pid]/mem", O_RDONLY) - 用
lseek定位,read读取 - 最后
ptrace(PTRACE_DETACH, pid, nullptr, nullptr)
读取结构体或字符串时容易忽略的对齐和编码问题
ReadProcessMemory只复制原始字节,不做任何解释。常见坑:
- 目标进程是x64,你用
int*读8字节字段却按sizeof(int)==4解析,导致偏移错乱 - 字符串地址指向的是UTF-16(Windows API常用)或UTF-8(Linux应用),直接当ASCII打印会乱码
- 类对象含虚表指针、vtable偏移、填充字节(padding),硬读
sizeof(MyClass)可能越界或漏字段 - 指针字段(如
char*)在目标进程有效,但在当前进程无意义——必须二次调用ReadProcessMemory读它指向的内容
真正安全的做法:只读基础类型(int32_t, uintptr_t)、确认目标进程架构与编译器ABI(如MSVC的#pragma pack设置),字符串务必先读长度字段再读内容。
没调试符号、没源码、没约定内存布局时,靠猜地址读数据本质上是脆弱的——哪怕一次成功,下次更新版本就失效。真要稳定获取数据,优先走目标进程公开的IPC机制(如共享内存、命名管道、socket),而不是硬扒内存。


















