【问题标题】:Is there a better way than parsing /proc/self/maps to figure out memory protection?有没有比解析 /proc/self/maps 更好的方法来找出内存保护?
【发布时间】:2010-09-21 02:58:29
【问题描述】:

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

例如,在 Windows 中,您有 VirtualQuery。

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

此外,有没有办法知道这些权限何时更改(例如,当有人在我背后的文件上使用 mmap 时)除了做一些非常侵入性的事情并在进程中的所有线程上使用 ptrace 并拦截任何尝试创建可能影响内存映射的syscall?

更新:

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

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

似乎解析文本以获取此信息并且不知道它何时更改是非常笨拙的。 (/dev/inotify 在/proc 中几乎没有任何作用)

【问题讨论】:

    标签: c linux system-calls mprotect virtualquery


    【解决方案1】:

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

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

    • 您可以跟踪每次调用mprotect 并构建相应的数据结构,以帮助您了解某个区域是读保护还是写保护。如果您可以访问所有使用 mprotect 的代码,那就太好了。

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

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

    【讨论】:

    • 当我得到一个 SIGSEGV 时为时已晚。我需要知道某些数据是否恒定,才能知道我可以“安全地”不断地折叠它。对常量 mmap'ed 非常量数据和 vsyscall 页面进行适当的 hack。
    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 2011-01-24
      • 2011-07-20
      • 2013-04-06
      • 2010-11-26
      • 2013-02-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-06
      相关资源
      最近更新 更多