如何调用Linux内核没有导出的函数

来源:互联网 发布:windows下多线程 编辑:程序博客网 时间:2024/06/16 06:45

Linux内核没有导出的函数不能调用,即使包含了头文件,也会出现符号未定义的警告,并在加载模块时失败。
以下是我的测试例子:

#include <linux/module.h>#include <linux/syscalls.h>MODULE_LICENSE("GPL");MODULE_AUTHOR("Linmiaohe");MODULE_DESCRIPTION("try to evole sys_umount");extern asmlinkage long sys_umount(char __user *name, int flags);static int __init sys_umount_init(void){    sys_umount("./proc",0);    return 0;}static void __exit sys_umount_exit(void){    printk(KERN_INFO "***********sys_umount module has been unregistered*************\n");}module_init(sys_umount_init);module_exit(sys_umount_exit);

编译并加载该模块:
这里写图片描述
可以看到,即使包含了对应的头文件syscalls.h,编译的时候也会报符号未定义的错误,然后insmod的时候因为找不到对应的符号而失败。
接下来是实现调用未导出符号sys_umount的方式:
首先在/proc/kallsyms中查看sys_umount的地址:
这里写图片描述
可以看到,sys_umount的虚拟地址为c0222f60,然后测试例子修改如下:

#include <linux/module.h>#include <linux/syscalls.h>MODULE_LICENSE("GPL");MODULE_AUTHOR("Linmiaohe");MODULE_DESCRIPTION("try to evole sys_umount");//extern asmlinkage long sys_umount(char __user *name, int flags);/*这里定义一个sys_umount类型的函数指针*/typedef typeof(sys_umount) *my_sys_umount;static int __init sys_umount_init(void){    my_sys_umount um;    //sys_umount("./proc",0);    /*      注:使用kallsyms_lookup_name()函数可以找到对应符号在内核中的虚拟地址:      是在kernel/kallsyms.c文件中定义的,要使用它必须启用CONFIG_KALLSYMS编译内核。      包含在头文件linux/kallsyms.h中.      kallsyms_lookup_name()接受一个字符串格式内核函数名,返回那个内核函数的地址。    um = (my_sys_umount)__symbol_get("sys_umount");    如果是导出符号,则可以直接通过函数__symbol_get或kallsyms_lookup_name获得符号地址*/    um = (my_sys_umount)0xc0222f60;/*直接把前面得到的地址转换为函数地址*/    um("./proc",0);/*执行*/    return 0;}static void __exit sys_umount_exit(void){    printk(KERN_INFO "***********sys_umount module has been unregistered*************\n");}module_init(sys_umount_init);module_exit(sys_umount_exit);

编译并加载模块,结果如下:
这里写图片描述
从图中可以知道,已经编译成功并且insmod成功了,并且没有警告。

0 0
原创粉丝点击