《Linux及安全》实践2

【edited by 5216lwr】

一、Linux基本内核模块

1.1理解什么是内核模块

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

1.2.c程序编写

  • 具体代码如下:

    • 代码——

        #include <linux/init.h>
      #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); static char *name =" lwr";
      static int __init name_init(void)
      {
      printk("==hello,world==\n");
      printk("==hello,%s\n",name);
      return 0;
      }
      static void __exit name_exit(void)
      {
      printk(KERN_INFO"name module exit\n");
      } module_init(name_init);
      module_exit(name_exit); module_param(name,charp,S_IRUGO);
  • 解释:

    1.关于 #include <linux/init.h>以及#include <linux/module.h>是编写内核模块程序所必须的2个头文件。由于内核编程和用户层编程所用的库函数不一样,所以它的头文件也和在用户层编写程序所用的头文件不一样。比如,内核头文件的位置 : /usr/src/linux-2.6.x/include/;而用户层头文件的位置 : /usr/include/

    1. 编写内核模块时必须要有的两个函数 :

      • 加载函数:

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

         static void cleaup_fun(void)
        {
        // 释放代码
        }
    2. printk是内核态信息打印函数,功能和比标准C库的printf类似。printk还有信息打印级别。其中的参数KERN_INFO的定义如下:
      • define KERN_INFO "<6>" /* 提示信息,如驱动程序启动时,打印硬件信息 */

    3. 为什么内核态使用 printk() 函数,而在用户态使用 printf() 函数?
      • printk() 函数是直接使用了向终端写函数 tty_write() 。而 printf() 函数是调用 write() 系统调用函数向标准输出设备写。
      • 所以在用户态(如进程 0 )不能够直接使用 printk() 函数,而在内核态由于它已是特权级,所以无需系统调用来改变特权级,因而能够直接使用 printk() 函数。 - printk 是内核输出,在终端是看不见的。我们使用 dmesg 命令看一下输出的信息(也就是下面要用到的命令)。
    4. module_init(fun):告诉内核模块程序从何处开始执行。module_exit(fun):告诉内核编写模块程序从何处离开。
    5. 模块许可声明:函数原型是MODULE_LICENSE(),告诉内核该程序使用的许可证,一般是GPL。

1.3Makefile编写

  1. 代码如下:

     obj-m:= lwr.o// 产生 lwr 模块的目标文件
    CURRENT_PATH:= $(shell pwd) // 定义内核源文件目录
    LINUX_KERNEL_PATH:=$usr/src/linux-headers-3.19.0-25-generic
    all:
    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules
    // 生成内核模块参数为内核源代码目录以及模块所在目录
    clean:
    make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean
    // 清除生成的模块文件以及中间文件
  2. 解释:

    • 其中make -C $(LINUX_KERNEL_PATH) 指明跳转到内核源码目录下读取Makefile

      M=$(CURRENT_PATH) 表明返回到当前目录继续执行当前的Makefile(M= 后指定的是 lwr.c 和 Makefile 所在的目录)
    • 关于个人虚拟机的内核版本号,可以再usr/src中查看

1.4操作

  1. 输入make进行自动编译

  2. 编译之后,可以看到生成了很多lwr.xx等文件

  3. 输入sudo insmod lwr.ko,加载模块(会要求输入当前用户的密码)

  4. 输入dmesg,测试模块输出

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

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

  1. 在上述步骤的基础上,可以对内核模块的.c文件进行修改以实现更多的功能

  2. 具体代码加下

  3. 解释:

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

  5. 进行make之后,顺利生成模块

  6. 再进行sudo insmod lwr.ko,之后dmesg,就可以查看进程链表的信息

三、Linux内核模块功能拓展

  1. 用如下代码进行文件信息的读取

  2. lwr.c代码如下:

     #include<linux/module.h>
    #include<linux/kernel.h>
    #include<linux/init.h>
    #include<linux/sched.h> MODULE_LICENSE("Dual BSD/GPL"); static int __init hello_init(void)
    {
    FILE *fp;
    if((fp = fopen( "/proc/cpuinfo","r" ))==NULL){
    printk("File can not be opened\n");
    }
    else{
    fseek(fp,79l,0);
    fgets(information,48,fp);
    printk("CPU is:%s\n",information);
    }
    fclose(fp);
    printk("hello world!\n");
    return 0;
    }
    static void __exit hello_exit(void)
    {
    printk("GoodBye!\n");
    }
    module_init(hello_init);
    module_exit(hello_exit);
  3. Makefile如上

  4. make编译之后,进行insomd之后dmesg查看信息

