Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux kernel 内核模块是否有办法找到另一个加载模块的节地址?_Linux Kernel_X86_Kernel_Kernel Module - Fatal编程技术网

Linux kernel 内核模块是否有办法找到另一个加载模块的节地址?

Linux kernel 内核模块是否有办法找到另一个加载模块的节地址?,linux-kernel,x86,kernel,kernel-module,Linux Kernel,X86,Kernel,Kernel Module,在x86系统上,我有一个Linux内核模块(“观察者模块”),每次加载特定的内核模块(“目标”)时,它都会收到内核的通知。几乎任何内核模块都可以成为目标。我在工作中使用这个 当观察者模块处理这样的通知时,出于某种原因,如果观察者知道加载的目标模块的ELF部分的地址,这可能会很方便。你知道如何在内核空间中获得这些信息吗 当然,我可能会在加载目标后立即在用户空间中的/sys/module//sections/中获取相应文件的内容,然后以某种方式将这些数据传递给watcher模块,但这太笨拙了。我想找

在x86系统上,我有一个Linux内核模块(“观察者模块”),每次加载特定的内核模块(“目标”)时,它都会收到内核的通知。几乎任何内核模块都可以成为目标。我在工作中使用这个

当观察者模块处理这样的通知时,出于某种原因,如果观察者知道加载的目标模块的ELF部分的地址,这可能会很方便。你知道如何在内核空间中获得这些信息吗

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


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

文件linux/kernel/module.c有一些非静态函数(但前面没有这个EXPORT\u符号),比如module\u address\u lookup(),但是这些函数使用preempt\u disable()和_enable()。我不想使用这个函数,并且建议使用sysfs接口,尽管您的驱动程序已经处于内核模式。

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

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

我承认,用户模式助手的技巧相当笨拙,但它完成了任务

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

有关用户模式帮助器API的详细信息,请参阅内核源代码中的
中的代码,即
调用\u usermodehelper()
的定义。API的典型用法的示例和解释可在中找到


请注意,中的示例有点不准确:模块的init函数返回那里的
call\u usermodehelper()
的结果。但是,后者返回2字节的状态代码(至少在使用
UMH_WAIT_PROC
调用时),而不是init函数预期返回的0或负错误代码。这可能会导致运行时警告。
call\u usermodehelper()
实际返回的内容已解释清楚。

谢谢您的回答。是的,我知道
模块\u地址\u查找()
等等。它们在kallsyms系统中用于符号查找等。但是我需要一个不同的东西,模块部分的地址(.text、.devinit.text、.exit.text等),而不是符号。我可以获得模块的“init”和“core”区域的地址,但每个区域都可能包含多个ELF节。从加载程序的源代码来看,在发出加载通知时,有关刚加载模块的节的信息仅在sysfs中可用。如果我没有弄错的话,sysfs中的每个文件都由一个内核对象支持。如果您知道我的模块如何找到与
/sys/module/
中的文件相对应的对象,那就太好了。除非您修改kernel/module.c以导出符号或函数,否则我无法从内核中获取此信息。你可以尝试发送一个带有合理信息的补丁,为什么你希望这样。是的,模块相关的东西本身不允许这样。我可能已经找到了一个解决方案,但它不是很可靠<代码>结构模块包含一个与sysfs中所需目录对应的kobject。有用于遍历此类目录的导出函数。当您访问一个节的dentry时,可以调用所提到的kobject的
show()
“method”,以获取所需属性的内容,并将其作为字符串,然后使用类似strtoul的函数进行解析。这可能会起作用,但它需要来自内部头文件fs/sysfs/sysfs.h的定义。(续)我更愿意远离该内部API。可能我可以通过
call\u usermodehelper
之类的东西逃脱惩罚,以这种方式生成一个用户空间进程,让它获取数据并将其传递回内核。用户模式助手API相当稳定,已经用于内核中的许多任务。我可能会研究这种方法。似乎
struct module
mkobj.kobj
字段)中包含的kobject参与了sysfs中模块的表示。等我有时间的时候,我会更深入地研究这个问题。可以使用该kobject作为起点来获取包含节的名称和地址的属性。