forked from WuBingzheng/memleax
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ptrace_utils.h
145 lines (130 loc) · 3.23 KB
/
ptrace_utils.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
* swappers of ptrace, on GNU/Linux and FreeBSD
*
* Author: Wu Bingzheng
* Date: 2016-5
*/
#ifndef MLD_PTRACE_UTILS_H
#define MLD_PTRACE_UTILS_H
#include <sys/ptrace.h>
#include <stdio.h>
#ifdef MLX_LINUX
#include <sys/user.h>
#include <elf.h>
#include <sys/uio.h>
#ifdef MLX_ARMv7
typedef struct user_regs registers_info_t;
#else
typedef struct user_regs_struct registers_info_t;
#endif
static inline void ptrace_get_regs(pid_t pid, registers_info_t *regs)
{
#if defined PTRACE_GETREGS || defined PT_GETREGS
ptrace(PTRACE_GETREGS, pid, 0, regs);
#else
long regset = NT_PRSTATUS;
struct iovec ioVec;
ioVec.iov_base = regs;
ioVec.iov_len = sizeof(*regs);
ptrace(PTRACE_GETREGSET, pid, (void *)regset, &ioVec);
#endif
}
static inline void ptrace_set_regs(pid_t pid, registers_info_t *regs)
{
#if defined PTRACE_GETREGS || defined PT_GETREGS
ptrace(PTRACE_SETREGS, pid, 0, regs);
#else
long regset = NT_PRSTATUS;
struct iovec ioVec;
ioVec.iov_base = regs;
ioVec.iov_len = sizeof(*regs);
ptrace(PTRACE_SETREGSET, pid, (void *)regset, &ioVec);
#endif
}
static inline uintptr_t ptrace_get_data(pid_t pid, uintptr_t address)
{
return ptrace(PTRACE_PEEKTEXT, pid, address, 0);
}
static inline void ptrace_set_data(pid_t pid, uintptr_t address, uintptr_t data)
{
ptrace(PTRACE_POKETEXT, pid, address, data);
}
static inline uintptr_t ptrace_get_child(pid_t pid)
{
uintptr_t child;
ptrace(PTRACE_GETEVENTMSG, pid, 0, &child);
return child;
}
static inline int ptrace_new_child(pid_t pid, int status)
{
return (status >> 16);
}
static inline void ptrace_continue(pid_t pid, int signum)
{
ptrace(PTRACE_CONT, pid, 0, signum);
}
static inline void ptrace_attach(pid_t pid)
{
if (ptrace(PTRACE_ATTACH, pid, 0, 0) != 0) {
perror("== Attach process error:");
exit(4);
}
}
static inline void ptrace_trace_child(pid_t pid)
{
ptrace(PTRACE_SETOPTIONS, pid, 0,
PTRACE_O_TRACECLONE |
PTRACE_O_TRACEVFORK |
PTRACE_O_TRACEFORK);
}
static inline void ptrace_detach(pid_t pid, int signum)
{
ptrace(PTRACE_DETACH, pid, 0, signum);
}
#endif /* MLX_LINUX */
#ifdef MLX_FREEBSD
#include <machine/reg.h>
typedef struct reg registers_info_t;
static inline void ptrace_get_regs(pid_t pid, registers_info_t *regs)
{
ptrace(PT_GETREGS, pid, (caddr_t)regs, 0);
}
static inline void ptrace_set_regs(pid_t pid, registers_info_t *regs)
{
ptrace(PT_SETREGS, pid, (caddr_t)regs, 0);
}
static inline int ptrace_get_data(pid_t pid, uintptr_t address)
{
return ptrace(PT_READ_I, pid, (caddr_t)address, 0);
}
static inline void ptrace_set_data(pid_t pid, uintptr_t address, int data)
{
ptrace(PT_WRITE_I, pid, (caddr_t)address, data);
}
static inline void ptrace_continue(pid_t pid, int signum)
{
ptrace(PT_CONTINUE, pid, (caddr_t)1, signum);
}
static inline void ptrace_attach(pid_t pid)
{
if (ptrace(PT_ATTACH, pid, 0, 0) != 0) {
perror("== Attach process error:");
exit(4);
}
}
static inline void ptrace_trace_child(pid_t pid)
{
ptrace(PT_FOLLOW_FORK, pid, 0, 1);
}
static inline void ptrace_detach(pid_t pid, int signum)
{
ptrace(PT_DETACH, pid, 0, signum);
}
static inline int ptrace_new_child(pid_t pid, int status)
{
struct ptrace_lwpinfo pi;
ptrace(PT_LWPINFO, pid, (caddr_t)&pi, sizeof(pi));
return (pi.pl_flags & PL_FLAG_FORKED);
}
#endif /* MLX_FREEBSD */
#endif