Changeset 2516 for neercs/trunk/src/mytrace.c
- Timestamp:
- Jul 2, 2008, 4:35:26 PM (15 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
neercs/trunk/src/mytrace.c
r2514 r2516 39 39 static int memcpy_into_target(struct mytrace *t, 40 40 long dest, char const *src, size_t n); 41 static long remote_syscall( pid_t pid, long call,41 static long remote_syscall(struct mytrace *t, long call, 42 42 long arg1, long arg2, long arg3); 43 43 # if defined DEBUG … … 53 53 #define SYSCALL_X86 0x80cd /* CD 80 = int $0x80 */ 54 54 #define SYSCALL_AMD64 0x050fL /* 0F 05 = syscall */ 55 56 #define MYCALL_OPEN 057 #define MYCALL_CLOSE 158 #define MYCALL_WRITE 259 #define MYCALL_DUP2 360 #define MYCALL_SETPGID 461 #define MYCALL_SETSID 562 #define MYCALL_KILL 663 55 64 56 #if defined __x86_64__ … … 84 76 #endif 85 77 78 #define MYCALL_OPEN 0 79 #define MYCALL_CLOSE 1 80 #define MYCALL_WRITE 2 81 #define MYCALL_DUP2 3 82 #define MYCALL_SETPGID 4 83 #define MYCALL_SETSID 5 84 #define MYCALL_KILL 6 85 #define MYCALL_FORK 7 86 #define MYCALL_EXIT 8 87 86 88 #if defined __x86_64__ 89 /* from unistd_32.h on an amd64 system */ 90 int syscalls32[] = { 5, 6, 4, 63, 57, 66, 37, 2, 1 }; 91 int syscalls64[] = 92 #else 87 93 int syscalls32[] = 88 { 5, 6, 4, 63, 57, 66, 37 }; /* from unistd_32.h on an amd64 system */89 int syscalls64[] =90 #else91 int syscalls32[] =92 94 #endif 93 95 { SYS_open, SYS_close, SYS_write, SYS_dup2, SYS_setpgid, SYS_setsid, 94 SYS_kill }; 96 SYS_kill, SYS_fork, SYS_exit }; 97 98 char const *syscallnames[] = 99 { "open", "close", "write", "dup2", "setpgid", "setsid", "kill", "fork", 100 "exit" }; 95 101 96 102 struct mytrace 97 103 { 98 pid_t pid ;104 pid_t pid, child; 99 105 }; 100 106 … … 103 109 #if defined USE_GRAB 104 110 struct mytrace *t; 111 int status; 105 112 106 113 if(ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) … … 109 116 return NULL; 110 117 } 111 waitpid(pid, NULL, 0); 118 if(waitpid(pid, &status, 0) < 0) 119 { 120 perror("waitpid"); 121 return NULL; 122 } 123 if(!WIFSTOPPED(status)) 124 { 125 fprintf(stderr, "traced process was not stopped\n"); 126 ptrace(PTRACE_DETACH, pid, 0, 0); 127 return NULL; 128 } 112 129 113 130 t = malloc(sizeof(struct mytrace)); 114 131 t->pid = pid; 132 t->child = 0; 115 133 116 134 return t; 135 #else 136 errno = ENOSYS; 137 return NULL; 138 #endif 139 } 140 141 struct mytrace* mytrace_fork(struct mytrace *t) 142 { 143 #if defined USE_GRAB 144 struct mytrace *child; 145 146 ptrace(PTRACE_SETOPTIONS, t->pid, NULL, PTRACE_O_TRACEFORK); 147 remote_syscall(t, MYCALL_FORK, 0, 0, 0); 148 waitpid(t->child, NULL, 0); 149 150 child = malloc(sizeof(struct mytrace)); 151 child->pid = t->child; 152 child->child = 0; 153 154 return child; 117 155 #else 118 156 errno = ENOSYS; … … 128 166 129 167 return 0; 168 #else 169 errno = ENOSYS; 170 return -1; 171 #endif 172 } 173 174 long mytrace_getpid(struct mytrace *t) 175 { 176 #if defined USE_GRAB 177 return t->pid; 130 178 #else 131 179 errno = ENOSYS; … … 154 202 memcpy_into_target(t, regs.RSP, path, size); 155 203 156 ret = remote_syscall(t ->pid, MYCALL_OPEN, regs.RSP, O_RDWR, 0755);204 ret = remote_syscall(t, MYCALL_OPEN, regs.RSP, O_RDWR, 0755); 157 205 158 206 /* Restore the data */ … … 175 223 { 176 224 #if defined USE_GRAB 177 return remote_syscall(t ->pid, MYCALL_CLOSE, fd, 0, 0);225 return remote_syscall(t, MYCALL_CLOSE, fd, 0, 0); 178 226 #else 179 227 errno = ENOSYS; … … 203 251 memcpy_into_target(t, regs.RSP, data, len); 204 252 205 ret = remote_syscall(t ->pid, MYCALL_WRITE, fd, regs.RSP, len);253 ret = remote_syscall(t, MYCALL_WRITE, fd, regs.RSP, len); 206 254 207 255 /* Restore the data */ … … 224 272 { 225 273 #if defined USE_GRAB 226 return remote_syscall(t ->pid, MYCALL_DUP2, oldfd, newfd, 0);274 return remote_syscall(t, MYCALL_DUP2, oldfd, newfd, 0); 227 275 #else 228 276 errno = ENOSYS; … … 234 282 { 235 283 #if defined USE_GRAB 236 return remote_syscall(t ->pid, MYCALL_SETPGID, pid, pgid, 0);284 return remote_syscall(t, MYCALL_SETPGID, pid, pgid, 0); 237 285 #else 238 286 errno = ENOSYS; … … 244 292 { 245 293 #if defined USE_GRAB 246 return remote_syscall(t ->pid, MYCALL_SETSID, 0, 0, 0);294 return remote_syscall(t, MYCALL_SETSID, 0, 0, 0); 247 295 #else 248 296 errno = ENOSYS; … … 254 302 { 255 303 #if defined USE_GRAB 256 return remote_syscall(t->pid, MYCALL_KILL, pid, sig, 0); 304 return remote_syscall(t, MYCALL_KILL, pid, sig, 0); 305 #else 306 errno = ENOSYS; 307 return -1; 308 #endif 309 } 310 311 int mytrace_exit(struct mytrace *t, int status) 312 { 313 #if defined USE_GRAB 314 ptrace(PTRACE_SETOPTIONS, t->pid, NULL, PTRACE_O_TRACEEXIT); 315 return remote_syscall(t, MYCALL_EXIT, status, 0, 0); 257 316 #else 258 317 errno = ENOSYS; … … 333 392 } 334 393 335 static long remote_syscall( pid_t pid, long call,336 394 static long remote_syscall(struct mytrace *t, long call, 395 long arg1, long arg2, long arg3) 337 396 { 338 397 /* Method for remote syscall: … … 347 406 int bits; 348 407 349 print_registers(pid); 408 if(call < 0 || call >= (long)(sizeof(syscallnames)/sizeof(*syscallnames))) 409 { 410 fprintf(stderr, "unknown remote syscall %li\n", call); 411 return -1; 412 } 413 414 debug("remote syscall %s(%lu, %lu, %lu)", 415 syscallnames[call], arg1, arg2, arg3); 416 417 print_registers(t->pid); 418 350 419 #if defined __x86_64__ 351 420 bits = 64; … … 356 425 for(;;) 357 426 { 358 if(ptrace(PTRACE_GETREGS, pid, NULL, &oldregs) < 0)427 if(ptrace(PTRACE_GETREGS, t->pid, NULL, &oldregs) < 0) 359 428 { 360 429 fprintf(stderr, "PTRACE_GETREGS failed\n"); … … 362 431 } 363 432 364 oinst = ptrace(PTRACE_PEEKTEXT, pid, oldregs.RIP - 2, 0) & 0xffff;433 oinst = ptrace(PTRACE_PEEKTEXT, t->pid, oldregs.RIP - 2, 0) & 0xffff; 365 434 366 435 #if defined __x86_64__ … … 377 446 #endif 378 447 379 if(ptrace(PTRACE_SYSCALL, pid, NULL, 0) < 0)448 if(ptrace(PTRACE_SYSCALL, t->pid, NULL, 0) < 0) 380 449 { 381 450 perror("ptrace_syscall (1)"); 382 451 return -1; 383 452 } 384 waitpid( pid, NULL, 0);385 386 if(ptrace(PTRACE_SYSCALL, pid, NULL, 0) < 0)453 waitpid(t->pid, NULL, 0); 454 455 if(ptrace(PTRACE_SYSCALL, t->pid, NULL, 0) < 0) 387 456 { 388 457 perror("ptrace_syscall (2)"); 389 458 return -1; 390 459 } 391 waitpid( pid, NULL, 0);392 } 393 394 print_registers( pid);460 waitpid(t->pid, NULL, 0); 461 } 462 463 print_registers(t->pid); 395 464 396 465 regs = oldregs; … … 413 482 } 414 483 415 if(ptrace(PTRACE_SETREGS, pid, NULL, ®s) < 0)484 if(ptrace(PTRACE_SETREGS, t->pid, NULL, ®s) < 0) 416 485 { 417 486 fprintf(stderr, "PTRACE_SETREGS failed\n"); … … 419 488 } 420 489 421 print_registers(pid); 422 423 if(ptrace(PTRACE_SINGLESTEP, pid, NULL, NULL) < 0) 424 { 425 fprintf(stderr, "PTRACE_SINGLESTEP failed\n"); 426 return -1; 427 } 428 waitpid(pid, NULL, 0); 429 430 print_registers(pid); 431 432 if(ptrace(PTRACE_GETREGS, pid, NULL, ®s) < 0) 490 for(;;) 491 { 492 int status; 493 494 print_registers(t->pid); 495 496 if(ptrace(PTRACE_SINGLESTEP, t->pid, NULL, NULL) < 0) 497 { 498 fprintf(stderr, "PTRACE_SINGLESTEP failed\n"); 499 return -1; 500 } 501 waitpid(t->pid, &status, 0); 502 503 if(WIFEXITED(status)) 504 return 0; 505 506 if(!WIFSTOPPED(status) || WSTOPSIG(status) != SIGTRAP) 507 continue; 508 509 /* Fuck Linux: there is no macro for this */ 510 switch((status >> 16) & 0xffff) 511 { 512 case PTRACE_EVENT_FORK: 513 if(ptrace(PTRACE_GETEVENTMSG, t->pid, 0, &t->child) < 0) 514 { 515 fprintf(stderr, "PTRACE_GETEVENTMSG failed\n"); 516 return -1; 517 } 518 continue; 519 case PTRACE_EVENT_EXIT: 520 /* The process is about to exit, don't do anything else */ 521 return 0; 522 } 523 524 break; 525 } 526 527 print_registers(t->pid); 528 529 if(ptrace(PTRACE_GETREGS, t->pid, NULL, ®s) < 0) 433 530 { 434 531 fprintf(stderr, "PTRACE_GETREGS failed\n"); … … 436 533 } 437 534 438 if(ptrace(PTRACE_SETREGS, pid, NULL, &oldregs) < 0)535 if(ptrace(PTRACE_SETREGS, t->pid, NULL, &oldregs) < 0) 439 536 { 440 537 fprintf(stderr, "PTRACE_SETREGS failed\n"); 441 538 return -1; 442 539 } 443 print_registers( pid);444 445 debug("syscall % ld returned %ld", call, regs.RAX);540 print_registers(t->pid); 541 542 debug("syscall %s returned %ld", syscallnames[call], regs.RAX); 446 543 447 544 if((long)regs.RAX < 0)
Note: See TracChangeset
for help on using the changeset viewer.