Chinaunix首页 | 论坛 | 博客
  • 博客访问: 362238
  • 博文数量: 35
  • 博客积分: 2176
  • 博客等级: 大尉
  • 技术积分: 797
  • 用 户 组: 普通用户
  • 注册时间: 2006-08-13 14:03
文章分类

全部博文(35)

文章存档

2012年(9)

2009年(14)

2008年(12)

我的朋友

分类: BSD

2008-07-09 10:43:42

这两天安装完FreeBSD,抽空也看看怎么编写KLD,还好觉得比LINUX容易些。
先完成一个内核模块,主要是按照rootkit来的,小做修改,因为我用的FreeBSD毕竟是7.0了,
也是些不同了。
example.c


#include <sys/types.h>
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/module.h>
#include <sys/sysent.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/sysproto.h>

/* The system call's arguments. */

struct example_args {
        char *str;
};

/* The system call function. */
static int
example(struct thread *td, void *syscall_args)
{
        struct example_args *uap;
        uap = (struct example_args *)syscall_args;

        printf("%s\n", uap->str);

        return(0);
}

/* The sysent for the new system call. */
static struct sysent example_sysent = {
        1, /* number of arguments */
        example, /* implementing function */
        0,
        NULL,
        0
};

/* The offset in sysent[] where the system call is to be allocated. */
static int offset = NO_SYSCALL;

/* 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("System call loaded at offset %d.\n", offset);
                break;

        case MOD_UNLOAD:
                uprintf("System call unloaded from offset %d.\n", offset);
                break;

        default:
                error = EOPNOTSUPP;
                break;
        }

        return(error);
}

SYSCALL_MODULE(example, &offset, &example_sysent, load, NULL);

其实我倒喜欢BSD的Makefile了,简单,呵呵
Makefile

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

.include <bsd.kmod.mk>


这样算一个模块就写完了,而且是新加了系统调用的哦。
make完了,kldload ./example.ko 算是load module了。
接下来的事就是完成,如何调用这个系统调用了。
写了个.c的应用程序

#include <stdio.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <sys/module.h>

int
main(int argc, char *argv[])
{
        int syscall_num;
        struct module_stat stat;
        if (argc != 2) {
                printf("Usage:\n%s \n", argv[0]);
                exit(0);
        }

        /* Determine example's offset value. */
        stat.version = sizeof(stat);
        /*1*/ modstat(modfind("example"), &stat);
        syscall_num = stat.data.intval;

        /* Call example. */
        return(/*2*/ syscall(syscall_num, argv[1]));
}

好象也没什么可说的,不过其实还可以更简单的测试模块是否正确。
perl帮我们解决了
perl -e '$str = "Hello, kernel!";' -e 'syscall(210, $str);'
这样就不需要写应用程序了,也测试了我们的模块,当然要看看结果了,呵呵,看日志吧。
dmesg | tail -n 1

算是给学习FreeBSD的一个开始吧。
阅读(1916) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~