截获linux系统调用

方法1:修改系统调用表(适用于linux-2.4内核)

内核使用sys_call_table数组来存储系统调用表,将系统调用号与系统调用处理函数对应起来,通过修改sys_call_table数组的某一个元素,即可实现截获系统调用的功能,在2.4内核中,sys_call_table符号是被导出的,外部模块可以使用,故能简单的实现截获系统调用,在加载模块时,修改sys_call_table的处理函数,并保存其原来的值,在卸载模块时,还原其处理函数。

2.6内核中,由于sys_call_table符号不可见,网上有介绍在内存中查找sys_call_table地址的方法,不过比较复杂,尚未弄清其原理。

方法2:通过修改VFS操作表

该方法只能截获vfs相关的系统调用,通过修改file_operationsinode_operations的成员操作函数来实现,代码如下所示:

#include <linux/sched.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/file.h>

MODULE_LICENSE("GPL");

char *root_fs="/";

typedef int (*readdir_t)(struct file *,void *,filldir_t);
readdir_t orig_root_readdir=NULL;

int myreaddir(struct file *fp,void *buf,filldir_t filldir)
{
       int r;
       printk("<1>You got me partner!\n");
       r=orig_root_readdir(fp,buf,filldir);
       return r;
}

int patch_vfs(const char *p,readdir_t *orig_readdir,readdir_t new_readdir)
{
       struct file *filep;
       filep=filp_open(p,O_RDONLY,0);
       if(IS_ERR(filep))
            return -1;
       if(orig_readdir)
            *orig_readdir=filep->f_op->readdir;

       filep->f_op->readdir=new_readdir;
       struct file_operations *fop = filep->f_op;
       fop->readdir = new_readdir;
       filep->f_op = fop;

       filp_close(filep,0);
       return 0;
}

int unpatch_vfs(const char *p,readdir_t orig_readdir)
{
       struct file *filep;
       filep=filp_open(p,O_RDONLY,0);
       if(IS_ERR(filep))
            return -1;
       filep->f_op->readdir=orig_readdir;
       struct file_operations *fop = filep->f_op;
       fop->readdir = orig_readdir;
       filep->f_op = fop;

       filp_close(filep,0);
       return 0;
}

static int patch_init(void)
{
       patch_vfs(root_fs,&orig_root_readdir,myreaddir);
       printk("<1>VFS is patched!\n");
       return 0;
}
static void patch_cleanup(void)
{
       unpatch_vfs(root_fs,orig_root_readdir);
       printk("<1>VFS is unpatched!\n");
}
module_init(patch_init);
module_exit(patch_cleanup);


以上模块在linux-2.6.19内核上编译不能通过,提示错误消息为:readdir成员为只读的,不能对其赋值(红色部分)。于是,我引入一个中间变量,来达到修改操作表的目的(将红色部分修改为蓝色部分)。

参考:http://hi.baidu.com/linzhangkun/blog/item/34fe208f268d37f3503d920d.html


转载于:https://www.cnblogs.com/yunnotes/archive/2013/04/19/3032454.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值