Path: blob/main/tests/sys/arch/amd64/ptrace-sce-tamper.c
289026 views
/*1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2026 Alex S <[email protected]>4*/56#include <machine/reg.h>7#include <sys/ptrace.h>8#include <sys/syscall.h>9#include <sys/wait.h>1011#include <assert.h>12#include <err.h>13#include <signal.h>14#include <stdio.h>15#include <stdlib.h>16#include <unistd.h>1718#ifndef __amd64__19#error "amd64 only"20#endif2122/*23* This test substitutes exit(42) instead of getpid() using ptrace.24*/2526static const int EXPECTED_EXIT_CODE = 42;2728static void29tamper(pid_t pid)30{31struct ptrace_lwpinfo info;32struct reg regs;3334if (ptrace(PT_LWPINFO, pid, (caddr_t)&info, sizeof(info)) == -1)35err(1, "ptrace(PT_LWPINFO)");3637if ((info.pl_flags & PL_FLAG_SCE) != 0 &&38info.pl_syscall_code == SYS_getpid) {39if (ptrace(PT_GETREGS, pid, (caddr_t)®s, sizeof(regs)) == -1)40err(1, "ptrace(PT_GETREGS)");4142regs.r_rax = SYS_exit;43regs.r_rdi = EXPECTED_EXIT_CODE;4445if (ptrace(PT_SETREGS, pid, (caddr_t)®s, sizeof(regs)) == -1)46err(1, "ptrace(PT_SETREGS)");47}48}4950int51main(void)52{53pid_t pid;54int status;5556pid = fork();57if (pid == -1)58err(1, "fork");5960if (pid == 0) {61raise(SIGSTOP);62(void)getpid();63exit(0);64} else {65if (ptrace(PT_ATTACH, pid, 0, 0) == -1)66err(1, "ptrace(PT_ATTACH)");6768for (;;) {69if (wait(&status) == -1)70err(1, "wait");7172if (WIFEXITED(status)) {73if (WEXITSTATUS(status) == EXPECTED_EXIT_CODE) {74printf("exit code changed\n");75exit(0);76} else {77printf("unable to change exit code\n");78exit(1);79}80}8182assert(WIFSTOPPED(status));83tamper(pid);8485if (ptrace(PT_TO_SCE, pid, (caddr_t)1, 0) == -1)86err(1, "ptrace(PT_TO_SCE)");87}88}89}909192