struct proc_process save_process(pid_t pid,char* name, int nokill) { struct proc_process saved_process; saved_process.name=name; struct list *chunks=malloc(sizeof(struct list)); list_init(chunks); long offset; if (ptrace(PTRACE_ATTACH, pid, NULL, NULL)== -1 && errno) { perror("error attach"); //TODO ERROR return saved_process; } waitpid(pid,0,0); #ifdef X32 fetch_chunks_tls(pid, chunks); #endif fetch_chunks_vma(pid, chunks, &offset); fetch_chunks_fd(pid, chunks); //fetch_chunks_sighand(pid, &chunks); fetch_chunks_regs(pid,chunks); if (nokill) { if (ptrace(PTRACE_CONT, pid, NULL, NULL)== -1 && errno) { perror("error cont"); //TODO ERROR return saved_process; } } else if (ptrace(PTRACE_KILL, pid, NULL, NULL)== -1 && errno) { perror("error kill"); //TODO ERROR return saved_process; } saved_process.chunks = chunks; return saved_process; }
void get_process(pid_t pid, int flags, struct list *process_image, long *bin_offset) { int success = 0; char* pagebackup; struct user_regs_struct r; struct cp_chunk *libcgp; start_ptrace(pid); if (save_registers(pid, &r) < 0) { fprintf(stderr, "Unable to save process's registers!\n"); goto out_ptrace; } /* The order below is very important. Do not change without good reason and * careful thought. */ fetch_chunks_tls(pid, flags, process_image); /* this gives us a scribble zone: */ fetch_chunks_vma(pid, flags, process_image, bin_offset); if (!scribble_zone) { fprintf(stderr, "[-] No suitable scribble zone could be found. Aborting.\n"); goto out_ptrace; } pagebackup = backup_page(pid, (void*)scribble_zone); fetch_chunks_fd(pid, flags, process_image); fetch_chunks_sighand(pid, flags, process_image); fetch_chunks_i387_data(pid, flags, process_image); fetch_chunks_regs(pid, flags, process_image, process_was_stopped); /* add __getpid chunk to the image list, if requested by the user */ if ((flags & REFRESH_PID) && fetch_chunk_libcgp(&libcgp) == 0) list_append(process_image, libcgp); success = 1; restore_page(pid, (void*)scribble_zone, pagebackup); restore_registers(pid, &r); out_ptrace: end_ptrace(pid, flags); if (!success) abort(); }