Created
July 7, 2014 10:58
-
-
Save blindFS/c0a1e45d14f069e4f653 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <string.h> | |
#include <regex.h> | |
#include <stdlib.h> | |
#include <sys/types.h> | |
#include <signal.h> | |
#include <sys/stat.h> | |
#include <unistd.h> | |
#include <fcntl.h> | |
int pid; | |
const char *p_heap = "([0-9A-Fa-f]+)-([0-9A-Fa-f]+) [-r].*heap"; | |
const char *p_stack = "([0-9A-Fa-f]+)-([0-9A-Fa-f]+) [-r].*stack"; | |
char n_mem[20], n_map[20]; | |
int find_boundary(long *start, long *end, const char *regex) { | |
regex_t ss; | |
char *line = NULL; | |
size_t len = 0; | |
regmatch_t matchptr[2]; | |
if (regcomp(&ss, regex, REG_EXTENDED)) { | |
perror("failed to compile the regexp...\n"); | |
return 2; | |
} | |
FILE *maps = fopen(n_map, "r"); | |
if (maps == NULL) { | |
perror("failed to open maps file ... maybe no such pid \n"); | |
return 1; | |
} | |
while (getline(&line, &len, maps) != -1) { | |
if (regexec(&ss, line, 3, matchptr, 0) == 0) { | |
puts(line); | |
int i; | |
for (i = 1; i < 3; i++) { | |
int size = matchptr[i].rm_eo-matchptr[i].rm_so; | |
char *buf = malloc(size); | |
memcpy(buf, &line[matchptr[i].rm_so], size); | |
buf[size] = '\0'; | |
if (i == 1) { | |
*start = strtol(buf, NULL, 16); | |
printf("start: %ld\n", *start); | |
} else { | |
*end = strtol(buf, NULL, 16); | |
printf("end: %ld\n", *end); | |
} | |
} | |
break; | |
} | |
} | |
if (line) | |
free(line); | |
regfree(&ss); | |
fclose(maps); | |
return 0; | |
} | |
void dump_to_file(int start, int end, char *fn) { | |
int mem_fd, core_fd; | |
int size = end - start; | |
char *buff = (char *)malloc(size); | |
printf("reading %d bytes from /proc/%d/mem\n", size, pid); | |
mem_fd = open(n_mem, O_RDONLY); | |
core_fd = open(fn, O_RDWR | O_CREAT); | |
lseek(mem_fd, start, SEEK_SET); | |
read(mem_fd, buff, size); | |
write(core_fd, buff, size); | |
free(buff); | |
close(mem_fd); | |
close(core_fd); | |
} | |
int main(int argc, char const* argv[]) | |
{ | |
if (argc != 2){ | |
puts("Usage: memdump pid\n"); | |
return -1; | |
} | |
pid = atoi(argv[1]); | |
printf("get pid %d\n", pid); | |
sprintf(n_mem, "/proc/%d/mem", pid); | |
sprintf(n_map, "/proc/%d/maps", pid); | |
if (kill(pid, SIGSTOP) == -1) { | |
printf("failed to sleep the process %d\n", pid); | |
return -3; | |
} | |
long off_start = 0, off_end = 0; | |
if (find_boundary(&off_start, &off_end, p_heap) != 0) { | |
perror(" find_boundary heap fails ... \n"); | |
return -4; | |
} | |
if (off_end != off_start) | |
dump_to_file(off_start, off_end, "./heap"); | |
if (find_boundary(&off_start, &off_end, p_stack) != 0) { | |
perror(" find_boundary stack fails ... \n"); | |
return -4; | |
} | |
if (off_end != off_start) | |
dump_to_file(off_start, off_end, "./stack"); | |
if (kill(pid, SIGCONT) == -1) { | |
printf("failed to sleep the process %d\n", pid); | |
return -4; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment