赞
踩
当插入一个内核驱动时,一般会使用工具insmod,该工具实际上调用了系统调用init_module,在该系统调用函数中,首先调用 load_module,把用户空间传入的整个内核模块文件创建成一个内核模块,返回一个struct module结构体。内核中便以这个结构体代表这个内核模块。
HOOK内核驱动:
struct notifier_block nb = {
.notifier_call = module_notifier,
.priority = INT_MAX
};
int module_notifier(struct notifier_block *nb, unsigned long action, void *data) { struct module *module; unsigned long flags; /*声明一个自旋锁x并初始化它*/ DEFINE_SPINLOCK(module_notifier_spinlock); module = data; /*自旋锁*/ spin_lock_irqsave(&module_notifier_spinlock, flags); switch (module->state) { case MODULE_STATE_COMING: printk("Kernel Module: %s\n", module->name); /*将初始化和退出函数换成自定义的函数*/ module->init = hook_init; module->exit = hook_exit; break; default: break; } /*解锁*/ spin_unlock_irqrestore(&module_notifier_spinlock, flags); return NOTIFY_DONE; }
# include <linux/module.h> # include <linux/kernel.h> # include <linux/notifier.h> int hook_init(void); void hook_exit(void); int module_notifier(struct notifier_block *nb, unsigned long action, void *data); struct notifier_block nb = { .notifier_call = module_notifier, .priority = INT_MAX }; int init_my_module(void) { printk("init_my_module!\n"); /*注册notifier_block,函数用于注册需要知道当前模块的状态,然后触发一个回调函数*/ int ret = register_module_notifier(&nb); if(ret){ printk("Failed to register tracepoint module enter notifier\n"); return -1; } printk("module name: %s\n", THIS_MODULE->name); printk("module state: %d\n", THIS_MODULE->state); return 0; } void exit_my_module(void) { unregister_module_notifier(&nb); printk("exit_my_module!\n"); return; } int module_notifier(struct notifier_block *nb, unsigned long action, void *data) { struct module *module; unsigned long flags; /*声明一个自旋锁x并初始化它*/ DEFINE_SPINLOCK(module_notifier_spinlock); module = data; /*自旋锁*/ spin_lock_irqsave(&module_notifier_spinlock, flags); switch (module->state) { case MODULE_STATE_COMING: printk("Kernel Module: %s\n", module->name); /*将初始化和退出函数换成自定义的函数*/ module->init = hook_init; module->exit = hook_exit; break; default: break; } /*解锁*/ spin_unlock_irqrestore(&module_notifier_spinlock, flags); return NOTIFY_DONE; } int hook_init(void) { printk("Fake init\n"); return 0; } void hook_exit(void) { printk("Fake exit\n"); return; } module_init(init_my_module); module_exit(exit_my_module); MODULE_LICENSE("Dual BSD/GPL"); MODULE_AUTHOR("lkm"); MODULE_DESCRIPTION("LKM rootkit");
Makefile:
KVERS = $(shell uname -r)
obj-m += kernelLoad.o
#EXTRA_CFLAGS = -g -O0
build: kernel_modules
kernel_modules:
make -C /lib/modules/$(KVERS)/build M=$(CURDIR) modules
clean:
make -C /lib/modules/$(KVERS)/build M=$(CURDIR) clean
参考:
https://0xax.gitbooks.io/linux-insides/content/Concepts/linux-cpu-4.html
https://www.opensourceforu.com/2009/01/the-crux-of-linux-notifier-chains/
https://www.cnblogs.com/sky-heaven/p/4554614.html
https://blog.csdn.net/damontive/article/details/18313729
https://www.cnblogs.com/likaiming/p/11002351.html
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。