Wie kann ich einen Prozess für Systemaufrufe verfolgen?

Ich versuche, ein Programm zu codieren, das sich für Systemaufrufe verfolgt. Es fällt mir schwer, diese Arbeit zu machen. Ich habe versucht, eine fork () aufzurufen, um eine Instanz von sich selbst (den Code) zu erstellen, und dann den resultierenden untergeordneten Prozess zu überwachen.

Das Ziel ist, dass der übergeordnete Prozess den Index jedes vom untergeordneten Prozess ausgeführten Systemaufrufs zurückgibt und auf dem Bildschirm ausgibt. Irgendwie funktioniert es nicht wie geplant.

Hier ist der Code:

#include <unistd.h>     /* for read(), write(), close(), fork() */
#include <fcntl.h>      /* for open() */
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/reg.h>
#include <sys/wait.h>
#include <sys/types.h>


int main(int argc, char *argv[]) {
    pid_t child;
    long orig_eax;
    child = fork();

    if (0 == child) 
    {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        if (argc != 3) {
           fprintf(stderr, "Usage: copy <filefrom> <fileto>\n"); 
           return 1;
        }

        int c;
        size_t file1_fd, file2_fd; 
        if ((file1_fd = open(argv[1], O_RDONLY)) < 0) {
           fprintf(stderr, "copy: can't open %s\n", argv[1]);
           return 1;
        }

        if ((file2_fd = open(argv[2], O_WRONLY | O_CREAT)) < 0) {
            fprintf(stderr, "copy: can't open %s\n", argv[2]);
            return 1;
        }

        while (read(file1_fd, &c, 1) > 0) 
        write(file2_fd, &c, 1);
    }
    else
    {
        wait(NULL);
        orig_eax = ptrace (PTRACE_PEEKUSER, child, 4 * ORIG_EAX, NULL);
        printf("copy made a system call %ld\n", orig_eax);
        ptrace(PTRACE_CONT, child, NULL, NULL);
    }           
return 0;
}

Dieser Code basierte auf diesem Code:

#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <linux/user.h>   /* For constants
                               ORIG_EAX etc */
int main()
{   
    pid_t child;
    long orig_eax;
    child = fork();
    if(child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);
    }
    else {
        wait(NULL);
        orig_eax = ptrace(PTRACE_PEEKUSER,
                          child, 4 * ORIG_EAX,
                          NULL);
        printf("The child made a "
               "system call %ld\n", orig_eax);
        ptrace(PTRACE_CONT, child, NULL, NULL);
    }
    return 0;
}

Die Ausgabe von diesem ist:

The child made a system call 11

Dies ist der Index für den Systemaufruf exec.

Nach den Manpages für wait ():

All of these system calls are used to wait for state changes in a child
of the calling process, and obtain information about  the  child  whose
state  has changed. A state change is considered to be: the child terminated; 
the child was stopped by a signal; or the child was resumed by
a  signal.

So wie ich es verstehe, prüft der Kernel jedes Mal, wenn ein Benutzerprogramm einen Systemaufruf aufruft, zuerst, ob der Prozess verfolgt wird, bevor die Systemaufrufroutine ausgeführt wird, und unterbricht diesen Prozess mit einem Signal und gibt die Kontrolle an das übergeordnete Programm zurück . Wäre das nicht schon eine Zustandsänderung?

Antworten auf die Frage(4)

Ihre Antwort auf die Frage