Chinaunix

标题: 截获execve系统调用,为什么出现“段错误” [打印本页]

作者: vfvf    时间: 2005-08-15 10:48
标题: 截获execve系统调用,为什么出现“段错误”
在linux下,使用LKM截获execve系统调用,编写新的new_execve系统调用时,为什么出现“段错误”呢?就算new_execve函数体内什么都不做,只返回原

来的execve系统调用,也会出现“段错误”。而截获其它的系统调用如open, read等都没问题。不知是不是new_execve函数参数传递有什么不

对的地方,请各位多多帮忙。多谢多谢了。

   代码是这样的:
   ……
   ……
   int new_execve(const char *filename,const char *argv[],const char *envp[])
  {
     return (*old_execve)(filename,argv,envp);
   }
   int init_module()
   {
     SYS_CALL_TABLE_ADDR=getscTable();
     sys_call_table=(void **)SYS_CALL_TABLE_ADDR;
     old_execve=sys_call_table[__NR_execve];
     sys_call_table[__NR_execve]=new_execve;
     return 0;
   }
   int cleanup_module()
   {
     sys_call_table[__NR_execve]=old_execve;
     return 0;
    }
作者: albcamus    时间: 2005-08-15 13:01
标题: 截获execve系统调用,为什么出现“段错误”
编译时加上-fomit-frame-pointer试试
作者: richardhesidu    时间: 2005-08-16 13:25
标题: 截获execve系统调用,为什么出现“段错误”
  int new_execve(const char *filename,const char *argv[],const char *envp[])
{
    return (*old_execve)(filename,argv,envp);
  }

这段代码有点问题
作者: jobman    时间: 2005-08-16 23:12
标题: 截获execve系统调用,为什么出现“段错误”
  1. int new_execve(const char *filename,const char *argv[],const char *envp[])
  2. {
  3.     return (*old_execve)(filename,argv,envp);
  4.   }
复制代码

这段不对,参看 sys_execve 原型声明,
另外,在 2。6。11 之前,请使用 do_execve 来完成截获,参看核心源码。
作者: vfvf    时间: 2005-08-17 10:33
标题: 截获execve系统调用,为什么出现“段错误”
编译时加上-fomit-frame-pointer还是不行。
execve系统调用的 原型声明就是这样的:
int execve(const char *filename,const char *argv[],const char *envp[]);
我觉得也肯定是我编的这个函数
int new_execve(const char *filename,const char *argv[],const char *envp[])
{
   return (*old_execve)(filename,argv,envp);
}
参数的问题,但不知应该是什么。请问要是用do_execve来实现怎么在LKM中用呢?万分感激
作者: jobman    时间: 2005-08-18 01:31
标题: 截获execve系统调用,为什么出现“段错误”
这是2。6 的,2。4的可以自己看,变化不大,就是锁粒度小了。
  1. asmlinkage int sys_execve(struct pt_regs regs)
  2. {
  3.         int error;
  4.         char * filename;

  5.         filename = getname((char __user *) regs.ebx);
  6.         error = PTR_ERR(filename);
  7.         if (IS_ERR(filename))
  8.                 goto out;
  9.         error = do_execve(filename,
  10.                 (char __user * __user *) regs.ecx,
  11.                 (char __user * __user *) regs.edx,
  12.                 &regs);
  13.         if (error == 0) {
  14.                 task_lock(current);
  15.                 current->;ptrace &= ~PT_DTRACE;
  16.                 task_unlock(current);
  17.                 /* Make sure we don't return using sysenter.. */
  18.                 set_thread_flag(TIF_IRET);
  19.         }
  20.         putname(filename);
  21. out:
  22.         return error;
  23. }
复制代码

我总是奇怪,他们为什么那么自信哪?
作者: vfvf    时间: 2005-08-20 20:17
标题: 截获execve系统调用,为什么出现“段错误”
嗯,没错,用do_execve()可以实现,可是为什么不能和截获其他的系统调用一样,用(*old_execve)(filename,argv,envp); 来实现呢?
作者: glinzx    时间: 2005-08-23 13:18
标题: 截获execve系统调用,为什么出现“段错误”
段错误一般是因为指针的问题引起的。
作者: albcamus    时间: 2006-05-18 16:13
原帖由 vfvf 于 2005-8-20 20:17 发表
嗯,没错,用do_execve()可以实现,可是为什么不能和截获其他的系统调用一样,用(*old_execve)(filename,argv,envp); 来实现呢?



明白了, 这是因为sys_execve传给do_execve的是一个解构, 而非指针,(这个时候内核栈只有一个pt_regs结构,就是sys_execve的参数) do_execve会直接操作内核栈, 而新的进程返回到用户空间时, 会根据内核栈上的内容执行……于是不可能找到解析器之类……

以前的一个nonexecstack补丁通过栈拷贝解决了这个问题, 可是代码太简洁了,目前还没弄懂, 而且它的一些写法gcc4不支持了。
作者: 思一克    时间: 2006-05-18 16:49
do_execve是系统调用入口吗? sys_




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2