forked from hexonxon/ftrace
-
Notifications
You must be signed in to change notification settings - Fork 0
/
task.c
112 lines (84 loc) · 2.32 KB
/
task.c
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
/**
* task.c
*
* Primary perpose of this file is to contain all architecture dependencies in accessing traced task memory and info.
*/
#include <stdlib.h>
#include <string.h>
#include <sys/ptrace.h>
#include <sys/user.h>
#include <sys/reg.h>
#include "task.h"
#include "ftrace.h"
ftrace_word_t task_peekword(struct ftrace_task* task, const void* uaddr)
{
return ptrace(PTRACE_PEEKDATA, task->pid, uaddr, NULL);
}
ftrace_word_t task_peekwordoff(struct ftrace_task* task, const void* uaddr, unsigned offset)
{
return ptrace(PTRACE_PEEKDATA, task->pid, uaddr + offset, NULL);
}
void task_peekmem(struct ftrace_task* task, const void* uaddr, void* out_buf, unsigned nbytes)
{
unsigned nwords = nbytes / FTRACE_WORD_SIZE;
unsigned residue = nbytes % FTRACE_WORD_SIZE;
while(nwords--) {
ftrace_word_t word = task_peekword(task, uaddr);
memcpy(out_buf, &word, sizeof(word));
out_buf += sizeof(word);
uaddr += sizeof(word);
}
if(residue) {
ftrace_word_t word = task_peekword(task, uaddr);
memcpy(out_buf, &word, residue);
}
}
unsigned task_peekstr(struct ftrace_task* task, const void* uaddr, char* out_str, unsigned bufsiz)
{
union {
ftrace_word_t word;
char bytes[sizeof(ftrace_word_t)];
} udata;
int eos = 0;
unsigned offset = 0;
while(!eos && (offset < bufsiz) /* -1 byte for NULL-terminator */) {
memset(&udata, 0, sizeof(udata));
udata.word = task_peekwordoff(task, uaddr, offset);
int i;
for(i = 0; i < sizeof(ftrace_word_t); ++i) {
//FTRACE_LOG("%c", udata.bytes[i]);
*out_str++ = udata.bytes[i];
if(udata.bytes[i] == '\0') {
eos++;
break;
}
}
offset += sizeof(udata.bytes);
}
//out_str[offset] = '\0';
return offset;
}
void task_syscall_info(struct ftrace_task* task, struct syscall_info* out_info)
{
struct user_regs_struct regs;
ptrace(PTRACE_GETREGS, task->pid, NULL, ®s);
#ifdef x86_64
out_info->sysno = regs.orig_rax;
out_info->rc = regs.rax;
out_info->p1 = regs.rdi;
out_info->p2 = regs.rsi;
out_info->p3 = regs.rdx;
out_info->p4 = regs.r10;
out_info->p5 = regs.r8;
out_info->p6 = regs.r9;
#elif defined(x86_32)
out_info->sysno = regs.orig_eax;
out_info->rc = regs.eax;
out_info->p1 = regs.ebx;
out_info->p2 = regs.ecx;
out_info->p3 = regs.edx;
out_info->p4 = regs.esi;
out_info->p5 = regs.edi;
out_info->p6 = regs.ebp;
#endif
}