Sunday, August 16, 2009

My First Kernel Module

Designing BSD Rootkits, 1st Edition を参考に、初体験 !? となる kernel module を作成してみた。つか、ほとんどコピペだ。

最初の 1 歩は、Loadable Kernel Modules を作成してみる作業だ。Loadable Kernel Modules は、kernel のサブシステムであり、boot した後にロードされたりアンロードされたりし、管理者が動的に機能を追加したり削除したりできる。

で... loadable kernel modul は LKM と省略されたりする。

本ページにて、これから記載しようとしている内容は、ここ Dynamic Kernel Linker Facility - KLD にオフィシャルドキュメントとして記載されている。ちなみに作業した OS は NetBSD でなく FreeBSD 7.2-RELEASE だ。


最初の KLD は、これだ。これは正しく完全な KDL だ。load 関数は、event handler を役割している。


#include <sys/param.h>
#include <sys/module.h>
#include <sys/kernel.h>
#include <sys/systm.h>

/* The function called at load/unload. */
static int
load(struct module *module, int cmd, void *arg)
{
    int error = 0;

    switch (cmd) {
    case MOD_LOAD:
        uprintf("Hello, world!\n");
        break;

    case MOD_UNLOAD:
        uprintf("Good-bye, cruel world!\n");
        break;

    default:
        error = EOPNOTSUPP;
        break;
    }

    return(error);

}

/* The second argument of DECLARE_MODULE. */
static moduledata_t hello_mod = {
    "hello",    /* module name */
    load,     /* event handler */
    NULL     /* extra data */

};

DECLARE_MODULE(hello, hello_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);



上記の内容をファイル hello.c として作成する。続いて Makefile を作成しよう。


KMOD=  hello        # Name of KLD to build.
SRCS=  hello.c      # List of source files.

.include



make を実行する。


% make
Warning: Object directory not changed from original /usr/home/satoshiabe
@ -> /usr/src/sys
machine -> /usr/src/sys/i386/include
cc -O2 -fno-strict-aliasing -pipe -D_KERNEL -DKLD_MODULE -std=c99 -nostdinc -I. -I@ -I@/contrib/altq -finline-limit=8000 --param inline-unit-growth=100 --param large-function-growth=1000 -fno-common -mno-align-long-strings -mpreferred-stack-boundary=2 -mno-mmx -mno-3dnow -mno-sse -mno-sse2 -mno-sse3 -ffreestanding -Wall -Wredundant-decls -Wnested-externs -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Winline -Wcast-qual -Wundef -Wno-pointer-sign -fformat-extensions -c hello.c
ld -d -warn-common -r -d -o hello.kld hello.o
:> export_syms
awk -f /sys/conf/kmod_syms.awk hello.kld export_syms | xargs -J% objcopy % hello.kld
ld -Bshareable -d -warn-common -o hello.ko hello.kld
objcopy --str
%



作成された kernel module つまり hello.ko をロードしたりアンロードしたりできる!


% sudo kldload ./hello.ko
Hello, world!
% sudo kldunload hello.ko
Good-bye, cruel world!
%



完璧だ。もし何もエラーが表示されないなら、起動してる kernel に kernel module をロードしたりアンロードしたことを意味する。次回、より高度 ? な内容にチャレンジしてみたいと思う。

No comments: