游戏程序能否检测到外部进程调用ReadProcessMemory读取其内存?
游戏进程内存读取的检测风险与实现分析
我正在编写程序读取运行中游戏进程的内存,担心游戏在被观测时出现异常行为,想避免被检测到。请问目标进程是否能检测到外部进程读取其内存的操作?以下是我使用的实现方法:
// 以下是获取目标进程句柄的方法 HANDLE findHandle(const wchar * exeFilename) { PROCESSENTRY32 entry; entry.dwSize = sizeof(PROCESSENTRY32); HANDLE target = NULL; HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); if (Process32First(snapshot, &entry) == TRUE) { while (Process32Next(snapshot, &entry) == TRUE) { if (wcscmp(entry.szExeFile, exeFilename) == 0) { target = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID); break; } } } CloseHandle(snapshot); return target; } // dst = 存储读取到的其他进程内存的目标缓冲区 // src = 目标进程中的内存源地址 // hProcess = 待检测进程的句柄 // protectedAccess = 用于绕过某些限制,具体原理尚不明确 // 返回成功读取的内存大小 size_t patchedRead(char* dst, char* src, uint32 size, HANDLE hProcess, bool protectedAccess) { SIZE_T readTotal = 0; if (protectedAccess) { DWORD oldprotect; if(!VirtualProtectEx(hProcess, src, size, PAGE_EXECUTE_READWRITE, &oldprotect)) return 0; ReadProcessMemory(hProcess, src, dst, size, &readTotal); if(!VirtualProtectEx(hProcess, src, size, oldprotect, &oldprotect)) return 0; } else { ReadProcessMemory(hProcess, src, dst, size, &readTotal); } return size_t(readTotal); }
核心结论
目标进程完全有可能检测到外部进程的内存读取操作,你的实现方式存在多处易被捕捉的风险点:
你的实现中的检测风险
句柄获取环节
- 你使用
CreateToolhelp32Snapshot枚举进程,再调用OpenProcess请求PROCESS_ALL_ACCESS全权限句柄。这类高权限的进程句柄请求是反作弊系统的重点监控对象,部分游戏会通过内核驱动或用户态钩子拦截OpenProcess调用,标记异常的权限请求。 - 反作弊还可以枚举系统中所有指向自身进程的句柄,一旦发现未知外部进程持有句柄,就会触发检测。
- 你使用
内存读取环节
ReadProcessMemory本身就是反作弊的核心监控API,频繁调用或读取游戏敏感内存区域(如玩家数据、反作弊模块内存)会直接触发检测。- 当
protectedAccess为true时,你调用VirtualProtectEx修改目标进程内存页的保护属性,这个操作会触发目标进程的内存保护事件。高等级反作弊系统可以通过内存断点、系统调用钩子捕捉到这类修改行为,几乎100%会被标记为异常。
降低检测概率的建议
- 最小权限原则:不要请求
PROCESS_ALL_ACCESS,只申请实际需要的PROCESS_VM_READ权限,减少权限请求的敏感度。 - 避免修改内存属性:除非明确必须,否则不要调用
VirtualProtectEx修改目标进程内存保护属性,这个操作的暴露风险极高。 - 控制读取频率:减少
ReadProcessMemory的调用次数,避免短时间内大量读取内存,模拟正常程序的行为模式。 - 尝试更隐蔽的读取方式:比如通过内核驱动读取内存(需驱动签名,门槛较高),或利用Windows合法机制(如进程内存快照的间接读取,局限性较大)。
内容的提问来源于stack exchange,提问作者Anne Quinn
相关产品推荐
相关产品推荐

