内核模块有没有办法找到另一个加载模块的节地址?

Eug*_*ene 8 x86 kernel kernel-module linux-kernel

在x86系统上,我有一个Linux内核模块("观察器模块"),每次加载特定的内核模块("目标")时,它都会被内核通知.几乎任何内核模块都可以成为目标.我在我正在研究的仪器系统中使用它.

当观察者模块处理这样的通知时,如果观察者知道所加载的目标模块的ELF部分的地址,则由于某种原因可能是方便的.有关如何在内核空间中获取此信息的任何想法?

当然,我可以在/sys/module/<target_name>/sections/加载目标后立即在用户空间中获取相应文件的内容,然后以某种方式将此数据传递给观察者模块,但这太笨拙了.我想找到一种直接在内核空间中获取此信息的方法.

据我所见,在模块加载器的源代码中,它不存储段地址struct module,只是为段创建sysfs文件.也许有可能以某种方式找到与这些文件对应的内核对象并从这些对象中读取所需的数据?或者可能使用其他方法?

Eug*_*ene 5

在深入了解有关模块各部分的信息如何进入sysfs之后,我发现如果不使用内核内部的结构定义就无法检索它.在我的项目中使用这些东西不是一个选项,所以我最终实现了另一种方法,希望更可靠.

简而言之,这个想法如下.我的内核模块使用用户模式帮助程序API来启动用户空间进程(实际上是执行我的脚本的shell).该进程将"目标"内核模块的名称作为参数获取,并从sysfs(/sys/module/<target_name>/sections/)收集有关其部分的信息.从用户空间,可以容易地获得该信息.之后,它通过debugfs中的文件将收集的数据作为字符串传递给我的内核模块.模块解析字符串并验证其内容.如果一切正常,ELF部分的名称和起始地址将可用.

我承认,使用用户模式助手的技巧非常笨拙,但它完成了工作.

我已经准备了上述方法的示例实现 - 请参阅"章节"示例.

有关用户模式的辅助API的详细信息,请参阅代码<linux/kmod.c><linux/kmod.h>内核源,即定义call_usermodehelper().这些例子以及API的典型用法的说明中可这篇文章.

请注意,该文章中的示例有点不准确:模块的init函数返回call_usermodehelper()那里的结果.然而,后者返回2字节状态代码(至少在调用时UMH_WAIT_PROC)而不是0或负错误代码,init函数应该返回.这可能会导致运行时警告.什么call_usermodehelper()实际返回,说明这里.