代码之家  ›  专栏  ›  技术社区  ›  Edward Kmett

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

  •  17
  • Edward Kmett  · 技术社区  · 17 年前

    /proc/self/maps 反复地弄清楚你是否能读、写或执行存储在内存中一个或多个地址上的内容?

    例如,在Windows中,您有 VirtualQuery .

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

    此外,是否有任何方法可以知道这些权限何时更改(例如,当有人使用 mmap 在我背后的一个文件中)而不是做一些非常有侵略性的事情和使用 ptrace 在进程中的所有线程上,并拦截进行 syscall

    更新:

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

    现在我要做的就是阅读 /proc/self/maps 并建立一个结构,我可以通过二进制搜索给定地址的保护。任何时候我需要了解一个不在我的结构中的页面,我都会重新阅读/proc/self/maps,假设它是在这段时间添加的,否则我就要出错了。

    似乎解析文本以获取这些信息而不知道它何时更改是非常粗糙的。( /dev/inotify 在任何领域都不起作用 /proc

    2 回复  |  直到 16 年前
        1
  •  6
  •   Pierre    17 年前

    我不知道一个相当于 VirtualQuery 在Linux上。但其他一些可能有效也可能无效的方法有:

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

    • 你每次打电话都可以追踪 mprotect 并构建相应的数据结构,帮助您了解某个区域是读保护还是写保护。如果您可以访问所有使用 .

    • 您可以监视所有 保护 通过将代码与重新定义函数的库链接,在进程中调用 保护 保护 为了真正设置保护。

    • 你可以尝试使用 /dev/inotify 并监视该文件 /proc/self/maps 任何改变。我想这一个不起作用,但应该值得一试。

        2
  •  0
  •   clam    11 年前

    https://lkml.org/lkml/2015/7/14/477 所以它不是完全无害的。。。