add strscan
authorJann Horn <jann@thejh.net>
Tue, 14 Jul 2015 14:56:08 +0000 (16:56 +0200)
committerJann Horn <jann@thejh.net>
Tue, 14 Jul 2015 14:56:08 +0000 (16:56 +0200)
tools/strscan.c [new file with mode: 0644]

diff --git a/tools/strscan.c b/tools/strscan.c
new file mode 100644 (file)
index 0000000..6060969
--- /dev/null
@@ -0,0 +1,63 @@
+// scans process memory for a given string, prints offsets of occurences
+// will ignore matches where the match is split over a mapping boundary
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <stdio.h>
+#include <assert.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <jh.h>
+#include <stdbool.h>
+#include <string.h>
+
+struct range {
+  void *a, *b;
+  char *line;
+};
+
+struct range *mappings;
+size_t mappings_used = 0;
+#define FOR_EACH_MAPPING FOR_EACH_IN_ARRAY(mappings, mappings_used, mapping)
+
+bool is_mapped(void *addr) {
+  FOR_EACH_MAPPING
+    if (mapping->a <= addr && mapping->b > addr) return true;
+  return false;
+}
+
+int main(int argc, char **argv) {
+  // init
+  if (argc != 3) xperror("invocation: anondump <pid> <searchstr>", 0);
+  TPRINTF(maps_path, "/proc/%s/maps", argv[1])
+  char *maps = CHK_PTR(slurp_file(maps_path, NULL, JH_SLURP_NO_STAT), "unable to read /proc/$pid/maps", 1);
+  TPRINTF(mem_path, "/proc/%s/mem", argv[1])
+  int memfd = fail_on_neg(open(mem_path, O_RDONLY), "unable to open /proc/$pid/mem", 1);
+
+  size_t n_mappings = count_char_occurences(maps, '\n');
+  mappings = CHK_PTR(calloc(n_mappings, sizeof(struct range)), "memory allocation failed", 1);
+
+  // do magic
+  for (char *line = strtok(maps, "\n"); line != NULL; line = strtok(NULL, "\n")) {
+    struct range *mapping = &mappings[mappings_used++];
+    mapping->line = CHK_PTR(strdup(line), "memory allocation failed", 1);
+    if (sscanf(line, "%p-%p", &mapping->a, &mapping->b) != 2) xperror("sscanf failed", 0);
+  }
+
+  FOR_EACH_MAPPING {
+    size_t len = mapping->b - mapping->a;
+    char *copy = CHK_PTR(malloc(len), "malloc failed", 1);
+    if (pread(memfd, copy, len, (off_t)mapping->a) != (ssize_t)len) xperror("pread failed", 0);
+    size_t pos = 0;
+    while (1) {
+      char *ptr = memmem(copy + pos, len, argv[2], strlen(argv[2]));
+      if (ptr == NULL) break;
+      pos = ptr - copy;
+      printf("at %p in %s\n", mapping->a + pos, mapping->line);
+      pos++;
+    }
+    free(copy);
+  }
+
+  return 0;
+}