linux – 如何使用ptrace跳过系统调用?
发布时间:2020-12-14 01:07:09 所属栏目:Linux 来源:网络整理
导读:我正在尝试使用ptrace编写一个程序来跟踪孩子所做的所有系统调用. 现在我有一个禁止孩子的系统调用列表.我能够使用ptrace跟踪所有系统调用,但我只是不知道如何跳过特定的系统调用. 目前,我的跟踪(父)进程在每次进入或退出系统调用(PTRACE_SYSCALL)时都会收到
我正在尝试使用ptrace编写一个程序来跟踪孩子所做的所有系统调用.
现在我有一个禁止孩子的系统调用列表.我能够使用ptrace跟踪所有系统调用,但我只是不知道如何跳过特定的系统调用. 目前,我的跟踪(父)进程在每次进入或退出系统调用(PTRACE_SYSCALL)时都会收到一个信号.但如果孩子试图进入禁止的系统呼叫,那么我不想让孩子跳过该呼叫并转到下一步.此外,当我这样做时,我希望孩子知道有一个权限被拒绝错误,所以我将设置errno = 13,这还够吗? 更新: 怎么实现呢? 更新: 解决方法
我找到了两个大学讲座,提到无法中止已启动的系统调用,这是ptrace的一个缺点(该联机帮助页提到了一个PTRACE_SYSEMU宏看起来可以这样做,但是较新的标题没有它).从理论上讲,你可以利用ptrace入口和出口停止来抵消你不想要的调用 – 通过交换导致系统调用失败或什么也不做的虚假参数,或者通过注入代码来反击以前的系统调用,但这似乎非常hacky.
在Linux上,您应该能够通过seccomp实现目标: #include <fcntl.h> #include <seccomp.h> #include <errno.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> static int set_security(){ int rc = -1; scmp_filter_ctx ctx; struct scmp_arg_cmp arg_cmp[] = { SCMP_A0(SCMP_CMP_EQ,2) }; ctx = seccomp_init(SCMP_ACT_ERRNO(ENOSYS)); /*ctx = seccomp_init(SCMP_ACT_ALLOW);*/ if (ctx == NULL) goto out; rc = seccomp_rule_add(ctx,SCMP_ACT_ALLOW,SCMP_SYS(exit),0); if (rc < 0) goto out; rc = seccomp_rule_add(ctx,SCMP_SYS(close),0); if (rc < 0) goto out; rc = seccomp_rule_add(ctx,SCMP_SYS(write),1,SCMP_CMP(0,SCMP_CMP_EQ,1)); if (rc < 0) goto out; rc = seccomp_rule_add_array(ctx,arg_cmp); if (rc < 0) goto out; rc = seccomp_load(ctx); if (rc < 0) goto out; /* ... */ out: seccomp_release(ctx); return -rc; } int main(int argc,char *argv[]) { int fd; const char out_msg[] = "stdout testn"; const char err_msg[] = "stderr testn"; if(0>set_security()) return 1; if(0>write(1,out_msg,sizeof(out_msg))) perror("Write stdout"); if(0>write(2,err_msg,sizeof(err_msg))) perror("Write stderr"); //This should fail with ENOSYS if(0>(fd=open("/dev/zero",O_RDONLY))) perror("open"); exit(0); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |