diff --git a/src/Makefile b/src/Makefile
index 8be6c3dc1933c971c9917393962629d1f5b42714..70f6e4b4dc53a5d34f6d0007cdb94254e45dc16c 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -9,7 +9,7 @@ INCLUDES := -I$(OUTPUT) -idirafter $(abspath ../libbpf/include)
 CFLAGS := -g -Wall
 ARCH := $(shell uname -m | sed 's/x86_64/x86/')
 
-APPS = minimal bootstrap uprobe task task_bulk task_mmap task_sleep task_bulk_minimal task_ag task_find task_find_magic
+APPS = minimal bootstrap uprobe task task_bulk task_mmap task_sleep task_bulk_minimal task_ag task_find task_filter_magic
 
 # Get Clang's default includes on this system. We'll explicitly add these dirs
 # to the includes list when compiling with `-target bpf` because otherwise some
diff --git a/src/task-find-magic b/src/task-find-magic
new file mode 100755
index 0000000000000000000000000000000000000000..a97489ec4c5adee70c69b99dae9b176972d42433
--- /dev/null
+++ b/src/task-find-magic
@@ -0,0 +1,9 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+path=$1
+args=${@:2}
+
+src_dir=$(dirname "$(command -v $0)")
+
+find "${path}" | env -C "$src_dir" ./task_filter_magic ${args}
diff --git a/src/task_find_magic.bpf.c b/src/task_filter_magic.bpf.c
similarity index 100%
rename from src/task_find_magic.bpf.c
rename to src/task_filter_magic.bpf.c
diff --git a/src/task_find_magic.c b/src/task_filter_magic.c
similarity index 57%
rename from src/task_find_magic.c
rename to src/task_filter_magic.c
index ff69d61eda637d2e60eb48d02181761253eb57a4..45a0c7a1fe4af4777e55a691d58743baa79744f2 100644
--- a/src/task_find_magic.c
+++ b/src/task_filter_magic.c
@@ -19,11 +19,11 @@
 #include <sys/resource.h>
 #include <bpf/libbpf.h>
 
-#define NAME task_find_magic
-#define NAME_BPF task_find_magic_bpf
-#define BPF_OPEN task_find_magic_bpf__open
-#define BPF_LOAD task_find_magic_bpf__load
-#define BPF_DESTROY task_find_magic_bpf__destroy
+#define NAME task_filter_magic
+#define NAME_BPF task_filter_magic_bpf
+#define BPF_OPEN task_filter_magic_bpf__open
+#define BPF_LOAD task_filter_magic_bpf__load
+#define BPF_DESTROY task_filter_magic_bpf__destroy
 
 /* https://stackoverflow.com/questions/5873722/c-macro-dynamic-include */
 #define __header(x) #x
@@ -144,18 +144,8 @@ static void plog(const unsigned int level, const char *fmt, ...) {
 	va_end(args);
 }
 
-static int search_buf_user(const char *buf, size_t f_len, const char *file_full_path,
-		      const char *literal) {
-	size_t literal_len = strlen(literal);
-	for (int i = 0; i < f_len - literal_len + 1; i++) {
-		if (!memcmp(buf + i, literal, literal_len))
-			printf("%d\n", i);
-	}
-	return EXIT_SUCCESS;
-}
-
 static int search_buf_bpf(const char *buf, size_t f_len, const char *file_full_path,
-			  const char *literal) {
+			  const char *magic) {
 	struct NAME_BPF *skel;
 	int err;
 
@@ -191,118 +181,60 @@ destroy:
 	return EXIT_SUCCESS;
 }
 
