免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3096 | 回复: 9
打印 上一主题 下一主题

截获execve系统调用,为什么出现“段错误” [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-08-15 10:48 |只看该作者 |倒序浏览
在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;
    }

论坛徽章:
0
2 [报告]
发表于 2005-08-15 13:01 |只看该作者

截获execve系统调用,为什么出现“段错误”

编译时加上-fomit-frame-pointer试试

论坛徽章:
0
3 [报告]
发表于 2005-08-16 13:25 |只看该作者

截获execve系统调用,为什么出现“段错误”

  int new_execve(const char *filename,const char *argv[],const char *envp[])
{
    return (*old_execve)(filename,argv,envp);
  }

这段代码有点问题

论坛徽章:
0
4 [报告]
发表于 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 来完成截获,参看核心源码。

论坛徽章:
0
5 [报告]
发表于 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中用呢?万分感激

论坛徽章:
0
6 [报告]
发表于 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. }
复制代码

我总是奇怪,他们为什么那么自信哪?

论坛徽章:
0
7 [报告]
发表于 2005-08-20 20:17 |只看该作者

截获execve系统调用,为什么出现“段错误”

嗯,没错,用do_execve()可以实现,可是为什么不能和截获其他的系统调用一样,用(*old_execve)(filename,argv,envp); 来实现呢?

论坛徽章:
0
8 [报告]
发表于 2005-08-23 13:18 |只看该作者

截获execve系统调用,为什么出现“段错误”

段错误一般是因为指针的问题引起的。

论坛徽章:
0
9 [报告]
发表于 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不支持了。

论坛徽章:
0
10 [报告]
发表于 2006-05-18 16:49 |只看该作者
do_execve是系统调用入口吗? sys_
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP