/* Author: Steve Fink (http://foxglove.dnsalias.org/~sfink/) */ #include #include #include #include #include #include #include #include #include int main(int argc, char ** argv) { char* pid_arg = argv[1]; char* offset_arg = argv[2]; char* size_arg = argv[3]; pid_t pid = strtol(pid_arg, NULL, 0); int fd; char fname[200]; long offset; long size = 4096; char buffer[4096]; if ((int)pid <= 0) { fprintf(stderr, "Invalid pid arg '%s'\n", pid_arg); exit(1); } fprintf(stderr, "attaching to process %d...\n", pid); if (ptrace(PTRACE_ATTACH, pid, NULL, NULL) < 0) { fprintf(stderr, "attach failed: %s\n", strerror(errno)); exit(1); } wait(NULL); sprintf(fname, "/proc/%d/mem", pid); fd = open(fname, O_RDONLY); if (fd < 0) { fprintf(stderr, "open %s: %s\n", fname, strerror(errno)); goto ERROR; } if (offset_arg != NULL) { offset = strtol(offset_arg, NULL, 0); if (offset <= 0) { fprintf(stderr, "invalid offset '%s'\n", offset_arg); goto ERROR; } } if (offset_arg != NULL && size_arg != NULL) { size = strtol(size_arg, NULL, 0); if (size <= 0) { fprintf(stderr, "invalid size '%s'\n", size_arg); goto ERROR; } } if (offset != 0) { if (lseek(fd, offset, SEEK_SET) == (off_t) -1) { fprintf(stderr, "seek failed: %s\n", strerror(errno)); goto ERROR; } } while (size > 0) { int n = (size > 4096) ? 4096 : size; int nread = read(fd, buffer, n); if (nread < 0) { fprintf(stderr, "read failed: %s\n", strerror(errno)); goto ERROR; } if (nread == 0) break; write(1, buffer, nread); size -= nread; } ptrace(PTRACE_DETACH, pid, NULL, NULL); return 0; ERROR: ptrace(PTRACE_DETACH, pid, NULL, NULL); return 1; }