-static int search_buf(const char *buf, size_t f_len, const char *file_full_path,
-		      const char *literal, bool variant_bpf) {
-	if (variant_bpf) {
-		return search_buf_bpf(buf, f_len, file_full_path, literal);
-	} else {
-		return search_buf_user(buf, f_len, file_full_path, literal);
-	}
+static char *safe_fgets(char *s, int size, FILE *stream) {
+    char *res = fgets(s, size, stream);
+    if (res == NULL && ferror(stream)) {
+        perror("fgets");
+        exit(EXIT_FAILURE);
+    }
+    return res;
 }
 
-static int search_file(const char *file_full_path, const char *literal, bool variant_bpf) {
-	int err = EXIT_SUCCESS;
-	int fd = -1;
-	off_t f_len = 0;
-	char *buf = NULL;
-	struct stat statbuf;
-	int rv = 0;
-	int matches_count = -1;
-	FILE *fp = NULL;
-
-	rv = stat(file_full_path, &statbuf);
-	if (rv != 0) {
-		log_err("Skipping %s: Error fstat()ing file.", file_full_path);
-		err = EXIT_FAILURE;
-		goto cleanup;
-	}
-
-	// handling only regular files and FIFOs
-	if (!S_ISREG(statbuf.st_mode) && !S_ISFIFO(statbuf.st_mode)) {
-		log_err("Skipping %s: Mode %u is not a file.", file_full_path, statbuf.st_mode);
-		err = EXIT_FAILURE;
-		goto cleanup;
-	}
-
-	fd = open(file_full_path, O_RDONLY);
-	if (fd < 0) {
-		/* XXXX: strerror is not thread-safe */
-		log_err("Skipping %s: Error opening file: %s", file_full_path, strerror(errno));
-		err = EXIT_FAILURE;
-		goto cleanup;
-	}
-
-	// repeating stat check with file handle to prevent TOCTOU issue
-	rv = fstat(fd, &statbuf);
-	if (rv != 0) {
-		log_err("Skipping %s: Error fstat()ing file.", file_full_path);
-		err = EXIT_FAILURE;
-		goto cleanup;
-	}
-
-	// handling only regular files and FIFOs
-	if (!S_ISREG(statbuf.st_mode) && !S_ISFIFO(statbuf.st_mode)) {
-		log_err("Skipping %s: Mode %u is not a file.", file_full_path, statbuf.st_mode);
-		err = EXIT_FAILURE;
-		goto cleanup;
-	}
-
-	if (statbuf.st_mode & S_IFIFO) {
-		log_debug("%s is a named pipe. stream searching", file_full_path);
-		err = EXIT_FAILURE;
-		goto cleanup;
-	}
+#define MAX_PATHLEN 512
 
-	f_len = statbuf.st_size;
-
-	buf = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0);
-	if (buf == MAP_FAILED) {
-		log_err("File %s failed to load: %s.", file_full_path, strerror(errno));
-		err = EXIT_FAILURE;
-		goto cleanup;
-	}
-#if HAVE_MADVISE
-	madvise(buf, f_len, MADV_SEQUENTIAL);
-#elif HAVE_POSIX_FADVISE
-	posix_fadvise(fd, 0, f_len, POSIX_MADV_SEQUENTIAL);
-#endif
+static int filter_magic(size_t offset, const char *magic) {
+	while (true) {
+		char pathbuf[MAX_PATHLEN];
+		char *ptr = fgets(pathbuf, MAX_PATHLEN, stdin);
+		if (ptr == NULL) {
+			if (ferror(stdin)) {
+				log_err("fgets(stdin) failed");
+				return EXIT_FAILURE;
+			} else {
+				log_debug("EOF reached");
+				return EXIT_SUCCESS;
+			}
+		}
 
-	search_buf(buf, f_len, file_full_path, literal, variant_bpf);
+		pathbuf[strlen(pathbuf)] = '\0';
 
-cleanup:
-	if (buf != NULL) {
-		if (buf != MAP_FAILED) {
-			munmap(buf, f_len);
-		}
-	}
-	if (fd != -1) {
-		close(fd);
+		log_debug("pathbuf = %s", pathbuf);
 	}
-
-	return err;
 }
 
 int main(int argc, char **argv)
 {
-	bool variant_bpf = true;
-	bool fixed_strings = false; /* literal */
 	bool debug = false;
-	char *literal;
-	char *path;
+	bool variant_bpf = true;
+	size_t offset = 0;
+	char *magic;
 
 	int c;
 	opterr = 0;
-	while ((c = getopt(argc, argv, "v:" "F" "D")) != -1) {
+	while ((c = getopt(argc, argv, "v:" "D" "o:" "m:")) != -1) {
 		switch (c) {
 		case 'v':
 			variant_bpf = strcmp("bpf", optarg) == 0;
 			break;
-		case 'F':
-			fixed_strings = true;
-			break;
 		case 'D':
 			debug = true;
 			break;
+		case 'o':
+			offset = atoi(optarg);
+			break;
+		case 'm':
+			magic = optarg;
+			break;
 		case '?':
 			if (optopt == 'v') {
 				fprintf(stderr, "Option -%c requires an argument.\n", optopt);
@@ -317,19 +249,17 @@ int main(int argc, char **argv)
 			return EXIT_FAILURE;
 		}
 	}
-	if (optind != argc - 2 || !fixed_strings) {
+	if (optind != argc) {
 		print_usage(argv);
 		return EXIT_FAILURE;
-	} else {
-		literal = argv[optind];
-		path = argv[optind+1];
 	}
 
 	if (debug) {
 		set_log_level(LOG_LEVEL_DEBUG);
-		fprintf(stderr, "%s: variant_bpf=%d, fixed_strings=%d, debug=%d, literal='%s', path='%s'\n",
-			argv[0], variant_bpf, fixed_strings, debug, literal, path);
+		fprintf(stderr, "%s: variant_bpf=%d, debug=%d, magic='%s', offset='%llu'\n",
+			argv[0], variant_bpf, debug, magic, offset);
 	}
 
-	return search_file(path, literal, variant_bpf);
+
+	filter_magic(offset, magic);
 }
diff --git a/src/task_find_magic.h b/src/task_filter_magic.h
similarity index 100%
rename from src/task_find_magic.h
rename to src/task_filter_magic.h