readProcessMemory函数报错“Attempted to read or write protected memory”求助
我太懂这个报错的糟心了——之前调试内存读取工具时也踩过一模一样的坑,咱们从最常见的原因一步步排查:
先把进程权限拉满再说
调用OpenProcess时,权限参数千万别吝啬!只传PROCESS_VM_READ经常不够,至少要加上PROCESS_QUERY_INFORMATION,复杂场景还要补PROCESS_VM_OPERATION。举个靠谱的调用示例:HANDLE hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, targetProcessId);如果返回的句柄是
NULL,立刻用GetLastError()查原因,大概率是权限不足——试试以管理员身份启动你的读取程序,尤其是读系统进程或带保护的游戏时。确认目标地址绝对有效
你以为的“正确地址”可能根本不对!比如测试程序里的整数变量,别凭感觉写地址,要么在调试器里看变量的实际虚拟地址,要么在测试程序里直接输出&testVar的值,再把这个值硬编码到读取程序里测试。另外必须保证读取程序和目标进程位数一致——32位程序读64位进程内存,地址会被截断,直接触发保护错误。检查目标内存页的访问属性
就算地址是对的,那个内存页可能被标记为不可读(比如PAGE_NOACCESS)。用VirtualQueryEx查一下内存属性,确认是允许读取的类型:MEMORY_BASIC_INFORMATION mbi; if (VirtualQueryEx(hProcess, (LPCVOID)targetAddr, &mbi, sizeof(mbi))) { // 只允许读取PAGE_READONLY/PAGE_READWRITE/PAGE_WRITECOPY类型的内存页 if (!(mbi.Protect & (PAGE_READONLY | PAGE_READWRITE | PAGE_WRITECOPY))) { // 这个内存页读不了,换个变量地址测试 } }别在缓冲区上犯低级错误
传递给ReadProcessMemory的缓冲区大小必须和目标数据的字节数完全匹配——读int就传sizeof(int),读字符串就传对应长度。另外一定要传有效的bytesRead指针,读完后检查实际读取的字节数是否符合预期:int result; SIZE_T bytesRead; BOOL success = ReadProcessMemory(hProcess, (LPCVOID)targetAddr, &result, sizeof(int), &bytesRead); if (success && bytesRead == sizeof(int)) { // 读取成功 }排查自己程序的内存损坏
报错里的“other memory is corrupt”不一定指目标进程,可能是你自己的程序出问题了!比如缓冲区指针是野指针、栈溢出导致参数被篡改,都会触发保护机制。先调试自己的程序,检查hProcess、lpBaseAddress、lpBuffer这些核心参数是不是都有效。
最后给你一个极简测试流程:
- 写个测试程序:定义全局变量
int testVar = 456;,加个while(1) Sleep(1000);让程序一直跑。 - 在测试程序里输出
&testVar的地址,记下来。 - 读取程序里用这个地址做目标,按上面的正确权限调用
OpenProcess和ReadProcessMemory。
如果这样还报错,再检查系统DEP/ASLR设置——不过自己写的测试程序默认ASLR是关闭的,只要内存页权限没问题,应该能跑通。
内容的提问来源于stack exchange,提问作者Kyle Wilson

