Ptrace

Från Wiki.linux.se
Hoppa till navigering Hoppa till sök

ptrace - Kontrollera och övervaka processer

`ptrace` är ett systemanrop som används för att kontrollera och övervaka processer. Det används främst av debuggers och andra verktyg för att undersöka och manipulera en annan process.

NAMN

ptrace - Kontrollera och övervaka processer

SYNOPSIS


#include <sys/ptrace.h>
long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data);

BESKRIVNING

`ptrace` är ett systemanrop som tillåter en process (spåraren) att observera och kontrollera en annan process (spårad process). `ptrace` används ofta av debuggers som GDB för att sätta brytpunkter, inspektera minne, och stegvis exekvera instruktioner.

ALTERNATIV

`ptrace` stöder flera alternativ som definieras av enum-typen `__ptrace_request`. Här är de vanligaste alternativen:

  • PTRACE_TRACEME - Gör den aktuella processen spårbar av sin förälder.
  • PTRACE_PEEKTEXT, PTRACE_PEEKDATA, PTRACE_PEEKUSER - Läs ett ord från minnet eller register från den spårade processen.
  • PTRACE_POKETEXT, PTRACE_POKEDATA, PTRACE_POKEUSER - Skriv ett ord till minnet eller register i den spårade processen.
  • PTRACE_CONT - Fortsätt exekveringen av en spårad process.
  • PTRACE_SYSCALL - Fortsätt en spårad process och stoppa vid nästa systemanrop.
  • PTRACE_SINGLESTEP - Stegvis exekvera en instruktion i den spårade processen.
  • PTRACE_GETREGS, PTRACE_SETREGS - Hämta eller ställ in registervärden i den spårade processen.
  • PTRACE_GETFPREGS, PTRACE_SETFPREGS - Hämta eller ställ in flyttalsregister i den spårade processen.
  • PTRACE_ATTACH - Fäst till en redan körande process och gör den spårbar.
  • PTRACE_DETACH - Koppla loss från en spårad process.
  • PTRACE_KILL - Skicka ett SIGKILL-signal till en spårad process.

ANVÄNDNING

Här är flera exempel på hur man använder `ptrace` för att kontrollera och övervaka processer:

Göra en process spårbar

För att en process ska kunna spåras av sin förälder, ska den anropa `ptrace` med `PTRACE_TRACEME`.

EXEMPEL

#include <sys/ptrace.h>
#include <unistd.h>
int main() {
    ptrace(PTRACE_TRACEME, 0, NULL, NULL);
    execl("/bin/ls", "ls", NULL);
    return 0;
}

Detta program gör sig självt spårbart och kör sedan `ls`.

Läsa från en spårad process

För att läsa ett ord från minnet i en spårad process, använd `PTRACE_PEEKDATA`.

EXEMPEL

#include <sys/ptrace.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int main() {
    pid_t child = fork();
    if (child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);
    } else {
        wait(NULL);
        long data = ptrace(PTRACE_PEEKDATA, child, (void*)0x400000, NULL);
        printf("Data at 0x400000: %lx\n", data);
        ptrace(PTRACE_CONT, child, NULL, NULL);
    }
    return 0;
}

Detta program spårar ett barnprocess som kör `ls` och läser ett ord från dess minne.

Stegvis exekvera instruktioner

För att stegvis exekvera instruktioner i en spårad process, använd `PTRACE_SINGLESTEP`.

EXEMPEL

#include <sys/ptrace.h>
#include <sys/wait.h>
#include <unistd.h>
int main() {
    pid_t child = fork();
    if (child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);
    } else {
        wait(NULL);
        for (int i = 0; i < 10; i++) {
            ptrace(PTRACE_SINGLESTEP, child, NULL, NULL);
            wait(NULL);
        }
        ptrace(PTRACE_CONT, child, NULL, NULL);
    }
    return 0;
}

Detta program stegvis exekverar 10 instruktioner i en spårad process som kör `ls`.

Fästa till en redan körande process

För att fästa till en redan körande process och göra den spårbar, använd `PTRACE_ATTACH`.

EXEMPEL

#include <sys/ptrace.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <pid>\n", argv[0]);
        return 1;
    }
    pid_t pid = atoi(argv[1]);
    ptrace(PTRACE_ATTACH, pid, NULL, NULL);
    wait(NULL);
    printf("Attached to process %d\n", pid);
    ptrace(PTRACE_DETACH, pid, NULL, NULL);
    return 0;
}

Detta program fäster till en redan körande process med angivet PID och gör den spårbar.

SKILLNADER MELLAN macOS OCH LINUX

Det finns viktiga skillnader att tänka på när man använder `ptrace` på macOS jämfört med Linux:

Tillgänglighet: `ptrace` är tillgängligt på både macOS och Linux, men implementationen och stödet för olika funktioner kan variera.

Funktionsuppsättning: Vissa `ptrace`-funktioner som är tillgängliga på Linux kanske inte är tillgängliga på macOS, och vice versa. Till exempel kan `PTRACE_SYSEMU` och `PTRACE_SYSEMU_SINGLESTEP` vara Linux-specifika.