《Linux及安全》实践2的更多相关文章

  1. paip.java win程序迁移linux的最佳实践

    paip.java win程序迁移linux的最佳实践 1.class load路径的问题... windows哈第一的从calsses目录加载,,而linux优先从jar加载.. 特别的是修理了ja ...

  2. 【转载】Linux小白最佳实践:《超容易的Linux系统管理入门书》(连载六)Linux的网络配置

    本篇是Linux小白最佳实践第6篇,目的就是让白菜们了解Linux网络是如何配置的.Linux系统在服务器市场占有很大的份额,尤其在互连网时代,要使用计算机就离不开网络. 想每天能听到小妞的语音播报, ...

  3. Linux小白最佳实践:《超容易的Linux系统管理入门书》(连载五)Linux系统的对话方式

    本篇是Linux小白最佳实践第5篇,目的就是让白菜们了解Linux进程之间是如何对话的.之前连载的几篇,在微信上引起了很多的反响,有人也反映图多文字少,感觉没有干货.本篇选了大部分是实战讲解的&quo ...

  4. Linux及安全实践五——字符集编码

    Linux及安全实践五——字符集编码 一.ASCII码 在表中查找出英文字母LXQ相对应的十六进制数值为: 4c 58 51 在终端中输入命令:vim test1.txt 在vim页面输入命令:%!x ...

  5. Linux及安全实践四——ELF文件格式分析

    Linux及安全实践四——ELF文件格式分析 一.ELF文件格式概述 1. ELF:是一种对象文件的格式,用于定义不同类型的对象文件中都放了什么东西.以及都以什么样的格式去放这些东西. 二.分析一个E ...

  6. Linux及安全实践三——程序破解

    Linux及安全实践三--程序破解 一.基本知识 常用指令机器码 指令 作用 机器码 nop 无作用(no operation) 90 call 调用子程序,子程序以ret结尾 e8 ret 返回程序 ...

  7. Linux及安全实践二——模块

    Linux及安全实践二--模块 一.模块的编译.生成.测试.删除 1.编写模块代码 编写:gedit 3.c 2.编写Makefile obj-m :这个变量是指定你要声称哪些模块模块的格式为 obj ...

  8. Linux及安全实践二

    Linux及安全实践二   基本内核模块 20135238 龚睿 1.  理解模块原理 linux模块是一些可以作为独立程序来编译的函数和数据类型的集合.之所以提供模块机制,是因为Linux本身是一个 ...

  9. 20135323符运锦----LINUX第二次实践:内核模块编译

    Linux实践二--模块 一.知识点总结 ①Linux模块是一些可以作为独立程序来编译的函数和数据类型的集合.之所以提供模块机制,是因为Linux本身是一个单内核.单内核由于所有内容都集成在一起,效率 ...

  10. linux内核分析实践二学习笔记

    Linux实践二--内核模块的编译 标签(空格分隔): 20135328陈都 理解内核的作用 Linux内核[kernel]是整个操作系统的最底层,它负责整个硬件的驱动,以及提供各种系统所需的核心功能 ...

随机推荐

  1. 【XLL 框架库函数】 TempBool/TempBool12

    创建一个包含了 Boolean 类型的 TRUE 或 FALSE 的 XLOPER/XLOPER12 LPXLOPER TempBool(int b); LPXLOPER12 TempBool12(i ...

  2. C的数值取反操作

    今儿在代码中发现一句"return x? ~0 : 0;"对~0这个取反操作相关的知识又还给老师了.一查,查到下面一道题,弄过来贴上. //-------------------- ...

  3. 多个SVG图形集成到一个SVG图形上

    SVG:使用XML格式定义图像的可缩放矢量图形(Scalable Vector Graphics). 优点就不多说了,下面看看怎么将多个svg图形集成到一个svg图形上. 如果使用bootstrap框 ...

  4. NSURLSession总结

    NSURLSession(会话)(ios7新增加) //英译  Session:会议,讲话 configuration:结构,配置 expect:预期 resume:取得 suspend:推迟 pro ...

  5. iOS键盘输入屏幕上移

    在iOS开法中经常会遇到键盘遮挡屏幕的事情(比如输入账号密码验证码等等),就使得原本都不大的屏幕直接占了一半甚至更多的位置,这倒无所谓,关键是挡住了下面的按钮.这样的话按钮的事件也就触发不了,最好的解 ...

  6. Python爬虫Scrapy框架入门(2)

    本文是跟着大神博客,尝试从网站上爬一堆东西,一堆你懂得的东西 附上原创链接: http://www.cnblogs.com/qiyeboy/p/5428240.html 基本思路是,查看网页元素,填写 ...

  7. WPF MVVM中在ViewModel中关闭或者打开Window

    这篇博客将介绍在MVVM模式ViewModel中关闭和打开View的方法. 1. ViewModel中关闭View public class MainViewModel { public Delega ...

  8. HTTP错误500.19-定义了重复的节点

    打开服务器的asp.net页面时出现这个错误: HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面,因为该页的相关配置数据无效.   解决办法: 打开II ...

  9. JupyterNotebook如何添加table of content

    不要总是等待,而是去创造 方法一 ipython notebook升级成了jupyter notebook,在4.x之后的版本,jupyter提供了jupyter-nbextension命令来安装和启 ...

  10. HDU 1074 Doing Homework (状压dp)

    题意:给你N(<=15)个作业,每个作业有最晚提交时间与需要做的时间,每次只能做一个作业,每个作业超出最晚提交时间一天扣一分 求出扣的最小分数,并输出做作业的顺序.如果有多个最小分数一样的话,则 ...