commit 8fde78de2cf95793fe4aed00b899aca2695164b6
Author: Louis Burda <quent.burda@gmail.com>
Date: Wed, 21 Sep 2022 00:51:10 +0200
Initial version
Diffstat:
3 files changed, 102 insertions(+), 0 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1 @@
+findhex
diff --git a/Makefile b/Makefile
@@ -0,0 +1,9 @@
+
+all: findhex
+
+clean:
+ rm -f findhex
+
+findhex: findhex.c
+
+.PHONY: all clean
diff --git a/findhex.c b/findhex.c
@@ -0,0 +1,92 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <stdarg.h>
+
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+void
+die(const char *msg, ...)
+{
+ va_list ap;
+
+ va_start(ap, msg);
+ vfprintf(stderr, "%s\n", ap);
+ va_end(ap);
+
+ exit(1);
+}
+
+int
+main(int argc, const char **argv)
+{
+ uint8_t *pattern, *pattern_mask;
+ size_t patlen;
+ uint8_t *buf;
+ size_t buflen;
+ ssize_t nread;
+ size_t i, k;
+ size_t pos, off;
+ size_t arglen;
+ FILE *file;
+
+ setvbuf(stdout, NULL, _IONBF, 0);
+
+ if (argc < 2 || argc > 3) die("Usage: findhex PATTERN [FILE]");
+
+ arglen = strlen(argv[1]);
+ if (!arglen || arglen % 2 != 0)
+ die("Pattern length invalid");
+ patlen = arglen / 2;
+
+ pattern = calloc(patlen, 1);
+ pattern_mask = calloc(patlen, 1);
+ if (!pattern || !pattern_mask) die("Out of Memory");
+
+ buflen = MAX(patlen * 2, 16 * 1024);
+ buf = malloc(buflen);
+ if (!buf) die("Out of Memory");
+
+ for (i = 0; i < arglen; i += 2) {
+ if (!strncmp(argv[1] + i, "__", 2))
+ continue;
+ if (!sscanf(argv[1] + i, "%02hX", &pattern[i / 2]))
+ die("Invalid hex in pattern");
+ pattern_mask[i / 2] = 0xff;
+ }
+
+ if (argc == 3) {
+ file = fopen(argv[1], "r");
+ if (!file) die("Failed to open file");
+ } else {
+ file = stdin;
+ }
+
+ off = patlen > 0 ? patlen - 1 : 0;
+ if (fread(buf, 1, off, file) != off)
+ exit(0);
+
+ pos = 0;
+ while (1) {
+ nread = fread(buf + off, 1, buflen - off, file);
+ if (nread == 0) break;
+ if (nread < 0) die("%016llX: Read failed", pos);
+
+ for (i = 0; i <= nread + off - patlen; i++) {
+ for (k = 0; k < patlen; k++) {
+ if (!pattern_mask[k])
+ continue;
+ if (buf[i+k] != pattern[k])
+ break;
+ }
+ if (k == patlen)
+ printf("%016llX\n", pos + i);
+ }
+
+ pos += nread;
+ memcpy(buf, buf + buflen - off, off);
+ }
+
+ fclose(file);
+}