Säkerhetsbegränsningar: macOS har strängare säkerhetsbegränsningar för `ptrace`-användning. På macOS kan det krävas att processen körs med root-behörighet eller att System Integrity Protection (SIP) är inaktiverat för att tillåta fullständig spårning.

Prestanda: Prestandan för `ptrace`-operationer kan variera mellan macOS och Linux beroende på operativsystemets kärnimplementation och optimeringar.

FELSÖKNING

Om du får ett felmeddelande när du använder `ptrace`, kontrollera följande:

Att du använder rätt syntax och alternativ för ditt specifika kommando. Att processen du försöker spåra existerar och har rätt behörigheter. Att alla nödvändiga paket och bibliotek är installerade och uppdaterade. Att du har tillräckliga användarrättigheter för att spåra processer.

Vanliga fel och deras lösningar:

  • Felmeddelande: "Permission denied":
 * Lösning: Kontrollera att du har nödvändiga behörigheter för att spåra de specifika processerna. På macOS kan det krävas root-behörighet eller att SIP är inaktiverat.
  • Felmeddelande: "No such process":
 * Lösning: Kontrollera att den angivna processen existerar och är korrekt stavad.
  • Felmeddelande: "Invalid request":
 * Lösning: Kontrollera att du använder en giltig `ptrace`-begäran för ditt operativsystem.

AVANCERAD ANVÄNDNING

`ptrace` erbjuder avancerade funktioner som kan användas för att spåra och analysera processer mer effektivt. Här är några exempel:

Inspektera och ändra registervärden

Du kan använda `PTRACE_GETREGS` och `PTRACE_SETREGS` för att inspektera och ändra registervärden i en spårad process.

EXEMPEL

#include <sys/ptrace.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h>
#include <stdio.h>
int main() {
    pid_t child = fork();
    if (child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);
    } else {
        wait(NULL);
        struct user_regs_struct regs;
        ptrace(PTRACE_GETREGS, child, NULL, &regs);
        printf("RIP: %llx\n", regs.rip);
        regs.rip += 2;  // Ändra instruktionspekaren
        ptrace(PTRACE_SETREGS, child, NULL, &regs);
        ptrace(PTRACE_CONT, child, NULL, NULL);
    }
    return 0;
}

Detta program inspekterar och ändrar instruktionspekaren i en spårad process som kör `ls`.

Spåra systemanrop

Du kan använda `PTRACE_SYSCALL` för att stoppa en process vid varje systemanrop.

EXEMPEL

#include <sys/ptrace.h>
#include <sys/wait.h>
#include <unistd.h>
#include <sys/user.h>
#include <stdio.h>
int main() {
    pid_t child = fork();
    if (child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);
    } else {
        int status;
        wait(&status);
        while (WIFSTOPPED(status)) {
            ptrace(PTRACE_SYSCALL, child, NULL, NULL);
            wait(&status);
            if (WIFSTOPPED(status)) {
                struct user_regs_struct regs;
                ptrace(PTRACE_GETREGS, child, NULL, &regs);
                printf("System call: %lld\n", regs.orig_rax);
            }
        }
    }
    return 0;
}

Detta program spårar systemanrop i en process som kör `ls`.

Fånga och hantera signaler

Du kan använda `ptrace` för att fånga och hantera signaler som skickas till en spårad process.

EXEMPEL

#include <sys/ptrace.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int main() {
    pid_t child = fork();
    if (child == 0) {
        ptrace(PTRACE_TRACEME, 0, NULL, NULL);
        execl("/bin/ls", "ls", NULL);
    } else {
        int status;
        wait(&status);
        while (WIFSTOPPED(status)) {
            int signal = WSTOPSIG(status);
            printf("Caught signal: %d\n", signal);
            ptrace(PTRACE_CONT, child, NULL, (void*)(long)signal);
            wait(&status);
        }
    }
    return 0;
}

Detta program fångar och hanterar signaler som skickas till en process som kör `ls`.

SE ÄVEN

  • strace - Spåra systemanrop och signaler (Linux).
  • dtrace - Dynamisk spårning av operativsystem och applikationer.
  • gdb - GNU Debugger.
  • lsof - Lista öppna filer och de processer som använder dem.

FÖRFATTARE

`ptrace` utvecklades som en del av Unix-operativsystemet och är nu en del av flera operativsystem inklusive Linux och macOS.

KOLOFON

Denna sida är en del av `ptrace`-projektet. Mer information om projektet finns på ⟨https://man7.org/linux/man-pages/man2/ptrace.2.html⟩. Om du har en buggrapport för denna manualsida, se ⟨https://man7.org/linux/man-pages⟩. Denna sida erhölls från projektets upstream Git-repository ⟨https://github.com/man-pages-5.10.git⟩ den 2023-12-22. Om du upptäcker några renderingsproblem i denna HTML-version av sidan, eller om du tror att det finns en bättre eller mer uppdaterad källa för sidan, eller om du har korrigeringar eller förbättringar av informationen i denna KOLOFON (som inte är en del av den ursprungliga manualsidan), skicka ett e-postmeddelande till man-pages@man7.org.

KÄLLOR

ptrace manual (Linux) ptrace GitHub Repository