【问题标题】:Where are page permissions stored on hardware and how can I alter them directly?页面权限存储在硬件上的什么位置,如何直接更改它们?
【发布时间】:2019-08-07 00:59:03
【问题描述】:

我正在尝试编写一个伪内核驱动程序(它使用 CVE 2018-8120 来获得内核权限,因此从技术上讲它不是驱动程序)并且我希望在进入 ring0 时尽可能安全。我正在编写一个函数来从用户区读取和写入 MSR,在转换到 ring0 之前,我试图保证可以写入给我的函数的 void 指针,我决定这样做的理想方法是让它如果还没有,则可写。

问题是我知道如何做到这一点的唯一方法是使用VirtualProtect()NtAllocateVirtualMemory,但VirtualProtect() 有时会失败并返回错误。我想知道这些访问权限的确切存储位置(在 ram 中?在某些特殊的 CPU 寄存器中?)如何获取它们的地址以及如何直接修改它们?

【问题讨论】:

  • 您不能直接修改它们,也不应该这样做。如果VirtualProtect() 失败,它这样做是有原因的,你无法绕过它。您正在尝试解决 XY 问题的 Y 部分。正确的解决方案是处理 X,即首先解决您做错的任何事情,而不是试图解决您正在创建的问题。
  • @KenWhite 这是不真实的,否则操作系统将无法做到这一点。
  • 嗯,没有。操作系统可以为所欲为。它负责。它也可以控制其他代码可以做什么。
  • @KenWhite 这就是我刚才所说的......我认为你没有理解我的评论。

标签: windows memory x86-64 paging


【解决方案1】:

用户模式代码不应该尝试在内核数据结构中乱七八糟,任何正确编写的内核都会阻止它。用户模式代码确保可以写入地址的最佳方法是写入它。如果页面不是已经可写的,页面错误将导致内核使其如此。

尽管如此,内核代码 /cannot/ 依赖于已经这样做的应用程序,原因有两个:
1) 即使应用程序正确执行,页面也可能在进入 ring 0 之前(或之后)再次取消映射。
2)内核应该/从不/依赖应用程序代码来做正确的事情。它总是要保护自己。

【讨论】:

  • 你似乎错过了这个问题。第一段是背景信息,我的问题仍然没有人回答,但有一个客观的答案是,存储页面的访问信息在哪里。我不能接受这个答案,因为它没有回答这个问题。幸运的是,我已经找到了一个恰好包含该信息的页面,正如我对自己问题的回答中所引用的那样。
【解决方案2】:

访问权限信息和页面数据存储在页面目录、页表、CR0和CR3中。

更多信息可以在这里找到:https://wiki.osdev.org/Paging

【讨论】:

  • 是的,这是正确的。但是,如果您开始弄乱内核数据,您最好保留文件系统的备份。您可能会破坏内存,这种方式不仅会崩溃,还会破坏磁盘上的数据,从而导致 FS 损坏。 (例如,如果一个页面是只读的,因为它是与另一个进程共享的写时复制,请更改页表以允许您编写它,而不是让页面错误处理程序在让您的进程写入之前制作物理页面的副本副本。或者更糟糕的是,将非零数据写入系统范围的共享零页面,用于 BSS/匿名页面的 COW 映射)
  • 指定x86-64的问题,此答案仅涵盖32位分页。
  • 另请注意,CR3 是页面目录的物理地址,但即使在内核代码分页中启用,所以您实际可以使用的地址是虚拟的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 2014-01-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多