SHOW:
|
|
- or go back to the newest paste.
1 | From : http://eli.thegreenplace.net/2011/01/23/how-debuggers-work-part-1 | |
2 | ||
3 | #include<stdio.h> | |
4 | #include<sys/reg.h> | |
5 | #include<sys/types.h> | |
6 | #include<sys/ptrace.h> | |
7 | #include<sys/wait.h> | |
8 | #include<unistd.h> | |
9 | #include<sys/user.h> | |
10 | #include<sys/syscall.h> | |
11 | ||
12 | void run_debugger(pid_t child_pid); | |
13 | void run_target(const char* programname); | |
14 | int main(int argc, char** argv) | |
15 | { | |
16 | pid_t child_pid; | |
17 | ||
18 | if (argc < 2) { | |
19 | printf("Expected a program name as argument\n"); | |
20 | return -1; | |
21 | } | |
22 | ||
23 | child_pid = fork(); | |
24 | if (child_pid == 0) | |
25 | run_target(argv[1]); | |
26 | else if (child_pid > 0) | |
27 | run_debugger(child_pid); | |
28 | else { | |
29 | printf("fork"); | |
30 | return -1; | |
31 | } | |
32 | ||
33 | return 0; | |
34 | } | |
35 | void run_target(const char* programname) | |
36 | { | |
37 | printf("target started.#include<stdio.h> | |
38 | #include<sys/reg.h> | |
39 | #include<sys/types.h> | |
40 | #include<sys/ptrace.h> | |
41 | #include<sys/wait.h> | |
42 | #include<unistd.h> | |
43 | #include<sys/user.h> | |
44 | #include<sys/syscall.h> | |
45 | ||
46 | void run_debugger(pid_t child_pid); | |
47 | void run_target(const char* programname); | |
48 | int main(int argc, char** argv) | |
49 | { | |
50 | pid_t child_pid; | |
51 | ||
52 | if (argc < 2) { | |
53 | printf("Expected a program name as argument\n"); | |
54 | return -1; | |
55 | } | |
56 | ||
57 | child_pid = fork(); | |
58 | if (child_pid == 0) | |
59 | run_target(argv[1]); | |
60 | else if (child_pid > 0) | |
61 | run_debugger(child_pid); | |
62 | else { | |
63 | printf("fork"); | |
64 | return -1; | |
65 | } | |
66 | ||
67 | return 0; | |
68 | } | |
69 | void run_target(const char* programname) | |
70 | { | |
71 | printf("target started.#include<stdio.h> | |
72 | #include<sys/reg.h> | |
73 | #include<sys/types.h> | |
74 | #include<sys/ptrace.h> | |
75 | #include<sys/wait.h> | |
76 | #include<unistd.h> | |
77 | #include<sys/user.h> | |
78 | #include<sys/syscall.h> | |
79 | ||
80 | void run_debugger(pid_t child_pid); | |
81 | void run_target(const char* programname); | |
82 | int main(int argc, char** argv) | |
83 | { | |
84 | pid_t child_pid; | |
85 | ||
86 | if (argc < 2) { | |
87 | printf("Expected a program name as argument\n"); | |
88 | return -1; | |
89 | } | |
90 | ||
91 | child_pid = fork(); | |
92 | if (child_pid == 0) | |
93 | run_target(argv[1]); | |
94 | else if (child_pid > 0) | |
95 | run_debugger(child_pid); | |
96 | else { | |
97 | printf("fork"); | |
98 | return -1; | |
99 | } | |
100 | ||
101 | return 0; | |
102 | } | |
103 | void run_target(const char* programname) | |
104 | { | |
105 | printf("target started.will run '%s'\n", programname); | |
106 | ||
107 | /* Allow tracing of this process */ | |
108 | if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) { | |
109 | printf("ptrace"); | |
110 | return; | |
111 | } | |
112 | printf("replacing process image"); | |
113 | /* Replace this process's image with the given program */ | |
114 | execl(programname, programname, NULL); | |
115 | } | |
116 | void run_debugger(pid_t child_pid) | |
117 | { | |
118 | int wait_status; | |
119 | unsigned icounter = 0; | |
120 | printf("debugger started\n"); | |
121 | ||
122 | /* Wait for child to stop on its first instruction */ | |
123 | wait(&wait_status); | |
124 | ||
125 | while (WIFSTOPPED(wait_status)) { | |
126 | icounter++; | |
127 | struct user_regs_struct regs; | |
128 | ptrace(PTRACE_GETREGS, child_pid, 0, ®s); | |
129 | unsigned instr = ptrace(PTRACE_PEEKTEXT, child_pid, regs.rip, 0); | |
130 | ||
131 | /*printf("icounter = %u. EIP = 0x%08lld. instr = 0x%08x\n", | |
132 | icounter, regs.rip, instr);*/ | |
133 | ||
134 | /* Make the child execute another instruction */ | |
135 | if (ptrace(PTRACE_SINGLESTEP, child_pid, 0, 0) < 0) { | |
136 | printf("ptrace"); | |
137 | return; | |
138 | } | |
139 | ||
140 | /* Wait for child to stop on its next instruction */ | |
141 | wait(&wait_status); | |
142 | } | |
143 | ||
144 | printf("the child executed %u instructions\n", icounter); | |
145 | } |