1 // scans process memory for a given string, prints offsets of occurences
2 // will ignore matches where the match is split over a mapping boundary
16 ssize_t getmem(pid_t pid, void *dst, void *src, size_t len) {
18 struct iovec local = {.iov_base = dst, .iov_len = len};
19 struct iovec remote = {.iov_base = src, .iov_len = len};
20 return process_vm_readv(pid, &local, 1, &remote, 1, 0);
29 struct range *mappings;
30 size_t mappings_used = 0;
31 #define FOR_EACH_MAPPING FOR_EACH_IN_ARRAY(mappings, mappings_used, mapping)
33 bool is_mapped(void *addr) {
35 if (mapping->a <= addr && mapping->b > addr) return true;
39 int main(int argc, char **argv) {
41 if (argc != 3) xperror("invocation: anondump <pid> <searchstr>", 0);
42 TPRINTF(maps_path, "/proc/%s/maps", argv[1])
43 char *maps = CHK_PTR(slurp_file(maps_path, NULL, JH_SLURP_NO_STAT), "unable to read /proc/$pid/maps", 1);
45 pid_t target = atoi(argv[1]);
47 size_t n_mappings = count_char_occurences(maps, '\n');
48 mappings = CHK_PTR(calloc(n_mappings+1, sizeof(struct range)), "memory allocation failed", 1);
51 for (char *line = strtok(maps, "\n"); line != NULL; line = strtok(NULL, "\n")) {
52 struct range *mapping = &mappings[mappings_used++];
53 mapping->line = CHK_PTR(strdup(line), "memory allocation failed", 1);
54 if (sscanf(line, "%p-%p %c", &mapping->a, &mapping->b, &mapping->readable) != 3) xperror("sscanf failed", 0);
55 assert(mapping->readable == 'r' || mapping->readable == '-');
59 //fprintf(stderr, "%s\n", mapping->line);
60 if (mapping->readable == '-') continue; /* guard page */
61 if (strchr(mapping->line, '/') == NULL && strstr(mapping->line, "[vvar]") != NULL) continue; /* vvar mapping is weird */
62 size_t len = mapping->b - mapping->a;
63 //printf("a=0x%llx b=0x%llx len=0x%llx\n", (unsigned long long)mapping->a, (unsigned long long)mapping->b, (unsigned long long)len);
64 char *copy = CHK_PTR(malloc(len), "malloc failed", 1);
66 if ((read_res=getmem(target, copy, mapping->a, len)) != len) {
68 fputs("warning: some read failed\n", stderr);
72 perror("warning: some read failed");
78 char *ptr = memmem(copy + pos, len - pos, argv[2], strlen(argv[2]));
79 if (ptr == NULL) break;
81 printf("at %p in %s\n", mapping->a + pos, mapping->line);