BSD下第一个syscall hook,监视SYS_open的情况
这两天看《BSD ROOTKIT 设计》,学着第二章的syscall hook写了一个对open的监视模块,算是迈出了第一步。
虽然代码很简单,不过整个编译过程还是遇到不少问题,这里记录一下方便以后查询
首先是几个写Hook会用到的文件:
sys_generic.c read/pread 等几个函数都在这个文件里
vfs_syscalls.c open/kern_open ...
syscall.h System call numbers (系统调用号)
sysproto.h System call prototypes
不过 vfs_syscalls.c 对 open() 的那种定义方法,在我FreeBSD 6.2上怎么也编译不过:
1 int
2 open(td, uap)
3 struct thread *td;
4 register struct open_args /* {
5 char *path;
6 int flags;
7 int mode;
8 } */ *uap;
9 {
10 //
11 }
2 open(td, uap)
3 struct thread *td;
4 register struct open_args /* {
5 char *path;
6 int flags;
7 int mode;
8 } */ *uap;
9 {
10 //
11 }
3: warning: function declaration isn't a prototype
总是在 struct thread *td; 这行上提示这个错误,查了半天也没找出原因。估计是CC不支持这样的定义(那内核怎么编译过的,真搞不懂)...
改成正规的声明方式,于是OK。
下面是完整的代码:
#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/syscall.h>
#include <sys/sysproto.h>
/* system call hook. */
static int
open_hook(struct thread *td, register struct open_args *uap)
{
// 输出 open 打开的文件到控制台
uprintf(" SYS_open: \"%s\", flags: %d, mode: %X\n", uap->path, uap->flags, uap->mode);
return (open(td, uap));
}
/* The function called at load/unload. */
static int
load(struct module *module, int cmd, void *arg)
{
int error = 0;
switch (cmd) {
case MOD_LOAD:
sysent[SYS_open].sy_call = (sy_call_t *)open_hook;
break;
case MOD_UNLOAD:
sysent[SYS_open].sy_call = (sy_call_t *)open;
break;
default:
error = EOPNOTSUPP;
break;
}
return(error);
}
static moduledata_t open_hook_mod = {
"open_hook", /* module name */
load, /* event handler */
NULL /* extra data */
};
DECLARE_MODULE(open_hook, open_hook_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
#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/syscall.h>
#include <sys/sysproto.h>
/* system call hook. */
static int
open_hook(struct thread *td, register struct open_args *uap)
{
// 输出 open 打开的文件到控制台
uprintf(" SYS_open: \"%s\", flags: %d, mode: %X\n", uap->path, uap->flags, uap->mode);
return (open(td, uap));
}
/* The function called at load/unload. */
static int
load(struct module *module, int cmd, void *arg)
{
int error = 0;
switch (cmd) {
case MOD_LOAD:
sysent[SYS_open].sy_call = (sy_call_t *)open_hook;
break;
case MOD_UNLOAD:
sysent[SYS_open].sy_call = (sy_call_t *)open;
break;
default:
error = EOPNOTSUPP;
break;
}
return(error);
}
static moduledata_t open_hook_mod = {
"open_hook", /* module name */
load, /* event handler */
NULL /* extra data */
};
DECLARE_MODULE(open_hook, open_hook_mod, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
kldload后执行命令可以看到输出:
# kldload ./h_open.ko
# ls
SYS_open: "/etc/libmap.conf", flags: 0, mode: 1B6
SYS_open: "/var/run/ld-elf.so.hints", flags: 0, mode: 0
SYS_open: "/lib/libutil.so.5", flags: 0, mode: 0
SYS_open: "/lib/libncurses.so.6", flags: 0, mode: BFBFEAC8
SYS_open: "/lib/libc.so.6", flags: 0, mode: BFBFEAC8
SYS_open: "/root/.termcap.db", flags: 0, mode: 0
SYS_open: "/root/.termcap", flags: 0, mode: 0
SYS_open: "/usr/share/misc/termcap.db", flags: 0, mode: 0
SYS_open: ".", flags: 0, mode: 0
SYS_open: ".", flags: 0, mode: 0
SYS_open: ".", flags: 4, mode: 0
@@ Makefile export_syms h_open.c h_open.ko* machine@
# kldstat
SYS_open: "/etc/libmap.conf", flags: 0, mode: 1B6
SYS_open: "/var/run/ld-elf.so.hints", flags: 0, mode: 0
SYS_open: "/lib/libc.so.6", flags: 0, mode: 0
Id Refs Address Size Name
1 4 0xc0400000 6f6544 kernel
2 1 0xc0af7000 59f20 acpi.ko
3 1 0xc1d78000 2000 h_open.ko
# kldunload ./h_open.ko
SYS_open: "/etc/libmap.conf", flags: 0, mode: 1B6
SYS_open: "/var/run/ld-elf.so.hints", flags: 0, mode: 0
SYS_open: "/lib/libc.so.6", flags: 0, mode: 0
# ls
SYS_open: "/etc/libmap.conf", flags: 0, mode: 1B6
SYS_open: "/var/run/ld-elf.so.hints", flags: 0, mode: 0
SYS_open: "/lib/libutil.so.5", flags: 0, mode: 0
SYS_open: "/lib/libncurses.so.6", flags: 0, mode: BFBFEAC8
SYS_open: "/lib/libc.so.6", flags: 0, mode: BFBFEAC8
SYS_open: "/root/.termcap.db", flags: 0, mode: 0
SYS_open: "/root/.termcap", flags: 0, mode: 0
SYS_open: "/usr/share/misc/termcap.db", flags: 0, mode: 0
SYS_open: ".", flags: 0, mode: 0
SYS_open: ".", flags: 0, mode: 0
SYS_open: ".", flags: 4, mode: 0
@@ Makefile export_syms h_open.c h_open.ko* machine@
# kldstat
SYS_open: "/etc/libmap.conf", flags: 0, mode: 1B6
SYS_open: "/var/run/ld-elf.so.hints", flags: 0, mode: 0
SYS_open: "/lib/libc.so.6", flags: 0, mode: 0
Id Refs Address Size Name
1 4 0xc0400000 6f6544 kernel
2 1 0xc0af7000 59f20 acpi.ko
3 1 0xc1d78000 2000 h_open.ko
# kldunload ./h_open.ko
SYS_open: "/etc/libmap.conf", flags: 0, mode: 1B6
SYS_open: "/var/run/ld-elf.so.hints", flags: 0, mode: 0
SYS_open: "/lib/libc.so.6", flags: 0, mode: 0
文中代码打包下载:hook_open.rar