gpt4 book ai didi

linux - 我可以写保护 Linux 进程地址空间中的每一页吗?

转载 作者:IT王子 更新时间:2023-10-29 01:20:25 25 4
gpt4 key购买 nike

我想知道是否有一种方法可以在 Linux 中对每个页面进行写保护进程的地址空间(从进程本身的内部,通过mprotect())。所谓“每一页”,我的意思是可能被普通程序写入的进程的地址空间在用户模式下运行的程序——所以,程序文本,常量,全局变量和堆——但我对常量很满意,全局变量和堆。我不想对堆栈进行写保护——那似乎是个坏主意。

一个问题是不知道从哪里开始写保护内存。查看 /proc/pid/maps,它显示了内存的各个部分在用于给定的 pid 时,它们似乎总是以地址开头0x08048000,带有程序文本。 (在 Linux 中,据我所知,进程的内存与程序文本一起布置在底部,然后是上面的常量,然后是全局变量,然后是堆,然后一个不同大小的空白空间,具体取决于堆的大小或堆栈,然后堆栈从内存顶部向下增长虚拟地址 0xffffffff。)有一种方法可以判断顶部在哪里堆是(通过调用 sbrk(0),它只是返回一个指向当前的“中断”,即堆的顶部),但不是真正的方法告诉堆从哪里开始。

如果我尝试保护所有页面免受 0x08048000 的破坏,我最终得到一个 mprotect: Cannot allocate memory 错误。我不知道为什么 mprotect 会是无论如何都要分配内存——谷歌并不是很有帮助。有什么想法吗?

顺便说一句,我想这样做的原因是因为我想创建一个在程序运行期间写入的所有页面的列表,以及我能想到的方法是写保护所有页面,让任何尝试的写入导致写入错误,然后实现写入将页面添加到列表然后删除写入的故障处理程序保护。我想我知道如何实现处理程序,如果我能的话弄清楚要保护哪些页面以及如何保护。

谢谢!

最佳答案

如果您尝试在未映射的页面上调用它,您会从 mprotect() 收到 ENOMEM

最好的办法是打开/proc/self/maps,然后使用fgets() 一次读取一行以找到进程中的所有映射.对于不是堆栈(在最后一个字段中指示)的每个可写映射(在第二个字段中指示),使用正确的基地址和长度(从开始和结束计算)调用 mprotect()第一个字段中的地址)。

请注意,此时您需要设置故障处理程序,因为读取 maps 文件本身的行为可能会导致在您的地址空间内进行写入。

关于linux - 我可以写保护 Linux 进程地址空间中的每一页吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3444052/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com