这里主要是用到int register_module_notifier(struct notifier_block *nb)的通知链机制,当有ko加载时,notifier函数被调用;
模块的四种状态

enum module_state {
	MODULE_STATE_LIVE, /* Normal state. */
	MODULE_STATE_COMING, /* Full formed, running module_init. */
	MODULE_STATE_GOING, /* Going away. */
	MODULE_STATE_UNFORMED, /* Still setting it up. */
};

当模块加载时,状态位MODULE_STATE_COMING;
register.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>

MODULE_LICENSE("GPL");

int success_int ( void )
{
    return 0;
}

void success_exit ( void )
{
}

int module_handler ( struct notifier_block *nblock, unsigned long code, void *_param )
{
    unsigned long flags;
    struct module *param = _param;
    //定义一个自旋锁,上锁前禁止中断
    DEFINE_SPINLOCK(module_event_spinlock);
    //开自旋锁
    spin_lock_irqsave(&module_event_spinlock, flags);

    switch ( param->state )
    {
        case MODULE_STATE_COMING:
            printk("Detected insertion of module '%s', neutralizing init and exit routines\n", param->name);
            //改变ko初始化的入口和出口函数
            param->init = success_int;
            param->exit = success_exit;
            break;

        default:
            break;
    }
    //释放自旋锁
    spin_unlock_irqrestore(&module_event_spinlock, flags);

    return NOTIFY_DONE;
}

static struct notifier_block nb = {
    .notifier_call = module_handler,
    .priority = INT_MAX,
};

static int __init register_init(void)
{
  printk("Function --> %s\n",__func__);
  register_module_notifier(&nb);
  return 0;
}

static void __exit register_exit(void)
{ 
  unregister_module_notifier(&nb);
  printk("the funciton is: %s\n",__func__);
}

module_init(register_init);
module_exit(register_exit)

Makefile:

obj-m   := register.o
KDIR    := /lib/modules/$(shell uname -r)/build
PWD	:= $(shell pwd)

default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) clean

实际效果:

[60187.494863] Function --> register_init
[60303.177354] Detected insertion of module 'lkm1', neutralizing init and exit routines

可以看到已经检测到ko的加载过程,并且替换入口函数,原lkm1的模块初始化函数并没有被执行;

Logo

更多推荐