随便在网上找了一个demo:
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
static int funcIn(void)
{
printk("in module");
return 0;
}
static void funcOut(void)
{
printk("out module");
return;
}
module_init(funcIn);
module_exit(funcOut);
MODULE_LICENSE("GPL");
链接如下:
https://blog.csdn.net/yangbingzhou/article/details/51177066
该文件编译得到ko文件后,执行sudo insmod xxx.ko
命令插入ko后,使用dmesg
命令后可以看到内核日志中有 in module 字符串,然后执行sudo rmmod xxx
命令卸载ko后,使用dmesg
命令后可以看到 out module 字符串。
其实也可以用gcc直接编译,如下:
gcc -DMODULE -D__KERNEL__ -isystem /lib/modules/`uname -r`/build/include -c test.c -o test.ko
不过有些版本的内核,可能会报头文件找不到的错误,原因可能是 /lib/modules/uname -r
/build/include 目录的子目录的名字与源码include使用的名字不一致导致的,解决方法可以参考如下链接:
https://stackoverflow.com/questions/54343325/lkm-cant-compile-module-missing-headers-files-but-header-packages-are-insta
为了避免产生上述问题,直接采用make进行编译,Makefile文件示例如下:
KDIR := /lib/modules/$(shell uname -r)/build # 内核头文件目录
KO_NAME := test # 输出生成的ko文件的名字
PWD = $(shell pwd) # Makefile文件所在目录
obj-m = $(KO_NAME).o
$(KO_NAME)-objs = test.o # 此处.o文件的名字必须与源码的.c文件保持一致
modules:
# 使用EXTRA_CFLAGS可以传入指定编译选项,比如 -fno-stack-protector 关闭SP保护
# -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0 -O0 关闭Fortify检查 等
$(MAKE) -C $(KDIR) M=$(PWD) EXTRA_CLFAGS+="" modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
将上述文件保存到名字为 Makefile 的文件中,然后在同一目录下新建 test.c 文件,将上一步的示例代码放进去,执行make KO_NAME="hello"
命令即可获得一个名为hello.ko的文件。
关于ko文件的Makefile文件的书写,可以参考如下链接:
https://www.cnblogs.com/downey-blog/p/10486907.html
在编译内核文件时,可以在Makefile文件中的 $(MAKE) 命令一行使用 EXTRA_CLFAGS 选项来添加编译选项或者定义宏,常用的一些安全编译选项如下:
安全功能 | 开启/关闭命令 | 功能描述 |
---|---|---|
NX(DEP) | -z execstack / -z noexecstack | 开启NX保护 堆栈禁止执行 |
RELRO | -z lazy(部分开启) / -z now(全部开启) / -z norelro(关闭) | 开启NX保护 堆栈禁止执行 |
PIE(ASLR) | -fpie -pie (开启PIE,此时强度为1) / -fPIE -pie (开启PIE,此时为最高强度2) | 代码段、数据段地址随机化 |
CANARY | -fstack-protector(开启) / -fstack-protector-all(完全开启) / -fno-stack-protector(关闭) | 堆栈溢出检测 |
FORTIFY | -U_FORTIFY_SOURCE -O0 (关闭) / -D_FORTIFY_SOURCE=1 -O1 (较弱的检查) / -D_FORTIFY_SOURCE=2 -O2 (较强的检查) | 常用函数加强检查,编译器会对memcpy、strcpy等内存操作相关函数增加检测,详情可自行百度 |
注意,FORTIFY 需要配合 -O 编译选项进行设置