SystemCall儿童父母执行问题(fork Execve)Linux

发布于 2025-02-06 05:03:33 字数 1005 浏览 2 评论 0原文

我是SystemCall的新手。我在孩子内使用execve,因此父母应像正常情况一样运行,而不是由execve打开。问题是孩子在执行后执行并停止整个事情。我的目标是计算Execve执行的BASH命令(参数)中执行的克隆数量。

我读了那个男人,我仍然有些困惑。 我只能使用ptrace,fork,等待/等待。

争论:

/bin/bash -c "echo 'first test' | wc -c"
int main(int argc, char *argv[]) {
    pid_t child_pid = fork();
    int status;
    int counter = 0;
    wait(&status);
    if (child_pid == -1) {
        exit(1);
    } else {
        while(status != child_pid){
            if (child_pid == 0) {
                ptrace(PTRACE_TRACEME, child_pid, 0, 0);
                raise(SIGSTOP);
                execve(argv[1], &argv[1], NULL);
                ptrace(PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACECLONE);
                ptrace(PTRACE_CONT, child_pid, 0L, 0L);
                if(status>>8 == (SIGTRAP | (PTRACE_EVENT_CLONE<<8)))
                    counter++;
            }
        }
    }
    printf("# of clone executions: %d", counter);
    return 0;
}

Im new to systemcall. Im using execve inside a child so the parent should run as normal and not be ovewritten by execve. The problem is that the child executes and stops the whole thing after execve. My goal here is to count the number of clone executed in the bash command(argument) executed by execve.

Ive read the man, Im still a bit confused.
I can only use ptrace, fork, wait/waitpid.

argument:

/bin/bash -c "echo 'first test' | wc -c"
int main(int argc, char *argv[]) {
    pid_t child_pid = fork();
    int status;
    int counter = 0;
    wait(&status);
    if (child_pid == -1) {
        exit(1);
    } else {
        while(status != child_pid){
            if (child_pid == 0) {
                ptrace(PTRACE_TRACEME, child_pid, 0, 0);
                raise(SIGSTOP);
                execve(argv[1], &argv[1], NULL);
                ptrace(PTRACE_SETOPTIONS, child_pid, 0, PTRACE_O_TRACECLONE);
                ptrace(PTRACE_CONT, child_pid, 0L, 0L);
                if(status>>8 == (SIGTRAP | (PTRACE_EVENT_CLONE<<8)))
                    counter++;
            }
        }
    }
    printf("# of clone executions: %d", counter);
    return 0;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

臻嫒无言 2025-02-13 05:03:36

execve将覆盖子进程,因此execve之后的任何指令都不会执行,除非呼叫execve失败。取而代之的是,您应该运行ptrace跟踪execve在父进程

编辑中出现:这是一个评论的解决方案,用于计算clone syscalls的数量:

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

int main(int argc, char *argv[]) {
  pid_t child_pid = fork();
  int counter = 0;
  int entering_syscall = 1;

  if(child_pid == -1) {
    perror("fork failed");
    exit(1);
  } else if(child_pid != 0) {
    // parent
    u_int64_t rax;
    int status;

    while(1) {
      // wait for the next signal by the child
      if(wait(&status) != child_pid)
        continue;

      if(WIFEXITED(status)) {
        puts("child exited");
        break;
      }

      // read the USER area, defined in sys/user.h, which contains the registers information
      // in linux, rax contains the syscall number
      rax = ptrace(PTRACE_PEEKUSER, child_pid, 8 * ORIG_RAX, NULL);

      if(rax == SYS_clone /* 56 */) {
        // PTRACE_SYSCALL generates a signal both when entering and exiting a syscall
        // only count the syscall during enter
        if(entering_syscall)
          counter++;

        entering_syscall = !entering_syscall;
      }

      //printf("syscall %ld\n", rax);

      // continue the child process until the next syscall enter/exit
      ptrace(PTRACE_SYSCALL, child_pid, NULL, NULL);
    }
  } else {
    // child

    // turns the calling thread into a tracee
    ptrace(PTRACE_TRACEME, child_pid, 0, 0);

    // signal and wait for the parent. This ensures that PTRACE_SYSCALL
    // will not miss any child syscall
    raise(SIGSTOP);

    execve(argv[1], &argv[1], NULL);

    // should be never reached
    perror("execve failed");
    exit(1);
  }

  printf("Num clone: %d\n", counter);
}

您可以交叉检查它反对strace strace 2&gt;&amp; 1 your_command | grep克隆| WC -L

execve will overwrite the child process, so any instruction after execve will not be executed, unless the call to execve fails. You should instead run the ptrace tracing that appears after the execve in the parent process

Edit: here is a commented solution to count the number of clone syscalls:

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

int main(int argc, char *argv[]) {
  pid_t child_pid = fork();
  int counter = 0;
  int entering_syscall = 1;

  if(child_pid == -1) {
    perror("fork failed");
    exit(1);
  } else if(child_pid != 0) {
    // parent
    u_int64_t rax;
    int status;

    while(1) {
      // wait for the next signal by the child
      if(wait(&status) != child_pid)
        continue;

      if(WIFEXITED(status)) {
        puts("child exited");
        break;
      }

      // read the USER area, defined in sys/user.h, which contains the registers information
      // in linux, rax contains the syscall number
      rax = ptrace(PTRACE_PEEKUSER, child_pid, 8 * ORIG_RAX, NULL);

      if(rax == SYS_clone /* 56 */) {
        // PTRACE_SYSCALL generates a signal both when entering and exiting a syscall
        // only count the syscall during enter
        if(entering_syscall)
          counter++;

        entering_syscall = !entering_syscall;
      }

      //printf("syscall %ld\n", rax);

      // continue the child process until the next syscall enter/exit
      ptrace(PTRACE_SYSCALL, child_pid, NULL, NULL);
    }
  } else {
    // child

    // turns the calling thread into a tracee
    ptrace(PTRACE_TRACEME, child_pid, 0, 0);

    // signal and wait for the parent. This ensures that PTRACE_SYSCALL
    // will not miss any child syscall
    raise(SIGSTOP);

    execve(argv[1], &argv[1], NULL);

    // should be never reached
    perror("execve failed");
    exit(1);
  }

  printf("Num clone: %d\n", counter);
}

You can cross-check it against strace strace 2>&1 your_command | grep clone | wc -l

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文