因此,您似乎无法修改内核代码,因为指向它的PTE被标记为可执行文件,而不是可写文件。我想知道是否可以使用以下方法覆盖内核代码? (这仅适用于x86,并假设我们具有root用户访问权限,因此我们将以下步骤作为内核模块运行)
在这一点上,假设一切正常,您是否能够覆盖返回地址和内核代码的其他部分?而在此之前,我们将停止使用分页机制保护?
答案 0 :(得分:1)
3。使用从CR3寄存器获得的值将所有分页数据复制到新分配的内存中
5。用指向我们在步骤2中kmalloc的内存的指针覆盖CR3寄存器
这两个步骤可能不起作用:
CR3为您提供物理地址;但是,要读取页面数据,您需要一个虚拟地址。甚至不能保证PTD当前已映射(因此可以访问)。
要覆盖CR3寄存器,您需要知道使用kmalloc
分配的内存的物理地址;但是,您只知道虚拟地址。
但是,您可以使用virt_to_phys
和phys_to_virt
将物理地址转换为虚拟地址。
是否可以覆盖内核代码...?
我不确定,但是以下尝试应该起作用:
页表本身应该是可读写的-至少是kmalloc
使用的页表。
您可以使用kmalloc
分配一些内存,而不是复制PTD和页表,该内存的大小为2页长(如果使用“传统” 4 KiB内存页,则为8 KiB)。这意味着在任何情况下,“您的”内存块都包含一个完整的内存页面。
当您拥有PTD和页表的虚拟地址时,可以重新映射“您的”内存页,这样它就不再指向“ kmalloc
”内存,而是指向您想要的内核代码修改...
在这一点上,假设这一切都可行,那么您是否能够覆盖返回地址和内核代码的其他部分?
我不确定我是否正确理解了你的问题。
但是内核模块是内核的一部分-因此,没有什么能阻止内核模块做完全愚蠢的事情(故意或由于错误)。
因此,在编程内核模块时必须非常小心。
由于“ root”具有加载内核模块的能力,因此黑客或恶意软件永远不要获得“ root”访问权限非常重要。否则,可以使用insmod
将恶意软件注入内核。