Linux kernel 如何在PPCLinux上运行时钩住syscall表?

Linux kernel 如何在PPCLinux上运行时钩住syscall表?,linux-kernel,kernel-module,system-calls,powerpc,hook,Linux Kernel,Kernel Module,System Calls,Powerpc,Hook,主题:PPC汇编语言-Linux可加载内核模块 详细信息:在syscall表钩子中从内核调用时如何访问本地TOC区域(r2) 我已经为Linux编写了一个可加载的内核模块,它使用syscall表挂钩拦截系统调用,并在将调用传递给原始处理程序之前记录有关系统调用的信息。这是安全产品的一部分。我的模块运行良好,并且在生产代码中运行在各种Linux内核版本和发行版上,32位和64位内核都在x86硬件上运行 我试图将此代码移植到Linux for PPC处理器上运行,但遇到了一些问题。使用Linux内核

主题:PPC汇编语言-Linux可加载内核模块

详细信息:在syscall表钩子中从内核调用时如何访问本地TOC区域(r2)

我已经为Linux编写了一个可加载的内核模块,它使用syscall表挂钩拦截系统调用,并在将调用传递给原始处理程序之前记录有关系统调用的信息。这是安全产品的一部分。我的模块运行良好,并且在生产代码中运行在各种Linux内核版本和发行版上,32位和64位内核都在x86硬件上运行

我试图将此代码移植到Linux for PPC处理器上运行,但遇到了一些问题。使用Linux内核源代码,可以很容易地看到系统调用表在PPC上是如何以不同的方式实现的。我可以用自己编译的处理程序中的函数地址替换表中的条目,没有问题

但是,这是我遇到的问题。PPC ABI使用一个名为目录(TOC)的地址,该地址存储在CPU的R2寄存器中,并期望通过使用该寄存器中包含的地址(TOC地址)的偏移量来寻址模块的全局和本地数据。这在进行函数调用的正常情况下很好,因为编译器知道在进行调用之前将模块的TOC地址加载到寄存器中(或者它已经存在,因为通常您的函数由自己的代码调用)

但是,当我将自己函数的地址(从运行时加载的内核模块)放入系统调用表时,内核使用R2值调用我的处理程序,R2值不是我编译的C代码所期望的值,因此我的代码在无法访问其数据的情况下获得控制权

有人知道有任何示例代码显示如何处理这种情况吗?我无法重新编译内核。这应该是运行时系统调用表挂钩的一个简单例子,但我还没有弄清楚,或者找到任何特定于PPC的示例

创意包括:

手工编写汇编语言存根,保存R2值,用本地TOC地址加载寄存器,执行代码,然后在调用原始处理程序之前恢复旧值。我没有足够的PPC组装经验来完成这项工作,我也不确定它是否能工作

一些神奇的gcc选项,可以在不使用TOC的情况下生成我的代码。有一个记录在案的gcc选项
“-mno-toc”
,在我的PPC6 Linux上不起作用。看起来它可能只是SystemV.4和嵌入式PowerPC的一个选项

非常感谢您的帮助


谢谢

您需要一个存根来加载
r2
。内核源代码中有一些示例。

Linux有一个通用的系统调用审计基础结构,它在powerpc上工作,您可以从用户空间访问。您是否考虑过使用它而不是编写内核模块?

恐怕我没有关于解决方案的建议,但您知道内核开发人员总是很难修改syscall表?这不是他们想要用内部API支持的东西。