c - 从 sysfs 恢复或删除 Linux 内核模块

标签 c linux linux-kernel kernel kernel-module

我最近编写了一个能够隐藏自身的 LKM。当我隐藏模块时一切正常,但当我恢复它并在 lsmod 中查看它时,Used By 的值列突然是-2

Module                  Size  Used by
my_module                13324  -2 
vboxsf                   43798  1 
dm_crypt                 23177  0 
nfsd                    284396  2 
auth_rpcgss              59309  1 nfsd
nfs_acl                  12837  1 nfsd
nfs                     240815  0

当我删除它时,我收到错误消息 rmmod: ERROR: Module my_module is builtin.我知道这是 kobject 的引用计数与模块关联,并且模块只有在0 时才能被移除.我几乎可以肯定它会发生,因为当我隐藏模块时,我删除了它在 /sys/modules 中的所有文件。 .(holdersparameterssectionssrcversion 等)。有人可以帮助我进行删除操作或恢复文件吗?(我在 dmesg 中没有收到任何错误)

这是代码:
`
void module_hide(void) {
    if(module_hidden) //is hidden
            return;
    module_prev = THIS_MODULE->list.prev;
    kobject_prev = &THIS_MODULE->mkobj.kobj;
    kobject_parent_prev = THIS_MODULE->mkobj.kobj.parent;

    sect_attrs_bkp = THIS_MODULE->sect_attrs;
    notes_attrs_bkp = THIS_MODULE->notes_attrs;

    list_del(&THIS_MODULE->list);             //remove from procfs
    //kobject_del(THIS_MODULE->holders_dir);
    kobject_del(&THIS_MODULE->mkobj.kobj);    //remove from sysfs

    THIS_MODULE->sect_attrs = NULL;
    THIS_MODULE->notes_attrs = NULL;
    module_hidden = (unsigned int)0x1;
}
void module_show(void) {
    int result, result2;
    if(!module_hidden) //is not hidden
            return;
    list_add(&THIS_MODULE->list, module_prev); //add to procfs

    result = kobject_add(&THIS_MODULE->mkobj.kobj, kobject_parent_prev, "my_module");     //add the module to sysfs
    if(result<0) {
            printk(KERN_ALERT "Error to restore the old kobject\n");
    }
    result2 = kobject_add(THIS_MODULE->holders_dir, &THIS_MODULE->mkobj.kobj, "holders"); //add the holders dir to the module folder
    if(!THIS_MODULE->holders_dir) {
            printk(KERN_ALERT "Error to restore the old holders_dir\n");
    }
    THIS_MODULE->sect_attrs = sect_attrs_bkp;
    THIS_MODULE->notes_attrs = notes_attrs_bkp;
    //kobject_get(&THIS_MODULE->mkobj.kobj);
    //tried using THIS_MODULE->refcnt = 0; and kobject_get(&THIS_MODULE->mkobj.kob) with no luck
    module_hidden = (unsigned int)0x0;
 }

谢谢

最佳答案

使用 kobject_add 只会添加您已经知道的目录,而使用 kobject_dell 将删除目录和所有子目录。
因此,正如您提到的,您需要添加所有需要的子目录。

要了解添加子目录的方法是什么,请仔细阅读 module.c 处的 sys_init_module 源代码或阅读kobject_del -> sys_remove_dir
递归清除时删除所有属性(文件)和子目录kobj->kernfs_nodes .

因此,您需要使用函数使用他的所有属性递归地创建结构

  • sysfs_add_file_mode_ns
  • sysfs_create_dir_ns

  • 或者:
  • __kernfs_create_file
  • kernfs_create_empty_dir

  • 例如,要添加节文件,请使用以下行:
    sysfs_create_group(&THIS_MODULE->mkobj.kobj, &sect_attrs_bkp->grp))
    您需要更改更多值才能解决问题,但要恢复目录就足够了。

    但是其他解决方案和 perherp 更简单的方法是通过劫持 getdents_t 和 getdents64_t 使您的模块目录不可见,就像在 Diamorphine 处所做的那样。 .

    关于c - 从 sysfs 恢复或删除 Linux 内核模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46502395/

    相关文章:

    c++ - 如何确保数据写入文件

    c++ - Linker cannot find qwebp lib - 静态Qt5.3.2编译

    c++ - 我们如何确保缓存以减少 SQLite 数据库的文件系统写入周期

    linux-kernel - 覆盆子 3 : booting a Kernel by using U-Boot

    c - 将两个指针数组合并为 C 中的第三个指针数组

    javascript - 是否有以下反射语言功能的名称和标准实现方式?

    c - 使用指针访问数组和通过指针访问非数组变量之间有什么区别

    在 Linux 中编译内核代码

    linux - linux内核中的大尺寸kmalloc kmalloc

    c - 如何将链接列表转换为动态数组