18

在 Linux(或 Solaris)上,有没有比/proc/self/maps反复手动解析更好的方法来确定您是否可以读取、写入或执行存储在内存中一个或多个地址的任何内容?

例如,在 Windows 中,您有VirtualQuery.

在 Linux 中,我可以mprotect更改这些值,但我无法将它们读回。

此外,除了做一些非常侵入性的事情并在进程中的所有线程上使用并拦截任何可能影响内存的尝试之外,还有什么方法可以知道这些权限何时更改(例如,当有人mmap在我背后使用文件时)地图?ptracesyscall

更新:

不幸的是,我在 JIT 内部使用了它,它几乎没有关于它正在执行的代码的信息来获得常量的近似值。是的,我意识到我可以拥有可变数据的常量映射,例如 Linux 使用的 vsyscall 页面。我可以放心地假设初始解析中未包含的任何内容都是可变且危险的,但我对该选项并不完全满意。

现在我要做的是阅读/proc/self/maps并构建一个结构,我可以通过二进制搜索来获得给定地址的保护。任何时候我需要了解一个不在我的结构中的页面,我会重新阅读 /proc/self/maps 假设它已经被同时添加,否则我将要进行段错误。

似乎解析文本以获取此信息并且不知道它何时更改是非常笨拙的。(/dev/inotify几乎对任何东西都不起作用/proc

4

2 回答 2

6

我不知道VirtualQueryLinux 上的等价物。但是其他一些可能有效也可能无效的方法是:

  • 您设置了一个捕获 SIGBUS/SIGSEGV 的信号处理程序并继续您的读取或写入。如果内存受到保护,您的信号捕获代码将被调用。如果不是,则不会调用您的信号捕获代码。不管怎样,你赢了。

  • 您可以跟踪每次调用mprotect并构建相应的数据结构,以帮助您了解区域是否受到读或写保护。如果您可以访问所有使用mprotect.

  • 您可以通过将代码与重新定义函数的库链接来监控mprotect进程中的所有调用mprotect。然后,您可以构建必要的数据结构来了解某个区域是读保护还是写保护,然后调用系统mprotect来真正设置保护。

  • 您可以尝试使用/dev/inotify和监视文件/proc/self/maps是否有任何更改。我想这个不起作用,但应该值得一试。

于 2008-11-06T17:40:45.307 回答
0

有点是/是/proc/[pid|self]/pagemap,内核中的文档,这里有警告: https ://lkml.org/lkml/2015/7/14/477 所以它不是完全无害的.. .

于 2015-08-17T00:18:59.900 回答