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

时间:2008-11-06 16:26:09

标签: c linux system-calls mprotect virtualquery

在Linux(或Solaris)上有一种比手动解析/proc/self/maps更好的方法来判断你是否可以读取,写入或执行存储在内存中一个或多个地址的任何内容吗?

例如,在Windows中,您有VirtualQuery

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

此外,有没有办法知道这些权限何时发生变化(例如,当有人在我背后的文件上使用mmap时),而不是做一些非常具有侵略性的事情,并且在所有线程上使用ptrace处理和拦截任何可能影响内存映射的syscall的尝试?

更新

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

现在我所做的是阅读/proc/self/maps并构建一个我可以二进制搜索的结构,以获得给定地址的保护。每当我需要了解一些不在我的结构中的页面时,我会重新阅读/ proc / self / maps,假设它已经在此期间添加,或者我将要进行段错误。

似乎解析文本以获取此信息并且不知道何时更改是非常苛刻的。 (/dev/inotify/proc}

中的任何内容都不起作用

2 个答案:

答案 0 :(得分:6)

我不知道Linux上的等效VirtualQuery。但其他一些可能或可能不起作用的方法是:

  • 你设置了一个信号处理程序捕获SIGBUS / SIGSEGV并继续你的读或写。如果内存受到保护,将调用您的信号捕获代码。如果不是,则不会调用您的信号捕获代码。无论哪种方式,你都会赢。

  • 您可以在每次调用mprotect时跟踪并构建相应的数据结构,以帮助您了解区域是读还是写保护。如果您可以访问使用mprotect

  • 的所有代码,这是很好的
  • 您可以通过将代码与重新定义函数mprotect的库相关联来监控流程中的所有mprotect次调用。然后,您可以构建必要的数据结构,以了解区域是读还是写保护,然后调用系统mprotect以实际设置保护。

  • 您可以尝试使用/dev/inotify并监控文件/proc/self/maps以进行任何更改。我想这个不行,但应该值得一试。

答案 1 :(得分:0)

sorta是/是/ proc / [pid | self] / pagemap,内核中的文档,请注意: https://lkml.org/lkml/2015/7/14/477 所以它并非完全无害......