Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/arch/amd64/ptrace-sce-tamper.c
289026 views
1
/*
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2026 Alex S <[email protected]>
5
*/
6
7
#include <machine/reg.h>
8
#include <sys/ptrace.h>
9
#include <sys/syscall.h>
10
#include <sys/wait.h>
11
12
#include <assert.h>
13
#include <err.h>
14
#include <signal.h>
15
#include <stdio.h>
16
#include <stdlib.h>
17
#include <unistd.h>
18
19
#ifndef __amd64__
20
#error "amd64 only"
21
#endif
22
23
/*
24
* This test substitutes exit(42) instead of getpid() using ptrace.
25
*/
26
27
static const int EXPECTED_EXIT_CODE = 42;
28
29
static void
30
tamper(pid_t pid)
31
{
32
struct ptrace_lwpinfo info;
33
struct reg regs;
34
35
if (ptrace(PT_LWPINFO, pid, (caddr_t)&info, sizeof(info)) == -1)
36
err(1, "ptrace(PT_LWPINFO)");
37
38
if ((info.pl_flags & PL_FLAG_SCE) != 0 &&
39
info.pl_syscall_code == SYS_getpid) {
40
if (ptrace(PT_GETREGS, pid, (caddr_t)&regs, sizeof(regs)) == -1)
41
err(1, "ptrace(PT_GETREGS)");
42
43
regs.r_rax = SYS_exit;
44
regs.r_rdi = EXPECTED_EXIT_CODE;
45
46
if (ptrace(PT_SETREGS, pid, (caddr_t)&regs, sizeof(regs)) == -1)
47
err(1, "ptrace(PT_SETREGS)");
48
}
49
}
50
51
int
52
main(void)
53
{
54
pid_t pid;
55
int status;
56
57
pid = fork();
58
if (pid == -1)
59
err(1, "fork");
60
61
if (pid == 0) {
62
raise(SIGSTOP);
63
(void)getpid();
64
exit(0);
65
} else {
66
if (ptrace(PT_ATTACH, pid, 0, 0) == -1)
67
err(1, "ptrace(PT_ATTACH)");
68
69
for (;;) {
70
if (wait(&status) == -1)
71
err(1, "wait");
72
73
if (WIFEXITED(status)) {
74
if (WEXITSTATUS(status) == EXPECTED_EXIT_CODE) {
75
printf("exit code changed\n");
76
exit(0);
77
} else {
78
printf("unable to change exit code\n");
79
exit(1);
80
}
81
}
82
83
assert(WIFSTOPPED(status));
84
tamper(pid);
85
86
if (ptrace(PT_TO_SCE, pid, (caddr_t)1, 0) == -1)
87
err(1, "ptrace(PT_TO_SCE)");
88
}
89
}
90
}
91
92