《Linux及安全》实践2

一、Linux基本内核模块

1.1什么是内核模块

  • linux模块是一些可以作为独立程序来编译的函数和数据类型的集合。之所以提供模块机制,是因为Linux本身是一个单内核。单内核由于所有内容都集成在一起,效率很高,但可扩展性和可维护性相对较差,模块机制可弥补这一缺陷。
  • Linux模块可以通过静态或动态的方法加载到内核空间,静态加载是指在内核启动过程中加载;动态加载是指在内核运行的过程中随时加载。(我们要做的实践内容就是动态加载内核模块)
  • 一个模块被加载到内核中时,就成为内核代码的一部分。模块加载入系统时,系统修改内核中的符号表,将新加载的模块提供的资源和符号添加到内核符号表中,以便进行模块间的通信。

1.2.c程序编写

  • 具体代码如下(打印学号):

  • 解释:

    (1)关于 #include <linux/init.h>以及#include <linux/module.h>是编写内核模块程序所必须的2个头文件。

    (2)编写内核模块时必须要有的两个函数 :
    - 加载函数:

      		static int init_fun(void)
      		{
      		// 初始化代码
      		} 
      		函数实例:
      		static int hello_init(void)// 不加void在调试时会出现报警
      		{
      		printk("hello world!/n");
      		return 0;
      		}
      -  卸载函数(出口函数) 无返回值
      		
      		static void cleaup_fun(void)
      		{
      		// 释放代码
      		}
    

    (3)printk是内核态信息打印函数,功能和比标准C库的printf类似

    (5)module_init(fun):告诉内核模块程序从何处开始执行。module_exit(fun):告诉内核编写模块程序从何处离开。

    (6)模块许可声明:函数原型是MODULE_LICENSE(),告诉内核该程序使用的许可证,一般是GPL。

1.3Makefile编写

  1. 代码如下:

  2. 解释:

    • 其中make -C $(LINUX_KERNEL_PATH) 指明跳转到内核源码目录下读取Makefile
      M=$(CURRENT_PATH) 表明返回到当前目录继续执行当前的Makefile(M= 后指定的是 lwr.c 和 Makefile 所在的目录)
    • 关于个人虚拟机的内核版本号,输入指令“uname - a”可查看,在usr/src中可找到

1.4操作

  • 输入make进行自动编译;编译之后,生成需要的文件

  • 输入sudo insmod lwr.ko,加载模块(root权限)

  • 输入dmesg,测试模块输出

  • 卸载模块:“sudo rmmod 模块名” 之后,就将内核中之前加载的模块删除,此时再输入dmesg测试,可以看到显示了exit信息

二、Linux内核模块的功能实现

1.实现输出当前进程信息的功能

  • 代码如下:

  • 结果如下:

  • 温馨提示需要改一下makefile哦,代码里使用了printk函数打印了进程的pid、state等信息

2.实现读取进程链表的功能

  • 代码如下:

  • 结果如下:

  • 这个与上述不同的地方在于要打印进程链表的,所以需要一个循环,连续打印

  • for_each_process()的函数本质即for循环,从第一个PCB(init_task)开始,顺着pcurrent链表进行遍历,输出所有当前进程的信息(pid,tgid等)。

posted on 2016-05-24 23:36  20135211李行之  阅读(373)  评论(0编辑  收藏  举报