Linux内核模块编程学习


=Start=

缘由:

学习需要

正文:

参考解答:
1.什么是内核模块?

简单点的解释一段可以动态加载进内核的代码
复杂点的解释内核模块是一些可以让操作系统内核在需要时载入和执行的代码,这同样意味着它可以在不需要时由操作系统卸载。它们扩展了操作系统内核的功能却不需要重新启动系统。举例来说,其中一个内核模块是设备驱动程序模块,它们用来让操作系统正确识别,使用安装在系统上的硬件设备。如果没有内核模块(的机制),我们不得不一次又一次重新编译生成单内核操作系统的内核镜像来加入新的功能。除此之外,这还意味着一个臃肿的内核。

模块是具有独立功能的程序,它可以被单独编译,但不能独立运行。它在运行时被插入到内核作为内核的一部分在内核空间运行,这与运行在用户空间的进程是不同的。模块通常由一组函数和数据结构组成,用来实现一种文件系统、一个驱动程序或其他内核上层的功能。

这样说吧,模块就是整个内核的一部分。但是跟C程序中函数不一样的一点是,内核模块可以在它所认为适当的时候,插入到内核或者从内核中删除,而且还不影响内核的正常运行。从而可以在必要的时候对内核进行裁剪,这样能够更好的适应于用户的需求。

2.内核模块是如何工作的?

内核模块是如何被调入内核进行工作的?当操作系统内核需要的扩展功能不存在时,内核模块管理守护进程kmod执行modprobe去加载内核模块。

当传递给modprobe是通用识别符时,modprobe首先在文件 /etc/modprobe.conf(/etc/modprobe.d 目录) 查找该字符串。如果它发现的一行别名像:
alias char-major-10-30 softdog
它就明白通用识别符是指向内核模块softdog.ko。

然后,modprobe遍历文件 /lib/modules/$(uname -r)/modules.dep 来判断是否有其它内核模块需要在该模块加载前被加载。该文件是由命令$(depmod -a)建立,保存着内核模块的依赖关系。

最终,modprobe调用命令$(insmod)先加载被依赖的模块,然后加载该被内核要求的模块。

3.一个简单的内核模块编写、编译、安装、删除过程

// C源文件

/* 
 *  hello-1.c - The simplest kernel module.
 */
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_ALERT */
int init_module(void)
{
    printk(KERN_ALERT "Hello world 1.\n");
    /*
     * A non 0 return means init_module failed; module can't be loaded.
     */
    return 0;
}
void cleanup_module(void)
{
    printk(KERN_ALERT "Goodbye world 1.\n");
}

// Makefile 文件

obj-m += hello-1.o

// 编译

make -C /usr/src/kernels/$(uname -r) SUBDIRS=$PWD modules
# 或
make -C /lib/modules/$(uname -r)/build M=$PWD modules

// 安装

# lsmod | grep --color -i "hello"
# insmod ./hello-1.ko
# lsmod | grep --color -i "hello"

// 删除

rmmod hello-1
lsmod | grep --color -i "hello"

// 验证

# dmesg
# tail -f /var/log/messages
4.一个复杂一点的内核模块

参考:
https://linux.cn/article-3251-1.html?pr
https://github.com/vsinitsyn/reverse

5.其它
// #include <linux/init.h>        /* Needed for the macros */
// __init 和 module_init
// __exit 和 module_exit
//模块许可证声明(必须)
MODULE_LICENSE("GPL");
//声明模块的作者(可选)
MODULE_AUTHOR("XXX");
//声明模块的描述(可选)
MODULE_DESCRIPTION("This is a simple example!/n");
//声明模块的别名(可选)
MODULE_ALIAS("A simplest example");
// 一个更为常见的Makefile文件(但不清楚为啥总是出现「make: Nothing to be done for `all'.」)
obj-m += hello.o
CFLAGS_hello.o += -DDEBUG
KERNEL_DIR := /lib/modules/$(shell uname -r)/build
all:
  make -C $(KERNEL_DIR) M=$(PWD) modules
clean:
  make -C $(KERNEL_DIR) M=$(PWD) clean
参考链接:

https://github.com/bashrc/LKMPG
http://www.tldp.org/LDP/lkmpg/2.6/html/index.html
http://www.tldp.org/LDP/lkmpg/2.6/lkmpg.pdf
http://www.dirac.org/linux/writing/lkmpg/2.6/chinese/lkmpg_chs/book1.html

http://derekmolloy.ie/writing-a-linux-kernel-module-part-1-introduction/

https://stackoverflow.com/questions/28631550/linux-kernel-programming-book-for-3-x-versions
https://kernelnewbies.org/

黑客内核:编写属于你的第一个Linux内核模块
https://linux.cn/article-3251-1.html?pr
https://github.com/vsinitsyn/reverse

linux内核编程(一)
http://blog.chinaunix.net/uid-26281173-id-2856305.html

linux内核编程4部曲之四:模块编程
http://blog.chinaunix.net/uid-24782829-id-3223901.html

Linux内核编程初体验 —— hello world
http://blog.csdn.net/chang198932/article/details/17006537
Linux_kernel编程基础总结
http://blog.csdn.net/zbh19921021/article/details/49019335

=END=


《 “Linux内核模块编程学习” 》 有 13 条评论

  1. Sutekh – Linux rootkit 样例,普通用户权限通过后门获取 root shell
    https://github.com/PinkP4nther/Sutekh
    `
    # Sutekh
    An example rootkit that gives a userland process root permissions
    Built for Linux kernel 4.x.x x86_64

    [INSTALL]
    1. Install latest Linux headers for your kernel. Example (debian): [apt install linux-headers-$(uname -r)]
    2. $ git clone https://github.com/PinkP4nther/Sutekh
    3. $ cd Sutekh && make
    4. $ gcc getroot.c -o getroot
    5. $ sudo insmod sutekh.ko

    [Run]
    $ ./getroot

    [Output example]
    $ ./getroot
    [+] UID = 0
    [+] EUID = 0
    [!!!] Popping r00t shell!!!
    [root@localhost Sutekh]# id
    uid=0(root) ..SNIP..

    [Remove]
    sudo rmmod sutekh
    `

  2. Linux Rootkit系列一:LKM的基础编写及隐藏
    https://www.freebuf.com/articles/system/54263.html

    rootkit-sample-code
    https://github.com/Arciryas/rootkit-sample-code

    lkm-rootkit
    https://github.com/croemheld/lkm-rootkit

    Linux内核模块基础
    http://www.ilinuxkernel.com/files/1/kernelmodule.html

    编写 Linux 内核模块——第一部分:前言
    https://www.infoq.cn/article/linux-kernel-module-part01

    使用 /proc 文件系统来访问 Linux 内核的内容
    https://www.ibm.com/developerworks/cn/linux/l-proc.html

    Linux Rootkit 实验
    https://wohin.me/rootkit/2017/05/08/LinuxRootkitExp-0001.html

    Kernel Module实战指南(一):Hello World!
    https://csprojectedu.com/2016/01/25/KernelModuleInAction-1/

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注