-
Notifications
You must be signed in to change notification settings - Fork 0
/
tracer.c
91 lines (75 loc) · 1.94 KB
/
tracer.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
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <syscall.h>
#include <sys/ptrace.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/reg.h>
#include <sys/user.h>
void procmsg(const char* format, ...)
{
va_list ap;
fprintf(stdout, "[%d] ", getpid());
va_start(ap, format);
vfprintf(stdout, format, ap);
va_end(ap);
}
void run_target(const char* name)
{
procmsg("target process started. will run '%s'\n", name);
if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
perror("ptrace");
return;
}
execl(name, name, 0);
}
void run_debugger(pid_t child_pid)
{
int wait_status;
struct user_regs_struct regs;
unsigned icounter = 0;
procmsg("debugger started\n");
wait(&wait_status);
/*Obtain and show child instruction pointer*/
ptrace(PTRACE_GETREGS, child_pid, 0, ®s);
procmsg("Child started. EIP = 0x%08x\n", regs.rip);
unsigned addr = regs.rip;
unsigned data = ptrace(PTRACE_PEEKTEXT, child_pid, (void*)addr, 0);
procmsg("Original data at 0x%08x: 0x%08x\n", addr, data);
unsigned data_with_trap = (data && 0xFFFFFFFFFFFFFF00) | 0xCC;
ptrace(PTRACE_POKETEXT, child_pid, (void*)addr, (void*)data_with_trap);
while(WIFSTOPPED(wait_status)){
icounter++;
// struct user_regs_struct regs;
ptrace(PTRACE_GETREGS, child_pid, 0, ®s);
unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.rip, 0);
// procmsg("icounter = %u EIP = 0x%08x instr = 0x%08x\n", icounter, regs.rip, instr);
if(ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0){
perror("ptrace");
return;
}
wait(&wait_status);
}
procmsg("the child executed %u instructions\n", icounter);
}
int main(int argc, char** argv)
{
pid_t child_pid;
if(argc < 2){
fprintf(stderr, "Expected a program name as an argument\n");
return -1;
}
child_pid = fork();
if(child_pid == 0)
run_target(argv[1]);
else if (child_pid > 0)
run_debugger(child_pid);
else {
perror("fork");
return -1;
}
return 0;
}