Linux kernel Linux内核模块-访问内存映射
我在内核模块加载方面遇到了一些奇怪的问题,我怀疑这与链接和加载有关。如何在将每个节加载到内存后(从模块本身内部)以编程方式计算出它们的地址。比如where is.bss/.data/.text等等 通过阅读本文Linux kernel Linux内核模块-访问内存映射,linux-kernel,android-kernel,Linux Kernel,Android Kernel,我在内核模块加载方面遇到了一些奇怪的问题,我怀疑这与链接和加载有关。如何在将每个节加载到内存后(从模块本身内部)以编程方式计算出它们的地址。比如where is.bss/.data/.text等等 通过阅读本文 我要找的是直接的地址。您可以从用户空间(需要根权限)中看到这样的地址开头部分: 这个属性是一组属性结构 1296 struct module_sect_attrs { 1297 struct attribute_group grp; 1298 unsig
我要找的是直接的地址。您可以从用户空间(需要根权限)中看到这样的地址开头部分: 这个属性是一组属性结构
1296 struct module_sect_attrs {
1297 struct attribute_group grp;
1298 unsigned int nsections;
1299 struct module_sect_attr attrs[0];
1300 };
你要找的是什么门派属性
1290 struct module_sect_attr {
1291 struct module_attribute mattr;
1292 char *name;
1293 unsigned long address;
您可以从userspace(需要根权限)中看到类似以下内容的地址开头部分: 这个属性是一组属性结构
1296 struct module_sect_attrs {
1297 struct attribute_group grp;
1298 unsigned int nsections;
1299 struct module_sect_attr attrs[0];
1300 };
你要找的是什么门派属性
1290 struct module_sect_attr {
1291 struct module_attribute mattr;
1292 char *name;
1293 unsigned long address;
从模块的代码
中,此\u模块
宏实际上是指向结构模块
对象的指针。它的module_init
和module_core
字段指向内存区域,所有模块部分都在这些区域中加载
据我所知,从模块代码中无法访问节划分(struct load_info
在模块加载到内存中后被删除)。但有了模块的文件,您可以在加载后轻松推断节的地址:
module_init:
- init sections with code (.init.text)
- init sections with readonly data
- init sections with writable data
module_core:
- sections with code (.text)
- sections with readonly data
- sections with writable data
如果多个部分适合一个类别,则它们将按照与模块文件相同的顺序放置
在模块的代码中,您还可以打印任何its符号的地址,并在计算包含此符号的节的开头之后。从模块的代码
中,此模块宏实际上是指向结构模块对象的指针。它的module_init
和module_core
字段指向内存区域,所有模块部分都在这些区域中加载
据我所知,从模块代码中无法访问节划分(struct load_info
在模块加载到内存中后被删除)。但有了模块的文件,您可以在加载后轻松推断节的地址:
module_init:
- init sections with code (.init.text)
- init sections with readonly data
- init sections with writable data
module_core:
- sections with code (.text)
- sections with readonly data
- sections with writable data
如果多个部分适合一个类别,则它们将按照与模块文件相同的顺序放置
在模块的代码中,您还可以打印任何its符号的地址,并在计算完包含此符号的部分开头后。这个问题已经问了五年了,我想我会贡献我的两分钱。受Alex Hoppus回答的启发,我能够以一种黑客的方式访问内核的部分。我不提倡这样做,除非您编写内核模块来调试或理解内核等
无论如何,我将以下两个结构复制到我的模块中,以帮助解决不完整的类型
struct module_sect_attr {
struct module_attribute mattr;
char *name;
unsigned long address;
};
struct module_sect_attrs {
struct attribute_group grp;
unsigned int nsections;
struct module_sect_attr attrs[0];
};
然后,在我的模块初始化函数中,我执行以下操作以获取节地址
unsigned long text = 0;
unsigned int nsections = 0;
unsigned int i;
struct module_sect_attr* sect_attr;
nsections = THIS_MODULE->sect_attrs->nsections;
sect_attr = THIS_MODULE->sect_attrs->attrs;
for (i = 0; i < nsections; i++) {
if (strcmp((sect_attr + i)->name, ".text") == 0)
text = (sect_attr + i)->address;
}
无符号长文本=0;
无符号整数n分段=0;
无符号整数i;
结构模块\u sect\u attr*sect\u attr;
n分区=此模块->分区属性->n分区;
sect\u attr=此\u模块->sect\u attrs->attrs;
对于(i=0;i名称,“.text”)==0)
text=(sect_attr+i)->地址;
}
最后,需要注意的是,如果要查找.rodata
、.bss
或.data
的地址,则需要分别定义常量全局变量、未初始化全局变量或常规全局变量,如果你不想省略这些部分的话。这个问题已经问了五年了,我想我会贡献我的两分钱。受Alex Hoppus回答的启发,我能够以一种黑客的方式访问内核的部分。我不提倡这样做,除非您编写内核模块来调试或理解内核等
无论如何,我将以下两个结构复制到我的模块中,以帮助解决不完整的类型
struct module_sect_attr {
struct module_attribute mattr;
char *name;
unsigned long address;
};
struct module_sect_attrs {
struct attribute_group grp;
unsigned int nsections;
struct module_sect_attr attrs[0];
};
然后,在我的模块初始化函数中,我执行以下操作以获取节地址
unsigned long text = 0;
unsigned int nsections = 0;
unsigned int i;
struct module_sect_attr* sect_attr;
nsections = THIS_MODULE->sect_attrs->nsections;
sect_attr = THIS_MODULE->sect_attrs->attrs;
for (i = 0; i < nsections; i++) {
if (strcmp((sect_attr + i)->name, ".text") == 0)
text = (sect_attr + i)->address;
}
无符号长文本=0;
无符号整数n分段=0;
无符号整数i;
结构模块\u sect\u attr*sect\u attr;
n分区=此模块->分区属性->n分区;
sect\u attr=此\u模块->sect\u attrs->attrs;
对于(i=0;i名称,“.text”)==0)
text=(sect_attr+i)->地址;
}
最后,需要注意的是,如果要查找.rodata
、.bss
或.data
的地址,则需要分别定义常量全局变量、未初始化全局变量或常规全局变量,如果您不想省略这些部分。我确实查看了/sys/module//sections/。对于我正在使用的内核,它没有填充节信息,我不知道为什么。如何从module init内部获取struct module或struct load_info的句柄?实际上,正如我看到的,这个函数部分是静态的,所以我认为这不是合适的方法。我需要看看它是如何在sysfs中完成的。对于我正在使用的内核,它没有填充节信息,我不知道为什么。如何从module init内部获取struct module或struct load_info的句柄?实际上,正如我看到的,这个函数部分是静态的,所以我认为这不是合适的方法。我需要看看它是如何在sysfs中完成的。我的问题是我认为加载程序有点不稳定。我的bss节的起始位置应该是none零,如果我写入它,我的模块将崩溃。所以我试图验证加载程序将bss放置在何处,以及变量实际结束在何处[THIS_MODULE->MODULE_core;THIS_MODULE->MODULE_core+THIS_MODULE->core_ro_size)区域:这个区域被模块的加载器标记为只读。实际上,我想我们可以浏览sysfs源代码来查看它是如何完成的……我的意思是部分解决了打印问题。我的问题是,我认为加载器有问题。从哪里开始