How to change vnode operations ?

furukawa jun z0.0z.furukawa at gmail.com
Thu Apr 29 13:10:04 UTC 2010


Hi,

I know the way for changing vnode operations because I did that for my
graduate thesis.

In that thesis I made a LKM that hooks vn_write() function.

To make that software I referenced a book and a website listed below.

"Joseph Kong. Designing BSD Rootkits: An Introduction to Kernel Hacking. No
Starch Press, 2007."
"Stephanie Wehner. Fun and games with freebsd kernel modules, April 2001.
http:/
/www.r4k.net/mod/fbsdfun.html"

As a reference, I show here the part of the source code of my software.

#include <sys/param.h>                /* module           */
#include <sys/module.h>               /* module           */
#include <sys/kernel.h>               /* module           */
#include <sys/types.h>                /* size_t, copystr  */
#include <sys/systm.h>              /* copystr */
#include <sys/proc.h>                 /* struct thread    */
#include <sys/file.h>                 /* vnops            */
#include <fs/msdosfs/msdosfs_vnops.c> /* msdosfs_vnodeops */

int
fo_write_hook(struct file *fp,
        struct uio *uio,
        struct ucred *active_cred,
        int flags,
        struct thread *td);

typedef int (*fow_t)(struct file*,
        struct uio*,
        struct ucred*,
        int flags,
        struct thread*);

fow_t old_fo_write;
char mybuf[256+1];

/* fo_write hook */
int
fo_write_hook(struct file *fp,
        struct uio *uio,
        struct ucred *active_cred,
        int flags,
        struct thread *td)
{
 *   /* You can add here a new functinality. */*

    return (old_fo_write(fp, uio, active_cred, flags, td));
}

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

    /* The declaration of msdosfs_vnodeops */
    /* from /usr/include/fs/msdosfs/msdosfs_vnops.c */
    /* extern struct vop_vector msdosfs_vnodeops */

    /* The initialization of msdosfs_vnodeops */
    /* from /usr/src/sys/fs/msdosfs/msdosfs_vnops.c */
    //struct vop_vector msdosfs_vnodeops = {
    //    ...
    //    .vop_read =             msdosfs_read,
    //    ...
    //    .vop_write =            msdosfs_write,
    //    ...
    //};
    switch (cmd) {
        case MOD_LOAD:
            uprintf("Module has loaded\n");
            /* Replace fo_write with fo_write_hook. */
            old_fo_write = (fow_t)(vnops.fo_write);
            vnops.fo_write = fo_write_hook;

            break;

        case MOD_UNLOAD:
            uprintf("Module has unloaded\n");

            /* Change everyhting back to normal. */
            vnops.fo_write = old_fo_write;
            break;

        default:
            error = EOPNOTSUPP;
            break;
    }

    return (error);
}

static moduledata_t fo_write_hook_mod = {
    "fo_write_hook", /* module name   */
    load,            /* event handler */
    NULL             /* EXTRA DATA    */
};

DECLARE_MODULE(fo_write_hook, fo_write_hook_mod,
        SI_SUB_DRIVERS, SI_ORDER_MIDDLE);

Jun Furukawa


More information about the freebsd-hackers mailing list