Search

linux kernel module 만들기

Date
2022/01/07 12:50
Person
Category
운영체제 & 커널
Tag
kernel
linux
틈틈히 리눅스 커널 익스 공부를 할 예정. 따라서 필요한 지식들을 간단히 정리해보자.
보통 리눅스 커널 CTF 문제에서 리눅스 커널모듈의 취약점을 이용해서 익스를 하는것 같다. 커널 모듈을 간단히 만들어보자.

test.c

test.c ---------------------- #include <linux/module.h> /* Needed by all modules */ #include <linux/kernel.h> /* Needed for KERN_INFO */ int init_module(void) { printk(KERN_INFO "init_ test kernel module!!.\n"); return 0; } void cleanup_module(void) { printk(KERN_INFO "remove test kernel module!!.\n"); }
C
복사
참고로 printk()는 커널 함수에서 사용되는 출력 함수임.
초기 init_module() 함수는 insmod 같이 커널 모듈이 올라갈때 동작되는 초기화 과정을 뜻한다. 작성한 커널 모듈이 커널에 올라갈때 "init_ test kernel module!!" 를 출력할것이다. 또한 반대로 cleanup_module() 함수는 rmmod 같이 커널 모듈이 내려갈때 수행되는 종료 루틴이라고 생각하면 된다. 우선 빌드를 수행해야 한다. 다음과 같이 makefile을 만들면 된다.

Makefile

obj-m += test.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
C
복사
M=$(PWD) : 외부 모듈이 위치한 디렉토리의 절대 경로
-C : 커널 소스 위치로, 실제 make 수행시 해당 경로로 이동해서 빌드됨. 그리고 다시 돌아옴
위와 같이 Makefile을 만들고 make를 조지면 test.ko가 생성된다. (make clean을 하면 빌드한거 정리됨.)
➜ develop_kermod make make -C /lib/modules/5.4.0-53-generic/build M=/home/wogh8732/Desktop/kernel_study/develop_kermod modules make[1]: Entering directory '/usr/src/linux-headers-5.4.0-53-generic' CC [M] /home/wogh8732/Desktop/kernel_study/develop_kermod/test.o Building modules, stage 2. MODPOST 1 modules WARNING: modpost: missing MODULE_LICENSE() in /home/wogh8732/Desktop/kernel_study/develop_kermod/test.o see include/linux/module.h for more information CC [M] /home/wogh8732/Desktop/kernel_study/develop_kermod/test.mod.o LD [M] /home/wogh8732/Desktop/kernel_study/develop_kermod/test.ko make[1]: Leaving directory '/usr/src/linux-headers-5.4.0-53-generic'
C
복사
보면 '/usr/src/linux-headers-5.4.0-53-generic' 여기로 이동해서 수행하는게 보임.
이제 insmod로 커널모듈을 올려보자.
╭─wogh8732@ubuntu ~/Desktop/kernel_study/develop_kermod ╰─$ sudo insmod ./test.ko 130 ↵ ╭─wogh8732@ubuntu ~/Desktop/kernel_study/develop_kermod ╰─$ dmesg | tail -1 [ 3178.151904] init_ test kernel module!!.
C
복사
init_module() 함수의 printk() 가 출력된것을 확인할 수 있다. rmmod를 하면 cleanup_module() 함수의 printk()가 호출된다.
참고로 init_module() 함수와 cleanup_module() 함수는 그대로 함수명을 써야하는데 이를 변경하고 싶으면 다음과 같이 해야한다.

test2.c

GNU nano 2.9.3 test2.c #include <linux/module.h> /* Needed by all modules */ #include <linux/kernel.h> /* Needed for KERN_INFO */ #include <linux/init.h> int custom_init(void){ printk(KERN_INFO "custom init_ test kernel module!!.\n"); return 0; } void custom_cleanup(void) { printk(KERN_INFO "custom remove test kernel module!!.\n"); } module_init(custom_init); module_exit(custom_cleanup);
C
복사
초기화 및 제거시 수행되는 함수명은 상관없이 module_init(), module_exit() 안의 인자로 각각 넣어주면 된다.

dmesg

[ 3485.369499] custom init_ test kernel module!!. [ 3547.925718] custom remove test kernel module!!.
C
복사