質問編集履歴

2

追記しました

2019/08/22 18:01

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -45,3 +45,241 @@
45
45
  //これ以降何も表示されない。sampleの方は動き続けている
46
46
 
47
47
  ```
48
+
49
+
50
+
51
+ ###追記
52
+
53
+ やはりaddrの値が違ったようで、自分で書いたコードでPTRACE_GETREGSでEIPを取得し、その位置にint3を書き込むことでブレークポイントを仕掛けることには成功しました。ただ、上記のサイトのように、目的の関数にブレークポイントを仕掛けることは未だできていません。目的の関数にブレークポイントを仕掛けるにはどうしたらいいでしょうか。
54
+
55
+
56
+
57
+ また、addrの値が違うなら、そもそもnmコマンドで表示されているアドレスは一体何なのでしょうか。
58
+
59
+ [あなたが知らないプログラムの真の始まり――main()関数の前にあるスタートアップとは (2/3)](https://www.atmarkit.co.jp/ait/articles/1703/01/news173_2.html)
60
+
61
+ こちらの記事によると、nmやreadelfで表示できるアドレスは実際に実行される際のアドレスのようですが、私の環境ではどうにも一致していません。
62
+
63
+
64
+
65
+ 以下自分で書いたコードです。都合上32bitでコンパイルしています。
66
+
67
+
68
+
69
+ ```
70
+
71
+ gcc -m32 -o TestHook TestHook.c
72
+
73
+ ```
74
+
75
+
76
+
77
+ ```TestHook
78
+
79
+ #include <stdio.h>
80
+
81
+ #include <stdlib.h>
82
+
83
+ #include <sys/ptrace.h>
84
+
85
+ #include <unistd.h>
86
+
87
+ #include <sys/types.h>
88
+
89
+ #include <sys/wait.h>
90
+
91
+ #include <sys/user.h>
92
+
93
+ #include <elf.h>
94
+
95
+
96
+
97
+
98
+
99
+ //forkしたプロセスをexecvp()で別のプロセスに置き換える
100
+
101
+ int child(int argc, char* argv[])
102
+
103
+ {
104
+
105
+ if(argc < 2){
106
+
107
+ puts("error : argument");
108
+
109
+ return -1;
110
+
111
+ }
112
+
113
+
114
+
115
+ long ret;
116
+
117
+ ret = ptrace(PTRACE_TRACEME, 0, 0, 0);
118
+
119
+ if(ret < 0){
120
+
121
+ perror("failed PTRACE_TRACEME");
122
+
123
+ exit(1);
124
+
125
+ }
126
+
127
+
128
+
129
+ ret = execvp(argv[1], argv);
130
+
131
+ if(ret < 0){
132
+
133
+ perror("failed to execvp");
134
+
135
+ exit(1);
136
+
137
+ }
138
+
139
+ puts("error"); //通常ならば実行されない
140
+
141
+ return 0;
142
+
143
+ }
144
+
145
+
146
+
147
+ //子の状態変化を待ち、SIGTRAPを受け取ると再開.int3を入れたりいろいろやる
148
+
149
+ void parent(pid_t pid)
150
+
151
+ {
152
+
153
+  int status;
154
+
155
+ int ret;
156
+
157
+ struct user_regs_struct regs;
158
+
159
+ unsigned addr;
160
+
161
+ unsigned original_data;
162
+
163
+ unsigned trap_data;
164
+
165
+ unsigned readback_data;
166
+
167
+ addr = strtol("0x0000051d", NULL, 0);
168
+
169
+
170
+
171
+ waitpid(pid, &status, 0);
172
+
173
+ if(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP){
174
+
175
+
176
+
177
+ //レジスタの値を取得
178
+
179
+ ret = ptrace(PTRACE_GETREGS, pid, 0, &regs);
180
+
181
+ if(ret < 0){
182
+
183
+ puts("Failed PTRACE_GETREGS");
184
+
185
+ }
186
+
187
+ printf("Child started. EIP = 0x%08x\n", regs.eip);
188
+
189
+
190
+
191
+ //元データの読み出し
192
+
193
+ original_data = ptrace(PTRACE_PEEKTEXT, pid, (void *)regs.eip, 0);
194
+
195
+ if(original_data == -1){
196
+
197
+ puts("PEEK_TEXT error");
198
+
199
+ }
200
+
201
+ printf("Original data at 0x%08x : 0x%08x\n",regs.eip, original_data);
202
+
203
+
204
+
205
+ //int3の書き込み
206
+
207
+ trap_data = (original_data & 0xFFFFFF00) | 0xCC;
208
+
209
+ ret = ptrace(PTRACE_POKETEXT, pid, (void *)regs.eip, (void *)trap_data);
210
+
211
+ if(ret < 0){
212
+
213
+ puts("Failed to PTRACE_POKETEXT");
214
+
215
+ }
216
+
217
+
218
+
219
+ //書き込み後のデータの所得
220
+
221
+ readback_data = ptrace(PTRACE_PEEKTEXT, pid, (void *)regs.eip, 0);
222
+
223
+ printf("After trap, data at 0x%08x : 0x%08x\n",regs.eip, readback_data);
224
+
225
+
226
+
227
+ sleep(3);
228
+
229
+
230
+
231
+ puts("\nRestart child process.");
232
+
233
+ puts("----------------------------");
234
+
235
+ ptrace(PTRACE_CONT, pid, 0, 0); //停止している子プロセスの再開
236
+
237
+ waitpid(pid, &status, 0);
238
+
239
+ if(WIFSTOPPED(status)){
240
+
241
+ puts("Breakpoint int3");
242
+
243
+ }
244
+
245
+ }
246
+
247
+ }
248
+
249
+
250
+
251
+
252
+
253
+ int main(int argc, char *argv[])
254
+
255
+ {
256
+
257
+ pid_t child_pid = fork();
258
+
259
+
260
+
261
+ switch(child_pid){
262
+
263
+ case 0:
264
+
265
+ {
266
+
267
+ child(argc, argv);
268
+
269
+ }
270
+
271
+ default :
272
+
273
+ {
274
+
275
+ parent(child_pid);
276
+
277
+ }
278
+
279
+ }
280
+
281
+ }
282
+
283
+
284
+
285
+ ```

1

リンクを修正しました

2019/08/22 18:01

投稿

退会済みユーザー
test CHANGED
File without changes
test CHANGED
@@ -1,6 +1,6 @@
1
1
  現在、ptraceを使ったデバッグの勉強をしています。以下のサイトのデバッガを試してみたのですが上手くいきません。元のコードに手は加えていません。
2
2
 
3
- https://th0x4c.github.io/blog/2013/08/27/debug-debugging-with-ptrace/
3
+ [[Debug] Ptrace によるデバッグ]( https://th0x4c.github.io/blog/2013/08/27/debug-debugging-with-ptrace/)
4
4
 
5
5
 
6
6
 
@@ -12,7 +12,7 @@
12
12
 
13
13
 
14
14
 
15
- 以下は実際に試した様子です。ubuntu64bitを使用しています。
15
+ 以下は実際に試した様子です。vmware上のubuntu-64bitを使用しています。
16
16
 
17
17
 
18
18
 
@@ -42,6 +42,6 @@
42
42
 
43
43
 
44
44
 
45
- これ以降何も表示されない。sampleの方は動き続けている
45
+ //これ以降何も表示されない。sampleの方は動き続けている
46
46
 
47
47
  ```