IA32架构下截获系统调用的方法

 


1 系统调用的基础

应用程序通过0x80号中断进入系统调用,所以首先要在硬件机制上铺好进入中断的道路
这是在系统初始化进行的:
void __init trap_init(void)
{
...
set_system_gate(SYSCALL_VECTOR,&system_call);
...
}


2 系统调用表
在IA32架构下,内核里所有的系统调用的入口函数,都被放入系统调用表中
在arch/i386/kernel/syscall_table.S中

ENTRY(sys_call_table)
 .long sys_restart_syscall
 .long sys_exit
 .long sys_fork
 .long sys_read
 .long sys_write
 .long sys_open  /* 5 */
 .long sys_close
 ......
}

这张表其实就是个函数指针表,这张表是系统调用总的转发依据


在进入system_call之后,内核以eax的系统调用号为索引,调用对应的系统调用入口函数:

syscall_call:

#eax存放着系统调用号,这里进入对应的系统调 用
 call *sys_call_table(,%eax,4)

# 从系统调用中返回,eax里存放系统调用的结果
 movl %eax,PT_EAX(%esp)    


3 系统调用的截获
我们就是要在进入系统调用之前和之后截获系统调用
首先准备我们的系统调用进入和退出时的截获函数

asmlinkage void senix_sys_enter(int call)
{
 printk("senix_sys_enter %d %s %d/n",current->pid,current->comm,call);
 
}

asmlinkage void senix_sys_exit(int ret)
{
 printk("senix_sys_exit %d %s %d/n",current->pid,current->comm,ret);

}

 

 

然后修改进入系统调用的流程

syscall_call:

#保存eax里的系统调用号,防止被修改
 pushl %eax    

#进入我们的截获函数,在里面截取系统调用号(也可截获其他参数)
 call senix_sys_enter 

#恢复系统调用号     

 popl %eax
 call *sys_call_table(,%eax,4)

#保存eax里的系统调用返回值,防止被修改
 pushl %eax     

#进入我们的截获函数,在里面截取系统返回值

call senix_sys_exit

#恢复系统调用返回值  
popl %eax
movl %eax,PT_EAX(%esp) 
...


4 讨论
以上代码在本人的机器上调试成功,内核版本为linux-2.6.21.5

 

 


===============================================================
讨论  linux_kernel_2_6@yahoo.com.cn
未经允许请勿用于商业用途
                                             wangsen
===============================================================

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值