有没有比解析/proc/self/maps更好的方法来确定内存保护?

18
在Linux(或Solaris)中,除了反复手动解析`/proc/self/maps`以确定你是否可以读取、写入或执行存储在一个或多个内存地址中的任何内容之外,还有更好的方法吗?例如,在Windows中,您可以使用`VirtualQuery`。在Linux中,我可以使用`mprotect`来更改这些值,但我不能读取它们。此外,是否有任何方法可以知道这些权限何时更改(例如,当某人在后台使用`mmap`映射文件时),而不是进行可怕的侵入式操作并在进程中拦截所有线程上的`syscall`以影响内存映射?
更新:不幸的是,我正在使用JIT,它对其执行的代码几乎没有任何信息,以获取有关常量的近似值。是的,我知道我可以具有可变数据的常量映射,例如Linux使用的vsyscall页面。我可以安全地假设初始解析未包含的所有东西都是可变且危险的,但我对该选项并不完全满意。现在我所做的就是读取 `/proc/self/maps` 并构建一个二进制搜索结构,以查找给定地址的保护。每次我需要了解我的结构中没有的页面信息时,我会重新读取 /proc/self/maps,假设它已被添加到其中或者我即将遇到段错误。似乎仅通过解析文本来获取此信息并不知道何时更改非常麻烦。(`/dev/inotify` 在`/proc`中几乎不起作用)
2个回答

6
我不知道Linux上是否有VirtualQuery的等效物。但是有其他一些方法可以尝试,也许会起作用,也可能不会:
  • 设置信号处理程序以捕获SIGBUS/SIGSEGV并继续进行读取或写入操作。如果内存受到保护,将调用您的信号处理代码。否则,不会调用您的信号处理代码。无论哪种方式,都能解决问题。

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

  • 通过链接您的代码与重新定义函数mprotect的库来监视进程中的所有mprotect调用。然后,您可以构建必要的数据结构以了解区域是否受到读取或写入保护,然后调用系统mprotect以实际设置保护。

  • 您可以尝试使用/dev/inotify并监视文件/proc/self/maps的任何更改。我猜这个方法不起作用,但应该值得一试。


1
当我收到SIGSEGV时,已经太晚了。我需要知道某些数据是否是常量,以便知道我可以“安全地”将其折叠为常量。对于常量mmap的非常量数据和vsyscall页面,需要适当的黑客技巧。 - Edward Kmett

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接