GCC如何在程序中阻止系统调用?[英] GCC how to block system calls within a program?

本文是小编为大家收集整理的关于GCC如何在程序中阻止系统调用?的处理方法,想解了GCC如何在程序中阻止系统调用?的问题怎么解决?GCC如何在程序中阻止系统调用?问题的解决办法?那么可以参考本文帮助大家快速定位并解决问题。

问题描述

有人告诉我如何阻止程序中的某些特定系统调用吗?我正在构建一个采用C源代码的系统,并使用GCC编译并运行它.出于安全原因,我需要防止编译程序调用某些系统调用.从源代码级别(例如,将GCC的标头文件剥离,将恶意外部调用...)到可执行级别,有什么方法可以做到这一点?

编辑#1:添加有关恶意电话的详细信息.

编辑#2:我的系统是GNU/Linux One.

编辑#3:

我在几天内尝试了一些方法,这是我到目前为止的结论:

  1. 扫描源代码无法解决主要问题,因为人们总是可以很好地观察他/她的C源文件.
  2. "覆盖C符号"非常适合库,但是对于系统调用,我没有实现我想要的.但是,这个想法还没有死,这样做肯定会使我大量的时间黑客入侵(GCC和/或LD).
  3. 允许的估算工作就像魅力一样.我可以使用Fakeroot或"访客"用户来做到这一点.此方法也是最容易实现的.

另一个是本地客户端我没有尝试过,但是由于项目和我的工作之间的共同点,我肯定会在不久的将来.

推荐答案

正如其他人所指出的那样,程序不可能避免进行系统调用,它们允许C库到整个地方.

但是,如果您的平台支持它(例如Linux),则可以通过仔细使用LD_Preload机制来取得进展而不是预期的libc函数. (例如,电气围栏是在基于Debian的系统上建立的,并拦截了malloc,free et al.)

)

我怀疑您可以使用此机制来捕获或参数检查您不喜欢的任何LIBC函数,也许可以注意您认为无条件安全的函数.然后,可以合理地扫描与INT 0x80相对应的代码可执行文件的可执行文件,以捕获制作原始Syscalls的任何尝试(0xcd 0x80 - 虽然要当心误报).但是,我只给了一些思考的时刻,我很容易错过一些东西,或者这可能是不切实际的...

其他推荐答案

您可以通过从包装器中拨出包装程序来运行编译程序,并使用Linux Ptrace(2)功能拦截和检查程序调用的所有系统调用.

以下示例代码显示一个运行/usr/bin/w命令的包装器,打印每个系统调用由命令调用,并终止命令,如果该命令试图调用Write(2)系统调用.

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/syscall.h>
#include <sys/reg.h>

#define BAD_SYSCALL __NR_write

int main(int argc, char *argv)
{
    pid_t child;
    int status, syscall_nr;

    child = fork();
    if (child == 0) {
        /* In child. */
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/usr/bin/w", NULL, NULL);
        // not reached
    }

    /* In parent. */
    while (1) {
        wait(&status);

        /* Abort loop if child has exited. */
        if (WIFEXITED(status) || WIFSIGNALED(status))
            break;

        /* Obtain syscall number from the child's process context. */
        syscall_nr = ptrace(PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
        printf("Child wants to execute system call %d: ", syscall_nr);

        if (syscall_nr != BAD_SYSCALL) {
            /* Allow system call. */
            printf("allowed.\n");
            ptrace(PTRACE_SYSCALL, child, NULL, NULL);
        } else {
            /* Terminate child. */
            printf("not allowed. Terminating child.\n");
            ptrace(PTRACE_KILL, child, NULL, NULL);
        }
    }

    exit(EXIT_SUCCESS);
}

您可以使用PTRACE做更强大的事情,例如检查和更改过程的地址空间(例如,获取并修改传递给系统调用的参数).

可以在此 Linux Journal文章及其随访.

其他推荐答案

你不能.

甚至这个程序:

#include <stdio.h>

int main()
{
    printf("Hello, World\n");
    return 0;
}

至少进行一个系统调用(将字符串" Hello,World \ n"发送到标准之处).系统调用是程序与外界互动的唯一方法.将操作系统的安全模型用于安全.

编辑此评论:

我的意思是不是所有系统调用,而是恶意系统调用,例如Execv()可用于执行BASH脚本,该脚本将我的数据删除在磁盘上.

您的操作系统已经包括阻止这种事情发生的机制.例如,为了使BASH脚本清除您的数据,该过程必须已经具有对该数据的写入访问权限.这意味着它一定是由您或根开始的.您唯一的真正选择是不安装不信任的软件.

顺便说一句,根据您的平台,Execv不一定是系统调用.在Linux上,它是真实系统调用(execve)的C库包装器.

本文地址:https://www.itbaoku.cn/post/359383.html