如何在Windows与Linux系统下保护应用内存不被其他进程读取?
Windows 和 Linux 下保护应用动态扩展内存的可靠方案
核心前提
不存在能完全阻止所有进程读取内存的方法——系统级权限进程(如Windows内核调试器、Linux root进程)拥有最高访问权限,可突破常规保护。但以下方案能可靠阻止普通权限进程读取你的应用内存,覆盖绝大多数场景。
Windows 平台实现
- 动态内存权限切换
对于通过VirtualAlloc动态分配/扩展的内存,采用"按需授权"策略:- 分配内存时指定
PAGE_READWRITE权限完成初始写入; - 操作完成后立即调用
VirtualProtect将内存权限改为PAGE_NOACCESS; - 后续需要访问该内存时,临时改回
PAGE_READWRITE,操作完成后再次恢复PAGE_NOACCESS。
示例代码片段:
// 分配动态内存 LPVOID mem = VirtualAlloc(NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); // 写入数据... // 锁定内存,禁止读取 DWORD oldProtect; VirtualProtect(mem, 4096, PAGE_NOACCESS, &oldProtect); // 需要访问时解锁 VirtualProtect(mem, 4096, PAGE_READWRITE, &oldProtect); // 读取/修改数据... // 再次锁定 VirtualProtect(mem, 4096, PAGE_NOACCESS, &oldProtect); - 分配内存时指定
- 限制进程访问权限
修改自身进程的安全描述符,拒绝其他进程获取PROCESS_VM_READ权限。普通进程无法通过OpenProcess获取读取你进程内存的权限,管理员进程仍可突破,但能阻挡绝大多数恶意工具。
Linux 平台实现
- mmap 内存权限动态调整
对于动态扩展的内存(如mmap分配、realloc扩容的内存),同样采用权限切换策略:- 用
mmap分配内存时指定PROT_NONE(无权限),或分配后立即用mprotect改为PROT_NONE; - 需要访问时,调用
mprotect改为PROT_READ | PROT_WRITE; - 操作完成后改回
PROT_NONE。
示例代码片段:
// 分配动态内存 void* mem = mmap(NULL, 4096, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); // 解锁权限进行写入 mprotect(mem, 4096, PROT_READ | PROT_WRITE); // 写入数据... // 锁定内存 mprotect(mem, 4096, PROT_NONE); // 需要访问时再次解锁 mprotect(mem, 4096, PROT_READ | PROT_WRITE); // 读取/修改数据... // 锁定 mprotect(mem, 4096, PROT_NONE); - 用
- 禁用 ptrace 附加
调用prctl(PR_SET_DUMPABLE, 0)关闭进程的dumpable属性,非root进程无法通过ptrace附加到你的进程,也就无法读取内存。root进程仍可绕过,但能有效阻挡普通权限的内存读取工具。
额外强化建议
- 对敏感数据额外加密:即使内存权限被意外打开,加密的数据也无法直接被读取。可使用平台内置的加密API(如Windows的
CryptProtectMemory、Linux的内核加密函数)。 - 避免敏感数据长期驻留内存:使用完敏感数据后立即用随机值覆盖内存区域,减少暴露窗口。
内容的提问来源于stack exchange,提问作者Algo Lith
相关产品推荐
相关产品推荐

